fork download
  1. #include <stdio.h>
  2. #include <sys/types.h>
  3. #include <sys/stat.h>
  4. #include <pwd.h>
  5. #include <grp.h>
  6. #include <fcntl.h>
  7. #include <dirent.h>
  8. #include <unistd.h>
  9. #include <string.h>
  10. #include <time.h>
  11. #include <stdlib.h>
  12. #include <limits.h>
  13.  
  14. int islsflag(char * arg);
  15. int printout(char * dir, int Rflag, int lflag, int gflag);
  16.  
  17. int main(int argc,char ** argv){
  18. int lflag=0,gflag=0,Rflag=0;
  19. int argexist=0; //флаг существования аргументов - каталогов
  20. for (int i=1;i<argc;i++)
  21. if (islsflag(argv[i])){
  22. char c;
  23. for (int j=1;(c=argv[i][j])!='\0';j++){
  24. if (c=='l') lflag=1;
  25. else if (c=='g') gflag=1;
  26. if (c=='R') Rflag=1;
  27. }
  28. }
  29. else argexist=1;
  30. if (lflag && gflag){
  31. fprintf(stderr,"ls: wrong usage of flags");
  32. return 1;
  33. }
  34.  
  35. char l[PATH_MAX];
  36. getcwd(l,PATH_MAX);
  37.  
  38. if (argexist){
  39. for (int i=1;i<argc;i++) if (!islsflag(argv[i])){
  40. char s[PATH_MAX];
  41. strcpy(s,l);
  42. strcat(s,"/");
  43. strcat(s,argv[i]);
  44. if (!Rflag) printf("%s:\n",argv[i]);
  45. if (!islsflag(argv[i]) && printout(s,Rflag,lflag,gflag))
  46. return 1; //в printout произошла ошибка
  47. }
  48. return 0; //ошибок не произошло
  49. }
  50. return printout(l,Rflag,lflag,gflag);
  51.  
  52. }
  53.  
  54. /* возвращает 0, если аргумент - не флаг, и 1 - если флаг*/
  55. int islsflag(char * arg){
  56. if (arg[0]=='-'){
  57. char c;
  58. for (int j=1;(c=arg[j])!='\0';j++){
  59. if ( (c!='l') && (c!='g') && (c!='R') )
  60. return 0;
  61. }
  62. return 1;
  63. }
  64. return 0;
  65. }
  66.  
  67. /* показать тип файла в первой позиции выходной строки */
  68. void display_file_type(int st_mode){
  69. switch ( st_mode & S_IFMT ){
  70. case S_IFDIR: putchar ( 'd' ); return;
  71. case S_IFCHR: putchar ( 'c' ); return;
  72. case S_IFBLK: putchar ( 'b' ); return;
  73. case S_IFREG: putchar ( '-' ); return;
  74. case S_IFLNK: putchar ( 'l' ); return;
  75. case S_IFSOCK: putchar ( 's' ); return;
  76. }
  77. }
  78.  
  79. /* показать права доступа для владельца, группы и прочих пользователей, а также все спец.флаги*/
  80. void display_permission(int st_mode){
  81. static const char rwxmas[10] = "rwxrwxrwx";
  82. char amode[10];
  83. int i, j;
  84.  
  85. for ( i = 0, j = ( 1 << 8 ); i < 9; i++, j >>= 1 )
  86. amode[i] = (st_mode&j) ? rwxmas[i]: '-';
  87. if ( st_mode & S_ISUID ) amode[2]= 's';
  88. if ( st_mode & S_ISGID ) amode[5]= 's';
  89. if ( st_mode & S_ISVTX ) amode[8]= 't';
  90. amode[9]='\0';
  91. printf ( "%s ",amode );
  92. }
  93.  
  94. char * settime(struct tm *u){
  95. char *s;
  96. int size=20;
  97. char *tmp;
  98. int length;
  99. s=(char*)malloc(size);
  100.  
  101. while (!(length=strftime(s,size,"%d.%m.%Y %H:%M:%S",u))){
  102. size+=10;
  103. s=(char*)realloc(s,size);
  104. }
  105. /* в строку s скопируем строку из кавычек, заменяя спецификаторы
  106. * данными из структуры времени, не более size символов*/
  107.  
  108. tmp=(char*)malloc(sizeof(s));
  109. strcpy(tmp,s);
  110. return(tmp);
  111. }
  112.  
  113. /* перечислить атрибуты одного файла*/
  114. /* от lflag (0 или 1) зависит, будет ли выводиться имя владельца*/
  115. void long_list(char * path_name, char * fname, int lflag){
  116. struct stat statv;
  117. struct passwd *pw_d;
  118. struct group *grpv;
  119. struct tm *timev;
  120.  
  121. if (lstat(path_name,&statv)){
  122. perror(path_name);
  123. return;
  124. }
  125. display_file_type(statv.st_mode);
  126. display_permission(statv.st_mode);
  127. printf("%4ld ",statv.st_nlink); /*значение счетчика жестких связей*/
  128.  
  129. if (lflag){
  130. if ((pw_d=getpwuid(statv.st_uid))==NULL){
  131. /* преобразовать UID в имя пользователя*/
  132. perror("");
  133. return;
  134. }
  135. printf ("%s ",pw_d->pw_name);
  136. }
  137.  
  138. if ((grpv=getgrgid(statv.st_gid))==NULL){
  139. /* преобразовать gid в имя группы*/
  140. perror("");
  141. return;
  142. }
  143. printf("%s ",grpv->gr_name);
  144.  
  145. /* показать размер файла*/
  146. printf("%8ld ",statv.st_size);
  147.  
  148. /* показать время последнего изменения файла*/
  149. const time_t ctime=statv.st_ctime;
  150. timev=localtime(&ctime);
  151. char * strtime=settime(timev);
  152. printf("%s",strtime);
  153.  
  154. /* показать имя файла*/
  155. printf(" %s\n", fname);
  156. }
  157.  
  158.  
  159.  
  160. /* вывод, возвращает 0, если ошибок нет, 1 - если есть*/
  161. int printout(char * dir,int Rflag,int lflag,int gflag){
  162. DIR *d;
  163. struct dirent *dd;
  164. off_t o;
  165. struct stat s;
  166. char name[PATH_MAX];
  167. char *delim="/";
  168.  
  169. /* если в качестве каталога передан корневой, то разделитель '/' не нужен*/
  170. if (!strcmp(dir, "/")) delim= "";
  171.  
  172. if (!(d=opendir(dir))){
  173. perror(dir);
  174. return 1;
  175. }
  176. if (Rflag) printf("%s:\n",dir);
  177. while ((dd=readdir(d))){
  178. if(!strcmp(dd->d_name, ".") || !strcmp(dd->d_name, ".."))
  179. continue;
  180.  
  181. //сформируем полный путь
  182. snprintf(name, PATH_MAX, "%s%s%s", dir, delim, dd->d_name);
  183.  
  184. if(lstat(name, &s) < 0)
  185. continue;
  186. if (lflag || gflag){
  187. printf(" ");
  188. long_list(name, dd->d_name, lflag); //вывод полной информации
  189. }
  190. else
  191. printf("%s ",dd->d_name);//только имя
  192. }
  193. if (!lflag && !gflag) printf("\n");
  194.  
  195. if (!Rflag) return 0;
  196. if (!strcmp(dir,"..") || !strcmp(dir,".")) return 0;
  197. printf("\n");
  198. seekdir(d,0);
  199. snprintf(name, PATH_MAX, "%s%s", dir, delim);
  200. while ((dd=readdir(d))){
  201. if(!strcmp(dd->d_name, ".") || !strcmp(dd->d_name, ".."))
  202. continue;
  203. char mas[PATH_MAX];
  204. strcpy(mas,name);
  205. strcat(mas,dd->d_name);
  206. if(lstat(mas, &s) < 0)
  207. continue;
  208. if(S_ISDIR(s.st_mode)){
  209. //если это каталог
  210. char mas[PATH_MAX];
  211. o=telldir(d); //запомнить место в записи
  212. closedir(d); //для экономии дескрипторов
  213. strcpy(mas,name);
  214. strcat(mas,dd->d_name);
  215.  
  216. chdir(mas);
  217. if (printout(mas,Rflag,lflag,gflag)) return 1;
  218. chdir(name);
  219. //вернемся в прежнюю директорию
  220. if(!(d=opendir(dir))) {
  221. perror(dir);
  222. return 1;
  223. }
  224. seekdir(d, o); //вернуться на прежнее место
  225. }
  226. }
  227. closedir(d);
  228. return 0;
  229. }
Compilation error #stdin compilation error #stdout 0s 0KB
stdin
Standard input is empty
compilation info
prog.c: In function ‘display_file_type’:
prog.c:69:21: error: ‘S_IFMT’ undeclared (first use in this function); did you mean ‘S_IXOTH’?
  switch ( st_mode & S_IFMT ){
                     ^~~~~~
                     S_IXOTH
prog.c:69:21: note: each undeclared identifier is reported only once for each function it appears in
prog.c:70:15: error: ‘S_IFDIR’ undeclared (first use in this function); did you mean ‘S_ISDIR’?
          case S_IFDIR:  putchar ( 'd' ); return;
               ^~~~~~~
               S_ISDIR
prog.c:71:15: error: ‘S_IFCHR’ undeclared (first use in this function); did you mean ‘S_ISCHR’?
          case S_IFCHR:  putchar ( 'c' ); return;
               ^~~~~~~
               S_ISCHR
prog.c:72:15: error: ‘S_IFBLK’ undeclared (first use in this function); did you mean ‘S_ISBLK’?
          case S_IFBLK:  putchar ( 'b' ); return;
               ^~~~~~~
               S_ISBLK
prog.c:73:15: error: ‘S_IFREG’ undeclared (first use in this function); did you mean ‘S_ISREG’?
          case S_IFREG:  putchar ( '-' ); return;
               ^~~~~~~
               S_ISREG
prog.c:74:15: error: ‘S_IFLNK’ undeclared (first use in this function); did you mean ‘S_ISLNK’?
          case S_IFLNK:  putchar ( 'l' ); return;
               ^~~~~~~
               S_ISLNK
prog.c:75:15: error: ‘S_IFSOCK’ undeclared (first use in this function); did you mean ‘S_ISLNK’?
          case S_IFSOCK: putchar ( 's' ); return;
               ^~~~~~~~
               S_ISLNK
prog.c: In function ‘display_permission’:
prog.c:89:17: error: ‘S_ISVTX’ undeclared (first use in this function); did you mean ‘S_ISCHR’?
  if ( st_mode & S_ISVTX )   amode[8]= 't';
                 ^~~~~~~
                 S_ISCHR
prog.c: In function ‘long_list’:
prog.c:121:6: warning: implicit declaration of function ‘lstat’; did you mean ‘fstat’? [-Wimplicit-function-declaration]
  if (lstat(path_name,&statv)){
      ^~~~~
      fstat
prog.c: In function ‘printout’:
prog.c:198:2: warning: implicit declaration of function ‘seekdir’; did you mean ‘readdir’? [-Wimplicit-function-declaration]
  seekdir(d,0);
  ^~~~~~~
  readdir
prog.c:211:6: warning: implicit declaration of function ‘telldir’; did you mean ‘lldiv’? [-Wimplicit-function-declaration]
    o=telldir(d); //запомнить место в записи
      ^~~~~~~
      lldiv
prog.c: In function ‘main’:
prog.c:36:2: warning: ignoring return value of ‘getcwd’, declared with attribute warn_unused_result [-Wunused-result]
  getcwd(l,PATH_MAX);
  ^~~~~~~~~~~~~~~~~~
prog.c: In function ‘printout’:
prog.c:216:4: warning: ignoring return value of ‘chdir’, declared with attribute warn_unused_result [-Wunused-result]
    chdir(mas);
    ^~~~~~~~~~
prog.c:218:4: warning: ignoring return value of ‘chdir’, declared with attribute warn_unused_result [-Wunused-result]
    chdir(name);
    ^~~~~~~~~~~
stdout
Standard output is empty