1: /* 2: * Delete an MSDOS file 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(); 25: 26: main(argc, argv) 27: int argc; 28: char *argv[]; 29: { 30: int i, ismatch, entry, nogo, verbose, fargn; 31: unsigned int start; 32: char *filename, *newfile, *get_name(), *unix_name(), *get_path(); 33: char *pathname, ans[10], drive, get_drive(), last_drive, *fix_mcwd(); 34: void exit(), fat_write(), dir_write(), dir_flush(), disk_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 && !strcmp(argv[1], "-v")) { 42: verbose = 1; 43: fargn = 2; 44: } 45: else { 46: verbose = 0; 47: fargn = 1; 48: } 49: if (argc < 2 || (argv[1][0] == '-' && !verbose)) { 50: fprintf(stderr, "Mtools version %s, dated %s\n", VERSION, DATE); 51: fprintf(stderr, "Usage: %s [-v] msdosfile [msdosfiles...]\n", argv[0]); 52: exit(1); 53: } 54: last_drive = 'x'; 55: mcwd = fix_mcwd(); 56: 57: for (i = fargn; i < argc; i++) { 58: drive = get_drive(argv[i]); 59: if (drive != last_drive) { 60: if (last_drive != 'x') { 61: fat_write(); 62: dir_flush(); 63: disk_flush(); 64: } 65: 66: if (init(drive, 2)) { 67: fprintf(stderr, "%s: Cannot initialize '%c:'\n", argv[0], drive); 68: continue; 69: } 70: last_drive = drive; 71: } 72: filename = get_name(argv[i]); 73: pathname = get_path(argv[i]); 74: if (subdir(drive, pathname)) 75: continue; 76: 77: nogo = 0; 78: ismatch = 0; 79: for (entry = 0; entry < dir_entries; entry++) { 80: dir = dir_read(entry); 81: /* if empty */ 82: if (dir->name[0] == 0x0) 83: break; 84: /* if erased */ 85: if (dir->name[0] == 0xe5) 86: continue; 87: /* if dir or volume label */ 88: if ((dir->attr & 0x10) || (dir->attr & 0x08)) 89: continue; 90: 91: newfile = unix_name(dir->name, dir->ext); 92: /* see it if matches the pattern */ 93: if (match(newfile, filename)) { 94: if (verbose) 95: printf("Removing %s\n", newfile); 96: ismatch = 1; 97: if (dir->attr & 0x01) { 98: while (!nogo) { 99: printf("%s: \"%s\" is read only, erase anyway (y/n) ? ", argv[0], newfile); 100: gets(ans); 101: if (ans[0] == 'y' || ans[0] == 'Y') 102: break; 103: if (ans[0] == 'n' || ans[0] == 'N') 104: nogo = 1; 105: } 106: if (nogo) 107: continue; 108: } 109: start = dir->start[1] * 0x100 + dir->start[0]; 110: if (fat_free(start)) 111: break; 112: dir->name[0] = 0xe5; 113: dir_write(entry, dir); 114: } 115: } 116: if (fat_error) 117: break; 118: 119: if (!ismatch) 120: fprintf(stderr, "%s: File \"%s\" not found\n", argv[0], filename); 121: } 122: /* write the FAT, flush the buffers */ 123: fat_write(); 124: dir_flush(); 125: disk_flush(); 126: close(fd); 127: exit(0); 128: } 129: 130: /* 131: * Do a graceful exit if the program is interrupted. This will reduce 132: * (but not eliminate) the risk of generating a corrupted disk on 133: * a user abort. 134: */ 135: 136: static int 137: got_signal() 138: { 139: void exit(), disk_flush(), fat_write(), dir_flush(); 140: 141: if (fd < 0) 142: exit(1); 143: fat_write(); 144: dir_flush(); 145: disk_flush(); 146: close(fd); 147: exit(1); 148: }