|
|
1.1 ! root 1: /* dutil.c - dutil */ ! 2: ! 3: #include <conf.h> ! 4: #include <kernel.h> ! 5: #include <proc.h> ! 6: #include <disk.h> ! 7: #include <lfile.h> ! 8: #include <dir.h> ! 9: #include <tty.h> ! 10: ! 11: #define TERMEOF '\004' /* interpreted as EOF at console*/ ! 12: #define DISKID 33 /* an arbitrary disk id number */ ! 13: #ifndef DISK0 ! 14: #define DISK0 4 ! 15: #endif ! 16: ! 17: struct dir *dirptr; /* pointer to the in-core dir */ ! 18: int diskdev; /* disk device operated on */ ! 19: int dsize; /* disk size in blocks */ ! 20: int niblks; /* number of i-blocks this disk */ ! 21: char buf[200]; /* buffer for input line */ ! 22: char dbuff[DBUFSIZ]; /* one disk buffer */ ! 23: char msg[] = ! 24: "Choose from: dir, read, write, create, or type help\n"; ! 25: #define PROMPT "\ncmd: " ! 26: char arg1[150]; ! 27: char arg2[150]; ! 28: Bool verbose; ! 29: ! 30: struct cmdname { /* list of valid commands */ ! 31: char *cname; ! 32: int cargs; ! 33: char *cexpl; ! 34: } cmds[] = { "append", 2, "append file1 onto file2", ! 35: "create", 1, "create a new (empty) file", ! 36: "dir", 0, "list directory", ! 37: "exec", 1, "execute a program from disk", ! 38: "freeze", 1, "freeze this program & save", ! 39: "help", 0, "print this page of info", ! 40: "iblock", 1, "print an iblock", ! 41: "init", 1, "initialize disk device number", ! 42: "mkfs", 0, "make a file system", ! 43: "name", 2, "rename file1 to file2", ! 44: "quit", 0, "quit running this program", ! 45: "read", 1, "read a file and display it", ! 46: "size", 0, "report the size of the disk", ! 47: "trace", 1, "trace a file's iblock list", ! 48: "verbose", 1, "set verbose output y or n", ! 49: "write", 1, "write a file from terminal", ! 50: "zap", 1, "remove a file from the disk", ! 51: "?", 0, "synonym for 'help'"}; ! 52: #define NCMDS sizeof(cmds)/sizeof(struct cmdname) ! 53: int ncmds; ! 54: ! 55: ! 56: /*------------------------------------------------------------------------ ! 57: * dutil -- general disk utility program. ! 58: *------------------------------------------------------------------------ ! 59: */ ! 60: dutil() ! 61: { ! 62: int ret; ! 63: ! 64: kprintf("\n\n*** Disk Utility Program ***\n\n"); ! 65: diskdev = DISK0; ! 66: verbose = FALSE; ! 67: ncmds = NCMDS; ! 68: kprintf("Starting with disk DISK0 (device id = %d)",diskdev); ! 69: kprintf(" type '?' for help\n"); ! 70: dirptr = dsdirec(diskdev); ! 71: sizeup(diskdev); ! 72: while (1) { ! 73: switch( getcmd() ) { ! 74: ! 75: case 0: ret = duapp(diskdev, arg1, arg2); ! 76: break; ! 77: ! 78: case 1: ret = ducreat(diskdev, arg1); ! 79: break; ! 80: ! 81: case 2: ret = dudir(diskdev); ! 82: break; ! 83: ! 84: case 3: ret = duexec(diskdev, arg1); ! 85: break; ! 86: ! 87: case 4: ret = dufreeze(diskdev, arg1); ! 88: break; ! 89: ! 90: case 5: ret = duhelp(); ! 91: break; ! 92: ! 93: case 6: ret = duiblk(diskdev, arg1); ! 94: break; ! 95: ! 96: case 7: ret = duinit(arg1); ! 97: if (ret != SYSERR) ! 98: diskdev = ret; ! 99: break; ! 100: ! 101: case 8: ret = dupmkfs(diskdev); ! 102: break; ! 103: ! 104: case 9: ret = duname(diskdev, arg1, arg2); ! 105: break; ! 106: ! 107: case 10: ret = duquit(); ! 108: break; ! 109: ! 110: case 11: ret = duread(diskdev, arg1); ! 111: break; ! 112: ! 113: case 12: ret = dusize(diskdev); ! 114: break; ! 115: ! 116: case 13: ret = dutrace(diskdev, arg1); ! 117: break; ! 118: ! 119: case 14: ret = duverbose(arg1); ! 120: break; ! 121: ! 122: case 15: ret = duwrite(diskdev, arg1); ! 123: break; ! 124: ! 125: case 16: ret = duzap(diskdev, arg1); ! 126: break; ! 127: ! 128: case 17: ret = duhelp(); ! 129: break; ! 130: ! 131: default: ret = SYSERR; ! 132: ! 133: } ! 134: if (verbose) ! 135: kprintf("Command completed with code %d\n",ret); ! 136: } ! 137: } ! 138: ! 139: ! 140: /*------------------------------------------------------------------------ ! 141: * duapp -- append one file to the end of another ! 142: *------------------------------------------------------------------------ ! 143: */ ! 144: duapp(diskdev, from, to) ! 145: int diskdev; ! 146: char *from, *to; ! 147: { ! 148: int f1, f2; ! 149: int ich; ! 150: ! 151: if (verbose) ! 152: kprintf("Appending files...\n"); ! 153: if ( (f2=open(diskdev,to,"rwo")) == SYSERR) { ! 154: kprintf("Can't open file %s\n",to); ! 155: return(SYSERR); ! 156: } ! 157: if (verbose) ! 158: kprintf("device id for file '%s' is %d\n",to,f2); ! 159: if (strcmp(from,"-") == 0) ! 160: f1 = CONSOLE; ! 161: else ! 162: if ( (f1=open(diskdev,from,"ro")) == SYSERR) { ! 163: kprintf("Can't open input file %s\n",from); ! 164: close(f2); ! 165: return(SYSERR); ! 166: } ! 167: if (verbose) ! 168: kprintf("device id for file '%s' is %d\n",from,f1); ! 169: while ( (ich=getc(f2)) != EOF) ! 170: if (ich == SYSERR) ! 171: kprintf("Error positioning file %s\n",to); ! 172: while ( (ich=inchar(f1)) != EOF) { ! 173: if (ich == SYSERR) { ! 174: kprintf("Error reading file %s\n", from); ! 175: close(f1); ! 176: close(f2); ! 177: return(SYSERR); ! 178: } ! 179: putc(f2, ich); ! 180: } ! 181: close(f1); ! 182: close(f2); ! 183: return(OK); ! 184: } ! 185: ! 186: ! 187: /*------------------------------------------------------------------------ ! 188: * ducreat -- create an empty disk file given its name ! 189: *------------------------------------------------------------------------ ! 190: */ ! 191: ducreat(diskdev, name) ! 192: int diskdev; ! 193: char *name; ! 194: { ! 195: int f1; ! 196: ! 197: if (verbose) ! 198: kprintf("Creating file %s\n", name); ! 199: if ( (f1=open(diskdev,name,"nr")) == SYSERR) { ! 200: kprintf("Can't create new file %s\n", name); ! 201: return(SYSERR); ! 202: } ! 203: close(f1); ! 204: return(OK); ! 205: } ! 206: ! 207: ! 208: /*------------------------------------------------------------------------ ! 209: * duexec -- unfreeze a program and execute from disk ! 210: *------------------------------------------------------------------------ ! 211: */ ! 212: duexec(diskdir, name) ! 213: int diskdir; ! 214: char *name; ! 215: { ! 216: int f1; ! 217: ! 218: if ( (f1=open(diskdev, name, "ro")) == SYSERR) { ! 219: kprintf("Can't frind program %s\n", name); ! 220: return(SYSERR); ! 221: } ! 222: kprintf("Command not implemented\n"); ! 223: close(f1); ! 224: return(SYSERR); ! 225: } ! 226: ! 227: ! 228: /*------------------------------------------------------------------------ ! 229: * dufreeze -- freeze this program and save it on disk ! 230: *------------------------------------------------------------------------ ! 231: */ ! 232: dufreeze(diskdev, name) ! 233: int diskdev; ! 234: char *name; ! 235: { ! 236: int f1; ! 237: ! 238: if ( (f1 = open(diskdev,name,"wn")) == SYSERR) { ! 239: kprintf("Can't create file %s\n", name); ! 240: return(SYSERR); ! 241: } ! 242: kprintf("Command not implemented\n"); ! 243: close(f1); ! 244: return(SYSERR); ! 245: } ! 246: ! 247: ! 248: /*------------------------------------------------------------------------ ! 249: * duhelp -- print help message ! 250: *------------------------------------------------------------------------ ! 251: */ ! 252: duhelp() ! 253: { ! 254: int i, len; ! 255: ! 256: kprintf("\nCommands available are:\n\n"); ! 257: kprintf(" Command #args Description\n"); ! 258: for (i=0 ; i<ncmds ; i++) { ! 259: kprintf(" %s",cmds[i].cname); ! 260: for (len=strlen(cmds[i].cname) ; len<16 ; len++) ! 261: kprintf(" "); ! 262: kprintf("%d %s\n",cmds[i].cargs, cmds[i].cexpl); ! 263: } ! 264: kprintf("\n"); ! 265: return(OK); ! 266: } ! 267: ! 268: ! 269: /*------------------------------------------------------------------------ ! 270: * duiblk -- print an iblock given its index ! 271: *------------------------------------------------------------------------ ! 272: */ ! 273: duiblk(diskdev, arg) ! 274: int diskdev; ! 275: char *arg; ! 276: { ! 277: struct iblk iblock; ! 278: int k, j; ! 279: char ch; ! 280: IBADDR ibnum; ! 281: ! 282: for (ibnum=0 ; (ch = *arg)!='\000' ; arg++) { ! 283: if (ch<'0' || ch>'9') ! 284: return(SYSERR); ! 285: ibnum = 10*ibnum + (ch - '0'); ! 286: } ! 287: if (ibnum < 0) ! 288: return(SYSERR); ! 289: ibget(diskdev, ibnum, &iblock); ! 290: kprintf("iblock %d: offset=%U next=%d\n\n ", ! 291: ibnum, iblock.ib_byte, iblock.ib_next); ! 292: for (j=IBLEN-1 ; j>=0&&iblock.ib_dba[j]==DBNULL ; j--) ! 293: ; ! 294: if (j < 0) ! 295: kprintf("empty\n"); ! 296: else { ! 297: for (k=0 ; k<=j ; k++) ! 298: kprintf("%u ", iblock.ib_dba[k]); ! 299: kprintf("\n"); ! 300: } ! 301: return(OK); ! 302: } ! 303: ! 304: ! 305: /*------------------------------------------------------------------------ ! 306: * duinit -- initialize disk drive number and size ! 307: *------------------------------------------------------------------------ ! 308: */ ! 309: duinit(drive) ! 310: char *drive; ! 311: { ! 312: int i,n; ! 313: char ch; ! 314: ! 315: n = 0; ! 316: for (i=0 ; i<20 ; i++) { ! 317: if ( (ch = *drive++) == '\000' || ch=='\n') { ! 318: sizeup(n); ! 319: return(n); ! 320: } else { ! 321: if (ch<'0' || ch>'9') { ! 322: kprintf("Digit expected; got '%c'\n",ch); ! 323: return(SYSERR); ! 324: } ! 325: n = 10*n + (ch - '0'); ! 326: } ! 327: } ! 328: kprintf("Argument too long.\n"); ! 329: return(SYSERR); ! 330: } ! 331: ! 332: ! 333: /*------------------------------------------------------------------------ ! 334: * dupmkfs -- make a file system from scratch ! 335: *------------------------------------------------------------------------ ! 336: */ ! 337: dupmkfs(diskdev) ! 338: int diskdev; ! 339: { ! 340: int ret; ! 341: ! 342: if (verbose) ! 343: kprintf("Making a file system...\n"); ! 344: ret = dumkfs(diskdev, niblks, dsize, DISKID, verbose); ! 345: return(ret); ! 346: } ! 347: ! 348: /*------------------------------------------------------------------------ ! 349: * duname -- rename one file into another ! 350: *------------------------------------------------------------------------ ! 351: */ ! 352: duname(diskdev, fname, tname) ! 353: int diskdev; ! 354: char *fname; ! 355: char *tname; ! 356: { ! 357: struct fdes *fdptr, *fdptr2; ! 358: struct dir *dirptr; ! 359: int i, pos; ! 360: int sem; ! 361: ! 362: if (verbose) ! 363: kprintf("Renaming file '%s' to '%s'\n", fname, tname); ! 364: dirptr = dsdirec(diskdev); ! 365: sem = ( (struct dsblk *)devtab[diskdev].dvioblk)->ddirsem; ! 366: wait(sem); ! 367: for (pos= -1,i=0 ; i<dirptr->d_nfiles ; i++) { ! 368: fdptr = &dirptr->d_files[i]; ! 369: if (strcmp(fname, fdptr->fdname) == 0) { ! 370: pos = i; ! 371: } else if (strcmp(tname, fdptr->fdname) == 0) { ! 372: kprintf("File '%s' already exists\n",tname); ! 373: signal(sem); ! 374: return(SYSERR); ! 375: } ! 376: } ! 377: if (pos >= 0) { ! 378: strcpy(dirptr->d_files[pos].fdname, tname); ! 379: write(diskdev, dskbcpy(dirptr), DIRBLK); ! 380: signal(sem); ! 381: return(OK); ! 382: } ! 383: kprintf("File '%s' not found in directory\n", fname); ! 384: signal(sem); ! 385: return(SYSERR); ! 386: } ! 387: ! 388: ! 389: /*------------------------------------------------------------------------ ! 390: * duquit -- stop executing ! 391: *------------------------------------------------------------------------ ! 392: */ ! 393: duquit() ! 394: { ! 395: int i; ! 396: ! 397: if (verbose) ! 398: kprintf("Exiting utility program...\n"); ! 399: for (i=1 ; i<NPROC ; i++) ! 400: if (i != currpid) ! 401: kill(i); ! 402: kill(currpid); ! 403: } ! 404: ! 405: ! 406: /*------------------------------------------------------------------------ ! 407: * duread -- read a file and display on the terminal ! 408: *------------------------------------------------------------------------ ! 409: */ ! 410: duread(diskdev, fname) ! 411: int diskdev; ! 412: char *fname; ! 413: { ! 414: int f, ich; ! 415: ! 416: if (verbose) ! 417: kprintf("Read file %s\n", fname); ! 418: if ( (f=open(diskdev, fname, "ro")) == SYSERR) { ! 419: kprintf("Can't open file %s\n", fname); ! 420: return(SYSERR); ! 421: } ! 422: while( (ich=getc(f)) != EOF ) ! 423: if (ich == SYSERR) { ! 424: kprintf("***ERROR ON READ***\n"); ! 425: return(SYSERR); ! 426: } else ! 427: kprintf("%c", ich); ! 428: close(f); ! 429: return(OK); ! 430: } ! 431: ! 432: ! 433: /*------------------------------------------------------------------------ ! 434: * dusize -- size the disk and print out the number of blocks ! 435: *------------------------------------------------------------------------ ! 436: */ ! 437: dusize() ! 438: { ! 439: kprintf("Disk has %u blocks on it\n", dsize); ! 440: } ! 441: ! 442: ! 443: /*------------------------------------------------------------------------ ! 444: * dutrace -- trace the iblock list for a given file ! 445: *------------------------------------------------------------------------ ! 446: */ ! 447: dutrace(diskdev, fname) ! 448: int diskdev; ! 449: char *fname; ! 450: { ! 451: int f; ! 452: int inum, i, j,k; ! 453: struct iblk iblock; ! 454: struct flblk *flptr; ! 455: ! 456: if (verbose) ! 457: kprintf("Tracing iblocks for file %s\n", fname); ! 458: if ( (f=open(diskdev, fname, "ro")) == SYSERR) { ! 459: kprintf("Can't open file %s\n", fname); ! 460: return(SYSERR); ! 461: } ! 462: flptr = (struct flblk *)devtab[f].dvioblk; ! 463: inum = flptr->fl_iba; ! 464: for (i=0 ; inum!=IBNULL && i<10 ; i++) { ! 465: kprintf("iblock %d: ",inum); ! 466: ibget(diskdev, inum, &iblock); ! 467: for (j=IBLEN-1 ; j>=0&&iblock.ib_dba[j]==DBNULL ; j--) ! 468: ; ! 469: if (j < 0) ! 470: kprintf("empty\n"); ! 471: else { ! 472: for (k=0 ; k<=j ; k++) ! 473: kprintf("%u ", iblock.ib_dba[k]); ! 474: kprintf("\n"); ! 475: } ! 476: inum = iblock.ib_next; ! 477: } ! 478: close(f); ! 479: return(OK); ! 480: } ! 481: ! 482: /*------------------------------------------------------------------------ ! 483: * duverbose -- turn on/off verbose output switch ! 484: *------------------------------------------------------------------------ ! 485: */ ! 486: duverbose(arg) ! 487: char *arg; ! 488: { ! 489: int len; ! 490: ! 491: if (verbose) ! 492: kprintf("Setting verbose option.\n"); ! 493: len = strlen(arg); ! 494: if (len<=3 && strncmp(arg,"yes",len) == 0) { ! 495: verbose = TRUE; ! 496: return(OK); ! 497: } else if (len<=2 && strncmp(arg,"no",len) == 0) { ! 498: verbose = FALSE; ! 499: return(OK); ! 500: } ! 501: kprintf("Argument must be 'yes' or 'no', not '%s'\n", arg); ! 502: return(SYSERR); ! 503: } ! 504: ! 505: ! 506: /*------------------------------------------------------------------------ ! 507: * duwrite -- overwrite a file taking input from terminal ! 508: *------------------------------------------------------------------------ ! 509: */ ! 510: duwrite(diskdev, fname) ! 511: { ! 512: int f, ich; ! 513: ! 514: if (verbose) ! 515: kprintf("Writing file %s\n", fname); ! 516: if ( (f=open(diskdev,fname,"wo")) == SYSERR) { ! 517: kprintf("Error opening file %s -- will attempt to create\n", ! 518: fname); ! 519: if ( (f=open(diskdev,fname,"wn")) == SYSERR) { ! 520: kprintf("Can't create file %s\n", fname); ! 521: return(SYSERR); ! 522: } ! 523: } ! 524: kprintf("Enter text; terminate with CNTL-d\n\n"); ! 525: while( (ich=inchar(CONSOLE)) != EOF ) ! 526: putc(f, ich); ! 527: close(f); ! 528: return(OK); ! 529: } ! 530: ! 531: ! 532: /*------------------------------------------------------------------------ ! 533: * dupzap -- zap a file from the directory ! 534: *------------------------------------------------------------------------ ! 535: */ ! 536: duzap(diskdev, fname) ! 537: int diskdev; ! 538: char *fname; ! 539: { ! 540: struct fdes *fdptr, *fdptr2; ! 541: struct dir *dirptr; ! 542: int i, j, sem; ! 543: IBADDR ilist; ! 544: ! 545: if (verbose) ! 546: kprintf("Removing file %s from directory\n", fname); ! 547: dirptr = dsdirec(diskdev); ! 548: sem = ((struct dsblk *)devtab[diskdev].dvioblk)->ddirsem; ! 549: wait(sem); ! 550: for (i=0 ; i<dirptr->d_nfiles ; i++) { ! 551: fdptr = &dirptr->d_files[i]; ! 552: if (strcmp(fname, fdptr->fdname) == 0) { ! 553: ilist = fdptr->fdiba; ! 554: dirptr->d_nfiles--; ! 555: fdptr2 = &dirptr->d_files[i+1]; ! 556: for (j=i ; j<dirptr->d_nfiles ; j++) ! 557: *fdptr++ = *fdptr2++; ! 558: write(diskdev, dskbcpy(dirptr), DIRBLK); ! 559: signal(sem); ! 560: iblfree(diskdev, ilist); ! 561: return(OK); ! 562: } ! 563: } ! 564: kprintf("File %s not found in directory\n", fname); ! 565: signal(sem); ! 566: return(SYSERR); ! 567: } ! 568: ! 569: ! 570: /*------------------------------------------------------------------------ ! 571: * sizeup -- size up the disk and place number of blocks in dsize ! 572: *------------------------------------------------------------------------ ! 573: */ ! 574: LOCAL sizeup(diskdev) ! 575: int diskdev; ! 576: { ! 577: DBADDR low, high, mid; ! 578: ! 579: low = 0; ! 580: high = 31000; ! 581: while (low < high-1) { ! 582: mid = (DBADDR)(low + high)/(DBADDR)2; ! 583: if (read(diskdev,dbuff,mid) == SYSERR) ! 584: high = mid; ! 585: else ! 586: low = mid; ! 587: } ! 588: dsize = low+1; ! 589: niblks = dsize/20; ! 590: } ! 591: ! 592: ! 593: /*------------------------------------------------------------------------ ! 594: * inchar -- get next input character ! 595: *------------------------------------------------------------------------ ! 596: */ ! 597: LOCAL inchar(dev) ! 598: { ! 599: int ich; ! 600: ! 601: if (dev!=CONSOLE) ! 602: return(getc(dev)); ! 603: if ( (ich=getc(CONSOLE)) == TERMEOF) { ! 604: while( getc(CONSOLE) != NEWLINE) ! 605: ; ! 606: return(EOF); ! 607: } else ! 608: return(ich); ! 609: } ! 610: ! 611: ! 612: /*------------------------------------------------------------------------ ! 613: * getcmd -- get next command and appropriate number of args. ! 614: *------------------------------------------------------------------------ ! 615: */ ! 616: getcmd() ! 617: { ! 618: int i; ! 619: ! 620: while (1) { ! 621: kprintf("%s", PROMPT); ! 622: i = duparse(); ! 623: sleep10(1); ! 624: if (i != SYSERR) ! 625: return(i); ! 626: else ! 627: kprintf("%s\n", msg); ! 628: } ! 629: } ! 630: ! 631: ! 632: /*------------------------------------------------------------------------ ! 633: * duparse -- parse one command line and return command index ! 634: *------------------------------------------------------------------------ ! 635: */ ! 636: LOCAL duparse() ! 637: { ! 638: int len, i, nargs, cindex; ! 639: char ch; ! 640: ! 641: while( (ch=getc(CONSOLE)) == ' ') ! 642: ; ! 643: for (len=0 ; ch!='\n' && ch!=' ' ; ch=getc(CONSOLE)) ! 644: buf[len++] = ch; ! 645: if (len == 0) ! 646: return(SYSERR); ! 647: buf[len] = '\000'; ! 648: if ( (cindex=lookup(len)) == SYSERR) { ! 649: read(CONSOLE, buf, 0); ! 650: return(SYSERR); ! 651: } ! 652: if ( (nargs=cmds[cindex].cargs) == 0) { ! 653: while (ch != '\n') ! 654: ch = getc(CONSOLE); ! 655: return(cindex); ! 656: } ! 657: while (ch == ' ') ! 658: ch=getc(CONSOLE); ! 659: if (ch == '\n') { ! 660: kprintf("\nToo few arguments for '%s'\n", ! 661: cmds[cindex].cname); ! 662: return(SYSERR); ! 663: } ! 664: for (len=0 ; ch!='\n' && ch!=' ' ; ch=getc(CONSOLE)) ! 665: arg1[len++] = ch; ! 666: arg1[len] = '\000'; ! 667: if ( (nargs=cmds[cindex].cargs) <= 1) { ! 668: while (ch != '\n') ! 669: ch = getc(CONSOLE); ! 670: return(cindex); ! 671: } ! 672: while (ch == ' ') ! 673: ch=getc(CONSOLE); ! 674: if (ch == '\n') { ! 675: kprintf("\nToo few arguments for '%s'\n", ! 676: cmds[cindex].cname); ! 677: return(SYSERR); ! 678: } ! 679: for (len=0 ; ch!='\n' && ch!=' ' ; ch=getc(CONSOLE)) ! 680: arg2[len++] = ch; ! 681: arg2[len] = '\000'; ! 682: while (ch != '\n') ! 683: ch = getc(CONSOLE); ! 684: return(cindex); ! 685: } ! 686: ! 687: ! 688: /*------------------------------------------------------------------------ ! 689: * lookup -- lookup a command name in the table, returning its index ! 690: *------------------------------------------------------------------------ ! 691: */ ! 692: LOCAL lookup(len) ! 693: int len; ! 694: { ! 695: int i; ! 696: ! 697: for (i=0 ; i<ncmds ; i++) ! 698: if (len <= strlen(cmds[i].cname) && ! 699: strncmp(cmds[i].cname, buf, len) == 0) ! 700: return(i); ! 701: return(SYSERR); ! 702: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.