#include "qfile-utils.h" char *get_abs_path(const char *cwd, const char *pathname) { char *ret; if (pathname[0] == '/') return strdup(pathname); if (asprintf(&ret, "%s/%s", cwd, pathname) < 0) return NULL; else return ret; } int do_fs_walk(const char *file) { char *newfile; struct stat st; struct dirent *ent; DIR *dir; if (lstat(file, &st)) gui_fatal("stat %s", file); single_file_processor(file, &st); if (!S_ISDIR(st.st_mode)) return 0; dir = opendir(file); if (!dir) gui_fatal("opendir %s", file); while ((ent = readdir(dir))) { char *fname = ent->d_name; if (!strcmp(fname, ".") || !strcmp(fname, "..")) continue; if (asprintf(&newfile, "%s/%s", file, fname) >= 0) { do_fs_walk(newfile); free(newfile); } else { fprintf(stderr, "asprintf failed\n"); exit(1); } } closedir(dir); // directory metadata is resent; this makes the code simple, // and the atime/mtime is set correctly at the second time single_file_processor(file, &st); return 0; } int main(int argc, char **argv) { int i; char *entry; char *cwd; char *sep; signal(SIGPIPE, SIG_IGN); // this will allow checking for possible feedback packet in the middle of transfer set_nonblock(0); register_notify_progress(¬ify_progress); notify_progress(0, PROGRESS_FLAG_INIT); crc32_sum = 0; cwd = getcwd(NULL, 0); for (i = 1; i < argc; i++) { if (strcmp(argv[i], "--ignore-symlinks")==0) { ignore_symlinks = 1; continue; } entry = get_abs_path(cwd, argv[i]); do { sep = rindex(entry, '/'); if (!sep) gui_fatal ("Internal error: nonabsolute filenames not allowed"); *sep = 0; } while (sep[1] == 0); if (entry[0] == 0) { if (chdir("/") < 0) { gui_fatal("Internal error: chdir(\"/\") failed?!"); } } else if (chdir(entry)) gui_fatal("chdir to %s", entry); do_fs_walk(sep + 1); free(entry); } notify_end_and_wait_for_result(); notify_progress(0, PROGRESS_FLAG_DONE); return 0; }