1: /* 2: * Delete an MSDOS subdirectory 3: * 4: * Emmet P. Gray US Army, HQ III Corps & Fort Hood 5: * ...!uunet!uiucuxc!fthood!egray Attn: AFZF-DE-ENV 6: * fthood!egray@uxc.cso.uiuc.edu Directorate of Engineering & Housing 7: * Environmental Management Office 8: * Fort Hood, TX 76544-5057 9: */ 10: 11: #include <stdio.h> 12: #include <signal.h> 13: #include "msdos.h" 14: #include "patchlevel.h" 15: 16: int fd = -1; /* the file descriptor for the device */ 17: int dir_start; /* starting sector for directory */ 18: int dir_len; /* length of directory (in sectors) */ 19: int dir_entries; /* number of directory entries */ 20: int clus_size; /* cluster size (in sectors) */ 21: char *mcwd; /* the Current Working Directory */ 22: int fat_error; /* FAT error detected? */ 23: 24: static int got_signal(), is_empty(); 25: 26: main(argc, argv) 27: int argc; 28: char *argv[]; 29: { 30: int i, ismatch, entry, oops, empty; 31: unsigned int start; 32: char *filename, *newfile, *get_name(), drive, *pathname, *get_path(); 33: char *unix_name(), get_drive(), last_drive, *fix_mcwd(); 34: void exit(), fat_write(), dir_write(), disk_flush(), dir_flush(); 35: struct directory *dir, *dir_read(); 36: /* catch signals */ 37: signal(SIGINT, (SIG_TYPE(*) ()) got_signal); 38: signal(SIGTERM, (SIG_TYPE(*) ()) got_signal); 39: signal(SIGQUIT, (SIG_TYPE(*) ()) got_signal); 40: 41: if (argc == 1) { 42: fprintf(stderr, "Mtools version %s, dated %s\n", VERSION, DATE); 43: fprintf(stderr, "Usage: %s mdsosdirectory [msdosdirectories...]\n", argv[0]); 44: exit(1); 45: } 46: 47: last_drive = 'x'; 48: mcwd = fix_mcwd(); 49: 50: for (i = 1; i < argc; i++) { 51: drive = get_drive(argv[i]); 52: if (drive != last_drive) { 53: if (last_drive != 'x') { 54: fat_write(); 55: dir_flush(); 56: disk_flush(); 57: } 58: 59: if (init(drive, 2)) { 60: fprintf(stderr, "%s: Cannot initialize '%c:'\n", argv[0], drive); 61: continue; 62: } 63: last_drive = drive; 64: } 65: 66: filename = get_name(argv[i]); 67: pathname = get_path(argv[i]); 68: if (subdir(drive, pathname)) 69: continue; 70: 71: oops = 0; 72: ismatch = 0; 73: for (entry = 0; entry < dir_entries; entry++) { 74: dir = dir_read(entry); 75: /* if empty */ 76: if (dir->name[0] == 0x0) 77: break; 78: /* if erased */ 79: if (dir->name[0] == 0xe5) 80: continue; 81: /* if not dir */ 82: if (!(dir->attr & 0x10)) 83: continue; 84: 85: newfile = unix_name(dir->name, dir->ext); 86: if (match(newfile, filename)) { 87: start = dir->start[1] * 0x100 + dir->start[0]; 88: if ((empty = is_empty(start)) < 0) 89: break; 90: if (!empty) { 91: fprintf(stderr, "%s: Directory \"%s\" is not empty\n", argv[0], filename); 92: oops++; 93: break; 94: } 95: if (!start) { 96: fprintf(stderr, "%s: Can't remove root directory\n", argv[0]); 97: oops++; 98: break; 99: } 100: if (fat_free(start)) 101: break; 102: dir->name[0] = 0xe5; 103: dir_write(entry, dir); 104: ismatch = 1; 105: } 106: } 107: if (fat_error) 108: break; 109: 110: if (oops) 111: continue; 112: 113: if (!ismatch) 114: fprintf(stderr, "%s: Directory \"%s\" not found\n", argv[0], filename); 115: } 116: /* write the FAT, flush the buffers */ 117: fat_write(); 118: dir_flush(); 119: disk_flush(); 120: close(fd); 121: exit(0); 122: } 123: 124: /* 125: * See if directory is empty. Returns 1 if empty, 0 if not, and -1 on error. 126: * Can't use subdir() and dir_read() as it would clobber the globals. 127: */ 128: 129: static int 130: is_empty(fat) 131: unsigned int fat; 132: { 133: register int i; 134: int next, buflen; 135: long sector; 136: extern unsigned int last_fat, fat_decode(); 137: unsigned char tbuf[MAX_CLUSTER]; 138: void disk_read(); 139: 140: /* CONSTCOND */ 141: while (1) { 142: sector = (long) (fat - 2) * clus_size + dir_start + dir_len; 143: buflen = clus_size * MSECTOR_SIZE; 144: disk_read(sector, tbuf, buflen); 145: 146: /* check first character of name */ 147: for (i = 0; i < MSECTOR_SIZE; i += MDIR_SIZE) { 148: if (tbuf[i] == '.') 149: continue; 150: if (tbuf[i] != 0x0 && tbuf[i] != 0xe5) 151: return(0); 152: } 153: /* get next cluster number */ 154: next = fat_decode(fat); 155: if (next == 1) { 156: fprintf(stderr, "is_empty: FAT problem\n"); 157: return(-1); 158: } 159: /* end of cluster chain */ 160: if (next >= last_fat) 161: break; 162: fat = next; 163: } 164: return(1); 165: } 166: 167: /* 168: * Do a graceful exit if the program is interrupted. This will reduce 169: * (but not eliminate) the risk of generating a corrupted disk on 170: * a user abort. 171: */ 172: 173: static int 174: got_signal() 175: { 176: void exit(), disk_flush(), fat_write(), dir_flush(); 177: 178: if (fd < 0) 179: exit(1); 180: fat_write(); 181: dir_flush(); 182: disk_flush(); 183: close(fd); 184: exit(1); 185: }