qfile-agent.c 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. #include "qfile-utils.h"
  2. char *get_abs_path(const char *cwd, const char *pathname)
  3. {
  4. char *ret;
  5. if (pathname[0] == '/')
  6. return strdup(pathname);
  7. asprintf(&ret, "%s/%s", cwd, pathname);
  8. return ret;
  9. }
  10. int do_fs_walk(const char *file)
  11. {
  12. char *newfile;
  13. struct stat st;
  14. struct dirent *ent;
  15. DIR *dir;
  16. if (lstat(file, &st))
  17. gui_fatal("stat %s", file);
  18. single_file_processor(file, &st);
  19. if (!S_ISDIR(st.st_mode))
  20. return 0;
  21. dir = opendir(file);
  22. if (!dir)
  23. gui_fatal("opendir %s", file);
  24. while ((ent = readdir(dir))) {
  25. char *fname = ent->d_name;
  26. if (!strcmp(fname, ".") || !strcmp(fname, ".."))
  27. continue;
  28. asprintf(&newfile, "%s/%s", file, fname);
  29. do_fs_walk(newfile);
  30. free(newfile);
  31. }
  32. closedir(dir);
  33. // directory metadata is resent; this makes the code simple,
  34. // and the atime/mtime is set correctly at the second time
  35. single_file_processor(file, &st);
  36. return 0;
  37. }
  38. int main(int argc, char **argv)
  39. {
  40. int i;
  41. char *entry;
  42. char *cwd;
  43. char *sep;
  44. signal(SIGPIPE, SIG_IGN);
  45. // this will allow checking for possible feedback packet in the middle of transfer
  46. set_nonblock(0);
  47. register_notify_progress(&notify_progress);
  48. notify_progress(0, PROGRESS_FLAG_INIT);
  49. crc32_sum = 0;
  50. cwd = getcwd(NULL, 0);
  51. for (i = 1; i < argc; i++) {
  52. if (strcmp(argv[i], "--ignore-symlinks")==0) {
  53. ignore_symlinks = 1;
  54. continue;
  55. }
  56. entry = get_abs_path(cwd, argv[i]);
  57. do {
  58. sep = rindex(entry, '/');
  59. if (!sep)
  60. gui_fatal
  61. ("Internal error: nonabsolute filenames not allowed");
  62. *sep = 0;
  63. } while (sep[1] == 0);
  64. if (entry[0] == 0)
  65. chdir("/");
  66. else if (chdir(entry))
  67. gui_fatal("chdir to %s", entry);
  68. do_fs_walk(sep + 1);
  69. free(entry);
  70. }
  71. notify_end_and_wait_for_result();
  72. notify_progress(0, PROGRESS_FLAG_DONE);
  73. return 0;
  74. }