/* Program: DELDIR.C Author : Kim Moser Date : March 17, 1991 System : IBM PC / Borland Turbo C 2.0 Descrip: Removes named directory (deleting any files in it); optionally does subdirectories. */ #include #include #include #include #include #include static int ASK_FIRST = 1; /* Assume */ static void usage(void); static void usage(void) { fputs("\ usage: DELDIR [-a] \n\ Removes specified directory(ies) (and any files within).\n\ '-a' for automatic mode (skips confirmation before deleting files)\n\ ", stderr); exit(-1); } static int process_directory(char *dirname); static int process_directory(char *dirname) /* 'dname' is full name of directory to remove; may contain files and/or subdirs; must NOT contain trailing backslash or wildcards! */ { static int level=0; int dirsfiles; /* 0=doing directories, 1=doing other files */ struct ffblk info; int first=1; char *fname = NULL; /* E.g. "C:\USR\MISC" */ char *maskfname = NULL; /* E.g. "C:\USR\MISC\*.*" */ printf("%*sDirectory '%s'\n", level, "", dirname ); for (dirsfiles=0; dirsfiles <= 1; dirsfiles++) { printf("%*s%s\n", level, "", dirsfiles ? "Doing files:" : "Doing subdirs:" ); first = 1; /* Create 'maskfname' (i.e. complete filespec): */ if (maskfname != NULL) free(maskfname); if ((maskfname = (char*) malloc(strlen(dirname)+13)) == NULL) { fprintf(stderr, "malloc() failed for maskfname.\n"); exit(-1); } strcpy(maskfname, dirname); /* maskfname = dirname + ['\'] "*.*": */ if (maskfname[strlen(dirname)-1] != '\\' && maskfname[strlen(dirname)-1] != ':') { strcat(maskfname, "\\"); } strcat(maskfname, "*.*"); #if 0 printf("%*smask = '%s'\n", level, "", maskfname ); #endif while (first ? !findfirst(maskfname, &info, (dirsfiles ? ~FA_DIREC : FA_DIREC)) : !findnext(&info)) { first = 0; /* fname = dirname + ['\'] + info.ff_name: */ if (fname != NULL) free(fname); if ((fname = (char*) malloc(strlen(dirname)+13)) == NULL) { fprintf(stderr, "malloc() failed for fname.\n"); exit(-1); } strcpy(fname, dirname); /* fname = dirname + ['\'] + ff_blk.ff_name: */ if (fname[strlen(dirname)-1] != '\\' && fname[strlen(dirname)-1] != ':') { strcat(fname, "\\"); } strcat(fname, info.ff_name); if (dirsfiles) { /* Doing files, so delete 'em: */ if (unlink(fname)) { fprintf(stderr, "unlink(\"%s\") failed.\n", fname); } #if 0 printf("%*sdelete file '%s'\n", level, "", fname ); #endif } else { /* Go through subdirectories: */ /* If it's a directory, and it's NOT named "." or ".." then recurse it: */ if ((info.ff_attrib & FA_DIREC) && (strcmp(info.ff_name, ".") && strcmp(info.ff_name, ".."))) { /* Doing subdirectories, so recurse it... */ #if 0 printf("%*s(recurse directory '%s')\n", level, "", fname ); #endif level++; process_directory(fname); level--; /* ...then delete it, since now it's (hopefully) empty: */ if (rmdir(fname)) { fprintf(stderr, "rmdir(\"%s\") failed.\n", fname); } #if 0 printf("%*srmdir '%s'\n", level, "", fname ); #endif } } } } if (fname != NULL) free(fname); if (maskfname != NULL) free(maskfname); return (1); } void main(int argc, char **argv) { int i; int any_done = 0; struct ffblk info; int first=1; char *dirname; int j; for (i=1; i < argc; i++) { if (argv[i][0] == '-') { switch (toupper(argv[i][1])) { case 'A': ASK_FIRST = 0; break; default: usage(); break; } } else { any_done = 1; if ((dirname = malloc(strlen(argv[i]) + 13)) == NULL) { fprintf(stderr, "malloc() failed.\n"); exit(-1); } while (first ? !findfirst(argv[i], &info, FA_DIREC) : !findnext(&info)) { first = 0; /* If it's a directory, and it's NOT named "." or ".." then process it: */ if ((info.ff_attrib & FA_DIREC) && (strcmp(info.ff_name, ".") && strcmp(info.ff_name, ".."))) { strcpy(dirname, argv[i]); if ((strchr(dirname, '?') != NULL) || (strchr(dirname, '*') != NULL)) { strcat(dirname, info.ff_name); /* Add info.ff_name in appropriate spot: */ for (j=strlen(dirname)-1; j>=0; j--) { if (dirname[j] == '\\' || dirname[j] == ':') break; } strcpy(dirname+j+1, info.ff_name); } process_directory(dirname); printf("remove dir '%s'\n", dirname); if (rmdir(dirname)) { fprintf(stderr, "rmdir(\"%s\") failed.\n", dirname); } } } } } if (!any_done) usage(); exit(0); }