qfile-agent.c 1.9 KB

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