diff --git a/source/directive.c b/source/directive.c index 59a1fb5..821c2a7 100644 --- a/source/directive.c +++ b/source/directive.c @@ -3,10 +3,10 @@ #include #include #include -#include #include #include #include +#include #include "kvec.h" #include "global.h" @@ -36,7 +36,7 @@ int add_directory(const char * const folder) { DIR * dir = opendir(folder); CHECK_OPEN(dir, folder, return 1); - char full_path[1024]; + char full_path[PATH_MAX]; struct stat file_stat; struct dirent * mydirent; entry_t entry; @@ -52,10 +52,7 @@ int add_directory(const char * const folder) { ); int e = stat(full_path, &file_stat); - if (e == -1) { - errorn(E_FILE_ACCESS, full_path); - return 1; - } + CHECK_OPEN(!(e == -1), full_path, return 1); entry = (entry_t) { .name = strdup(full_path), @@ -74,14 +71,16 @@ int add_directory(const char * const folder) { return 0; } -int init_directive_c(const char * folder) { +int init_directive_c(const char * const folder) { init_file_utils(is_dry_run); kv_init(entries); kv_init(directory_queue); kv_push(const char*, directory_queue, folder); while (directory_queue.n) { - add_directory(kv_pop(directory_queue)); + if (add_directory(kv_pop(directory_queue))) { + return 1; + } } qsort( @@ -225,5 +224,6 @@ int execute_directive_file(FILE * f) { } } + #undef NEXT_FIELD return 0; } diff --git a/source/directive.h b/source/directive.h index 5afd6ae..68c49d1 100644 --- a/source/directive.h +++ b/source/directive.h @@ -3,7 +3,7 @@ #include -extern int init_directive_c(const char * folder_); +extern int init_directive_c(const char * const folder); extern int deinit_directive_c(void); extern int make_directive_file(FILE * f); extern int execute_directive_file(FILE * f); diff --git a/source/error.c b/source/error.c index e805947..d9bd081 100644 --- a/source/error.c +++ b/source/error.c @@ -27,11 +27,12 @@ void errorn(int i, ...) { va_start(argv, i); switch (i) { - case E_OPEN_EDITOR: verror("failed to open editor '%s'", argv); break; + case E_OPEN_EDITOR: verror("failed to open editor '%s'", argv); break; case E_FILE_ACCESS: verror("failed to interact with file '%s'", argv); break; - case E_FILE_DELETE: verror("failed to delete file '%s'", argv); break; - case E_FILE_MOVE: verror("failed to move '%s' to '%s'", argv); break; - case E_FORMAT: verror("directive-file format violation", argv); break; + case E_FILE_DELETE: verror("failed to delete file '%s'", argv); break; + case E_FILE_MOVE: verror("failed to move '%s' to '%s'", argv); break; + case E_FORMAT: verror("directive-file format violation", argv); break; + default: verror("unknown error encountered; this is an illegal inner state", 0); break; } va_end(argv); diff --git a/source/error.h b/source/error.h index 141e237..7175f5b 100644 --- a/source/error.h +++ b/source/error.h @@ -2,7 +2,7 @@ #define ERROR_H enum { - E_OPEN_EDITOR, + E_OPEN_EDITOR = 1, E_FILE_ACCESS, E_FILE_DELETE, E_FILE_MOVE, diff --git a/source/file_utils.c b/source/file_utils.c index 7941f57..fce464a 100644 --- a/source/file_utils.c +++ b/source/file_utils.c @@ -2,12 +2,23 @@ #include #include +#include #include #include #include #include #include "error.h" +extern char * trim_trailing_slashes(char * path) { + int len = strlen(path); + while (len > 1 + && path[len-1] == '/') { + path[len-1] = '\0'; + --len; + } + return path; +} + int (*mytouch)(const char *filename) = NULL; int (*mydelete)(const char *filename) = NULL; int (*mychmod)(const char *filename, mode_t mode) = NULL; diff --git a/source/file_utils.h b/source/file_utils.h index 2d7bf46..675f2eb 100644 --- a/source/file_utils.h +++ b/source/file_utils.h @@ -7,6 +7,8 @@ extern int init_file_utils(bool is_dry_run); extern int deinit_file_utis(); +extern char * trim_trailing_slashes(char * path); + extern char mode_type_to_char(mode_t m); extern mode_t char_to_mode_type(const char c); extern char * mode_to_str(mode_t mode, char * buffer); diff --git a/source/global.h b/source/global.h index 5a2baec..241f21e 100644 --- a/source/global.h +++ b/source/global.h @@ -1,6 +1,8 @@ #ifndef GLOBAL_H #define GLOBAL_H +#include + extern char * editor; extern char * folder; extern char * custom_rm; diff --git a/source/main.c b/source/main.c index 0834fdc..ccffcf8 100644 --- a/source/main.c +++ b/source/main.c @@ -5,6 +5,7 @@ #include "error.h" #include "opts.h" #include "directive.h" +#include "file_utils.h" char * editor = NULL; char * folder = NULL; @@ -14,7 +15,22 @@ bool is_recursive = false; bool do_permissions = false; bool do_owner = false; -#define DEBUG +int get_tmpfile_name(char * name_buffer) { + #if DEBUG == 1 + strcpy(name_buffer, "vimdir_test_file.vimdir"); + + return 0; + #else + int fd; + + strcpy(name_buffer, "/tmp/vidirXXXXXX.vimdir"); + fd = mkstemps(tmpfile_name); + if (fd == -1) { return 1; } + close(fd); + + return 0; + #endif +} int edit(const char * filename) { size_t cmd_len = strlen(editor) + sizeof(' ') + strlen(filename) + 1; @@ -22,10 +38,11 @@ int edit(const char * filename) { snprintf(cmd, cmd_len, "%s %s", editor, filename); - // XXX int result = system(cmd); - if (result == -1) { + if (result == 127 // shell could not be executed + || result == -1) { // child process could not be created errorn(E_OPEN_EDITOR, editor); + return 1; } else if (WIFEXITED(result) && WEXITSTATUS(result) != 0) { @@ -51,19 +68,14 @@ signed main(int argc, char * * argv) { get_env(); parse_args(argc, argv); - // XXX: what if the user passed '/'? - size_t len = strlen(folder); - if (folder[len-1] == '/') { - folder[len-1] = '\0'; - } + folder = trim_trailing_slashes(folder); - char * tmpfile_name; + create: FILE * tmpfile; - #ifdef DEBUG - tmpfile_name = "vimdir_test_file.vimdir"; - #else - tmpfile_name = mktemp("/tmp/vidirXXXXXX.vimdir"); - #endif + char tmpfile_name[32]; + + CHECK(get_tmpfile_name(tmpfile_name)); + tmpfile = fopen(tmpfile_name, "w+"); CHECK_OPEN(tmpfile, tmpfile_name, goto end); @@ -73,8 +85,10 @@ signed main(int argc, char * * argv) { fflush(tmpfile); + edit: CHECK(edit(tmpfile_name)); + process: fclose(tmpfile); tmpfile = fopen(tmpfile_name, "r"); CHECK_OPEN(tmpfile, tmpfile_name, goto end); diff --git a/source/opts.h b/source/opts.h index ddf4ce0..0591da3 100644 --- a/source/opts.h +++ b/source/opts.h @@ -1,9 +1,6 @@ #ifndef OPTS_H #define OPTS_H -#include -#include - extern void get_env(void); extern void parse_args(int argc, char * * argv);