/* * @(#) dirtree.c - Recursive directory lister. * (c) 1996 Ivan Maidanski http://ivmai.chat.ru * Freeware program source. All rights reserved. ** * Language: ANSI C * Tested with: Watcom C16 v10.0 * Last modified: 1996-07-11 16:50:00 GMT+04:00 */ #include #include #include #include /* */ #define DRIVESPEC ':' /* Drive letter delimiter in MS-DOS */ #define DELIMITER '\\' /* MS-DOS style of directory names delimiter */ #ifndef PATH_MAX #define PATH_MAX FILENAME_MAX /* MS-DOS style of path name length */ #endif #define SPECIALCH '.' /* for '.' and '..' files */ void putnspace(int n) { while (n--) putchar(' '); } void printerror(char *errmsg,char *path) { fputs("Error: ",stderr); fputs(errmsg,stderr); fputs(" - ",stderr); fputs(path,stderr); fputs("\n",stderr); } int checkfilename(char *path) { struct stat info; char *pc=strchr(path,'\0'); if (path==pc || *(pc-1)==DRIVESPEC) { *pc=DELIMITER; *(pc+1)='\0'; } if (stat(path,&info)<0) return (0); if (!*pc && S_ISDIR(info.st_mode)) { *pc=DELIMITER; *(pc+1)='\0'; } return (1); } int findnextname(char *path) { DIR *dirp; struct dirent *entry; char savech,*pc=strchr(path,'\0'); char *name; do pc--; while (*pc!=DELIMITER); name=pc+1; if (path==pc || *(pc-1)==DRIVESPEC) pc++; savech=*pc; *pc='\0'; if (!(dirp=opendir(path))) { printerror("Cannot open directory",path); return (0); } *pc=savech; if (*name) { do entry=readdir(dirp); while (entry && strcmp(&entry->d_name[0],name)); if (!entry) { printerror("Cannot find file",path); closedir (dirp); *pc='\0'; return (0); } } do entry=readdir(dirp); while (entry && entry->d_name[0]==SPECIALCH); if (!entry) { closedir (dirp); *pc='\0'; return (0); } strcpy(name,&entry->d_name[0]); closedir(dirp); return (1); } void printtree(char *path) { int level=0; do { if (*(strchr(path,'\0')-1)==DELIMITER) level++; while (level && !findnextname(path)) level--; if (level) { char *name; checkfilename(path); name=strchr(path,'\0')-1; while (*(name-1)!=DELIMITER) name--; putnspace(level); puts(name); } } while (level); } int main(int argc,char *argv[]) { static char path[PATH_MAX+2]; if (argc!=2) puts("Directory Tree.\n" "Usage:\n" " DIRTREE pathname [ > filelist ]"); if (argc>2) { fputs("Error: Too many arguments!\n",stderr); return (2); } if (argc==2) if (strlen(argv[1])>PATH_MAX) { fputs("Error: Path name too long!\n",stderr); return (2); } else if (argv[1][0]!='\0') { char *pc; strcpy(&path[0],argv[1]); if (*(pc=strchr(&path[0],'\0')-1)==DELIMITER) *pc='\0'; if (!checkfilename(path)) { printerror("Invalid file name",path); return (1); } puts(path); printtree(&path[0]); } return (0); }