Advertisement
Guest User

C

a guest
Apr 23rd, 2019
114
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.06 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdbool.h>
  3. #include <stdlib.h>
  4. #include <string.h>
  5. #include <dirent.h>
  6. #include <linux/limits.h>
  7. #include <sys/types.h>
  8. #include <sys/stat.h>
  9. #include <unistd.h>
  10. #include <errno.h>
  11. #include <ctype.h>
  12.  
  13. static char* prog_name;
  14.  
  15. #define BUFF_SIZE 1024*1024
  16.  
  17. typedef struct {
  18. char *path;
  19. char filename[NAME_MAX];
  20. off_t file_size;
  21. } Fileinfo;
  22.  
  23. int cmp_filename(const void *fst, const void *snd)
  24. {
  25. return strcmp( ((Fileinfo*)fst)->filename, ((Fileinfo*)snd)->filename );
  26. }
  27.  
  28. int cmp_size(const void *fst, const void *snd)
  29. {
  30. return ((Fileinfo*)fst)->file_size > ((Fileinfo*)snd)->file_size;
  31. }
  32.  
  33. char* basename(char *filename)
  34. {
  35. char *p = strrchr(filename, '/');
  36. return p ? p + 1 : filename;
  37. }
  38.  
  39. void walk_dir(const char *src_dir, Fileinfo **files, int *files_count)
  40. {
  41. DIR *curr = opendir(src_dir);
  42. if (!curr) {
  43. fprintf(stderr, "%s Cannot open dir: %s, %s \n",prog_name, src_dir, strerror(errno));
  44. return;
  45. }
  46. struct dirent *info;
  47. char *full_path = NULL;
  48. if (!(full_path = realpath(src_dir, NULL))) {
  49. fprintf(stderr, "%s Cannot get full path of file: %s, %s \n", prog_name, src_dir, strerror(errno));
  50. closedir(curr);
  51. return;
  52. }
  53. char *file_path = NULL;
  54. while ((info = readdir(curr))) {
  55. file_path = malloc(strlen(full_path) + 2 + strlen(info->d_name));
  56. strcpy(file_path, full_path);
  57. strcat(file_path, "/");
  58. strcat(file_path, info->d_name);
  59. if (info->d_type == DT_DIR && strcmp(info->d_name, ".") && strcmp(info->d_name, "..")) {
  60. walk_dir(file_path, files, files_count);
  61. free(file_path);
  62. } else if (info->d_type == DT_DIR) {
  63. free(file_path);
  64. }
  65. if (info->d_type == DT_REG) {
  66. struct stat file_stat;
  67. if (stat(file_path, &file_stat) == -1) {
  68. fprintf(stderr, "%s Cannot get stat's from file: %s, %s \n", prog_name, file_path, strerror(errno));
  69. continue;
  70. }
  71. Fileinfo* old_files = *files;
  72. *files = (Fileinfo*)realloc(*files, ++(*files_count) * sizeof (Fileinfo));
  73. if (!*files) {
  74. fprintf(stderr, "%s Cannot alloc memory for file %s \n", prog_name, file_path);
  75. *files = old_files;
  76. --(*files_count);
  77. continue;
  78. }
  79. Fileinfo *files_arr = *files;
  80. int pos = *files_count - 1;
  81. files_arr[pos].path = file_path;
  82. strcpy(files_arr[pos].filename, info->d_name);
  83. files_arr[pos].file_size = file_stat.st_size;
  84. }
  85. }
  86. free(full_path);
  87. closedir(curr);
  88. }
  89.  
  90. void write_files(Fileinfo *files, size_t files_count, const char* out_dir)
  91. {
  92. char *out_path = NULL;
  93. if (!(out_path = realpath(out_dir, NULL))) {
  94. fprintf(stderr, "%s Cannot get full path of file: %s, %s \n", prog_name, out_dir, strerror(errno));
  95. return;
  96. }
  97. for (int i = 0; i < files_count; ++i) {
  98. int size = strlen(out_path) + 2 + strlen(files[i].filename);
  99. char *out_name = malloc(size);
  100. strcpy(out_name, out_path);
  101. strcat(out_name, "/");
  102. strcat(out_name, files[i].filename);
  103. while (access(out_name, F_OK) != -1) {
  104. out_name = realloc(out_name, ++size);
  105. strcat(out_name, "_");
  106. }
  107. FILE *in = fopen(files[i].path, "r");
  108. if (!in) {
  109. fprintf(stderr, "%s Cannot open for read file: %s, %s \n", prog_name, files[i].path, strerror(errno));
  110. continue;
  111. }
  112. FILE *out = fopen(out_name, "w+");
  113. if (!out) {
  114. fprintf(stderr, "%s Cannot open for write file: %s, %s \n", prog_name, out_name, strerror(errno));
  115. fclose(in);
  116. continue;
  117. }
  118. char *buff = malloc(BUFF_SIZE);
  119. int bytes_read;
  120. while ((bytes_read = fread(buff, 1, BUFF_SIZE, in))) {
  121. if (fwrite(buff, 1, bytes_read, out) != bytes_read) {
  122. fprintf(stderr, "%s Error writing file %s, %s \n", prog_name, out_name, strerror(errno));
  123. }
  124. }
  125. fclose(in);
  126. fclose(out);
  127. free(buff);
  128. free(out_name);
  129. }
  130. free(out_path);
  131. }
  132.  
  133. int main(int argc, char *argv[])
  134. {
  135. prog_name = basename(argv[0]);
  136. if (argc != 4) {
  137. fprintf(stderr, "%s Program need 3 arguments \n", prog_name);
  138. return 1;
  139. }
  140. char *src_dir = argv[1];
  141. int mode = atoi(argv[2]);
  142. if (mode != 1 && mode != 2) {
  143. fprintf(stderr, "%s Correct mode: 1 (by size) and 2 (by filename) \n", prog_name);
  144. return 1;
  145. }
  146. char *dest_dir = argv[3];
  147. Fileinfo *files = NULL;
  148. int files_count = 0;
  149. walk_dir(src_dir, &files, &files_count);
  150. qsort(files, files_count, sizeof (*files), mode == 1 ? cmp_size : cmp_filename);
  151. write_files(files, files_count, dest_dir);
  152. for (int i = 0; i < files_count; i++)
  153. free(files[i].path);
  154. free(files);
  155. return 0;
  156. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement