myls.c 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255
  1. #define _POSIX_C_SOURCE 200809L
  2. #include <stdlib.h>
  3. #include <stdio.h>
  4. #include <dirent.h>
  5. #include <sys/types.h>
  6. #include <sys/stat.h>
  7. #include <unistd.h>
  8. #include <string.h>
  9. #include <grp.h>
  10. #include <pwd.h>
  11. #include "error.h"
  12. #include "color.h"
  13. #include "myls.h"
  14. void printls(char* path, char* filename){
  15. int length;
  16. char* completePath;
  17. char permission[11];
  18. char mois[5];
  19. struct stat info;
  20. struct group* grp;
  21. struct passwd* user;
  22. struct tm* date;
  23. //Création chemin vers le fichier
  24. length = strlen(path) + strlen(filename) + 2;
  25. completePath = malloc(sizeof(char) * length);
  26. memset(completePath, 0, length);
  27. if(path[strlen(path)-1] != '/'){
  28. snprintf(completePath, length, "%s/%s", path, filename);
  29. } else {
  30. snprintf(completePath, length, "%s%s", path, filename);
  31. }
  32. //Recup info fichier
  33. if(stat(completePath, &info) == ERR){
  34. addperror("Erreur stat");
  35. return;
  36. }
  37. //Calcul permission
  38. memset(permission, 0, 11);
  39. if(S_ISDIR(info.st_mode)){
  40. permission[0] = 'd';
  41. }
  42. else if(S_ISBLK(info.st_mode)){
  43. permission[0] = 'b';
  44. }
  45. else if(S_ISCHR(info.st_mode)){
  46. permission[0] = 'c';
  47. }
  48. #ifdef S_ISFIFO
  49. else if(S_ISFIFO(info.st_mode)){
  50. permission[0] = 'p';
  51. }
  52. #endif
  53. #ifdef S_ISLINK
  54. else if(S_ISLINK(info.st_mode)){
  55. permission[0] = 'l';
  56. }
  57. #endif
  58. #ifdef S_ISSOCK
  59. else if(S_ISSOCK(info.st_mode)){
  60. permission[0] = 's';
  61. }
  62. #endif
  63. else
  64. permission[0] = '-';
  65. info.st_mode & S_IRUSR ? (permission[1] = 'r') : (permission[1] = '-');
  66. info.st_mode & S_IWUSR ? (permission[2] = 'w') : (permission[2] = '-');
  67. info.st_mode & S_IXUSR ? (permission[3] = 'x') : (permission[3] = '-');
  68. info.st_mode & S_IRGRP ? (permission[4] = 'r') : (permission[4] = '-');
  69. info.st_mode & S_IWGRP ? (permission[5] = 'w') : (permission[5] = '-');
  70. info.st_mode & S_IXGRP ? (permission[6] = 'x') : (permission[6] = '-');
  71. info.st_mode & S_IROTH ? (permission[7] = 'r') : (permission[7] = '-');
  72. info.st_mode & S_IWOTH ? (permission[8] = 'w') : (permission[8] = '-');
  73. info.st_mode & S_IXOTH ? (permission[9] = 'x') : (permission[9] = '-');
  74. //Recup le groupe et l'utilisateur
  75. grp = getgrgid(info.st_gid);
  76. user = getpwuid(info.st_uid);
  77. //Recup la date
  78. memset(mois, 0, 5);
  79. date = gmtime(&info.st_mtime);
  80. switch(date->tm_mon){
  81. case 0:
  82. strcpy(mois, "jan.");
  83. break;
  84. case 1:
  85. strcpy(mois, "fev.");
  86. break;
  87. case 2:
  88. strcpy(mois, "mar.");
  89. break;
  90. case 3:
  91. strcpy(mois, "avr.");
  92. break;
  93. case 4:
  94. strcpy(mois, "mai.");
  95. break;
  96. case 5:
  97. strcpy(mois, "jui.");
  98. break;
  99. case 6:
  100. strcpy(mois, "jul.");
  101. break;
  102. case 7:
  103. strcpy(mois, "aou.");
  104. break;
  105. case 8:
  106. strcpy(mois, "sep.");
  107. break;
  108. case 9:
  109. strcpy(mois, "oct.");
  110. break;
  111. case 10:
  112. strcpy(mois, "nov.");
  113. break;
  114. case 11:
  115. strcpy(mois, "dec.");
  116. break;
  117. }
  118. //Affiche
  119. printf("%s 1 %s %s %s %d %d:%d %ld ", permission, user->pw_name, grp->gr_name, mois, date->tm_mday, date->tm_hour, date->tm_min, info.st_size);
  120. //color the name
  121. if(permission[0] == 'd'){
  122. printf(BLUE "%s\n" RESET, filename);
  123. }
  124. else if(permission[3] == 'x'){
  125. printf(GREEN "%s\n" RESET, filename);
  126. }
  127. else{
  128. printf("%s\n", filename);
  129. }
  130. }
  131. void printdir(char* path, boolean subdir, boolean hidden){
  132. struct dirent** contentsDir;
  133. int nbFile;
  134. int j = 0;
  135. //Recup info
  136. if((nbFile = scandir(path, &contentsDir, 0, alphasort)) == ERR){
  137. addperror("Erreur scandir()");
  138. return;
  139. }
  140. //Si sous dossier on affiche le dossier d'origine
  141. if(subdir){
  142. printf("%s :\n", path);
  143. }
  144. //Si besoins passe les fichiers cachés
  145. while(j < nbFile && !hidden && *contentsDir[j]->d_name == '.') j++;
  146. //Parcours les fichiers du dossier
  147. while(j < nbFile){
  148. printls(path, contentsDir[j]->d_name);
  149. j++;
  150. }
  151. //Si on affiche les sous dossiers on parcours le contenue pour les trouver
  152. if(subdir){
  153. char* completePath;
  154. int length;
  155. struct stat info;
  156. j = 0;
  157. //Si besoins passe les fichiers cachés
  158. while(j < nbFile && !hidden && *contentsDir[j]->d_name == '.') j++;
  159. //Cherche les sous dossiers
  160. while(j < nbFile){
  161. length = strlen(contentsDir[j]->d_name);
  162. if(strncmp(contentsDir[j]->d_name, ".", length) == 0 || strncmp(contentsDir[j]->d_name, "..", length) == 0){
  163. j++;
  164. continue;
  165. }
  166. //Création chemin vers le dossier
  167. length += strlen(path) + 2;
  168. completePath = malloc(sizeof(char) * length);
  169. memset(completePath, 0, length);
  170. if(path[strlen(path)-1] != '/'){
  171. snprintf(completePath, length, "%s/%s", path, contentsDir[j]->d_name);
  172. } else {
  173. snprintf(completePath, length, "%s%s", path, contentsDir[j]->d_name);
  174. }
  175. //Recup info fichier
  176. if(stat(completePath, &info) == ERR){
  177. addperror("Erreur stat");
  178. free(completePath);
  179. j++;
  180. continue;
  181. }
  182. //Si c'est un dossier
  183. if(S_ISDIR(info.st_mode)){
  184. //On l'affiche
  185. printf("\n");
  186. printdir(completePath, subdir, hidden);
  187. }
  188. //Tour suivant
  189. free(completePath);
  190. j++;
  191. }
  192. }
  193. //Nettoyage
  194. while (nbFile--) {
  195. free(contentsDir[nbFile]);
  196. }
  197. free(contentsDir);
  198. }
  199. int main(int argc, char* argv[]){
  200. struct stat info;
  201. int i = 1, displayed = 0, opt;
  202. boolean hiddenFile = false;
  203. boolean displaySubDir = false;
  204. //Gestion des options
  205. while((opt = getopt(argc, argv, "aR")) != ERR){
  206. switch(opt){
  207. case 'a' :
  208. hiddenFile = true;
  209. break;
  210. case 'R' :
  211. displaySubDir = true;
  212. break;
  213. default:
  214. addperror("getotp error");
  215. }
  216. }
  217. //Time to display
  218. for(i = 1; i < argc; i++){
  219. if(argv[i][0] != '-'){
  220. if(stat(argv[i], &info) == ERR){
  221. addperror("Erreur stat");
  222. return EXIT_FAILURE;
  223. }
  224. if(S_ISDIR(info.st_mode)){
  225. //Affiche le dossier
  226. printdir(argv[i], displaySubDir, hiddenFile);
  227. displayed = true;
  228. }
  229. else{
  230. //printls(argv[i]);
  231. displayed = true;
  232. }
  233. }
  234. }
  235. //Si aucun dossier ou fichier en argument
  236. if(!displayed){
  237. //On affiche le dossier courrant
  238. printdir(".", displaySubDir, hiddenFile);
  239. }
  240. return EXIT_SUCCESS;
  241. }