/*
* Amrita Vishwa Vidyapeetham
* TIFAC-CORE in Cyber Security
* 20CYS181 - Computer Programming Lab Project
* Database Management System with Access Control
* Authors: Akshit Singh, Avi Nair, G Hamsini, Kolluru Sai Supraj
* Created Date: 28-June-2023
* Updated Date: 27-July-2023
*/
//including necessary header files to run the program
#include<stdio.h>
#include<string.h>
#include<sys/stat.h>
#include<ctype.h>
#include<stdlib.h>
#include<dirent.h>
enum login {No_Match, Match};
typedef enum command {create, addrow, display, delete, logout, Exit, list} COMMAND;
//struct to store enum values and their correspond string values, to convert text command recieved as input to enum
const static struct {
COMMAND cmd;
const char *str;
} conversion [] = {
{create, "create"},
{addrow, "addrow"},
{display, "display"},
{delete, "delete"},
{logout, "logout\n"},
{Exit, "exit\n"},
{list, "list\n"}
};
// function to convert string fragment from command to enum
COMMAND str2enum (const char *str)
{
//j, variable to loop
int j;
for (j = 0; j < sizeof (conversion) / sizeof (conversion[0]); ++j)
{
//comparing string to strings stored in struct
if (!strcmp (str, conversion[j].str))
{
//returning respective enum value
return conversion[j].cmd;
}
}
}
//declaring function prototypes
int authenticate_user();
int create_user();
int create_table(char *cmd_part);
int add_row(char *cmd_part);
int display_table(char *cmd_part);
int delete_table(char *cmd_part);
int delete_row(char *cmd_part);
int list_tables();
void encrypt(char *values);
void decrypt(char *values);
//declaring key and current user global variables to be freely used in any function
char key[30], current_user[30];
//main program
int main()
{
//enum to print login result
enum login auth;
//restart label, to continue after one user logs out
restart:
//calling function for user to log in
auth = authenticate_user();
//printing result of authentication/login process
switch (auth)
{
case 0:
printf("Invalid credentials\n");
goto restart;
break;
case 1:
printf("Login successful\n");
break;
}
//going to directory named after current user to access tables more easily
chdir(current_user);
//declaring variable to store command entered
char cmd_str[100], *cmd_part;
//clearing string of garbage values
strcpy(cmd_str, "\0");
//declaring enum to perform functions based on command recieved
COMMAND cmd;
//next command label to continue code after executing one command
nextcmd:
//recieving command as string
printf("USER - %s/ ", current_user);
strcpy(cmd_str, "\0");
fgets(cmd_str, 100, stdin);
//splitting command and getting enum value to use switch case
cmd_part = strtok(cmd_str, " ");
cmd = str2enum(cmd_part);
int res = 0;
//switch case to perform function based on recieved command
switch (cmd)
{
case 0:
cmd_part = strtok(NULL, " ");
res = create_table(cmd_part);
switch (res)
{
case 0:
printf("USER - %s/ Table created successfully\n", current_user);
break;
case 1:
printf("USER - %s/ Table already exists\n", current_user);
break;
case 2:
printf("USER - %s/ Invalid command\n", current_user);
break;
}
goto nextcmd;
break;
case 1:
cmd_part = strtok(NULL, " ");
int add_success = add_row(cmd_part);
switch (add_success)
{
case 0:
printf("USER - %s/ Added row\n", current_user);
break;
case 1:
printf("USER - %s/ Table does not exist\n", current_user);
break;
case 2:
printf("USER - %s/ Invalid command\n", current_user);
break;
}
goto nextcmd;
break;
case 2:
cmd_part = strtok(NULL, " ");
int display_check = display_table(cmd_part);
switch (display_check)
{
case 0:
printf("\nUSER - %s/ Contents displayed\n", current_user);
break;
case 1:
printf("USER - %s/ Table does not exist\n", current_user);
break;
case 2:
printf("USER - %s/ Invalid command\n", current_user);
break;
}
goto nextcmd;
break;
case 3:
int deletion_success;
cmd_part = strtok(NULL, " ");
if (strcmp(cmd_part, "table")==0)
{
cmd_part = strtok(NULL, " \n");
if (cmd_part==NULL)
{
deletion_success = 3;
}
else
{
deletion_success = delete_table(cmd_part);
}
}
else if (strcmp(cmd_part, "row")==0)
{
cmd_part = strtok(NULL, " \n");
if (cmd_part==NULL)
{
deletion_success = 3;
}
else
{
deletion_success = delete_row(cmd_part);
}
}
else
{
deletion_success = 3;
}
switch (deletion_success)
{
case 0:
printf("USER - %s/ Deleted successfully\n", current_user);
break;
case 1:
printf("USER - %s/ Table not found\n", current_user);
break;
case 2:
printf("USER - %s/ Row not found\n", current_user);
break;
case 3:
printf("USER - %s/ Invalid command\n", current_user);
break;
case 4:
printf("USER - %s/ Aborted\n", current_user);
break;
default:
printf("SEGF");
break;
}
goto nextcmd;
break;
case 4:
printf("USER - %s/ Logout Successful\n", current_user);
chdir("..");
chdir("20cys113_Project");
goto restart;
break;
case 5:
break;
case 6:
printf("USER - %s/ List of existing tables - \n", current_user);
int no_of_tables = list_tables();
printf("%d tables successfully listed\n", no_of_tables);
goto nextcmd;
break;
default:
printf("Invalid command\n");
goto nextcmd;
break;
}
}
int authenticate_user()
{
char line[65],username[30], password[30], *u_name, *p_word;
printf("\nUsername-");
scanf("%s", username);
FILE *userlist;
userlist = fopen("userlist.txt", "r");
if (userlist==NULL)
{
printf("Unable to open file");
}
int username_found=0, condition=0;
while (condition == 0)
{
fgets(line, 65, userlist);
if (!feof(userlist))
{
line[strlen(line)-1]='\0';
u_name = strtok(line, ";");
p_word = strtok(NULL, ";");
if (strcmp(u_name, username)==0)
{
username_found = 1;
condition = 1;
}
}
else
{
condition = 1;
}
}
rewind(userlist);
if (username_found==1)
{
printf("Password-");
scanf("\n%s", password);
condition = 0;
while (condition == 0)
{
fgets(line, 65, userlist);
if (!feof(userlist))
{
line[strlen(line)-1]='\0';
u_name = strtok(line, ";");
p_word = strtok(NULL, ";");
if (strcmp(u_name, username)==0)
{
if (strcmp(p_word, password)==0)
{
condition = 1;
strncpy(current_user, username, 30);
strncpy(key, password, strlen(password));
return 1;
}
else
{
condition = 1;
return 0;
}
}
}
else
{
return 2;
}
}
}
else
{
char choice;
printf("User not found, create new? y/n");
scanf("\n%c", &choice);
if (choice=='y')
{
return create_user(username);
}
else
{
return authenticate_user();
}
}
fclose(userlist);
}
int create_user(char username[])
{
int check=0;
for (int i=0; i<strlen(username) ; i++)
{
if (isalnum(username)!=1)
{
check+=1;
}
}
if (check>0)
{
FILE *userlist;
userlist = fopen("userlist.txt", "a");
if (userlist==NULL)
{
printf("Unable to open file");
}
fputs(username, userlist);
fputc(';', userlist);
int loopbreak=1;
char password[30], confirm_pass[30];
do
{
printf("Enter password - ");
scanf("%s", password);
printf("Confirm Password - ");
scanf("%s", confirm_pass);
if (strcmp(password, confirm_pass)==0)
{
fputs(password, userlist);
loopbreak=0;
}
}while(loopbreak!=0);
fputc('\n', userlist);
fclose(userlist);
mkdir(username, 0777);
return 0;
}
else
{
printf("Invalid username");
authenticate_user();
}
}
int create_table(char *cmd_part)
{
FILE *check_table;
char table_name[15];
if (cmd_part!=NULL)
{
strcpy(table_name, "\0");
strncat(table_name, cmd_part, strlen(cmd_part));
strncat(table_name, ".txt", 5);
check_table = fopen(table_name, "r");
if (check_table!=NULL)
return 1;
cmd_part = strtok(NULL, " ");
if (cmd_part == NULL)
return 2;
for (int i = 0; i < strlen(cmd_part); i++)
{
if (*(cmd_part+i)<48 && *(cmd_part+i)>57)
return 2;
}
int no_of_cols = atoi(cmd_part);
char line[150];
strncpy(line, cmd_part, strlen(cmd_part));
strncat(line, ",", 2);
for (int i = 0; i<no_of_cols ; i++)
{
cmd_part= strtok(NULL, " \n ");
if (cmd_part == NULL)
{
return 2;
}
strncat(line, cmd_part, strlen(cmd_part));
strncat(line, ",", 2);
}
FILE *table_fp = fopen(table_name, "w+");
encrypt(line);
strncat(line, "\n", 2);
fputs(line, table_fp);
fclose(table_fp);
return 0;
}
return 2;
}
int add_row(char *cmd_part)
{
FILE *table_fp;
char table_name[15];
if (cmd_part!=NULL)
{
strcpy(table_name, "\0");
strncat(table_name, cmd_part, strlen(cmd_part));
strncat(table_name, ".txt", 5);
table_fp = fopen(table_name, "r+");
if (table_fp==NULL)
{
return 1;
}
char line[150];
fgets(line, 150, table_fp);
decrypt(line);
char col_nos[2];
for (int i = 0; i < strlen(line); i++)
{
if (line[i]==',')
break;
else
col_nos[i] = line[i];
}
int no_of_cols = atoi(col_nos);
int row_count = 0;
while(!feof(table_fp))
{
fgets(line, 150, table_fp);
row_count++;
}
char rowcount[3];
sprintf(rowcount, "%d", row_count);
strcpy(line, "\0");
strncat(line, rowcount, strlen(rowcount));
strncat(line, ",", 2);
for (int i = 0; i<no_of_cols ; i++)
{
cmd_part = strtok(NULL, " \n");
if (cmd_part == NULL)
{
return 2;
}
strncat(line, cmd_part, strlen(cmd_part));
strncat(line, ",", 2);
}
encrypt(line);
strncat(line, "\n", 2);
fputs(line, table_fp);
fclose(table_fp);
return 0;
}
return 2;
}
int display_table(char *cmd_part)
{
FILE *table_fp;
char table_name[15];
if (cmd_part!=NULL)
{
char *table = strtok(cmd_part, "\n");
strcpy(table_name, "\0");
strncat(table_name, table, strlen(table));
strncat(table_name, ".txt", 5);
table_fp = fopen(table_name, "r");
if (table_fp==NULL)
{
return 1;
}
char line[150];
int i=0;
printf("\n\n");
fgets(line, 150, table_fp);
decrypt(line);
while(line[i]!=',')
{
i++;
printf("0");
}
printf(" | ");
int count = 3;
i++;
while(i<strlen(line))
{
if (line[i]==',')
{
printf(" | ");
}
else
{
printf("%c", line[i]);
}
i++;
count++;
}
for(int j = 0 ; j<count; j++)
{
printf("__");
}
printf("\n");
while(!feof(table_fp))
{
strcpy(line,"\0");
fgets(line, 150, table_fp);
decrypt(line);
i=0;
while (i<strlen(line))
{
if (line[i]==',')
{
printf(" | ");
}
else
{
printf("%c", line[i]);
}
i++;
}
}
return 0;
}
return 2;
}
int delete_table(char *cmd_part)
{
FILE *table_fp;
char table_name[15];
printf("%s", cmd_part);
strcpy(table_name, "\0");
strncat(table_name, cmd_part, strlen(cmd_part));
strncat(table_name, ".txt", 5);
table_fp = fopen(table_name, "r");
if (table_fp==NULL)
{
return 1;
}
char confirm = '0';
printf("confirm delete table? y/n");
confirm = getchar();
if (confirm == 'y' || confirm == 'Y')
{
remove(table_name);
return 0;
}
else
{
return 4;
}
}
int delete_row(char *cmd_part)
{
int depression = 0, depressed = 0;
char *row_num = strtok(NULL, " \n");
printf("%s\n", row_num);
for (int i = 0; i < strlen(row_num); i++)
{
if (*(row_num+i)<48 || *(row_num+i)>57)
{
return 3;
}
}
FILE *table_fp;
char table_name[15];
strcpy(table_name, "\0");
strncat(table_name, cmd_part, strlen(cmd_part));
strncat(table_name, ".txt", 5);
printf("%s\n", table_name);
table_fp = fopen(table_name, "r");
if (table_fp==NULL)
{
return 1;
}
char confirm[3];
printf("confirm delete row? y/n");
fgets(confirm, 3, stdin);
char line[150], check_row_num[4], a[2];
int check;
if (confirm[0] == 'y' || confirm[0] == 'Y')
{
FILE *tempfile = fopen("temp.txt", "w");
fgets(line, 149, table_fp);
fputs(line, tempfile);
while(!feof(table_fp))
{
strcpy(check_row_num, "\0");
strcpy(line, "\0");
fgets(line, 150, table_fp);
decrypt(line);
check = 0;
while(line[check]!=',')
{
a[0] = line[check];
a[1] = '\0';
strncat(check_row_num, a, 3);
check++;
}
printf("%s %s", check_row_num, row_num);
if (strcmp(check_row_num, row_num)!=0)
{
fputs(line, tempfile);
depression++;
}
}
fclose(tempfile);
fclose(table_fp);
remove(table_name);
table_fp = fopen(table_name, "w");
tempfile = fopen("temp.txt", "r");
printf("--\n");
while(!feof(tempfile))
{
strcpy(line, "\0");
fgets(line, 150, tempfile);
fputs(line, stdout);
}
rewind(tempfile);
int lci = 1, comma_check;
char lc[3];
strcpy(line, "\0");
fgets(line, 150, tempfile);
fputs(line, table_fp);
while(!feof(tempfile) && depressed < depression-1)
{
sprintf(lc, "%d", lci);
strcpy(line, "\0");
fgets(line, 150, tempfile);
comma_check = 0;
while(line[comma_check]!=',')
{
if (lc[comma_check]!='\0')
{
line[comma_check] = lc[comma_check];
}
else
{
line[comma_check] = '\0';
}
comma_check++;
}
encrypt(line);
fputs(line, table_fp);
lci++;
depressed++;
}
fclose(tempfile);
fclose(table_fp);
remove("temp.txt");
return 0;
}
else
{
return 4;
}
}
int list_tables()
{
int count = 0;
struct dirent *d;
DIR *dr = opendir(".");
while ((d= readdir(dr)) != NULL)
{
if ((strcmp(d->d_name, ".")!=0) && (strcmp(d->d_name, "..")!=0))
{
printf("%d . %s \n", count+1, d->d_name);
count++;
}
}
closedir(dr);
return count;
}
void encrypt(char *values)
{
for (int i=0; i<strlen(values); i++)
{
if (i>=strlen(key))
{
*(values+i) += key[(i%strlen(key))];
}
else
{
*(values+i) += key[i];
}
}
}
void decrypt(char *values)
{
for (int i=0; i<strlen(values)-1; i++)
{
if (i>=strlen(key))
{
*(values+i) -= key[(i%strlen(key))];
}
else
{
*(values+i) -= key[i];
}
}
}