You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
550 lines
14 KiB
550 lines
14 KiB
/*
|
|
|
|
Twiki! The Small Wiki!
|
|
|
|
This file is the final version of the wiki. This will be submitted, if all goes well.
|
|
|
|
Version 1.4
|
|
|
|
Author : Aaruni Kaushik ( aaruni@krow.me | http://u.krow.me/1197 )
|
|
|
|
I'll make you an offer you can't refuse.
|
|
|
|
*/
|
|
|
|
#include<iostream> //for basic I/O operations
|
|
#include<fstream> //for file I/O operations
|
|
#include<unistd.h> //for getpass()
|
|
#include<string.h> //for string type related operations
|
|
#include<cstdlib> //for system calls
|
|
#include<ctype.h> //for character type related operations
|
|
#include<time.h> //for timestamps in logs.
|
|
|
|
using namespace std; //to avoid std::cin, std::cout, std::fstream, etc.
|
|
|
|
char uname[1024]; //for logging user name
|
|
int hash[256]; //required for hash1 and hash2
|
|
|
|
int hash1(); //required for register
|
|
int hash2(); //required for login
|
|
int hashi(); //required for initializing the password database
|
|
int index(); //required for search
|
|
int login(); //login function
|
|
int logout(); //logout function
|
|
int registeR(); //new user register function
|
|
int convert (char *); //required for hash1 and hash2
|
|
|
|
class io
|
|
{
|
|
char out[1024],in[4096],ch,ttl[1024],fint[4096]; //large sizes because I have plent of RAM to spare.
|
|
int flag;
|
|
fstream outfile; //fstream object because I use ios::in to check whether or not the file exists.
|
|
ifstream infile;
|
|
ifstream obj;
|
|
ofstream log; //because you always only append to the logfile. overwriting logfile = phail.
|
|
time_t rawtime; //for timestamps for logfile
|
|
struct tm * timeinfo; //for timestamps for logfile
|
|
|
|
public:
|
|
io()
|
|
{
|
|
strcpy(in,"\0");
|
|
strcpy(ttl,"\0");
|
|
ch='\0';
|
|
strcpy(fint,"./content/data/");
|
|
flag=0;
|
|
infile.open("index.out");
|
|
obj.open("index.out");
|
|
log.open("./content/logs/log.log",ios::app);
|
|
}
|
|
|
|
int write(); //write/append file function
|
|
int read(); //read file function
|
|
int prindex(); //prints the content of index file to screen
|
|
int search(); //search function
|
|
};
|
|
|
|
int main()
|
|
{
|
|
strcpy(uname,"\0"); //pre-requisite section
|
|
int ch,logged=1;
|
|
io obj;
|
|
ofstream log("./content/logs/log.log",ios::app); //because you always only append to the logfile. overwriting logfile = phail.
|
|
time_t rawtime; //timestamps for logfile
|
|
struct tm * timeinfo; //timestamps for logfile
|
|
|
|
time (&rawtime);
|
|
timeinfo = localtime (&rawtime);
|
|
log<<asctime(timeinfo)<<'\t'<<"Begin logging to file "<<endl;
|
|
index();
|
|
|
|
cout<<"\n\n\t\tWelcome to Twiki!\n\n\n";
|
|
while(1)
|
|
{
|
|
cout<<"\n\n\t\tMenu\n";
|
|
cout<<"\t1.Sign Up\n\t2.Sign In\n\t3.List Files\n\t4.View File\n\t5.Write File\n\t6.Search File\n\t7.Log Out\n\t8.Exit\n\n";
|
|
cin>>ch;
|
|
cout<<endl<<endl;
|
|
switch (ch)
|
|
{
|
|
case 1:
|
|
registeR();
|
|
break;
|
|
case 2:
|
|
if(!logged)
|
|
{
|
|
cout<<"You are already logged in. Please sign out and then sign in as another user\n";
|
|
time (&rawtime);
|
|
timeinfo = localtime (&rawtime);
|
|
log<<asctime(timeinfo)<<'\t'<<uname<<'\t'<<"tried to sign in again "<<endl;
|
|
break;
|
|
}
|
|
logged=login(); //to ascertain whether the user has logged in
|
|
break;
|
|
|
|
case 3:
|
|
obj.prindex();
|
|
break;
|
|
case 4:
|
|
obj.read();
|
|
break;
|
|
case 5:
|
|
if(!logged)
|
|
{
|
|
obj.write();
|
|
index();
|
|
}
|
|
else
|
|
{
|
|
cout<<"Please log in to open the file in edit mode\n\n";
|
|
time (&rawtime);
|
|
timeinfo = localtime (&rawtime);
|
|
log<<asctime(timeinfo)<<'\t'<<"Write blocked. User not logged in "<<endl;
|
|
|
|
}
|
|
break;
|
|
case 6:
|
|
obj.search();
|
|
break;
|
|
case 7:
|
|
logged=logout(); //to ascertain whether the user has logged out
|
|
break;
|
|
case 8:
|
|
cout<<"Goodbye!\n";
|
|
time (&rawtime);
|
|
timeinfo = localtime (&rawtime);
|
|
log<<asctime(timeinfo)<<'\t'<<"End of log "<<endl;
|
|
return 0;
|
|
|
|
default:
|
|
cout<<"Please input a valid chooice\n";
|
|
time (&rawtime);
|
|
timeinfo = localtime (&rawtime);
|
|
log<<asctime(timeinfo)<<'\t'<<"Invalid choice entered by user";
|
|
if(!logged)
|
|
{
|
|
cout<<"\t"<<uname<<endl;
|
|
}
|
|
else
|
|
cout<<endl;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
int io::read()
|
|
{
|
|
cout<<"Please enter the filename to be opened\n";
|
|
cin.getline(ttl,1024); //this is simply to flush out the input buffer from the previous cin operation
|
|
cin.getline(ttl,1024); //this one actually gets the input
|
|
strcpy(fint,"./content/data/");
|
|
strcat(fint,ttl);
|
|
infile.close(); //object is shared between the class functions. hence needs to be closed and re-opened
|
|
infile.open(fint);
|
|
if(infile) //stores non-null if file is opened.
|
|
{
|
|
time (&rawtime);
|
|
timeinfo = localtime (&rawtime);
|
|
log<<asctime(timeinfo)<<'\t'<<"File\t"<<ttl<<"\tsuccesfully opened for reading."<<endl;
|
|
infile.getline(out,80);
|
|
}
|
|
else
|
|
{
|
|
time (&rawtime);
|
|
timeinfo = localtime (&rawtime);
|
|
log<<asctime(timeinfo)<<'\t'<<"Error : File\t"<<ttl<<"\tdoes not exist."<<endl;
|
|
cout<<"File does not exist\n";
|
|
cout<<fint<<endl;
|
|
return 1;
|
|
}
|
|
|
|
while(!infile.eof())
|
|
{
|
|
cout<<out<<endl;
|
|
infile.getline(out,80);
|
|
}
|
|
cout<<endl;
|
|
return 0;
|
|
}
|
|
|
|
int io::write()
|
|
{
|
|
cout<<"Please enter the title of the file\n";
|
|
cin.getline(ttl,1024); //this is simply to flush out the input buffer from the previous cin operation
|
|
cin.getline(ttl,1204); //this one actually gets the input
|
|
strcpy(fint,"./content/data/");
|
|
strcat(fint,ttl);
|
|
outfile.open(fint,ios::in);
|
|
if(!outfile) // if open fails, the stream objects stores Null(zero) value.
|
|
{
|
|
time (&rawtime);
|
|
timeinfo = localtime (&rawtime);
|
|
log<<asctime(timeinfo)<<'\t'<<"Created file\t"<<ttl<<"\tby user\t"<<uname<<endl;
|
|
outfile.open(fint,ios::out);
|
|
}
|
|
else
|
|
{
|
|
outfile.open(fint,ios::in);
|
|
if(!outfile)
|
|
{
|
|
cout<<"The file exists. Replace file?\n";
|
|
cin>>ch;
|
|
flag=1;
|
|
if(toupper(ch)=='Y')
|
|
{
|
|
outfile.close();
|
|
outfile.open(fint,ios::out); //ios::out replaces the good file
|
|
time (&rawtime);
|
|
timeinfo = localtime (&rawtime);
|
|
log<<asctime(timeinfo)<<'\t'<<"Opened file for overwriting"<<"\tby user\t"<<uname<<endl;
|
|
time (&rawtime);
|
|
timeinfo = localtime (&rawtime);
|
|
log<<asctime(timeinfo)<<'\t'<<"Overwrote file\t"<<ttl<<"\tby user\t"<<uname<<endl;
|
|
}
|
|
else
|
|
{
|
|
outfile.close();
|
|
outfile.open(fint,ios::out|ios::app); //ios::app appends to the file. we aint replacing stuff.
|
|
time (&rawtime);
|
|
timeinfo = localtime (&rawtime);
|
|
log<<asctime(timeinfo)<<'\t'<<"Opened file\t"<<ttl<<"\tfor appending by user\t"<<uname<<endl;
|
|
time (&rawtime);
|
|
timeinfo = localtime (&rawtime);
|
|
log<<asctime(timeinfo)<<'\t'<<"Appending to file\t"<<ttl<<"\tby user\t"<<uname<<endl;
|
|
}
|
|
}
|
|
}
|
|
cout<<"Please enter file contents (Enter to submit)\n";
|
|
if(flag)
|
|
cin.getline(in,4096); //this is simply to flush out the input buffer from the previous cin operation
|
|
cin.getline(in,4096); //this one actually gets the input
|
|
outfile<<in<<endl;
|
|
outfile.close();
|
|
time (&rawtime);
|
|
timeinfo = localtime (&rawtime);
|
|
log<<asctime(timeinfo)<<'\t'<<"Closed file\t"<<ttl<<"\tafter output operation by user\t"<<uname<<endl;
|
|
return 0;
|
|
}
|
|
|
|
int io::search()
|
|
{
|
|
char in[256],out[256];
|
|
int flag=0;
|
|
ifstream infile("index.out");
|
|
ofstream log("./content/logs/log.log",ios::app); //because you always only append to the logfile. overwriting logfile = phail.
|
|
time_t rawtime; //timestamps for logfile
|
|
struct tm * timeinfo; //timestamps for logfile
|
|
|
|
if(!infile) //lel, impossible case
|
|
{
|
|
cout<<"The programmer messed up, and the index isn't created. Go sue him and/or update your copy of the wiki\n";
|
|
time (&rawtime);
|
|
timeinfo = localtime (&rawtime);
|
|
log<<asctime(timeinfo)<<'\t'<<"Fatal error : index file not found "<<endl;
|
|
return 1;
|
|
}
|
|
|
|
cout<<"Please enter the name of file to be searched\n";
|
|
cin.getline(in,256); //this is simply to flush out the input buffer from the previous cin operation
|
|
cin.getline(in,256); //this one actually gets the input
|
|
while(!infile.eof())
|
|
{
|
|
infile.getline(out,256);
|
|
if(strcmp(in,out))
|
|
{
|
|
flag=1;
|
|
}
|
|
else
|
|
{
|
|
cout<<"File "<<out<<" exists!\n";
|
|
time (&rawtime);
|
|
timeinfo = localtime (&rawtime);
|
|
log<<asctime(timeinfo)<<'\t'<<"Search function found a match for\t"<<in<<endl;
|
|
return 0;
|
|
}
|
|
}
|
|
if(flag)
|
|
{
|
|
cout<<"File does not exist\n";
|
|
time (&rawtime);
|
|
timeinfo = localtime (&rawtime);
|
|
log<<asctime(timeinfo)<<'\t'<<"Search function did not find\t"<<in<<endl;
|
|
return 0;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int registeR()
|
|
{
|
|
char in[1024],out[1024];
|
|
int sflag=0;
|
|
ofstream outp("./content/user/user.db",ios::app);
|
|
ifstream check("./content/user/user.db",ios::in);
|
|
ofstream log("./content/logs/log.log",ios::app); //because you always only append to the logfile. overwriting logfile = phail.
|
|
time_t rawtime; //timestamps for logfile
|
|
struct tm * timeinfo; //timestamps for logfile
|
|
|
|
|
|
cout<<"Please enter name for registry\n";
|
|
cin.getline(in,1024); //this is simply to flush out the input buffer from the previous cin operation
|
|
cin.getline(in,1024); //this one actually gets the input
|
|
for(int i=0;in[i]!='\0';i++)
|
|
{
|
|
in[i]=tolower(in[i]);
|
|
}
|
|
check.getline(out,1024);
|
|
while(!check.eof())
|
|
{
|
|
for(int j=0;out[j]!='\0';j++)
|
|
{
|
|
out[j]=tolower(out[j]);
|
|
}
|
|
if(!strcmp(in,out))
|
|
{
|
|
sflag=0;
|
|
break;
|
|
}
|
|
sflag=1;
|
|
check.getline(out,1024);
|
|
}
|
|
|
|
check.close();
|
|
if (!sflag)
|
|
{
|
|
cout<<"The username is already registered\n";
|
|
time (&rawtime);
|
|
timeinfo = localtime (&rawtime);
|
|
log<<asctime(timeinfo)<<'\t'<<"User creation failed. User\t"<<in<<"\talready exists."<<endl;
|
|
return 1;
|
|
}
|
|
outp<<in<<endl;
|
|
hash1();
|
|
time (&rawtime);
|
|
timeinfo = localtime (&rawtime);
|
|
log<<asctime(timeinfo)<<'\t'<<"Created user\t"<<in<<'\t'<<endl;
|
|
return 0;
|
|
}
|
|
|
|
int io::prindex()
|
|
{
|
|
ifstream obj("index.out");
|
|
ofstream log("./content/logs/log.log",ios::app); //because you always only append to the logfile. overwriting logfile = phail.
|
|
char out[1024];
|
|
time_t rawtime; //timestamps for logfile
|
|
struct tm * timeinfo; //timestamps for logfile
|
|
if(!obj) //if directory structure is fine, this is an impossible case.
|
|
{
|
|
time (&rawtime);
|
|
timeinfo = localtime (&rawtime);
|
|
log<<asctime(timeinfo)<<'\t'<<"Fatal error : index could not be opened\n";
|
|
cout<<"Could not open index file for content listing\n";
|
|
return 1;
|
|
}
|
|
|
|
time (&rawtime);
|
|
timeinfo = localtime (&rawtime);
|
|
log<<asctime(timeinfo)<<'\t'<<"Index successfully opened\n";
|
|
obj.getline(out,80);
|
|
while(!obj.eof())
|
|
{
|
|
cout<<out<<endl;
|
|
obj.getline(out,80);
|
|
}
|
|
cout<<endl;
|
|
return 0;
|
|
}
|
|
|
|
int login()
|
|
{
|
|
char in[1024],com[1024],pass[1024];
|
|
int k=0;
|
|
ifstream ob1("./content/user/pass.db"), ob2("./content/user/user.db");
|
|
ofstream log("./content/logs/log.log",ios::app); //because you always only append to the logfile. overwriting logfile = phail.
|
|
time_t rawtime; //timestamps for logfile
|
|
struct tm * timeinfo; //timestamps for logfile
|
|
|
|
cout<<"login\t";
|
|
cin.getline(in,1024); //this is simply to flush out the input buffer from the previous cin operation
|
|
cin.getline(in,1024); //this one actually gets the input
|
|
for(int i=0;in[i]!='\0';i++)
|
|
{
|
|
in[i]=tolower(in[i]);
|
|
}
|
|
while(!ob2.eof())
|
|
{
|
|
ob2.getline(com,1024);
|
|
if(!strcmp(in,com))
|
|
{
|
|
k=0;
|
|
break;
|
|
}
|
|
k=1;
|
|
}
|
|
if(!k)
|
|
{
|
|
hash2();
|
|
ifstream ob3("temp.db");
|
|
ob3.getline(pass,1024);
|
|
while(!ob1.eof())
|
|
{
|
|
ob1.getline(com,1024);
|
|
if(!strcmp(pass,com))
|
|
{
|
|
cout<<"Login Succesful\n";
|
|
remove("temp.db");
|
|
time (&rawtime);
|
|
timeinfo = localtime (&rawtime);
|
|
log<<asctime(timeinfo)<<'\t'<<"Successfully looged in\t"<<in<<endl;
|
|
strcpy(uname,in);
|
|
return 0;
|
|
}
|
|
}
|
|
remove("temp.db");
|
|
cout<<"Bad Password\n";
|
|
time (&rawtime);
|
|
timeinfo = localtime (&rawtime);
|
|
log<<asctime(timeinfo)<<'\t'<<"User\t"<<in<<"\tsubmitted wrong password."<<endl;
|
|
return 1;
|
|
}
|
|
cout<<"User not registered\n";
|
|
time (&rawtime);
|
|
timeinfo = localtime (&rawtime);
|
|
log<<asctime(timeinfo)<<'\t'<<"User\t"<<in<<"\tnot registered"<<endl;
|
|
return 2;
|
|
}
|
|
|
|
int index() //linux specific because of "ls" system call. makes an "index.out" with names of all file in the directory.
|
|
{
|
|
ofstream log("./content/logs/log.log",ios::app); //because you always only append to the logfile. overwriting logfile = phail.
|
|
time_t rawtime; //timestamps for logfile
|
|
struct tm * timeinfo; //timestamps for logfile
|
|
fstream obj;
|
|
ofstream ob;
|
|
|
|
system("ls ./content/data/ > index.out");
|
|
obj.open("./content/user/user.db",ios::in);
|
|
if(!obj)
|
|
{
|
|
ob.open("./content/user/user.db");
|
|
ob<<"admin"<<endl;
|
|
}
|
|
ob.close();
|
|
obj.close();
|
|
obj.open("./content/user/pass.db",ios::in);
|
|
if(!obj)
|
|
{
|
|
ob.open("./content/user/pass.db");
|
|
hashi();
|
|
}
|
|
time (&rawtime);
|
|
timeinfo = localtime (&rawtime);
|
|
log<<asctime(timeinfo)<<'\t'<<"Index successfuly created"<<endl;
|
|
|
|
return 0;
|
|
}
|
|
|
|
int hash1()
|
|
{
|
|
//Hashing algorithm is simple. Converts each caracter to its ascii value, adds an '0x' between them, and stores them in a text file
|
|
char name[256], pass[256];
|
|
ofstream obj("./content/user/pass.db",ios::app);
|
|
|
|
cout<<"login:\t";
|
|
cin.getline(name, 256);
|
|
strcpy(pass,getpass("password:\t"));
|
|
convert(pass);
|
|
for(unsigned int i=0; i<strlen(pass) ;i++)
|
|
{
|
|
obj<<hash[i]<<"0x";
|
|
}
|
|
obj<<endl;
|
|
|
|
return 0;
|
|
}
|
|
|
|
int convert (char p[256]) //hash depends on this function
|
|
{
|
|
int l=strlen(p);
|
|
for (int i=0; i<l; i++)
|
|
{
|
|
hash[i]=int(p[i]);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int hash2() //same as the first hash function, just works on a different file.
|
|
{
|
|
char pass[1024];
|
|
ofstream obj("temp.db");
|
|
|
|
strcpy(pass,getpass("password:\t"));
|
|
convert(pass);
|
|
for(unsigned int i=0; i<strlen(pass) ;i++)
|
|
{
|
|
obj<<hash[i]<<"0x";
|
|
}
|
|
obj<<endl;
|
|
|
|
return 0;
|
|
}
|
|
|
|
int hashi() //basically same as the first and second hash functions, just works on a different file.
|
|
{
|
|
char pass[]="password";
|
|
ofstream obj("./content/user/pass.db");
|
|
|
|
convert(pass);
|
|
for(unsigned int i=0; i<strlen(pass) ;i++)
|
|
{
|
|
obj<<hash[i]<<"0x";
|
|
}
|
|
obj<<endl;
|
|
|
|
return 0;
|
|
}
|
|
|
|
int logout()
|
|
{
|
|
ofstream log("./content/logs/log.log",ios::app); //because you always only append to the logfile. overwriting logfile = phail.
|
|
time_t rawtime; //timestamps for logfile
|
|
struct tm * timeinfo; //timestamps for logfile
|
|
if(!strcmp(uname,"\0"))
|
|
{
|
|
cout<<"Must be logged in to log out!\n";
|
|
|
|
time (&rawtime);
|
|
timeinfo = localtime (&rawtime);
|
|
log<<asctime(timeinfo)<<'\t'<<"Logout function activated, but, can't logout if not logged in!\n";
|
|
return 2; //this is both a non-zero value and an error code
|
|
}
|
|
|
|
time (&rawtime);
|
|
timeinfo = localtime (&rawtime);
|
|
log<<asctime(timeinfo)<<'\t'<<"User\t"<<uname<<"\tlogging out\n";
|
|
strcpy(uname,"\0");
|
|
cout<<"User succesfully logged out!\n";
|
|
time (&rawtime);
|
|
timeinfo = localtime (&rawtime);
|
|
log<<asctime(timeinfo)<<'\t'<<"User logged out succesfully\n";
|
|
return 1; //so that logged variable stores non-zero. is not an error code.
|
|
}
|
|
|