Advertisement
Guest User

Untitled

a guest
Mar 26th, 2019
81
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.40 KB | None | 0 0
  1. /*
  2. * Обработать строки a.a.a.a..a.a.a.a и т.д.
  3. * */
  4.  
  5. #include <stdio.h>
  6. #include <dirent.h>
  7. #include <errno.h>
  8. #include <unistd.h>
  9. #include <sys/types.h>
  10. #include <sys/stat.h>
  11. #include <ftw.h>
  12. #include <pwd.h>
  13. #include <grp.h>
  14. #include <memory.h>
  15. #include <stdlib.h>
  16.  
  17. typedef struct dir_info_arr dir_info_arr;
  18. typedef struct dirent dirent;
  19.  
  20. int cmpfunc(const void *a, const void *b) {
  21. const dirent **ia = (const dirent **)a;
  22. const dirent **ib = (const dirent **)b;
  23.  
  24. return strcmp((*ia)->d_name, (*ib)->d_name);
  25. }
  26.  
  27. struct dir_info_arr {
  28. dirent **arr_;
  29. size_t size_;
  30. size_t capacity_;
  31. };
  32.  
  33. dir_info_arr *new_dir_info_arr() {
  34. dir_info_arr *result = (dir_info_arr *)malloc(sizeof(dir_info_arr));
  35. result->size_ = 0;
  36. result->capacity_ = 256;
  37. result->arr_ = (dirent **)malloc(sizeof(dirent *) * result->capacity_);
  38.  
  39. return result;
  40. }
  41.  
  42. void push_to_dir_info(dir_info_arr *dia, dirent *d) {
  43. dia->arr_[dia->size_] = d;
  44. ++dia->size_;
  45.  
  46. if (dia->size_ >= dia->capacity_) {
  47. dia->capacity_ *= 2;
  48. dia->arr_ = (dirent **)realloc(dia->arr_, sizeof(dirent *) * dia->capacity_);
  49. }
  50. }
  51.  
  52.  
  53.  
  54. void print_filetype(mode_t mode) {
  55. /*switch (mode & S_IFMT) {
  56. case S_IFREG: putchar('-'); break;
  57. case S_IFDIR: putchar('d'); break;
  58. case S_IFLNK: putchar('l'); break;
  59. case S_IFCHR: putchar('c'); break;
  60. case S_IFBLK: putchar('b'); break;
  61. case S_IFSOCK: putchar('s'); break;
  62. case S_IFIFO: putchar('f'); break;
  63. default: putchar('-'); break;
  64. }*/
  65. if (S_ISREG(mode))
  66. putchar('-');
  67. else if (S_ISDIR(mode))
  68. putchar('d');
  69. else if (S_ISLNK(mode))
  70. putchar('l');
  71. else if (S_ISCHR(mode))
  72. putchar('c');
  73. else if (S_ISBLK(mode))
  74. putchar('b');
  75. /* else if (S_ISSOCK(mode))
  76. putchar('s'); */
  77. else if (S_ISFIFO(mode))
  78. putchar('p');
  79. else
  80. putchar('-');
  81. }
  82.  
  83. void print_permissions(mode_t mode) {
  84. putchar((mode & S_IRUSR) ? 'r' : '-');
  85. putchar((mode & S_IWUSR) ? 'w' : '-');
  86. putchar((mode & S_IXUSR) ? 'x' : '-');
  87. putchar((mode & S_IRGRP) ? 'r' : '-');
  88. putchar((mode & S_IWGRP) ? 'w' : '-');
  89. putchar((mode & S_IXGRP) ? 'x' : '-');
  90. putchar((mode & S_IROTH) ? 'r' : '-');
  91. putchar((mode & S_IWOTH) ? 'w' : '-');
  92. putchar((mode & S_IXOTH) ? 'x' : '-');
  93. }
  94.  
  95. void print_ug_name(__uid_t st_uid, __gid_t st_gid) {
  96. struct passwd *pw = getpwuid(st_uid); //for username
  97. struct group *gr = getgrgid(st_gid); //for groupname
  98.  
  99. if (pw == NULL) {
  100. printf("%d ", st_uid);
  101. } else {
  102. printf("%s ", pw->pw_name);
  103. }
  104.  
  105. if (gr == NULL) {
  106. printf("%d ", st_gid);
  107. } else {
  108. printf("%s ", gr->gr_name);
  109. }
  110. }
  111.  
  112. dir_info_arr *pr(dir_info_arr *arr, char *prefix) {
  113. struct stat sb;
  114. struct passwd *pw;
  115. struct group *gr;
  116.  
  117. char path[2048];
  118. char link_buff[1024];
  119. path[0] = 0;
  120. strcat(path, prefix);
  121. size_t len = strlen(path);
  122. if (path[len - 1] != '/') {
  123. path[len] = '/';
  124. ++len;
  125. }
  126.  
  127. size_t size_dirs = 0;
  128.  
  129. for (size_t i = 0; i < arr->size_; ++i) {
  130. if (arr->arr_[i]->d_name[0] == '.') {
  131. continue;
  132. }
  133. path[len] = 0;
  134. strcat(path, arr->arr_[i]->d_name);
  135. if (lstat(path, &sb) == -1) {
  136. perror("lstat");
  137. }
  138.  
  139. print_filetype(sb.st_mode);
  140. print_permissions(sb.st_mode);
  141. printf(" %lu ", sb.st_nlink);
  142. print_ug_name(sb.st_uid, sb.st_gid);
  143. printf("%lu %s", sb.st_size, arr->arr_[i]->d_name);
  144. if (S_ISLNK(sb.st_mode)) { //print symbolic link
  145. ssize_t l = readlink(path, link_buff, sizeof(link_buff));
  146. if (l >= 0) {
  147. link_buff[l] = 0;
  148. printf(" -> %s", link_buff);
  149. }
  150. }
  151. printf("\n");
  152.  
  153. if (S_ISDIR(sb.st_mode)) {
  154. arr->arr_[size_dirs] = arr->arr_[i];
  155. ++size_dirs;
  156. }
  157. /*if (arr->arr_[i]->d_type == FTW_D) {
  158. arr->arr_[size_dirs] = arr->arr_[i];
  159. ++size_dirs;
  160. }*/
  161. }
  162.  
  163. arr->size_ = size_dirs;
  164. return arr;
  165. }
  166.  
  167. void file_tree_walk(char *pathname, dir_info_arr *(*pr)(dir_info_arr *arr, char *prefix)) {
  168. DIR *dir = opendir(pathname);
  169. dir_info_arr *dia = new_dir_info_arr();
  170. struct dirent *dir_info;
  171.  
  172. if (dir) {
  173. printf("%s:\n", pathname);
  174. while ((dir_info = readdir(dir)) != NULL) {
  175. push_to_dir_info(dia, dir_info);
  176. }
  177. qsort(dia->arr_, dia->size_, sizeof(dia->arr_), cmpfunc);
  178. dia = pr(dia, pathname);
  179. char path[2048];
  180. path[0] = 0;
  181.  
  182. strcat(path, pathname);
  183. size_t len = strlen(path);
  184.  
  185. if (path[len - 1] != '/') {
  186. path[len] = '/';
  187. path[len + 1] = '\0';
  188. ++len;
  189. }
  190.  
  191. for (size_t i = 0; i < dia->size_; ++i) {
  192. path[len] = 0;
  193. strcat(path, dia->arr_[i]->d_name);
  194.  
  195. file_tree_walk(path, pr);
  196. }
  197. closedir(dir);
  198. } else {
  199. perror(pathname);
  200. return;
  201. }
  202. }
  203.  
  204. int main(int argc, char **argv) {
  205. if (argc == 1) {
  206. file_tree_walk(".", &pr);
  207. return 0;
  208. }
  209.  
  210. file_tree_walk(argv[1], &pr);
  211.  
  212. return 0;
  213. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement