From b8b18f32a0158f5ff956613bb2503f677e607b1d Mon Sep 17 00:00:00 2001 From: "Rustem Gimadutdinov (rgimad)" Date: Thu, 16 Apr 2020 21:50:49 +0000 Subject: [PATCH] SHELL 0.8 changelog - added mv command - added ren command - now ls works also with relative pathes - fixed bug in strrchr git-svn-id: svn://kolibrios.org@7802 a494cfbc-eb01-0410-851d-a64ba20cac60 --- programs/system/shell/all.h | 7 + programs/system/shell/cmd/cmd_cp.c | 244 +++++++++++---------- programs/system/shell/cmd/cmd_ls.c | 19 +- programs/system/shell/cmd/cmd_mv.c | 164 ++++++++++++++ programs/system/shell/cmd/cmd_ren.c | 50 +++++ programs/system/shell/globals.h | 4 +- programs/system/shell/locale/eng/globals.h | 2 + programs/system/shell/locale/rus/globals.h | 2 + programs/system/shell/shell.c | 16 ++ programs/system/shell/system/string.c | 2 +- 10 files changed, 388 insertions(+), 122 deletions(-) create mode 100644 programs/system/shell/cmd/cmd_mv.c create mode 100644 programs/system/shell/cmd/cmd_ren.c diff --git a/programs/system/shell/all.h b/programs/system/shell/all.h index 145b85ab08..d630ab843c 100644 --- a/programs/system/shell/all.h +++ b/programs/system/shell/all.h @@ -15,6 +15,9 @@ #include "globals.h" #include "prototypes.h" +// from main file (shell.c). TODO - in future move to library +void get_file_dir_loc(char *filepath, char *dir_path); + #include "system/console.c" #include "cmd/cmd_about.c" @@ -42,6 +45,8 @@ #include "cmd/cmd_uptime.c" #include "cmd/cmd_history.c" #include "cmd/cmd_cp.c" +#include "cmd/cmd_mv.c" +#include "cmd/cmd_ren.c" #include "cmd/cmd_waitfor.c" #include "modules/module_command.c" @@ -52,4 +57,6 @@ #include "modules/module_alias.c" #include "modules/module_parameters.c" +typedef unsigned int size_t; + /// =========================================================== diff --git a/programs/system/shell/cmd/cmd_cp.c b/programs/system/shell/cmd/cmd_cp.c index da8e1206ef..6b4feae597 100644 --- a/programs/system/shell/cmd/cmd_cp.c +++ b/programs/system/shell/cmd/cmd_cp.c @@ -1,144 +1,152 @@ int cmd_cp(char param[]) { + char* argv[100]; + int argc; + char *filename_in = NULL; + char *filename_out = NULL; + char *buffer = NULL; -char* argv[100]; -int argc; -char *filename_in = NULL; -char *filename_out = NULL; -char *buffer = NULL; + kol_struct70 k70_in; + kol_struct70 k70_out; -kol_struct70 k70_in; -kol_struct70 k70_out; + kol_struct_BDVK bdvk; -kol_struct_BDVK bdvk; + unsigned long long filesize; + unsigned result, buf_size; -unsigned long long filesize; -unsigned result, buf_size; + argc = parameters_prepare(param, argv); -argc = parameters_prepare(param, argv); + if (argc != 2) + { + #if LANG_ENG + printf(" cp \n\r"); + #elif LANG_RUS + printf(" cp <источник> <результат>\n\r"); + #endif + parameters_free(argc, argv); + return TRUE; + } -if (argc != 2) - { - #if LANG_ENG - printf(" cp \n\r"); - #elif LANG_RUS - printf(" cp <источник> <результат>\n\r"); - #endif + filename_in = (char*) malloc(FILENAME_MAX); + filename_out = (char*) malloc(FILENAME_MAX); - parameters_free(argc, argv); - - return TRUE; - } - -filename_in = (char*) malloc(FILENAME_MAX); -filename_out = (char*) malloc(FILENAME_MAX); - -if (argv[0][0] != '/') - { - strcpy(filename_in, cur_dir); - if (filename_in[strlen(filename_in)-1] != '/') - strcat(filename_in, "/"); // add slash - strcat(filename_in, argv[0]); - } - else - { - strcpy(filename_in, argv[0]); - } - -if (argv[1][0] != '/') - { - strcpy(filename_out, cur_dir); - if (filename_out[strlen(filename_out)-1] != '/') - strcat(filename_out, "/"); // add slash - strcat(filename_out, argv[1]); - } - else - { - strcpy(filename_out, argv[1]); - } - -// add ability to use directory as destination -if ( dir_check(filename_out) ) - { - char *fname = strrchr(filename_in, '/') + 1; // always exist, as we add curdir - if (filename_out[strlen(filename_out)-1] != '/') - strcat(filename_out, "/"); // add slash - strcat(filename_out, fname); - } + if (argv[0][0] != '/') + { + strcpy(filename_in, cur_dir); + if (filename_in[strlen(filename_in)-1] != '/') + { + strcat(filename_in, "/"); // add slash + } + strcat(filename_in, argv[0]); + } else + { + strcpy(filename_in, argv[0]); + } + // ----- + if (argv[1][0] != '/') + { + strcpy(filename_out, cur_dir); + if (filename_out[strlen(filename_out)-1] != '/') + { + strcat(filename_out, "/"); // add slash + } + strcat(filename_out, argv[1]); + } else + { + strcpy(filename_out, argv[1]); + } + + // add ability to use directory as destination + if ( dir_check(filename_out) ) + { + char *fname = strrchr(filename_in, '/') + 1; // always exist, as we add curdir + if (filename_out[strlen(filename_out)-1] != '/') + { + strcat(filename_out, "/"); // add slash + } + strcat(filename_out, fname); + } -k70_in.p00 = 5; -k70_in.p04 = 0LL; -k70_in.p12 = 0; -k70_in.p16 = (unsigned) &bdvk; -k70_in.p20 = 0; -k70_in.p21 = filename_in; + k70_in.p00 = 5; + k70_in.p04 = 0LL; + k70_in.p12 = 0; + k70_in.p16 = (unsigned) &bdvk; + k70_in.p20 = 0; + k70_in.p21 = filename_in; -result = kol_file_70(&k70_in); // получаем информацию о файле -if ( 0 != result ) - goto lbl_exit; + result = kol_file_70(&k70_in); // get information about file + if ( 0 != result ) + goto lbl_exit; -// count buffer size up to 1Mb, but no more than 1/2 of free memory -buf_size = 1 << 20; // 1Mb -while( ((buf_size >> 10) > kol_system_memfree()) && (buf_size > 4096) ) - buf_size /= 2; + // count buffer size up to 1Mb, but no more than 1/2 of free memory + buf_size = 1 << 20; // 1Mb + while( ((buf_size >> 10) > kol_system_memfree()) && (buf_size > 4096) ) + buf_size /= 2; -filesize = bdvk.p32; // получаем размер файла(ограничение - 4 Гбайта только для FAT) -if (buf_size > filesize) - buf_size = (unsigned)filesize; // may be zero! -if (buf_size == 0) buf_size = 4096; // ... + filesize = bdvk.p32; // getting file size (restriction - 4 GB only for FAT) + if (buf_size > filesize) + buf_size = (unsigned)filesize; // may be zero! + if (buf_size == 0) buf_size = 4096; // ... -buffer = (char*) malloc(buf_size); -if (!buffer) - { - result = E_NOMEM; - goto lbl_exit; - } + buffer = (char*) malloc(buf_size); + if (!buffer) + { + result = E_NOMEM; + goto lbl_exit; + } -k70_in.p00 = 0; -//k70_in.p08 = 0; -k70_in.p12 = buf_size; -k70_in.p16 = (unsigned) buffer; -k70_in.p20 = 0; -k70_in.p21 = filename_in; + k70_in.p00 = 0; + //k70_in.p08 = 0; + k70_in.p12 = buf_size; + k70_in.p16 = (unsigned) buffer; + k70_in.p20 = 0; + k70_in.p21 = filename_in; -k70_out.p00 = 2; -//k70_out.p08 = 0; -k70_out.p12 = buf_size; -k70_out.p16 = (unsigned) buffer; -k70_out.p20 = 0; -k70_out.p21 = filename_out; + k70_out.p00 = 2; + //k70_out.p08 = 0; + k70_out.p12 = buf_size; + k70_out.p16 = (unsigned) buffer; + k70_out.p20 = 0; + k70_out.p21 = filename_out; -unsigned long long offset = 0; -do { - k70_in.p04 = offset; - if (offset + buf_size > filesize) // last chunk - { - k70_in.p12 = k70_out.p12 = (unsigned)(filesize - offset); // filesize % buf_size; - } - - result = kol_file_70(&k70_in); // чтение - if (result != 0) - goto lbl_exit; + unsigned long long offset = 0; + do + { + k70_in.p04 = offset; + if (offset + buf_size > filesize) // last chunk + { + k70_in.p12 = k70_out.p12 = (unsigned)(filesize - offset); // filesize % buf_size; + } + + result = kol_file_70(&k70_in); // read + if (result != 0) + { + goto lbl_exit; + } - k70_out.p04 = offset; - result = kol_file_70(&k70_out); // запись - if (result != 0) - goto lbl_exit; + k70_out.p04 = offset; + result = kol_file_70(&k70_out); // write + if (result != 0) + { + goto lbl_exit; + } - if (k70_out.p00 == 2) - k70_out.p00 = 3; // меняем функцию с создания (2) на дозапись (3) - offset += buf_size; -} while (offset < filesize); + if (k70_out.p00 == 2) + { + k70_out.p00 = 3; // changing function from create (2) to append (3) + } + offset += buf_size; + } while (offset < filesize); -lbl_exit: + lbl_exit: -parameters_free(argc, argv); -free(filename_in); -free(filename_out); -free(buffer); + parameters_free(argc, argv); + free(filename_in); + free(filename_out); + free(buffer); -return (result == 0); + return (result == 0); } diff --git a/programs/system/shell/cmd/cmd_ls.c b/programs/system/shell/cmd/cmd_ls.c index ae4caecd2c..b8ef045e4a 100644 --- a/programs/system/shell/cmd/cmd_ls.c +++ b/programs/system/shell/cmd/cmd_ls.c @@ -8,6 +8,7 @@ unsigned num_of_file; // number of files in directory unsigned *t; unsigned type_of_file; // check is this a file or a folder int i, result; +char tmp[FILENAME_MAX]; bool single_column_mode = FALSE; @@ -26,10 +27,24 @@ if (!strnicmp(dir,"-1",1)) dir += 3; } -if ( !strlen(dir) ) +if ( !strlen(dir) ) // if argument is empty, list current directory k70.p21 = cur_dir; else - k70.p21 = dir; +{ + if (dir[0] != '/') // if given directory is relative path, then append cur_dir on left side + { + strcpy(tmp, cur_dir); + if (tmp[strlen(tmp)-1] != '/') + { + strcat(tmp, "/"); // add slash + } + strcat(tmp, dir); + k70.p21 = tmp; + } else // if given directory is an absolute path + { + k70.p21 = dir; + } +} result = kol_file_70(&k70); if ( !((result==0) || (result==6)) ) // check does the directory exists diff --git a/programs/system/shell/cmd/cmd_mv.c b/programs/system/shell/cmd/cmd_mv.c new file mode 100644 index 0000000000..03507de471 --- /dev/null +++ b/programs/system/shell/cmd/cmd_mv.c @@ -0,0 +1,164 @@ + +int cmd_mv(char param[]) +{ + char* argv[100]; + int argc; + char *filename_in = NULL; + char *filename_out = NULL; + char *buffer = NULL; + + kol_struct70 k70_in; + kol_struct70 k70_out; + + kol_struct_BDVK bdvk; + + unsigned long long filesize; + unsigned result, buf_size; + + argc = parameters_prepare(param, argv); + + /* + argv[0] - path (abs or rel) to file + argv[1] - new location: path (abs or rel) to dir or file + */ + + if (argc != 2) + { + #if LANG_ENG + printf(" mv \n\r"); + #elif LANG_RUS + printf(" mv <источник> <результат>\n\r"); + #endif + parameters_free(argc, argv); + return TRUE; + } + + filename_in = (char*) malloc(FILENAME_MAX); + filename_out = (char*) malloc(FILENAME_MAX); + + if (argv[0][0] != '/') + { + strcpy(filename_in, cur_dir); + if (filename_in[strlen(filename_in)-1] != '/') + { + strcat(filename_in, "/"); // add slash + } + strcat(filename_in, argv[0]); + } else + { + strcpy(filename_in, argv[0]); + } + // ----- + if (argv[1][0] != '/') + { + strcpy(filename_out, cur_dir); + if (filename_out[strlen(filename_out)-1] != '/') + { + strcat(filename_out, "/"); // add slash + } + strcat(filename_out, argv[1]); + } else + { + strcpy(filename_out, argv[1]); + } + + // add ability to use directory as destination + if ( dir_check(filename_out) ) + { + char *fname = strrchr(filename_in, '/') + 1; // always exist, as we add curdir + if (filename_out[strlen(filename_out)-1] != '/') + { + strcat(filename_out, "/"); // add slash + } + strcat(filename_out, fname); + } + + if (strcmp(filename_in, filename_out) == 0) // if source file and destination file are same then exist with success + { + result = 0; + goto lbl_exit; + } + + + k70_in.p00 = 5; + k70_in.p04 = 0LL; + k70_in.p12 = 0; + k70_in.p16 = (unsigned) &bdvk; + k70_in.p20 = 0; + k70_in.p21 = filename_in; + + result = kol_file_70(&k70_in); // get information about file + if ( 0 != result ) + goto lbl_exit; + + // count buffer size up to 1Mb, but no more than 1/2 of free memory + buf_size = 1 << 20; // 1Mb + while( ((buf_size >> 10) > kol_system_memfree()) && (buf_size > 4096) ) + buf_size /= 2; + + filesize = bdvk.p32; // getting file size (restriction - 4 GB only for FAT) + if (buf_size > filesize) + buf_size = (unsigned)filesize; // may be zero! + if (buf_size == 0) buf_size = 4096; // ... + + buffer = (char*) malloc(buf_size); + if (!buffer) + { + result = E_NOMEM; + goto lbl_exit; + } + + k70_in.p00 = 0; + //k70_in.p08 = 0; + k70_in.p12 = buf_size; + k70_in.p16 = (unsigned) buffer; + k70_in.p20 = 0; + k70_in.p21 = filename_in; + + k70_out.p00 = 2; + //k70_out.p08 = 0; + k70_out.p12 = buf_size; + k70_out.p16 = (unsigned) buffer; + k70_out.p20 = 0; + k70_out.p21 = filename_out; + + unsigned long long offset = 0; + do + { + k70_in.p04 = offset; + if (offset + buf_size > filesize) // last chunk + { + k70_in.p12 = k70_out.p12 = (unsigned)(filesize - offset); // filesize % buf_size; + } + + result = kol_file_70(&k70_in); // read + if (result != 0) + { + goto lbl_exit; + } + + k70_out.p04 = offset; + result = kol_file_70(&k70_out); // write + if (result != 0) + { + goto lbl_exit; + } + + if (k70_out.p00 == 2) + { + k70_out.p00 = 3; // changing function from create (2) to append (3) + } + offset += buf_size; + } while (offset < filesize); + + cmd_rm(filename_in); // remove source file + + lbl_exit: + + parameters_free(argc, argv); + free(filename_in); + free(filename_out); + free(buffer); + + return (result == 0); +} \ No newline at end of file diff --git a/programs/system/shell/cmd/cmd_ren.c b/programs/system/shell/cmd/cmd_ren.c new file mode 100644 index 0000000000..6eb3141e0a --- /dev/null +++ b/programs/system/shell/cmd/cmd_ren.c @@ -0,0 +1,50 @@ + +int cmd_ren(char param[]) +{ + char* argv[100]; + int argc; + /* + argv[0] - path (abs or rel) to file + argv[1] - new filename + */ + + argc = parameters_prepare(param, argv); + if (argc != 2) + { + #if LANG_ENG + printf(" ren \n\r"); + #elif LANG_RUS + printf(" ren <файл> <новое_имя>\n\r"); + #endif + parameters_free(argc, argv); + return TRUE; + } + char *x; + if (x = strrchr(argv[1], '/') != 0) // argv[1] must be file name, not path + { + //printf("%d %s", x, argv[1]); + return FALSE; + } + + char *new_filename = (char*)malloc(FILENAME_MAX); new_filename[0] = '\0'; + + get_file_dir_loc(argv[0], new_filename); + if (strlen(new_filename) > 0) + { + strcat(new_filename, "/"); + } + strcat(new_filename, argv[1]); + + char *mv_params = (char*)malloc(FILENAME_MAX*2 + 1); mv_params[0] = '\0'; + strcat(mv_params, argv[0]); + strcat(mv_params, " "); + strcat(mv_params, new_filename); + + //printf("(%s)\n", mv_params); + int res = cmd_mv(mv_params); + + free(new_filename); + free(mv_params); + + return res; +} diff --git a/programs/system/shell/globals.h b/programs/system/shell/globals.h index 6960f44ba0..5480c09bd7 100644 --- a/programs/system/shell/globals.h +++ b/programs/system/shell/globals.h @@ -1,5 +1,5 @@ -#define SHELL_VERSION "0.7.8a" +#define SHELL_VERSION "0.7.9" extern char PATH[256]; extern char PARAM[256]; @@ -67,6 +67,8 @@ int cmd_uptime(char param[]); int cmd_killall(char process_name[]); int cmd_history(char arg[]); int cmd_cp(char param[]); +int cmd_mv(char param[]); +int cmd_ren(char param[]); int cmd_waitfor(char param[]); /// =========================================================== diff --git a/programs/system/shell/locale/eng/globals.h b/programs/system/shell/locale/eng/globals.h index ae1b9d14df..1e08ab364b 100644 --- a/programs/system/shell/locale/eng/globals.h +++ b/programs/system/shell/locale/eng/globals.h @@ -6,6 +6,8 @@ const command_t COMMANDS[]= {"cd", " Changes current directory. Usage:\n\r cd \n\r", &cmd_cd}, {"clear", " Clears the screen\n\r", &cmd_clear}, {"cp", " Copies file\n\r", &cmd_cp}, + {"mv", " Moves file\n\r", &cmd_mv}, + {"ren", " Renames file\n\r", &cmd_ren}, {"date", " Returns the current date and time\n\r", &cmd_date}, {"echo", " Echoes the data to the screen. Usage:\n\r echo \n\r", &cmd_echo}, {"exit", " Exits from Shell\n\r", &cmd_exit}, diff --git a/programs/system/shell/locale/rus/globals.h b/programs/system/shell/locale/rus/globals.h index 26c16f98e1..9c430d8e7a 100644 --- a/programs/system/shell/locale/rus/globals.h +++ b/programs/system/shell/locale/rus/globals.h @@ -6,6 +6,8 @@ const command_t COMMANDS[]= {"cd", " Изменяет текущую дерикторию. Использование:\n\r cd <директория>\n\r", &cmd_cd}, {"clear", " Очищает экран\n\r", &cmd_clear}, {"cp", " Копирует файл\n\r", &cmd_cp}, + {"mv", " Перемещает файл\n\r", &cmd_mv}, + {"ren", " Переименовывает файл\n\r", &cmd_ren}, {"date", " Показывает текущую дату и время\n\r", &cmd_date}, {"echo", " Выводит данные на экран. Использование:\n\r echo <данные>\n\r", &cmd_echo}, {"exit", " Завершение работы Shell\n\r", &cmd_exit}, diff --git a/programs/system/shell/shell.c b/programs/system/shell/shell.c index 72c82df3a9..563f7fc387 100644 --- a/programs/system/shell/shell.c +++ b/programs/system/shell/shell.c @@ -41,6 +41,20 @@ for (;;i--) break; } } +/// =========================================================== + +void get_file_dir_loc(char *filepath, char *dir_path) +{ + char *res = strrchr(filepath, '/'); + if (res == 0) + { + dir_path = '\0'; + return; + } + size_t pos = res - filepath; + strncpy(dir_path, filepath, pos); + dir_path[pos] = '\0'; +} /// =========================================================== @@ -160,7 +174,9 @@ command_execute(); for (;;) { + //printf("\033[32;1m"); printf ("# "); + //printf("\033[0m"); command_get(); command_execute(); } diff --git a/programs/system/shell/system/string.c b/programs/system/shell/system/string.c index 1541b32e4c..be56e44b69 100644 --- a/programs/system/shell/system/string.c +++ b/programs/system/shell/system/string.c @@ -144,7 +144,7 @@ char* strchr(const char* string, int c) char* strrchr(const char* string, int c) { - char* last_found; + char* last_found = 0; // ! while (*string) { if (*string==c)