struct-lab-03/handler.h

628 lines
11 KiB
C
Raw Permalink Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#include "include/ui.h"
#include <stdio.h>
#include "structs.h"
#define MAX_ARG_LEN 200
#define OBJECT_WRONG 0
#define OBJECT_FOLDER 1
#define OBJECT_FILE 2
#define SAVEFILENAME "file_tree.save"
int checkCommandValid(char *command)
{
for (size_t i = 0; i < COMMAND_COUNT; i++)
{
if (strcmp(allowedCommands[i], command) == 0)
{
return SUCCESS;
}
}
return FAILURE;
}
int checkMinorArgumentValid(char *command, char *argument)
{
if (argument[1] == 'l' || argument[1] == 'r')
{
if (strlen(argument) == 2)
{
if (!strcmp(command, "ls"))
{
if (argument[1] != 'l')
return FAILURE;
}
else if (!strcmp(command, "rm"))
{
if (argument[1] != 'r')
return FAILURE;
}
else
{
return FAILURE;
}
return SUCCESS;
}
else
{
return FAILURE;
}
}
else
return FAILURE;
}
int checkMajorArgumentValid(char *argument, Folder *RootFolder, Folder *CurrentFolder, Folder **ResultFolder, File **ResultFile)
{
Folder *ptr;
char *path = (char *)malloc(MAX_COMMAND_LEN);
strcpy(path, argument);
// char *sep2 = "$";
// argument = strtok(NULL, sep2);
// printf("i = %d, istr = %s\n", 10, argument);
for (size_t i = 0; i < strlen(path); i++)
{
if (path[i] == '\n')
{
path[i] = '\0';
}
}
if (path[0] == '/')
{
// Абсолютный путь
ptr = RootFolder;
}
else
{
// Относительный путь
ptr = CurrentFolder;
}
char *sep = "/", *istr;
istr = strtok(path, sep);
int foundFlag;
while (istr != NULL)
{
foundFlag = 1;
for (size_t i = 0; i < ptr->folders_count_cur; i++)
{
if (!strcmp(ptr->folders[i].filename, istr))
{
foundFlag = 0;
ptr = &ptr->folders[i];
break;
}
}
// printf("ptr: %s\n", ptr->filename);
if (foundFlag)
{
int isFileFlag = 0;
for (size_t i = 0; i < strlen(istr); i++)
{
if (istr[i] == '.')
{
isFileFlag = 1;
break;
}
}
if (isFileFlag)
{
char *filename = (char *)malloc(filename_lenth + 1);
char *extension = (char *)malloc(extinsion_lenth + 1);
int extFlag = 1;
int writeCount = 0;
for (size_t i = 0; i < strlen(istr); i++) // Отделяем имя файла от расширения
{
if (istr[i] == '.')
{
extFlag = 0;
filename[writeCount + 1] = '\0';
writeCount = 0;
continue;
}
if (extFlag)
{
filename[writeCount] = istr[i];
}
else
{
extension[writeCount] = istr[i];
}
writeCount++;
}
for (size_t i = 0; i < ptr->files_count_cur; i++)
{
if (!strcmp(ptr->files[i].filename, filename) && !strcmp(ptr->files[i].extension, extension))
{
free(path);
free(filename);
free(extension);
*ResultFile = &ptr->files[i];
return OBJECT_FILE;
}
}
free(filename);
free(extension);
}
// printf("Cannot resolve %s\n", istr);
return WRONG_ARGUMENT_FAILURE;
}
istr = strtok(NULL, sep);
}
free(path);
*ResultFolder = ptr;
// printf("--- %d %d\n", ptr, ResultFolder);
return OBJECT_FOLDER;
}
int checkArgumentValid(char *command, char *argument, Folder *RootFolder, Folder *CurrentFolder, Folder **resultFolder, File **resultFile)
{
Folder *_ResultFolder;
File *_ResultFile;
int iResult;
if (argument == NULL)
{
return WRONG_ARGUMENT_FAILURE;
}
if (argument[0] == '-')
{
if (checkMinorArgumentValid(command, argument))
{
return WRONG_OPTION;
}
}
else
{
// Обрабатываем объект
iResult = checkMajorArgumentValid(argument, RootFolder, CurrentFolder, &_ResultFolder, &_ResultFile);
if (iResult == WRONG_ARGUMENT_FAILURE)
{
return WRONG_ARGUMENT_FAILURE;
}
if (iResult == OBJECT_FILE)
{
*resultFile = _ResultFile;
}
if (iResult == OBJECT_FOLDER)
{
*resultFolder = _ResultFolder;
}
}
return SUCCESS;
}
int executeCommand(char *command, char *minorArg, Folder **majorArgFolder, File **majorArgFile, int majorArgIsFolder, Folder *RootFolder, Folder **CurrentFolder)
{
if (!strcmp(command, "cd"))
{
if (!majorArgIsFolder)
{
return FAILURE;
}
*CurrentFolder = *majorArgFolder;
return SUCCESS;
}
else if (!strcmp(command, "ls"))
{
Folder *PrintDirectory;
if (!majorArgIsFolder)
{
PrintDirectory = *CurrentFolder;
}
else
{
PrintDirectory = *majorArgFolder;
}
if (!strcmp(minorArg, "-l"))
print_list(PrintDirectory, 1);
else
print_list(PrintDirectory, 0);
return SUCCESS;
}
else if (!strcmp(command, "rm"))
{
if (!majorArgIsFolder)
{
// Работаем с файлом, удаление MajorArgFile
delete_file(*majorArgFile);
}
else
{
// Работаем с папкой, рекурсивное удаление MajorArgFolder
delete_folder(*majorArgFolder);
}
return SUCCESS;
}
else if (!strcmp(command, "find"))
{
// printf("FIND!\n");
char *buf = (char *)malloc(MAX_ARG_LEN);
char *fname = (char *)malloc(MAX_ARG_LEN);
char *ext = (char *)malloc(MAX_ARG_LEN);
int count = 0;
// printf("MinorArg: %s\n", minorArg);
strcpy(buf, minorArg);
char *sep = ".";
char *istr = strtok(buf, sep);
while (istr != NULL)
{
if (count == 0)
{
strcpy(fname, istr);
count++;
}
else
{
strcpy(ext, istr);
count++;
break;
}
istr = strtok(NULL, sep);
}
// printf("Count: %d\n", count);
if (count == 1)
{
// printf("tryin to find folder\n");
// printf("*majorArgFolder: %s\n", (*majorArgFolder));
// printf("majorArgIsFolder: %d\n", (majorArgIsFolder));
find_folder(fname, *CurrentFolder);
}
else
{
// printf("tryin to find file\n");
find_file(fname, ext, *CurrentFolder);
}
free(buf);
free(fname);
free(ext);
}
else if (!strcmp(command, "touch"))
{
char *buf = (char *)malloc(MAX_ARG_LEN);
char *fname = (char *)malloc(MAX_ARG_LEN);
char *ext = (char *)malloc(MAX_ARG_LEN);
int count = 0;
// printf("MinorArg: %s\n", minorArg);
strcpy(buf, minorArg);
char *sep = ".";
char *istr = strtok(buf, sep);
while (istr != NULL)
{
if (count == 0)
{
strcpy(fname, istr);
count++;
}
else
{
strcpy(ext, istr);
count++;
break;
}
istr = strtok(NULL, sep);
}
addFile(fname, ext, *CurrentFolder);
*majorArgFile = &(*CurrentFolder)->files[(*CurrentFolder)->files_count_cur - 1];
// printf("--- %s\n", (*majorArgFile)->creation_time);
free(buf);
free(fname);
free(ext);
}
else if (!strcmp(command, "mkdir"))
{
addFolder(minorArg, *CurrentFolder);
*majorArgFolder = &(*CurrentFolder)->folders[(*CurrentFolder)->folders_count_cur - 1];
}
else
{
// printf("Unknown command: %s", command);
return FAILURE;
}
return SUCCESS;
}
FILE *SAVE;
int cansave = 0;
int newRecord(char *time, char *date, Folder *folder, char *command)
{
if (cansave)
{
SAVE = fopen(SAVEFILENAME, "a");
if (SAVE == NULL)
{
// printf("Unable to open %s\n", SAVEFILENAME);
}
if (time != NULL)
{
fprintf(SAVE, "%s=%s=", time, date);
}
save_path(0, folder, NULL, SAVE);
fprintf(SAVE, "=%s", command);
fclose(SAVE);
}
}
int commandParserHandler(char *input, Folder *RootFolder, Folder **CurrentFolder)
{
// printf("%sfdfdf\n", input);
int result = SUCCESS; // Если что-то пойдет не так, то он изменится
char *sep = " ";
char *str = (char *)malloc(MAX_COMMAND_LEN), *istr;
int i = 0; // Счетчик обработанных лексемм
strcpy(str, input);
for (size_t i = 0; i < strlen(str); i++)
{
if (str[i] == '\n')
{
str[i] = ' ';
}
}
istr = strtok(str, sep);
char *command = (char *)malloc(MAX_COMMAND_LEN);
char *arg1 = (char *)malloc(MAX_COMMAND_LEN);
char *arg2 = (char *)malloc(MAX_COMMAND_LEN);
int optionFlag = 0;
int r1, r2;
File *ResultFile = NULL;
Folder *ResultFolder = NULL;
while (istr != NULL)
{
// Обрабатываем команду/аргумент
// printf("%d\n", i);
switch (i)
{
case 0:
// команда
for (size_t i = 0; i < strlen(istr); i++)
{
if (istr[i] == '\n')
{
istr[i] = '\0';
}
}
if (checkCommandValid(istr)) // Если команда неправильная
{
printf("Incorrect Command!\n");
result = FAILURE;
goto cleanup;
}
strcpy(command, istr);
break;
case 1:
// аргумент 1
r1 = strcmp(command, "mkdir");
r2 = strcmp(command, "touch");
if (strcmp(command, "find") && r1 && r2)
{
if (checkArgumentValid(command, istr, RootFolder, *CurrentFolder, &ResultFolder, &ResultFile))
{
result = WRONG_OPTION;
goto cleanup;
}
if (istr[0] == '-')
optionFlag = 1;
}
else
{
if (!r1 || !r2)
{
optionFlag = 0;
}
else
optionFlag = 1;
}
strcpy(arg1, istr);
break;
case 2:
// аргумент 2
if (!optionFlag)
{
result = WRONG_ARGUMENT_FAILURE;
goto cleanup;
}
if (checkArgumentValid(command, istr, RootFolder, *CurrentFolder, &ResultFolder, &ResultFile))
{
result = WRONG_OPTION;
goto cleanup;
}
strcpy(arg2, istr);
break;
default:
break;
}
i++;
istr = strtok(NULL, sep); // Выделяем следующую часть
}
// printf("%d: %s, %s, %s\n", i, command, arg1, arg2);
// printf("Result folder: %s\n", ResultFolder);
result = executeCommand(command, arg1, &ResultFolder, &ResultFile, ResultFolder != NULL, RootFolder, CurrentFolder);
// printf("Writing...\n");
if (result == SUCCESS)
{
if (!strcmp(command, "mkdir"))
{
newRecord(ResultFolder->creation_time, ResultFolder->creation_date, *CurrentFolder, input);
}
else if (!strcmp(command, "touch"))
{
newRecord(ResultFile->creation_time, ResultFile->creation_date, *CurrentFolder, input);
}
else if (!strcmp(command, "rm"))
{
newRecord(NULL, NULL, *CurrentFolder, input);
}
}
// printf("- exec: %d", r);
cleanup:
free(str);
free(command);
free(arg1);
free(arg2);
return result;
}
int readRecords(Folder *RootFolder)
{
SAVE = fopen(SAVEFILENAME, "r");
char buf[MAX_COMMAND_LEN * 4];
buf[0] = '\0';
char *sep = "=";
char data[4][MAX_COMMAND_LEN];
int kolvo = 0;
if (SAVE == NULL)
{
printf("Unable to open %s\n", SAVEFILENAME);
return 0;
}
Folder *CurrentFolder;
size_t read;
while (!feof(SAVE))
{
fgets(buf, MAX_COMMAND_LEN * 4, SAVE);
if (strlen(buf) > 1)
{
kolvo = 0;
// printf("buf = %s, EOF = %d\n", buf, feof(SAVE));
// fscanf(SAVE, "%s", buf);
char *istr = strtok(buf, sep);
while (istr != NULL)
{
strcpy(data[kolvo], istr);
// printf("data[%d] = %s\n", kolvo, data[kolvo]);
kolvo++;
istr = strtok(NULL, sep);
}
// printf("kolvo = %d\n", kolvo);
if (kolvo == 4)
{
char *time = (char *)malloc(9);
char *date = (char *)malloc(9);
strcpy(date, data[0]);
strcpy(time, data[1]);
checkMajorArgumentValid(data[2], RootFolder, CurrentFolder, &CurrentFolder, NULL);
commandParserHandler(data[3], RootFolder, &CurrentFolder);
if (data[3][0] == 'm')
{
strcpy(CurrentFolder->folders[CurrentFolder->folders_count_cur - 1].creation_date, date);
strcpy(CurrentFolder->folders[CurrentFolder->folders_count_cur - 1].creation_time, time);
}
free(time);
free(date);
}
else if (kolvo == 2)
{
checkMajorArgumentValid(data[0], RootFolder, CurrentFolder, &CurrentFolder, NULL);
commandParserHandler(data[1], RootFolder, &CurrentFolder);
}
}
}
}