|
|
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.