|
|
1.1 ! root 1: /* ! 2: * dos0.c ! 3: * cc -o dos dos[01234].c ! 4: * Read, write or format an MS-DOS filesystem (default: INFILE in dos1.h). ! 5: * For usage, see USAGE in dos0.h. ! 6: * Understands DOS 2.0 tree structured disks. ! 7: * Understands 1.5 and 2-byte FAT entries; ! 8: * does not understand 4-byte FAT entries. ! 9: * Prints some debugging information if compiled -DDEBUG. ! 10: */ ! 11: ! 12: #include "dos0.h" ! 13: ! 14: /* Globals. */ ! 15: short oldstyle; /* Indicates the this was a dos */ ! 16: short aflag; /* ASCII text file */ ! 17: short bflag; /* Binary text file */ ! 18: unsigned char cohfile[NAMEMAX]; /* COHERENT filename */ ! 19: unsigned char cmd[6 + NAMEMAX]; /* system() command buffer */ ! 20: char * device = INFILE; /* Input device filename */ ! 21: short estat; /* Exit status */ ! 22: short (*fun)(); /* Function to execute */ ! 23: short kflag; /* Use mtime, not current time */ ! 24: short nflag; /* Sort by time, newest first */ ! 25: short fflag; /* Force removal of rdonly files*/ ! 26: long partseek; /* Extended MS-DOS part. seek */ ! 27: short pflag; /* Extract/replace is piped */ ! 28: DIR * root; /* Root directory */ ! 29: short sflag; /* Suppress subdirectory x/r */ ! 30: MDIR * volume; /* Volume label */ ! 31: ! 32: short xpart; /* Extended MS-DOS partition */ ! 33: char * base, basehold[35]; /* Base for path-including copies */ ! 34: char * base1; ! 35: ! 36: char ext[512]; /* Ascii Extension list */ ! 37: short sext = 0; /* size of extension list */ ! 38: short numargs; ! 39: short isdir_keep; ! 40: ! 41: char *tran_dev(); ! 42: char *tran_file(); ! 43: short die_signal(); ! 44: ! 45: main(argc, argv) short argc; char *argv[]; ! 46: { ! 47: register short mode; ! 48: short tv, c, i = 0, dev = 2, j, k = 0, dargs = 0; ! 49: char *tmp; ! 50: ! 51: argv0 = argv[0]; ! 52: ! 53: if (strcmp((argv[0] + strlen(argv[0]) - 3), "dos")) { ! 54: usagemsg = USAGE; ! 55: if (argc < 2) ! 56: usage(NULL); ! 57: ! 58: mode = 2; ! 59: tmp = argv[0]; ! 60: if ((*argv[1] == '-') && (argv[1][1] != '\0')) { ! 61: while ((c = *argv[1]++) != '\0') { ! 62: dargs = 1; ! 63: switch (c) { ! 64: case 'a': ! 65: case 'm': aflag++; break; ! 66: case 'b': ! 67: case 'r': bflag++; break; ! 68: case 'k': kflag++; break; ! 69: case 'f': fflag++; break; ! 70: case 's': sflag++; break; ! 71: case 'n': nflag++; break; ! 72: case 'v': vflag++; break; ! 73: case '1': ! 74: case '2': ! 75: case '3': ! 76: case '4': ! 77: case '5': ! 78: case '6': ! 79: case '7': ! 80: case '8': ! 81: case '9': xpart = c - '0'; ! 82: break; ! 83: case '-': break; ! 84: default: ! 85: fatal1("Invalid argument %c", c); ! 86: break; ! 87: } ! 88: } ! 89: } ! 90: else ! 91: dev--; ! 92: ! 93: if ((strstr(tmp, "cp")) || (strstr(tmp, "copy"))) { ! 94: if (!strstr(tmp, "dir")) ! 95: sflag++; ! 96: if (dev+2 > argc) ! 97: fatal1("Copy must include both a source and a" ! 98: " destination\n"); ! 99: c=0; ! 100: for (j=dev; j < argc; j++) ! 101: if (strchr(argv[j], ':')) { ! 102: k++; ! 103: c=j; ! 104: } ! 105: if (k>1) ! 106: fatal1("Copy can only specify one DOS devic" ! 107: "e at a time.\n"); ! 108: else if (!k) ! 109: fatal1("Use cp for COHERENT-COHERENT copies.\n"); ! 110: if (c == dev) { ! 111: mode = 0; ! 112: fun = extract; ! 113: device = tran_dev(argv[dev]); ! 114: if((argv[dev] = tran_file(argv[dev])) != NULL) ! 115: tv=1; ! 116: else ! 117: tv=0; ! 118: tmp = &argv[dev]; ! 119: base1 = argv[dev+1]; ! 120: } ! 121: else { ! 122: fun = replace; ! 123: device = tran_dev(argv[argc-1]); ! 124: base1 = tran_file(argv[argc-1]); ! 125: argv[argc-1] = NULL; ! 126: tv = argc - (1 + dev); ! 127: tmp = &argv[dev]; ! 128: } ! 129: } ! 130: else if (strstr(tmp, "format")) { ! 131: tv=argc - (2 + dargs); ! 132: tmp = &argv[dev+1]; ! 133: device = tran_dev(argv[dev]); ! 134: fun = format; ! 135: } ! 136: else if (strstr(tmp, "mkdir")) { ! 137: if (argc > 2 + dargs) ! 138: fatal("Too many arguments for MKDIR\n"); ! 139: ! 140: device = tran_dev(argv[dev]); ! 141: if ((argv[dev] = tran_file(argv[dev])) != NULL) ! 142: tv=1; ! 143: else ! 144: fatal("Must specify a directory to create.\n"); ! 145: tmp = &argv[dev]; ! 146: fun = createdir; ! 147: } ! 148: else if (strstr(tmp, "cat")) { ! 149: if (argc > 2 + dargs) ! 150: fatal1("Too many arguments for doscat\n"); ! 151: ! 152: device = tran_dev(argv[dev]); ! 153: if ((argv[dev] = tran_file(argv[dev])) != NULL) ! 154: tv=1; ! 155: else ! 156: fatal1("Must specify a file to display.\n"); ! 157: tmp = &argv[dev]; ! 158: fun = extract; ! 159: pflag++; ! 160: mode = 0; ! 161: } ! 162: else if ((strstr(tmp, "rm")) || (strstr(tmp, "del"))) { ! 163: device = tran_dev(argv[dev]); ! 164: if ((argv[dev] = tran_file(argv[dev])) != NULL) ! 165: tv=1; ! 166: else ! 167: tv=0; ! 168: tmp = &argv[dev]; ! 169: fun = delete; ! 170: } ! 171: else if ((strstr(tmp, "dir")) || (strstr(tmp, "ls"))) { ! 172: device = tran_dev(argv[dev]); ! 173: if ((argv[dev] = tran_file(argv[dev])) != NULL) ! 174: tv=1; ! 175: else ! 176: tv=0; ! 177: tmp = &argv[dev]; ! 178: fun = table; ! 179: mode = 0; ! 180: } ! 181: else if (strstr(tmp, "label")) { ! 182: tv=argc - (2 + dargs); ! 183: tmp = &argv[dev+1]; ! 184: device = tran_dev(argv[dev]); ! 185: fun = label; ! 186: } ! 187: else ! 188: usage("Invalid command.\n\n"); ! 189: } ! 190: else { ! 191: oldstyle = 1; ! 192: usagemsg = OUSAGE; ! 193: if (argc < 2) ! 194: usage(NULL); ! 195: if (argc == 2) ! 196: ++argc; ! 197: else ! 198: device = argv[2]; ! 199: mode = key(argv[1]); ! 200: tv = argc - 3; ! 201: tmp = &argv[3]; ! 202: strcpy(adev, device); ! 203: } ! 204: ! 205: make_lock(); ! 206: if ((fsfd = open(device, mode)) < 0) ! 207: fatal("cannot open device %s", device); ! 208: ! 209: if (fun != format) { ! 210: /* Read the FAT and the root directory. */ ! 211: readfat(); ! 212: root = newdir(NULL, NULL, bpb->b_files); ! 213: readmdir(root); ! 214: } ! 215: numargs = tv; ! 216: (*fun)(tv , tmp); ! 217: if (fun != format) { ! 218: writedir(root); ! 219: if (fatcflag) ! 220: writefat(); ! 221: free(fatcache); ! 222: } ! 223: rm_lock(); ! 224: exit(estat); ! 225: } ! 226: ! 227: ! 228: #define DEFFILE "/etc/default/msdos" ! 229: char adev[80], dev[80]; ! 230: char file[80]; ! 231: ! 232: char *tran_dev(arg) char *arg; ! 233: { ! 234: FILE *fp; ! 235: char *b, c[80]; ! 236: short found = 0; ! 237: ! 238: strcpy(dev, arg); ! 239: if ((b = strchr(dev, ':')) == NULL) ! 240: fatal1("Error: No device specified\n"); ! 241: ! 242: *b = '\0'; ! 243: ! 244: strcpy(adev, dev); ! 245: if (adev[0] != '/') ! 246: adev[0] = toupper(adev[0]); ! 247: ! 248: if ((fp = fopen(DEFFILE, "r")) != NULL) { ! 249: while (!feof(fp)) { ! 250: if(fgets(c, 79, fp)) { ! 251: if ((c[0] != '#') && (c[0] != '\n')) { ! 252: if (c[0] == '.') { ! 253: short i = 0; ! 254: while (c[i] != '\n') ! 255: ext[sext++] = c[i++]; ! 256: } ! 257: else if (!found){ ! 258: if (b = strchr(c, '=')) { ! 259: *b++ = '\0'; ! 260: if (!strcmp(c, dev)) { ! 261: *strpbrk(b,"\t\n #")='\0'; ! 262: strcpy(dev, b); ! 263: if(b=strchr(dev,';')){ ! 264: *b='\0'; ! 265: xpart=atoi(b+1); ! 266: } ! 267: found++; ! 268: } ! 269: } ! 270: } ! 271: } ! 272: } ! 273: } ! 274: } ! 275: fclose(fp); ! 276: ext[sext++] = '.'; ! 277: ext[sext++] = '\0'; ! 278: return dev; ! 279: } ! 280: ! 281: ! 282: char *tran_file(arg) char *arg; ! 283: { ! 284: char *t; ! 285: ! 286: t = strchr(arg, ':') + 1; ! 287: if (*t == '/') ! 288: t++; ! 289: if (*t) { ! 290: if (strcpy(file, t)); ! 291: return file; ! 292: } ! 293: else ! 294: return NULL; ! 295: } ! 296: ! 297: ! 298: #define SPOOLDIR "/tmp" ! 299: #define LOCKPRE "LCK.." ! 300: char lockfn[64]; ! 301: ! 302: make_lock() ! 303: { ! 304: short lockfd, i; ! 305: char pidstring[6]; ! 306: char *tmp = strrchr(device, '/') + 1; ! 307: ! 308: #ifdef _I386 ! 309: for (i=1; i < 13; i++) ! 310: #else ! 311: for (i=1; i < 12; i++) ! 312: #endif ! 313: signal(i, die_signal); ! 314: ! 315: sprintf(lockfn, "%s/%s%s", SPOOLDIR, LOCKPRE, tmp ? tmp : device); ! 316: if ((lockfd = open(lockfn, O_RDONLY)) != -1) ! 317: { ! 318: if ((read(lockfd, &i, sizeof(int)) != sizeof(int)) ! 319: || (kill(i, 0) == -1)) ! 320: { ! 321: close(lockfd); ! 322: } ! 323: else ! 324: fatal1("Device %s is in use.\n", device); ! 325: } ! 326: if((lockfd=creat(lockfn, 0644)) == -1) ! 327: fatal1("Cannot lock Device %s.\n", device); ! 328: ! 329: sprintf(pidstring, "%d", getpid()); ! 330: write(lockfd, pidstring, strlen(pidstring)); ! 331: close(lockfd); ! 332: } ! 333: ! 334: short die_signal(s) short s; ! 335: { ! 336: fflush(stdout); ! 337: fatal("received signal %d, quitting.\n", s); ! 338: } ! 339: ! 340: rm_lock() ! 341: { ! 342: short lockfd; /* pointer to file to read */ ! 343: int chars_read; ! 344: char gotpid[7]; /* String of the PID that was in the lockfile */ ! 345: ! 346: /* open the lock file for read, abort on failure */ ! 347: if(-1 == (lockfd = (open(lockfn, 0)))) ! 348: fatal1("Error opening %s\n", argv0, lockfn); ! 349: ! 350: /* read the contents of the file. Abort if empty */ ! 351: if ( -1 == (chars_read = read(lockfd, gotpid, 6))) { ! 352: close(lockfd); ! 353: fatal1("Error reading %s\n", lockfn); ! 354: } ! 355: ! 356: gotpid[chars_read] = '\0'; /* NUL terminate the string. */ ! 357: if (atoi(gotpid) != getpid()){ ! 358: close(lockfd); ! 359: fatal1("%s is not our lock file\n", lockfn); ! 360: }else{ ! 361: if ( unlink(lockfn) < 0 ) { ! 362: close(lockfd); ! 363: fatal1("Can't unlink: %s\n", lockfn); ! 364: } ! 365: close(lockfd); ! 366: return( 0 ); ! 367: } ! 368: } ! 369: ! 370: /* end of dos0.c */ ! 371: ! 372: ! 373: ! 374: ! 375: ! 376: ! 377:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.