|
|
1.1 root 1: #line 1 "/usr/include/stdio.h"
2:
3:
4:
5: extern struct _iobuf {
6: int _cnt;
7: unsigned char *_ptr;
8: unsigned char *_base;
9: short _flag;
10: char _file;
11: } _iob[ 120 ];
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38: struct _iobuf *fopen();
39: struct _iobuf *fdopen();
40: struct _iobuf *freopen();
41: struct _iobuf *popen();
42: long ftell();
43: char *fgets();
44:
45:
46: #line 1 "/usr/include/tmpnam.h"
47:
48:
49: #line 46 "/usr/include/stdio.h"
50:
51: #line 2 "fsck.c"
52: #line 1 "/usr/include/ctype.h"
53:
54:
55:
56:
57:
58:
59:
60:
61:
62: extern char _ctype[];
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79: #line 3 "fsck.c"
80: #line 1 "/usr/include/sys/param.h"
81:
82: #line 4 "/usr/include/sys/param.h"
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94: #line 19 "/usr/include/sys/param.h"
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109: #line 36 "/usr/include/sys/param.h"
110:
111:
112: #line 1 "/usr/include/signal.h"
113:
114:
115:
116:
117:
118:
119:
120:
121:
122:
123:
124:
125:
126:
127:
128:
129:
130:
131:
132:
133:
134:
135:
136:
137:
138:
139:
140:
141:
142:
143:
144:
145:
146:
147:
148:
149:
150:
151: typedef int (*SIG_TYP)();
152:
153: SIG_TYP signal();
154:
155:
156:
157:
158:
159:
160:
161:
162:
163:
164:
165:
166:
167:
168:
169:
170:
171:
172: #line 39 "/usr/include/sys/param.h"
173:
174:
175:
176: #line 44 "/usr/include/sys/param.h"
177:
178:
179:
180:
181:
182:
183:
184:
185:
186:
187:
188:
189:
190: #line 63 "/usr/include/sys/param.h"
191:
192:
193:
194:
195:
196:
197:
198:
199:
200:
201: #line 75 "/usr/include/sys/param.h"
202:
203:
204:
205:
206:
207:
208:
209:
210:
211:
212:
213:
214:
215:
216:
217:
218:
219:
220:
221:
222:
223:
224:
225:
226: #line 101 "/usr/include/sys/param.h"
227:
228:
229:
230:
231: #line 107 "/usr/include/sys/param.h"
232:
233:
234:
235:
236:
237:
238: #line 115 "/usr/include/sys/param.h"
239:
240:
241:
242: #line 121 "/usr/include/sys/param.h"
243:
244:
245:
246:
247:
248:
249:
250:
251: #line 131 "/usr/include/sys/param.h"
252: #line 1 "/usr/include/sys/types.h"
253:
254: #line 4 "/usr/include/sys/types.h"
255:
256:
257:
258: #line 9 "/usr/include/sys/types.h"
259:
260:
261:
262:
263:
264:
265:
266:
267:
268:
269:
270:
271:
272:
273:
274:
275:
276:
277:
278:
279:
280: #line 33 "/usr/include/sys/types.h"
281: typedef unsigned char u_char;
282: typedef unsigned short u_short;
283: typedef unsigned int u_int;
284: typedef unsigned long u_long;
285:
286: typedef long daddr_t;
287: typedef char * caddr_t;
288: typedef unsigned short ino_t;
289: typedef long swblk_t;
290: typedef long clicks_t;
291: typedef long time_t;
292: typedef long label_t[14];
293: typedef unsigned short dev_t;
294: typedef long off_t;
295: typedef struct { unsigned long lo; long hi; } llong_t;
296:
297:
298:
299:
300:
301:
302:
303:
304:
305:
306:
307: #line 62 "/usr/include/sys/types.h"
308:
309: typedef struct fd_set { unsigned int fds_bits[ (128+ sizeof(int) * 8 -1)/( sizeof(int) * 8 ) ]; } fd_set;
310:
311:
312:
313:
314: #line 132 "/usr/include/sys/param.h"
315:
316:
317: #line 136 "/usr/include/sys/param.h"
318:
319: llong_t ltoL();
320: llong_t Lladd();
321: llong_t Luadd();
322: llong_t LLadd();
323:
324: unsigned Lshift();
325: #line 4 "fsck.c"
326: #line 1 "/usr/include/sys/filsys.h"
327:
328: #line 4 "/usr/include/sys/filsys.h"
329: struct filsys
330: {
331: unsigned short s_isize;
332: daddr_t s_fsize;
333: short s_ninode;
334: ino_t s_inode[ 100 ];
335: char s_flock;
336: char s_ilock;
337: char s_fmod;
338: char s_ronly;
339: time_t s_time;
340: daddr_t s_tfree;
341: ino_t s_tinode;
342: short s_dinfo[2];
343:
344:
345:
346:
347: char s_fsmnt[14];
348: ino_t s_lasti;
349: ino_t s_nbehind;
350: union {
351: struct {
352: short S_nfree;
353: daddr_t S_free[ 178 ];
354: } R;
355: struct {
356: char S_valid;
357: char S_flag;
358:
359: long S_bfree[ 961 ];
360: } B;
361: struct {
362: char S_valid;
363: char S_flag;
364: long S_bsize;
365: struct buf * S_blk[ 961 -1];
366: } N;
367: } U;
368: };
369:
370:
371:
372:
373:
374:
375: #line 53 "/usr/include/sys/filsys.h"
376:
377:
378:
379:
380:
381:
382:
383:
384: #line 5 "fsck.c"
385: #line 1 "/usr/include/sys/dir.h"
386:
387:
388:
389: struct direct
390: {
391: ino_t d_ino;
392: char d_name[ 14 ];
393: };
394: #line 6 "fsck.c"
395: #line 1 "/usr/include/sys/fblk.h"
396: struct fblk
397: {
398: int df_nfree;
399: daddr_t df_free[ 178 ];
400: };
401: #line 7 "fsck.c"
402: #line 1 "/usr/include/sys/ino.h"
403:
404: #line 5 "/usr/include/sys/ino.h"
405: struct dinode
406: {
407: unsigned short di_mode;
408: short di_nlink;
409: short di_uid;
410: short di_gid;
411: off_t di_size;
412: char di_addr[40];
413: time_t di_atime;
414: time_t di_mtime;
415: time_t di_ctime;
416: };
417:
418: #line 22 "/usr/include/sys/ino.h"
419: #line 8 "fsck.c"
420: #line 1 "/usr/include/sys/inode.h"
421:
422: #line 11 "/usr/include/sys/inode.h"
423:
424:
425:
426: struct inode
427: {
428: short i_flag;
429: dev_t i_dev;
430: char i_fstyp;
431: unsigned short i_count;
432: long i_number;
433: unsigned short i_mode;
434: short i_nlink;
435: short i_uid;
436: short i_gid;
437: off_t i_size;
438: struct inode *i_mroot;
439: struct inode *i_mpoint;
440: struct stdata *i_sptr;
441: union {
442: struct {
443: daddr_t I_addr[ 13 ];
444: daddr_t I_lastr;
445: struct buf *I_bufp;
446: } i_f;
447:
448:
449:
450: struct {
451: daddr_t I_rdev;
452: } i_d;
453:
454: struct {
455: long I_tag;
456: struct inode *I_cip;
457: int I_fsflags;
458: time_t I_atime;
459: time_t I_mtime;
460: time_t I_ctime;
461: dev_t I_rdev;
462: } i_a;
463:
464:
465:
466:
467:
468:
469:
470: struct {
471: struct proc *I_proc;
472: int I_sigmask;
473: } i_p;
474:
475:
476: } i_un;
477: struct inode *i_hlink;
478: };
479:
480:
481:
482:
483:
484:
485:
486:
487:
488:
489:
490:
491:
492:
493:
494:
495:
496:
497:
498:
499:
500:
501:
502:
503:
504:
505:
506:
507:
508:
509:
510:
511:
512:
513:
514:
515:
516:
517:
518:
519:
520:
521: struct argnamei {
522: short flag;
523: short len;
524: union {
525: short mode;
526: struct inode *il;
527: caddr_t buf;
528: } un;
529: };
530:
531:
532:
533:
534:
535:
536:
537:
538:
539:
540:
541: struct nx {
542: struct inode *dp;
543: char *cp;
544: char *nbuf;
545: short nlen;
546: short nlink;
547: };
548:
549:
550: #line 140 "/usr/include/sys/inode.h"
551:
552:
553:
554:
555: #line 151 "/usr/include/sys/inode.h"
556:
557:
558: #line 160 "/usr/include/sys/inode.h"
559:
560:
561: #line 9 "fsck.c"
562: #line 1 "/usr/include/sys/stat.h"
563: struct stat
564: {
565: dev_t st_dev;
566: ino_t st_ino;
567: unsigned short st_mode;
568: short st_nlink;
569: short st_uid;
570: short st_gid;
571: dev_t st_rdev;
572: off_t st_size;
573: time_t st_atime;
574: time_t st_mtime;
575: time_t st_ctime;
576: };
577:
578:
579:
580:
581:
582:
583:
584:
585:
586:
587:
588:
589:
590:
591:
592: #line 10 "fsck.c"
593: #line 1 "/usr/include/fstab.h"
594:
595: #line 7 "/usr/include/fstab.h"
596:
597:
598: #line 11 "/usr/include/fstab.h"
599:
600:
601:
602:
603:
604: struct fstab{
605: char fs_spec[ 32 ];
606: char fs_file[ 32 ];
607: int fs_ftype;
608: int fs_flags;
609: int fs_passno;
610: };
611:
612:
613: #line 28 "/usr/include/fstab.h"
614:
615:
616:
617:
618: struct fstab *getfsent();
619: struct fstab *getfsspec();
620: struct fstab *getfsfile();
621: int setfsent();
622: int endfsent();
623:
624:
625: #line 41 "/usr/include/fstab.h"
626:
627: struct mtab {
628: char file[ 32 ];
629: char spec[ 32 -1];
630: char type;
631: };
632:
633:
634: #line 11 "fsck.c"
635: #line 1 "/usr/include/pwd.h"
636: struct passwd {
637: char *pw_name;
638: char *pw_passwd;
639: int pw_uid;
640: int pw_gid;
641: int pw_quota;
642: char *pw_comment;
643: char *pw_gecos;
644: char *pw_dir;
645: char *pw_shell;
646: };
647: extern struct passwd *getpwent();
648: extern struct passwd *getpwuid();
649: extern struct passwd *getpwnam();
650: extern struct passwd *pwdecode();
651: #line 12 "fsck.c"
652:
653:
654:
655:
656:
657:
658:
659:
660:
661:
662:
663:
664:
665:
666:
667:
668:
669:
670:
671:
672:
673:
674:
675:
676:
677:
678:
679:
680:
681: typedef struct dinode DINODE;
682: typedef struct direct DIRECT;
683:
684:
685:
686:
687:
688:
689:
690:
691:
692:
693:
694:
695:
696: daddr_t startib;
697: unsigned niblk;
698:
699: struct bufarea {
700: struct bufarea *b_next;
701: daddr_t b_bno;
702: union {
703: char b_buf[ ( (( 64 ) & 64) ? 4096: 1024) ];
704: short b_lnks[ ( ( (( 64 ) & 64) ? 4096: 1024) /sizeof(short)) ];
705: daddr_t b_indir[ ( ( (( 64 ) & 64) ? 4096: 1024) /sizeof(daddr_t)) ];
706: struct filsys b_fs;
707: struct fblk b_fb;
708: struct dinode b_dinode[ ( (( 64 ) & 64) ? 64: 16) ];
709: DIRECT b_dir[ ( ( (( 64 ) & 64) ? 4096: 1024) /sizeof(struct direct)) ];
710: } b_un;
711: char b_dirty;
712: };
713:
714: typedef struct bufarea BUFAREA;
715:
716: BUFAREA inoblk;
717: BUFAREA fileblk;
718: BUFAREA sblk;
719: BUFAREA *poolhead;
720:
721:
722:
723:
724:
725:
726:
727:
728:
729:
730:
731: struct filecntl {
732: int rfdes;
733: int wfdes;
734: int mod;
735: };
736:
737: struct filecntl dfile;
738: struct filecntl sfile;
739:
740: typedef unsigned MEMSIZE;
741:
742: MEMSIZE memsize;
743:
744:
745:
746:
747:
748:
749:
750:
751: daddr_t duplist[ 100 ];
752: daddr_t *enddup;
753: daddr_t *muldup;
754:
755:
756: ino_t badlncnt[ 500 ];
757: ino_t *badlnp;
758:
759: char sflag;
760: char csflag;
761: char nflag;
762: char yflag;
763: char tflag;
764: char preen;
765: char rplyflag;
766: char hotroot;
767: char rawflg;
768: char rmscr;
769: char fixfree;
770: char *membase;
771: char *blkmap;
772: char *freemap;
773: char *statemap;
774: char *pathp;
775: char *thisname;
776: char *srchname;
777: char pathname[200];
778: char scrfile[80];
779: char *lfname = "lost+found";
780: char *checklist = "/etc/fstab" ;
781: char big;
782:
783: short *lncntp;
784:
785: int cylsize;
786: int stepsize;
787: int badblk;
788: int dupblk;
789: int (*pfunc)();
790: int zcleared;
791:
792: ino_t inum;
793: ino_t imax;
794: ino_t parentdir;
795: ino_t lastino;
796: ino_t lfdir;
797: ino_t orphan;
798:
799: off_t filsize;
800: off_t maxblk;
801: off_t bmapsz;
802:
803: daddr_t smapblk;
804: daddr_t lncntblk;
805: daddr_t fmapblk;
806: daddr_t n_free;
807: daddr_t n_blks;
808: daddr_t n_files;
809: daddr_t fmin;
810: daddr_t fmax;
811:
812:
813:
814:
815:
816:
817:
818:
819:
820:
821:
822:
823:
824:
825:
826:
827:
828:
829:
830:
831:
832:
833:
834:
835:
836:
837:
838:
839: int (*signal())();
840: long lseek();
841: long time();
842: DINODE *ginode();
843: BUFAREA *getblk();
844: BUFAREA *search();
845: int dirscan();
846: int findino();
847: int catch();
848: int mkentry();
849: int chgdd();
850: int pass1();
851: int pass1b();
852: int pass2();
853: int pass3();
854: int pass4();
855: int pass5();
856:
857: char *devname;
858:
859: main(argc,argv)
860: int argc;
861: char *argv[];
862: {
863: register struct _iobuf *fp;
864: register n;
865: register char *p;
866: char filename[50];
867: char *sbrk();
868:
869: setbuf( (&_iob[1]) , 0 );
870: sync();
871: while(--argc > 0 && **++argv == '-') {
872: switch(*++*argv) {
873: case 'p':
874: preen++;
875: break;
876: case 't':
877: case 'T':
878: tflag++;
879: if(**++argv == '-' || --argc <= 0)
880: errexit("Bad -t option\n");
881: p = scrfile;
882: while(*p++ = **argv)
883: (*argv)++;
884: break;
885: case 's':
886: stype(++*argv);
887: sflag++;
888: break;
889: case 'S':
890: stype(++*argv);
891: csflag++;
892: break;
893: case 'n':
894: case 'N':
895: nflag++;
896: yflag = 0;
897: break;
898: case 'y':
899: case 'Y':
900: yflag++;
901: nflag = 0;
902: break;
903: default:
904: errexit("%c option?\n",**argv);
905: }
906: }
907: if(nflag && (sflag || csflag))
908: errexit("Incompatible options: -n and -%s\n",sflag?"s":"S");
909: if(sflag && csflag)
910: sflag = 0;
911: memsize = (MEMSIZE)sbrk(0);
912: memsize = MAXDATA - memsize - sizeof(int);
913: while(memsize >= 2*sizeof(BUFAREA) &&
914: (membase = sbrk(memsize)) == (char *)-1)
915: memsize -= 1024;
916: if(memsize < 2*sizeof(BUFAREA))
917: errexit("Can't get memory\n");
918: if (signal( 2 , (SIG_TYP)1 ) != (SIG_TYP)1 )
919: signal( 2 , catch);
920: if(argc) {
921: while(argc-- > 0){
922: hotroot = 0;
923: check(*argv++);
924: }
925: }
926: else {
927: struct fstab *fsp;
928: int pid, passno, anygtr, sumstatus = 0;
929: passno = 1;
930: do {
931: anygtr = 0;
932: if (setfsent() == 0)
933: errexit("Can't open checklist file: %s\n",
934: "/etc/fstab" );
935: while ( (fsp = getfsent()) != 0){
936: if (fsp->fs_ftype != 0)
937: continue;
938: if (preen == 0 ||
939: passno == 1 && fsp->fs_passno == passno) {
940: if (blockcheck(fsp->fs_spec) == 0 &&
941: preen)
942: exit(8);
943: } else if (fsp->fs_passno > passno)
944: anygtr = 1;
945: else if (fsp->fs_passno == passno) {
946: pid = fork();
947: if (pid < 0) {
948: perror("fork");
949: exit(8);
950: }
951: if (pid == 0)
952: if (blockcheck(fsp->fs_spec)== 0 )
953: exit(8);
954: else
955: exit(0);
956: }
957: }
958: if (preen) {
959: int status;
960: while (wait(&status) != -1)
961: sumstatus |= status;
962: }
963: passno++;
964: } while (anygtr);
965: if (sumstatus)
966: exit(8);
967: endfsent();
968: }
969: exit(0);
970: }
971:
972: char *rawname(), *strrchr(), *unrawname();
973:
974: blockcheck(name)
975: char *name;
976: {
977: struct stat stat_slash, stat_block, stat_char;
978: char *raw;
979: int looped = 0;
980:
981: hotroot = 0;
982: if (stat("/", &stat_slash) < 0){
983: error("Can't stat root\n");
984: return( 0 );
985: }
986: retry:
987: if (stat(name, &stat_block) < 0){
988: error("Can't stat %s\n", name);
989: return( 0 );
990: }
991: big = 0 ;
992: if (stat_block.st_mode & 0060000 ){
993: if( (( stat_block.st_rdev ) & 64) )
994: big = 64 ;
995: raw = rawname(name);
996: if (stat(raw, &stat_char) < 0){
997: error("Can't stat %s\n", raw);
998: return( 0 );
999: }
1000: if (stat_char.st_mode & 0020000 ){
1001: if (stat_slash.st_dev == stat_block.st_rdev) {
1002: hotroot++;
1003: raw = unrawname(name);
1004: }
1005: check(raw);
1006: return( 1 );
1007: } else if(big == 64 ) {
1008: check(name);
1009: return( 1 );
1010: } else {
1011: error("%s is not a character device\n", raw);
1012: return( 0 );
1013: }
1014: } else
1015: if (stat_block.st_mode & 0020000 ){
1016: if (looped) {
1017: error("Can't make sense out of name %s\n", name);
1018: return( 0 );
1019: }
1020: name = unrawname(name);
1021: looped++;
1022: goto retry;
1023: }
1024: error("Can't make sense out of name %s\n", name);
1025: return( 0 );
1026: }
1027:
1028: char *
1029: unrawname(cp)
1030: char *cp;
1031: {
1032: char *dp = strrchr(cp, '/');
1033: struct stat stb;
1034: if (dp == 0)
1035: return(cp);
1036: if (stat(cp, &stb) < 0)
1037: return(cp);
1038: if ((stb.st_mode& 0170000 ) != 0020000 )
1039: return(cp);
1040: if (*(dp+1) != 'r')
1041: return(cp);
1042: strcpy(dp+1, dp+2);
1043: return(cp);
1044: }
1045:
1046: char *
1047: rawname(cp)
1048: char *cp;
1049: {
1050: static char rawbuf[32];
1051: char *dp = strrchr(cp, '/');
1052:
1053: if (dp == 0)
1054: return (0);
1055: if(big == 64 )
1056: return(cp);
1057: *dp = 0;
1058: strcpy(rawbuf, cp);
1059: *dp = '/';
1060: strcat(rawbuf, "/r");
1061: strcat(rawbuf, dp+1);
1062: return (rawbuf);
1063: }
1064:
1065: check(dev)
1066: char *dev;
1067: {
1068:
1069: devname = dev;
1070: check1(dev);
1071: devname = 0;
1072: }
1073:
1074: check1(dev)
1075: char *dev;
1076: {
1077: register DINODE *dp;
1078: register n;
1079: register ino_t *blp;
1080: ino_t savino;
1081: daddr_t blk;
1082: BUFAREA *bp1, *bp2;
1083:
1084: if(setup(dev) == 0 )
1085: return;
1086: if (preen==0) {
1087: printf("** Checking %s\n", dev);
1088: printf("** Phase 1 - Check Blocks and Sizes\n");
1089: }
1090: pfunc = pass1;
1091: for(inum = 1; inum <= imax; inum++) {
1092: if((dp = ginode()) == 0 )
1093: continue;
1094: if( ((dp->di_mode & 0170000 ) != 0) ) {
1095: lastino = inum;
1096: if(ftypeok(dp) == 0 ) {
1097: pfatal("UNKNOWN FILE TYPE I=%u",inum);
1098: if(reply("CLEAR") == 1 ) {
1099: clear((char *)( dp ),sizeof(DINODE)) ;
1100: inoblk.b_dirty = 1 ;
1101: }
1102: continue;
1103: }
1104: n_files++;
1105: if( dolncnt( dp->di_nlink ,0) <= 0) {
1106: if(badlnp < &badlncnt[ 500 ])
1107: *badlnp++ = inum;
1108: else {
1109: pfatal("LINK COUNT TABLE OVERFLOW");
1110: if(reply("CONTINUE") == 0 )
1111: errexit("");
1112: }
1113: }
1114: dostate( ((dp->di_mode & 0170000 ) == 0040000 ) ? 02 : 01 ,0) ;
1115: badblk = dupblk = 0;
1116: filsize = 0;
1117: maxblk = 0;
1118: ckinode(dp, 0 );
1119: if((n = dostate(0,1) ) == 02 || n == 01 )
1120: sizechk(dp);
1121: }
1122: else if(dp->di_mode != 0) {
1123: pfatal("PARTIALLY ALLOCATED INODE I=%u",inum);
1124: if(reply("CLEAR") == 1 ) {
1125: clear((char *)( dp ),sizeof(DINODE)) ;
1126: inoblk.b_dirty = 1 ;
1127: }
1128: }
1129: }
1130:
1131:
1132: if(enddup != &duplist[0]) {
1133: if (preen)
1134: pfatal("INTERNAL ERROR: dups with -p");
1135: printf("** Phase 1b - Rescan For More DUPS\n");
1136: pfunc = pass1b;
1137: for(inum = 1; inum <= lastino; inum++) {
1138: if( dostate(0,1) != 0 && (dp = ginode()) != 0 )
1139: if(ckinode(dp, 0 ) & 01 )
1140: break;
1141: }
1142: }
1143: if(rawflg) {
1144: if(inoblk.b_dirty)
1145: bwrite(&dfile,membase,startib,(int)niblk* ( (( big ) & 64) ? 4096: 1024) );
1146: inoblk.b_dirty = 0;
1147: if(poolhead) {
1148: clear(membase,niblk* ( (( 64 ) & 64) ? 4096: 1024) );
1149: for(bp1 = poolhead;bp1->b_next;bp1 = bp1->b_next);
1150: bp2 = &((BUFAREA *)membase)[(niblk* ( (( 64 ) & 64) ? 4096: 1024) )/sizeof(BUFAREA)];
1151: while(--bp2 >= (BUFAREA *)membase) {
1152: ( bp2 )->b_dirty = 0;( bp2 )->b_bno = (daddr_t)-1 ;
1153: bp2->b_next = bp1->b_next;
1154: bp1->b_next = bp2;
1155: }
1156: }
1157: rawflg = 0;
1158:
1159: }
1160:
1161:
1162: if (preen == 0)
1163: printf("** Phase 2 - Check Pathnames\n");
1164: inum = ((ino_t)2) ;
1165: thisname = pathp = pathname;
1166: pfunc = pass2;
1167: switch( dostate(0,1) ) {
1168: case 0 :
1169: errexit("ROOT INODE UNALLOCATED. TERMINATING.\n");
1170: case 01 :
1171: pfatal("ROOT INODE NOT DIRECTORY");
1172: if(reply("FIX") == 0 || (dp = ginode()) == 0 )
1173: errexit("");
1174: dp->di_mode &= ~ 0170000 ;
1175: dp->di_mode |= 0040000 ;
1176: inoblk.b_dirty = 1 ;
1177: dostate( 02 ,0) ;
1178: case 02 :
1179: descend();
1180: break;
1181: case 03 :
1182: pfatal("DUPS/BAD IN ROOT INODE");
1183: printf("\n");
1184: if(reply("CONTINUE") == 0 )
1185: errexit("");
1186: dostate( 02 ,0) ;
1187: descend();
1188: }
1189:
1190:
1191: if (preen == 0)
1192: printf("** Phase 3 - Check Connectivity\n");
1193: for(inum = 1; inum <= lastino; inum++) {
1194: if( dostate(0,1) == 02 ) {
1195: pfunc = findino;
1196: srchname = "..";
1197: savino = inum;
1198: do {
1199: orphan = inum;
1200: if((dp = ginode()) == 0 )
1201: break;
1202: filsize = dp->di_size;
1203: parentdir = 0;
1204: ckinode(dp, 1 );
1205: if((inum = parentdir) == 0)
1206: break;
1207: } while( dostate(0,1) == 02 );
1208: inum = orphan;
1209: if(linkup() == 1 ) {
1210: thisname = pathp = pathname;
1211: *pathp++ = '?';
1212: pfunc = pass2;
1213: descend();
1214: }
1215: inum = savino;
1216: }
1217: }
1218:
1219:
1220: if (preen == 0)
1221: printf("** Phase 4 - Check Reference Counts\n");
1222: pfunc = pass4;
1223: zcleared = 0;
1224: for(inum = 1; inum <= lastino; inum++) {
1225: switch( dostate(0,1) ) {
1226: case 01 :
1227: if(n = dolncnt(0,1) )
1228: adjust((short)n);
1229: else {
1230: for(blp = badlncnt;blp < badlnp; blp++)
1231: if(*blp == inum) {
1232: clri("UNREF",preen? 0 : 1 , 1 );
1233: break;
1234: }
1235: }
1236: break;
1237: case 02 :
1238: clri("UNREF", 1 , 0 );
1239: break;
1240: case 03 :
1241: clri("BAD/DUP", 1 , 0 );
1242: }
1243: }
1244: if (zcleared)
1245: pwarn("%u LINKLESS FILES CLEARED\n", zcleared);
1246: if(imax - n_files != sblk.b_un.b_fs .s_tinode) {
1247: pwarn("FREE INODE COUNT %u SHOULD BE %u IN SUPERBLK",
1248: sblk.b_un.b_fs .s_tinode, imax - n_files);
1249: if (preen)
1250: printf(" (FIXED)\n");
1251: if (preen || reply("FIX") == 1 ) {
1252: sblk.b_un.b_fs .s_tinode = imax - n_files;
1253: sblk.b_dirty = 1 ;
1254: }
1255: }
1256: flush(&dfile,&fileblk);
1257:
1258: if (preen == 0)
1259: printf("** Phase 5 - Check Free List ");
1260: if(sflag || (csflag && rplyflag == 0)) {
1261: if (preen == 0)
1262: printf("(Ignored)\n");
1263: fixfree = 1;
1264: }
1265: else {
1266: if (preen == 0)
1267: printf("\n");
1268: if(freemap)
1269: copy(blkmap,freemap,(MEMSIZE)bmapsz);
1270: else {
1271: for(blk = 0; blk < fmapblk; blk++) {
1272: bp1 = getblk((BUFAREA *) 0 ,blk);
1273: bp2 = getblk((BUFAREA *) 0 ,blk+fmapblk);
1274: copy(bp1->b_un.b_buf,bp2->b_un.b_buf, ( (( big ) & 64) ? 4096: 1024) );
1275: ( bp2 )->b_dirty = 1 ;
1276: }
1277: }
1278: badblk = dupblk = 0;
1279: if(big == 0 ) {
1280: fileblk.b_un.b_fb .df_nfree = sblk.b_un.b_fs . U.R.S_nfree ;
1281: for(n = 0; n < 178 ; n++)
1282: fileblk.b_un.b_fb .df_free[n] = sblk.b_un.b_fs . U.R.S_free [n];
1283: }
1284: freechk();
1285: if(badblk) {
1286: pfatal("%d BAD BLKS IN FREE LIST",badblk);
1287: printf("\n");
1288: }
1289: if(dupblk)
1290: pwarn("%d DUP BLKS IN FREE LIST\n",dupblk);
1291: if(fixfree == 0) {
1292: if((n_blks+n_free) != (fmax-fmin)) {
1293: pwarn("%ld BLK(S) MISSING\n",
1294: fmax-fmin-n_blks-n_free);
1295: fixfree = 1;
1296: }
1297: else if(big == 0 && n_free != sblk.b_un.b_fs .s_tfree) {
1298: pwarn("FREE BLK COUNT WRONG IN SUPERBLK");
1299: if (preen)
1300: printf(" (FIXED)\n");
1301: if(preen || reply("FIX") == 1 ) {
1302: sblk.b_un.b_fs .s_tfree = n_free;
1303: sblk.b_dirty = 1 ;
1304: }
1305: }
1306: }
1307: if(fixfree) {
1308: pwarn("BAD FREE LIST");
1309: if (preen)
1310: printf(" (SALVAGED)\n");
1311: else if(reply("SALVAGE") == 0 )
1312: fixfree = 0;
1313: }
1314: }
1315:
1316: if(fixfree) {
1317: if (preen == 0)
1318: printf("** Phase 6 - Salvage Free List\n");
1319: makefree();
1320: n_free = sblk.b_un.b_fs .s_tfree;
1321: }
1322:
1323: pwarn("%ld files %ld blocks %ld free\n", n_files,n_blks,n_free);
1324: if(dfile.mod) {
1325: time(& sblk.b_un.b_fs .s_time);
1326: sblk.b_dirty = 1 ;
1327: }
1328: ckfini();
1329: sync();
1330: if(dfile.mod && hotroot) {
1331: printf("ROOT MODIFIED\n");
1332: }
1333: if(dfile.mod && preen == 0)
1334: printf("\n***** FILE SYSTEM WAS MODIFIED *****\n");
1335: }
1336:
1337:
1338: error(s1,s2,s3,s4)
1339: char *s1;
1340: {
1341: printf(s1,s2,s3,s4);
1342: }
1343:
1344:
1345: errexit(s1,s2,s3,s4)
1346: char *s1;
1347: {
1348: error(s1,s2,s3,s4);
1349: exit(8);
1350: }
1351:
1352:
1353: #line 718 "fsck.c"
1354: pfatal(s,a1,a2,a3)
1355: {
1356:
1357: if (preen) {
1358: printf("%s: ", devname);
1359: printf(s, a1, a2, a3);
1360: printf("\n");
1361: preendie();
1362: }
1363: printf(s, a1, a2, a3);
1364: }
1365:
1366:
1367: #line 734 "fsck.c"
1368: preendie()
1369: {
1370:
1371: printf("%s: UNEXPECTED INCONSISTENCY; RUN fsck MANUALLY.\n", devname);
1372: exit(8);
1373: }
1374:
1375:
1376: #line 745 "fsck.c"
1377: pwarn(s,a1,a2,a3,a4,a5,a6)
1378: {
1379:
1380: if (preen)
1381: printf("%s: ", devname);
1382: printf(s, a1, a2, a3, a4, a5, a6);
1383: }
1384:
1385: ckinode(dp,flg)
1386: DINODE *dp;
1387: register flg;
1388: {
1389: register daddr_t *ap;
1390: register ret;
1391: int (*func)(), n;
1392: daddr_t iaddrs[ 13 ];
1393:
1394: if( ( ((dp->di_mode & 0170000 ) == 0060000 ) || ((dp->di_mode & 0170000 ) == 0020000 ) ) )
1395: return( 04 );
1396: l3tol(iaddrs,dp->di_addr, 13 );
1397: func = (flg == 0 ) ? pfunc : dirscan;
1398: for(ap = iaddrs; ap < &iaddrs[ 13 -3]; ap++) {
1399: if(*ap && (ret = (*func)(*ap)) & 01 )
1400: return(ret);
1401: }
1402: for(n = 1; n < 4; n++) {
1403: if(*ap && (ret = iblock(*ap,n,flg)) & 01 )
1404: return(ret);
1405: ap++;
1406: }
1407: return( 04 );
1408: }
1409:
1410:
1411: iblock(blk,ilevel,flg)
1412: daddr_t blk;
1413: register ilevel;
1414: {
1415: register daddr_t *ap;
1416: register n;
1417: int (*func)();
1418: BUFAREA ib;
1419:
1420: if(flg == 0 ) {
1421: func = pfunc;
1422: if(((n = (*func)(blk)) & 04 ) == 0)
1423: return(n);
1424: }
1425: else
1426: func = dirscan;
1427: if( ( blk < fmin || blk >= fmax) )
1428: return( 02 );
1429: ( &ib )->b_dirty = 0;( &ib )->b_bno = (daddr_t)-1 ;
1430: if(getblk(&ib,blk) == 0 )
1431: return( 02 );
1432: ilevel--;
1433: for(ap = ib.b_un.b_indir; ap < &ib.b_un.b_indir[ ( ( (( big ) & 64) ? 4096: 1024) /sizeof(daddr_t)) ]; ap++) {
1434: if(*ap) {
1435: if(ilevel > 0) {
1436: n = iblock(*ap,ilevel,flg);
1437: }
1438: else
1439: n = (*func)(*ap);
1440: if(n & 01 )
1441: return(n);
1442: }
1443: }
1444: return( 04 );
1445: }
1446:
1447:
1448: pass1(blk)
1449: daddr_t blk;
1450: {
1451: register daddr_t *dlp;
1452:
1453: if( ( blk < fmin || blk >= fmax) ) {
1454: blkerr("BAD",blk);
1455: if(++badblk >= 10 ) {
1456: printf("EXCESSIVE BAD BLKS I=%u",inum);
1457: if(reply("CONTINUE") == 0 )
1458: errexit("");
1459: return( 01 );
1460: }
1461: return( 02 );
1462: }
1463: if( domap( blk ,1) ) {
1464: blkerr("DUP",blk);
1465: if(++dupblk >= 10 ) {
1466: printf("EXCESSIVE DUP BLKS I=%u",inum);
1467: if(reply("CONTINUE") == 0 )
1468: errexit("");
1469: return( 01 );
1470: }
1471: if(enddup >= &duplist[ 100 ]) {
1472: printf("DUP TABLE OVERFLOW.");
1473: if(reply("CONTINUE") == 0 )
1474: errexit("");
1475: return( 01 );
1476: }
1477: for(dlp = duplist; dlp < muldup; dlp++) {
1478: if(*dlp == blk) {
1479: *enddup++ = blk;
1480: break;
1481: }
1482: }
1483: if(dlp >= muldup) {
1484: *enddup++ = *muldup;
1485: *muldup++ = blk;
1486: }
1487: }
1488: else {
1489: n_blks++;
1490: domap( blk ,0) ;
1491: }
1492: filsize++;
1493: return( 04 );
1494: }
1495:
1496:
1497: pass1b(blk)
1498: daddr_t blk;
1499: {
1500: register daddr_t *dlp;
1501:
1502: if( ( blk < fmin || blk >= fmax) )
1503: return( 02 );
1504: for(dlp = duplist; dlp < muldup; dlp++) {
1505: if(*dlp == blk) {
1506: blkerr("DUP",blk);
1507: *dlp = *--muldup;
1508: *muldup = blk;
1509: return(muldup == duplist ? 01 : 04 );
1510: }
1511: }
1512: return( 04 );
1513: }
1514:
1515:
1516: pass2(dirp)
1517: register DIRECT *dirp;
1518: {
1519: register char *p;
1520: register n;
1521: DINODE *dp;
1522:
1523: if((inum = dirp->d_ino) == 0)
1524: return( 04 );
1525: thisname = pathp;
1526: for(p = dirp->d_name; p < &dirp->d_name[ 14 ]; )
1527: if((*pathp++ = *p++) == 0) {
1528: --pathp;
1529: break;
1530: }
1531: *pathp = 0;
1532: n = 0 ;
1533: if(inum > imax || inum <= 0)
1534: n = direrr("I OUT OF RANGE");
1535: else {
1536: again:
1537: switch( dostate(0,1) ) {
1538: case 0 :
1539: n = direrr("UNALLOCATED");
1540: break;
1541: case 03 :
1542: if((n = direrr("DUP/BAD")) == 1 )
1543: break;
1544: if((dp = ginode()) == 0 )
1545: break;
1546: dostate( ((dp->di_mode & 0170000 ) == 0040000 ) ? 02 : 01 ,0) ;
1547: goto again;
1548: case 01 :
1549: dolncnt(0,2) ;
1550: break;
1551: case 02 :
1552: dolncnt(0,2) ;
1553: descend();
1554: }
1555: }
1556: pathp = thisname;
1557: if(n == 0 )
1558: return( 04 );
1559: dirp->d_ino = 0;
1560: return( 04 | 010 );
1561: }
1562:
1563:
1564: pass4(blk)
1565: daddr_t blk;
1566: {
1567: register daddr_t *dlp;
1568:
1569: if( ( blk < fmin || blk >= fmax) )
1570: return( 02 );
1571: if( domap( blk ,1) ) {
1572: for(dlp = duplist; dlp < enddup; dlp++)
1573: if(*dlp == blk) {
1574: *dlp = *--enddup;
1575: return( 04 );
1576: }
1577: domap( blk ,2) ;
1578: n_blks--;
1579: }
1580: return( 04 );
1581: }
1582:
1583:
1584: pass5(blk)
1585: daddr_t blk;
1586: {
1587: if( ( blk < fmin || blk >= fmax) ) {
1588: fixfree = 1;
1589: if (preen)
1590: pfatal("BAD BLOCKS IN FREE LIST.");
1591: if(++badblk >= 10 ) {
1592: printf("EXCESSIVE BAD BLKS IN FREE LIST.");
1593: if(reply("CONTINUE") == 0 )
1594: errexit("");
1595: return( 01 );
1596: }
1597: return( 02 );
1598: }
1599: if( domap( blk ,1+4) ) {
1600: fixfree = 1;
1601: if(++dupblk >= 100 ) {
1602: printf("EXCESSIVE DUP BLKS IN FREE LIST.");
1603: if(reply("CONTINUE") == 0 )
1604: errexit("");
1605: return( 01 );
1606: }
1607: }
1608: else {
1609: n_free++;
1610: domap( blk ,0+4) ;
1611: }
1612: return( 04 );
1613: }
1614:
1615:
1616: blkerr(s,blk)
1617: daddr_t blk;
1618: char *s;
1619: {
1620: pfatal("%ld %s I=%u",blk,s,inum);
1621: printf("\n");
1622: dostate( 03 ,0) ;
1623: }
1624:
1625:
1626: descend()
1627: {
1628: register DINODE *dp;
1629: register char *savname;
1630: off_t savsize;
1631:
1632: dostate( 01 ,0) ;
1633: if((dp = ginode()) == 0 )
1634: return;
1635: savname = thisname;
1636: *pathp++ = '/';
1637: savsize = filsize;
1638: filsize = dp->di_size;
1639: ckinode(dp, 1 );
1640: thisname = savname;
1641: *--pathp = 0;
1642: filsize = savsize;
1643: }
1644:
1645:
1646: dirscan(blk)
1647: daddr_t blk;
1648: {
1649: register DIRECT *dirp;
1650: register char *p1, *p2;
1651: register n;
1652: DIRECT direntry;
1653:
1654: if( ( blk < fmin || blk >= fmax) ) {
1655: filsize -= ( (( big ) & 64) ? 4096: 1024) ;
1656: return( 02 );
1657: }
1658: for(dirp = fileblk.b_un .b_dir; dirp < & fileblk.b_un .b_dir[ ( ( (( big ) & 64) ? 4096: 1024) /sizeof(struct direct)) ] &&
1659: filsize > 0; dirp++, filsize -= sizeof(DIRECT)) {
1660: if(getblk(&fileblk,blk) == 0 ) {
1661: filsize -= (& fileblk.b_un .b_dir[ ( ( (( big ) & 64) ? 4096: 1024) /sizeof(struct direct)) ]-dirp)*
1662: sizeof(DIRECT);
1663: return( 02 );
1664: }
1665: p1 = &dirp->d_name[ 14 ];
1666: p2 = &direntry.d_name[ 14 ];
1667: while(p1 > (char *)dirp)
1668: *--p2 = *--p1;
1669: if((n = (*pfunc)(&direntry)) & 010 ) {
1670: if(getblk(&fileblk,blk) != 0 ) {
1671: p1 = &dirp->d_name[ 14 ];
1672: p2 = &direntry.d_name[ 14 ];
1673: while(p1 > (char *)dirp)
1674: *--p1 = *--p2;
1675: fileblk.b_dirty = 1 ;
1676: }
1677: else
1678: n &= ~ 010 ;
1679: }
1680: if(n & 01 )
1681: return(n);
1682: }
1683: return(filsize > 0 ? 04 : 01 );
1684: }
1685:
1686:
1687: direrr(s)
1688: char *s;
1689: {
1690: register DINODE *dp;
1691:
1692: pwarn("%s ",s);
1693: pinode();
1694: printf("\n");
1695: if((dp = ginode()) != 0 && ftypeok(dp))
1696: pfatal("%s=%s", ((dp->di_mode & 0170000 ) == 0040000 ) ?"DIR":"FILE",pathname);
1697: else
1698: pfatal("NAME=%s",pathname);
1699: return(reply("REMOVE"));
1700: }
1701:
1702:
1703: adjust(lcnt)
1704: register short lcnt;
1705: {
1706: register DINODE *dp;
1707:
1708: if((dp = ginode()) == 0 )
1709: return;
1710: if(dp->di_nlink == lcnt) {
1711: if(linkup() == 0 )
1712: clri("UNREF", 0 , 0 );
1713: }
1714: else {
1715: pwarn("LINK COUNT %s",
1716: (lfdir==inum)?lfname:( ((dp->di_mode & 0170000 ) == 0040000 ) ?"DIR":"FILE"));
1717: pinode();
1718: printf(" COUNT %d SHOULD BE %d",
1719: dp->di_nlink,dp->di_nlink-lcnt);
1720: if (preen) {
1721: if (lcnt < 0) {
1722: printf("\n");
1723: preendie();
1724: }
1725: printf(" (ADJUSTED)\n");
1726: }
1727: if(preen || reply("ADJUST") == 1 ) {
1728: dp->di_nlink -= lcnt;
1729: inoblk.b_dirty = 1 ;
1730: }
1731: }
1732: }
1733:
1734:
1735: clri(s,flg,jclr)
1736: char *s;
1737: {
1738: register DINODE *dp;
1739:
1740: if((dp = ginode()) == 0 )
1741: return;
1742: if(flg == 1 ) {
1743: pwarn("%s %s",s, ((dp->di_mode & 0170000 ) == 0040000 ) ?"DIR":"FILE");
1744: pinode();
1745: }
1746: if(preen || reply("CLEAR") == 1 ) {
1747: if (preen)
1748: if (jclr == 1 )
1749: zcleared++;
1750: else
1751: printf(" (CLEARED)\n");
1752: n_files--;
1753: pfunc = pass4;
1754: ckinode(dp, 0 );
1755: clear((char *)( dp ),sizeof(DINODE)) ;
1756: inoblk.b_dirty = 1 ;
1757: }
1758: }
1759:
1760:
1761: setup(dev)
1762: char *dev;
1763: {
1764: register n;
1765: register BUFAREA *bp;
1766: register MEMSIZE msize;
1767: char *mbase;
1768: daddr_t bcnt, nscrblk;
1769: dev_t rootdev;
1770: off_t smapsz, lncntsz, totsz;
1771: struct stat statarea;
1772:
1773: if(stat("/",&statarea) < 0)
1774: errexit("Can't stat root\n");
1775: rootdev = statarea.st_dev;
1776: if(stat(dev,&statarea) < 0) {
1777: error("Can't stat %s\n",dev);
1778: return( 0 );
1779: }
1780: rawflg = 0;
1781: big = 0 ;
1782: if((statarea.st_mode & 0170000 ) == 0060000 ) {
1783: if( (( statarea.st_rdev ) & 64) )
1784: big = 64 ;
1785: }
1786: else if((statarea.st_mode & 0170000 ) == 0020000 )
1787: rawflg++;
1788: else {
1789: if (reply("file is not a block or character device; OK") == 0 )
1790: return( 0 );
1791: }
1792: if(rootdev == statarea.st_rdev)
1793: hotroot++;
1794: if((dfile.rfdes = open(dev,0)) < 0) {
1795: error("Can't open %s\n",dev);
1796: return( 0 );
1797: }
1798: if (preen == 0)
1799: printf("\n%s",dev);
1800: if(nflag || (dfile.wfdes = open(dev,1)) < 0) {
1801: dfile.wfdes = -1;
1802: if (preen)
1803: pfatal("NO WRITE ACCESS");
1804: printf(" (NO WRITE)");
1805: }
1806: if (preen == 0)
1807: printf("\n");
1808: fixfree = 0;
1809: dfile.mod = 0;
1810: n_files = n_blks = n_free = 0;
1811: muldup = enddup = &duplist[0];
1812: badlnp = &badlncnt[0];
1813: lfdir = 0;
1814: rplyflag = 0;
1815: ( &sblk )->b_dirty = 0;( &sblk )->b_bno = (daddr_t)-1 ;
1816: ( &fileblk )->b_dirty = 0;( &fileblk )->b_bno = (daddr_t)-1 ;
1817: ( &inoblk )->b_dirty = 0;( &inoblk )->b_bno = (daddr_t)-1 ;
1818: sfile.wfdes = sfile.rfdes = -1;
1819: rmscr = 0;
1820: if(getblk(&sblk, ((daddr_t)1) ) == 0 ) {
1821: ckfini();
1822: return( 0 );
1823: }
1824: imax = ((ino_t) sblk.b_un.b_fs .s_isize - ( ((daddr_t)1) +1)) * ( (( big ) & 64) ? 64: 16) ;
1825: fmin = (daddr_t) sblk.b_un.b_fs .s_isize;
1826: fmax = sblk.b_un.b_fs .s_fsize;
1827: if(fmin >= fmax ||
1828: (imax/ ( (( big ) & 64) ? 64: 16) ) != ((ino_t) sblk.b_un.b_fs .s_isize-( ((daddr_t)1) +1))) {
1829: pfatal("Size check: fsize %ld isize %d",
1830: sblk.b_un.b_fs .s_fsize, sblk.b_un.b_fs .s_isize);
1831: printf("\n");
1832: ckfini();
1833: return( 0 );
1834: }
1835: if (preen == 0)
1836: printf("File System: %.12s\n\n", sblk.b_un.b_fs .s_fsmnt);
1837: bmapsz = (((( ((( fmax )+(( 8 )-1))/( 8 )) )+(( sizeof(*lncntp) )-1))/( sizeof(*lncntp) ))*( sizeof(*lncntp) )) ;
1838: smapsz = (((( ((( (long)(imax+1) )+(( ( 8 / 2 ) )-1))/( ( 8 / 2 ) )) )+(( sizeof(*lncntp) )-1))/( sizeof(*lncntp) ))*( sizeof(*lncntp) )) ;
1839: lncntsz = (long)(imax+1) * sizeof(*lncntp);
1840: if(bmapsz > smapsz+lncntsz)
1841: smapsz = bmapsz-lncntsz;
1842: totsz = bmapsz+smapsz+lncntsz;
1843: msize = memsize;
1844: mbase = membase;
1845: if(rawflg) {
1846: if(msize < (MEMSIZE)( 11 * ( (( big ) & 64) ? 4096: 1024) ) + 2*sizeof(BUFAREA))
1847: rawflg = 0;
1848: else {
1849: msize -= (MEMSIZE) 11 * ( (( big ) & 64) ? 4096: 1024) ;
1850: mbase += (MEMSIZE) 11 * ( (( big ) & 64) ? 4096: 1024) ;
1851: niblk = 11 ;
1852: startib = fmax;
1853: }
1854: }
1855: clear(mbase,msize);
1856: if((off_t)msize < totsz) {
1857: bmapsz = (((( bmapsz )+(( ( (( big ) & 64) ? 4096: 1024) )-1))/( ( (( big ) & 64) ? 4096: 1024) ))*( ( (( big ) & 64) ? 4096: 1024) )) ;
1858: smapsz = (((( smapsz )+(( ( (( big ) & 64) ? 4096: 1024) )-1))/( ( (( big ) & 64) ? 4096: 1024) ))*( ( (( big ) & 64) ? 4096: 1024) )) ;
1859: lncntsz = (((( lncntsz )+(( ( (( big ) & 64) ? 4096: 1024) )-1))/( ( (( big ) & 64) ? 4096: 1024) ))*( ( (( big ) & 64) ? 4096: 1024) )) ;
1860: nscrblk = (bmapsz+smapsz+lncntsz)>> ( (( big ) & 64) ? 12: 10) ;
1861: if(tflag == 0) {
1862: printf("\nNEED SCRATCH FILE (%ld BLKS)\n",nscrblk);
1863: do {
1864: printf("ENTER FILENAME: ");
1865: if((n = getline( (&_iob[0]) ,scrfile,sizeof(scrfile))) == (-1) )
1866: errexit("\n");
1867: } while(n == 0);
1868: }
1869: if(stat(scrfile,&statarea) < 0 ||
1870: (statarea.st_mode & 0170000 ) == 0100000 )
1871: rmscr++;
1872: if((sfile.wfdes = creat(scrfile,0666)) < 0 ||
1873: (sfile.rfdes = open(scrfile,0)) < 0) {
1874: error("Can't create %s\n",scrfile);
1875: ckfini();
1876: return( 0 );
1877: }
1878: bp = &((BUFAREA *)mbase)[(msize/sizeof(BUFAREA))];
1879: poolhead = 0 ;
1880: while(--bp >= (BUFAREA *)mbase) {
1881: ( bp )->b_dirty = 0;( bp )->b_bno = (daddr_t)-1 ;
1882: bp->b_next = poolhead;
1883: poolhead = bp;
1884: }
1885: bp = poolhead;
1886: for(bcnt = 0; bcnt < nscrblk; bcnt++) {
1887: bp->b_bno = bcnt;
1888: ( bp )->b_dirty = 1 ;
1889: flush(&sfile,bp);
1890: }
1891: blkmap = freemap = statemap = (char *) 0 ;
1892: lncntp = (short *) 0 ;
1893: smapblk = bmapsz / ( (( big ) & 64) ? 4096: 1024) ;
1894: lncntblk = smapblk + smapsz / ( (( big ) & 64) ? 4096: 1024) ;
1895: fmapblk = smapblk;
1896: }
1897: else {
1898: if(rawflg && (off_t)msize > totsz+ ( (( big ) & 64) ? 4096: 1024) ) {
1899: niblk += (unsigned)((off_t)msize-totsz)>> ( (( big ) & 64) ? 12: 10) ;
1900: if(niblk > 110 )
1901: niblk = 110 ;
1902: msize = memsize - (niblk* ( (( big ) & 64) ? 4096: 1024) );
1903: mbase = membase + (niblk* ( (( big ) & 64) ? 4096: 1024) );
1904: }
1905: poolhead = 0 ;
1906: blkmap = mbase;
1907: statemap = &mbase[(MEMSIZE)bmapsz];
1908: freemap = statemap;
1909: lncntp = (short *)&statemap[(MEMSIZE)smapsz];
1910: }
1911: return( 1 );
1912: }
1913:
1914:
1915: DINODE *
1916: ginode()
1917: {
1918: register DINODE *dp;
1919: register char *mbase;
1920: daddr_t iblk;
1921:
1922: if(inum > imax)
1923: return( 0 );
1924: iblk = ((daddr_t)((((unsigned)( inum )+2* ( (( big ) & 64) ? 64: 16) -1)/ ( (( big ) & 64) ? 64: 16) ))) ;
1925: if(rawflg) {
1926: mbase = membase;
1927: if(iblk < startib || iblk >= startib+niblk) {
1928: if(inoblk.b_dirty)
1929: bwrite(&dfile,mbase,startib,(int)niblk* ( (( big ) & 64) ? 4096: 1024) );
1930: inoblk.b_dirty = 0;
1931: if(bread(&dfile,mbase,iblk,(int)niblk* ( (( big ) & 64) ? 4096: 1024) ) == 0 ) {
1932: startib = fmax;
1933: return( 0 );
1934: }
1935: startib = iblk;
1936: }
1937: dp = (DINODE *)&mbase[(unsigned)((iblk-startib)<< ( (( big ) & 64) ? 12: 10) )];
1938: }
1939: else if(getblk(&inoblk,iblk) != 0 )
1940: dp = inoblk.b_un.b_dinode;
1941: else
1942: return( 0 );
1943: return(dp + ((int)((( inum )+2* ( (( big ) & 64) ? 64: 16) -1)% ( (( big ) & 64) ? 64: 16) )) );
1944: }
1945:
1946:
1947: ftypeok(dp)
1948: DINODE *dp;
1949: {
1950: switch(dp->di_mode & 0170000 ) {
1951: case 0040000 :
1952: case 0100000 :
1953: case 0060000 :
1954: case 0020000 :
1955:
1956: case 0120000 :
1957:
1958: return( 1 );
1959: default:
1960: return( 0 );
1961: }
1962: }
1963:
1964:
1965: reply(s)
1966: char *s;
1967: {
1968: char line[80];
1969:
1970: if (preen)
1971: pfatal("INTERNAL ERROR: GOT TO reply()");
1972: rplyflag = 1;
1973: printf("\n%s? ",s);
1974: if(nflag || csflag || dfile.wfdes < 0) {
1975: printf(" no\n\n");
1976: return( 0 );
1977: }
1978: if(yflag) {
1979: printf(" yes\n\n");
1980: return( 1 );
1981: }
1982: if(getline( (&_iob[0]) ,line,sizeof(line)) == (-1) )
1983: errexit("\n");
1984: printf("\n");
1985: if(line[0] == 'y' || line[0] == 'Y')
1986: return( 1 );
1987: else
1988: return( 0 );
1989: }
1990:
1991:
1992: getline(fp,loc,maxlen)
1993: struct _iobuf *fp;
1994: char *loc;
1995: {
1996: register n;
1997: register char *p, *lastloc;
1998:
1999: p = loc;
2000: lastloc = &p[maxlen-1];
2001: while((n = (--( fp )->_cnt>=0? (int)*( fp )->_ptr++:_filbuf( fp )) ) != '\n') {
2002: if(n == (-1) )
2003: return( (-1) );
2004: if(! ((_ctype+1)[ n ]& 010 ) && p < lastloc)
2005: *p++ = n;
2006: }
2007: *p = 0;
2008: return(p - loc);
2009: }
2010:
2011:
2012: stype(p)
2013: register char *p;
2014: {
2015: if(*p == 0)
2016: return;
2017: cylsize = atoi(p);
2018: while(*p && *p != ':')
2019: p++;
2020: if(*p)
2021: p++;
2022: stepsize = atoi(p);
2023: if(stepsize <= 0 || stepsize > cylsize ||
2024: cylsize <= 0 || cylsize > 1000 ) {
2025: error("Invalid -s argument, defaults assumed\n");
2026: cylsize = stepsize = 0;
2027: }
2028: }
2029:
2030:
2031: dostate(s,flg)
2032: {
2033: register char *p;
2034: register unsigned byte, shift;
2035: BUFAREA *bp;
2036:
2037: byte = (inum)/ ( 8 / 2 ) ;
2038: shift = 2 * ((inum)% ( 8 / 2 ) );
2039: if(statemap != 0 ) {
2040: bp = 0 ;
2041: p = &statemap[byte];
2042: }
2043: else if((bp = getblk((BUFAREA *) 0 ,
2044: (daddr_t)(smapblk+(byte/ ( (( big ) & 64) ? 4096: 1024) )))) == 0 )
2045: errexit("Fatal I/O error\n");
2046: else
2047: p = &bp->b_un.b_buf[byte% ( (( big ) & 64) ? 4096: 1024) ];
2048: switch(flg) {
2049: case 0:
2050: *p &= ~( 03 <<(shift));
2051: *p |= s<<(shift);
2052: if(bp != 0 )
2053: ( bp )->b_dirty = 1 ;
2054: return(s);
2055: case 1:
2056: return((*p>>(shift)) & 03 );
2057: }
2058: return( 0 );
2059: }
2060:
2061:
2062: domap(blk,flg)
2063: daddr_t blk;
2064: {
2065: register char *p;
2066: register unsigned n;
2067: register BUFAREA *bp;
2068: off_t byte;
2069:
2070: byte = blk >> 3 ;
2071: n = 1<<((unsigned)(blk & 07 ));
2072: if(flg & 04) {
2073: p = freemap;
2074: blk = fmapblk;
2075: }
2076: else {
2077: p = blkmap;
2078: blk = 0;
2079: }
2080: if(p != 0 ) {
2081: bp = 0 ;
2082: p += (unsigned)byte;
2083: }
2084: else if((bp = getblk((BUFAREA *) 0 ,blk+(byte>> ( (( big ) & 64) ? 12: 10) ))) == 0 )
2085: errexit("Fatal I/O error\n");
2086: else
2087: p = &bp->b_un.b_buf[(unsigned)(byte& ( (( big ) & 64) ? 07777: 01777) )];
2088: switch(flg&03) {
2089: case 0:
2090: *p |= n;
2091: break;
2092: case 1:
2093: n &= *p;
2094: bp = 0 ;
2095: break;
2096: case 2:
2097: *p &= ~n;
2098: }
2099: if(bp != 0 )
2100: ( bp )->b_dirty = 1 ;
2101: return(n);
2102: }
2103:
2104:
2105: dolncnt(val,flg)
2106: short val;
2107: {
2108: register short *sp;
2109: register BUFAREA *bp;
2110:
2111: if(lncntp != 0 ) {
2112: bp = 0 ;
2113: sp = &lncntp[inum];
2114: }
2115: else if((bp = getblk((BUFAREA *) 0 ,(daddr_t)(lncntblk+(inum/ ( ( (( big ) & 64) ? 4096: 1024) /sizeof(short)) )))) == 0 )
2116: errexit("Fatal I/O error\n");
2117: else
2118: sp = &bp->b_un.b_lnks[inum% ( ( (( big ) & 64) ? 4096: 1024) /sizeof(short)) ];
2119: switch(flg) {
2120: case 0:
2121: *sp = val;
2122: break;
2123: case 1:
2124: bp = 0 ;
2125: break;
2126: case 2:
2127: (*sp)--;
2128: }
2129: if(bp != 0 )
2130: ( bp )->b_dirty = 1 ;
2131: return(*sp);
2132: }
2133:
2134:
2135: BUFAREA *
2136: getblk(bp,blk)
2137: daddr_t blk;
2138: register BUFAREA *bp;
2139: {
2140: register struct filecntl *fcp;
2141:
2142: if(bp == 0 ) {
2143: bp = search(blk);
2144: fcp = &sfile;
2145: }
2146: else
2147: fcp = &dfile;
2148: if(bp->b_bno == blk)
2149: return(bp);
2150: flush(fcp,bp);
2151: if(bread(fcp,bp->b_un.b_buf,blk, ( (( big ) & 64) ? 4096: 1024) ) != 0 ) {
2152: bp->b_bno = blk;
2153: return(bp);
2154: }
2155: bp->b_bno = (daddr_t)-1;
2156: return( 0 );
2157: }
2158:
2159:
2160: flush(fcp,bp)
2161: struct filecntl *fcp;
2162: register BUFAREA *bp;
2163: {
2164: if(bp->b_dirty) {
2165: bwrite(fcp,bp->b_un.b_buf,bp->b_bno, ( (( big ) & 64) ? 4096: 1024) );
2166: }
2167: bp->b_dirty = 0;
2168: }
2169:
2170:
2171: rwerr(s,blk)
2172: char *s;
2173: daddr_t blk;
2174: {
2175: if (preen == 0)
2176: printf("\n");
2177: pfatal("CAN NOT %s: BLK %ld",s,blk);
2178: if(reply("CONTINUE") == 0 )
2179: errexit("Program terminated\n");
2180: }
2181:
2182:
2183: sizechk(dp)
2184: register DINODE *dp;
2185: {
2186:
2187: #line 1559 "fsck.c"
2188: if( ((dp->di_mode & 0170000 ) == 0040000 ) && (dp->di_size % sizeof(DIRECT)) != 0) {
2189: pwarn("DIRECTORY MISALIGNED I=%u\n",inum);
2190: if (preen == 0)
2191: printf("\n");
2192: }
2193: }
2194:
2195:
2196: ckfini()
2197: {
2198: flush(&dfile,&fileblk);
2199: flush(&dfile,&sblk);
2200: flush(&dfile,&inoblk);
2201: close(dfile.rfdes);
2202: close(dfile.wfdes);
2203: close(sfile.rfdes);
2204: close(sfile.wfdes);
2205: if(rmscr) {
2206: unlink(scrfile);
2207: }
2208: }
2209:
2210:
2211: pinode()
2212: {
2213: register DINODE *dp;
2214: register char *p;
2215: struct passwd *passwd;
2216: char *ctime();
2217:
2218: printf(" I=%u ",inum);
2219: if((dp = ginode()) == 0 )
2220: return;
2221: printf(" OWNER=");
2222: if((passwd = getpwuid((int)dp->di_uid)) != 0) {
2223: printf("%s ", passwd->pw_name);
2224: }
2225: else {
2226: printf("%d ",dp->di_uid);
2227: }
2228: printf("MODE=%o\n",dp->di_mode);
2229: if (preen)
2230: printf("%s: ", devname);
2231: printf("SIZE=%ld ",dp->di_size);
2232: p = ctime(&dp->di_mtime);
2233: printf("MTIME=%12.12s %4.4s ",p+4,p+20);
2234: }
2235:
2236:
2237: copy(fp,tp,size)
2238: register char *tp, *fp;
2239: MEMSIZE size;
2240: {
2241: while(size--)
2242: *tp++ = *fp++;
2243: }
2244:
2245:
2246: freechk()
2247: {
2248: register daddr_t *ap;
2249: register int i, j;
2250:
2251: if(big == 64 ) {
2252: for(i = sblk.b_un.b_fs .s_isize; i < sblk.b_un.b_fs .s_fsize; i++) {
2253: j = i - sblk.b_un.b_fs .s_isize;
2254: if(! domap( i ,1+4) ) {
2255: sblk.b_un.b_fs . U.B.S_bfree [j>>5] |= (1 << (j&31));
2256: n_free++;
2257: }
2258: else
2259: sblk.b_un.b_fs . U.B.S_bfree [j>>5] &= ~(1 << (j&31));
2260: }
2261: sblk.b_un.b_fs . U.B.S_valid = 1;
2262: sblk.b_un.b_fs .s_tfree = n_free;
2263: sblk.b_dirty = 1 ;
2264: return;
2265: }
2266: if( fileblk.b_un.b_fb .df_nfree == 0)
2267: return;
2268: do {
2269: if( fileblk.b_un.b_fb .df_nfree <= 0 || fileblk.b_un.b_fb .df_nfree > 178 ) {
2270: pwarn("BAD FREEBLK COUNT");
2271: printf("\n");
2272: fixfree = 1;
2273: return;
2274: }
2275: ap = & fileblk.b_un.b_fb .df_free[ fileblk.b_un.b_fb .df_nfree];
2276: while(--ap > & fileblk.b_un.b_fb .df_free[0]) {
2277: if(pass5(*ap) == 01 )
2278: return;
2279: }
2280: if(*ap == (daddr_t)0 || pass5(*ap) != 04 )
2281: return;
2282: } while(getblk(&fileblk,*ap) != 0 );
2283: }
2284:
2285:
2286: makefree()
2287: {
2288: register i, cyl, step;
2289: int j;
2290: char flg[ 1000 ];
2291: short addr[ 1000 ];
2292: daddr_t blk, baseblk;
2293:
2294: if(big == 64 )
2295: return;
2296: sblk.b_un.b_fs . U.R.S_nfree = 0;
2297: sblk.b_un.b_fs .s_flock = 0;
2298: sblk.b_un.b_fs .s_fmod = 0;
2299: sblk.b_un.b_fs .s_tfree = 0;
2300: sblk.b_un.b_fs .s_ninode = 0;
2301: sblk.b_un.b_fs .s_ilock = 0;
2302: sblk.b_un.b_fs .s_ronly = 0;
2303: if(cylsize == 0 || stepsize == 0) {
2304: step = sblk.b_un.b_fs .s_dinfo[0];
2305: cyl = sblk.b_un.b_fs .s_dinfo[1];
2306: }
2307: else {
2308: step = stepsize;
2309: cyl = cylsize;
2310: }
2311: if(step > cyl || step <= 0 || cyl <= 0 || cyl > 1000 ) {
2312: error("Default free list spacing assumed\n");
2313: step = 9 ;
2314: cyl = 400 ;
2315: }
2316: sblk.b_un.b_fs .s_dinfo[0] = step;
2317: sblk.b_un.b_fs .s_dinfo[1] = cyl;
2318: clear(flg,sizeof(flg));
2319: i = 0;
2320: for(j = 0; j < cyl; j++) {
2321: while(flg[i])
2322: i = (i + 1) % cyl;
2323: addr[j] = i + 1;
2324: flg[i]++;
2325: i = (i + step) % cyl;
2326: }
2327: baseblk = (daddr_t) (((( fmax )+(( cyl )-1))/( cyl ))*( cyl )) ;
2328: clear((char *)& fileblk.b_un.b_fb , ( (( big ) & 64) ? 4096: 1024) );
2329: fileblk.b_un.b_fb .df_nfree++;
2330: for( ; baseblk > 0; baseblk -= cyl)
2331: for(i = 0; i < cyl; i++) {
2332: blk = baseblk - addr[i];
2333: if(! ( blk < fmin || blk >= fmax) && ! domap( blk ,1) ) {
2334: sblk.b_un.b_fs .s_tfree++;
2335: if( fileblk.b_un.b_fb .df_nfree >= 178 ) {
2336: fileblk.b_dirty = 1 ;
2337: fileblk.b_bno = blk;
2338: flush(&dfile,&fileblk);
2339: clear((char *)& fileblk.b_un.b_fb , ( (( big ) & 64) ? 4096: 1024) );
2340: }
2341: fileblk.b_un.b_fb .df_free[ fileblk.b_un.b_fb .df_nfree] = blk;
2342: fileblk.b_un.b_fb .df_nfree++;
2343: }
2344: }
2345: sblk.b_un.b_fs . U.R.S_nfree = fileblk.b_un.b_fb .df_nfree;
2346: for(i = 0; i < 178 ; i++)
2347: sblk.b_un.b_fs . U.R.S_free [i] = fileblk.b_un.b_fb .df_free[i];
2348: sblk.b_dirty = 1 ;
2349: }
2350:
2351:
2352: clear(p,cnt)
2353: register char *p;
2354: MEMSIZE cnt;
2355: {
2356: while(cnt--)
2357: *p++ = 0;
2358: }
2359:
2360:
2361: BUFAREA *
2362: search(blk)
2363: daddr_t blk;
2364: {
2365: register BUFAREA *pbp, *bp;
2366:
2367: for(bp = (BUFAREA *) &poolhead; bp->b_next; ) {
2368: pbp = bp;
2369: bp = pbp->b_next;
2370: if(bp->b_bno == blk)
2371: break;
2372: }
2373: pbp->b_next = bp->b_next;
2374: bp->b_next = poolhead;
2375: poolhead = bp;
2376: return(bp);
2377: }
2378:
2379:
2380: findino(dirp)
2381: register DIRECT *dirp;
2382: {
2383: register char *p1, *p2;
2384:
2385: if(dirp->d_ino == 0)
2386: return( 04 );
2387: for(p1 = dirp->d_name,p2 = srchname;*p2++ == *p1; p1++) {
2388: if(*p1 == 0 || p1 == &dirp->d_name[ 14 -1]) {
2389: if(dirp->d_ino > 0 && dirp->d_ino <= imax)
2390: parentdir = dirp->d_ino;
2391: return( 01 );
2392: }
2393: }
2394: return( 04 );
2395: }
2396:
2397:
2398: mkentry(dirp)
2399: register DIRECT *dirp;
2400: {
2401: register ino_t in;
2402: register char *p;
2403:
2404: if(dirp->d_ino)
2405: return( 04 );
2406: dirp->d_ino = orphan;
2407: in = orphan;
2408: p = &dirp->d_name[8];
2409: *--p = 0;
2410: while(p > dirp->d_name) {
2411: *--p = (in % 10) + '0';
2412: in /= 10;
2413: }
2414: *p = '#';
2415: return( 010 | 01 );
2416: }
2417:
2418:
2419: chgdd(dirp)
2420: register DIRECT *dirp;
2421: {
2422: if(dirp->d_name[0] == '.' && dirp->d_name[1] == '.' &&
2423: dirp->d_name[2] == 0) {
2424: dirp->d_ino = lfdir;
2425: return( 010 | 01 );
2426: }
2427: return( 04 );
2428: }
2429:
2430:
2431: linkup()
2432: {
2433: register DINODE *dp;
2434: register lostdir;
2435: register ino_t pdir;
2436:
2437: if((dp = ginode()) == 0 )
2438: return( 0 );
2439: lostdir = ((dp->di_mode & 0170000 ) == 0040000 ) ;
2440: pdir = parentdir;
2441: if (preen && dp->di_size == 0)
2442: return( 0 );
2443: pwarn("UNREF %s ",lostdir ? "DIR" : "FILE");
2444: pinode();
2445: if (preen)
2446: printf(" (RECONNECTED)\n");
2447: else
2448: if (reply("RECONNECT") == 0 )
2449: return( 0 );
2450: orphan = inum;
2451: if(lfdir == 0) {
2452: inum = ((ino_t)2) ;
2453: if((dp = ginode()) == 0 ) {
2454: inum = orphan;
2455: return( 0 );
2456: }
2457: pfunc = findino;
2458: srchname = lfname;
2459: filsize = dp->di_size;
2460: parentdir = 0;
2461: ckinode(dp, 1 );
2462: inum = orphan;
2463: if((lfdir = parentdir) == 0) {
2464: pfatal("SORRY. NO lost+found DIRECTORY");
2465: printf("\n\n");
2466: return( 0 );
2467: }
2468: }
2469: inum = lfdir;
2470: if((dp = ginode()) == 0 || ! ((dp->di_mode & 0170000 ) == 0040000 ) || dostate(0,1) != 01 ) {
2471: inum = orphan;
2472: pfatal("SORRY. NO lost+found DIRECTORY");
2473: printf("\n\n");
2474: return( 0 );
2475: }
2476: if(dp->di_size & ( (( big ) & 64) ? 07777: 01777) ) {
2477: dp->di_size = (((( dp->di_size )+(( ( (( big ) & 64) ? 4096: 1024) )-1))/( ( (( big ) & 64) ? 4096: 1024) ))*( ( (( big ) & 64) ? 4096: 1024) )) ;
2478: inoblk.b_dirty = 1 ;
2479: }
2480: filsize = dp->di_size;
2481: inum = orphan;
2482: pfunc = mkentry;
2483: if((ckinode(dp, 1 ) & 010 ) == 0) {
2484: pfatal("SORRY. NO SPACE IN lost+found DIRECTORY");
2485: printf("\n\n");
2486: return( 0 );
2487: }
2488: dolncnt(0,2) ;
2489: if(lostdir) {
2490: pfunc = chgdd;
2491: dp = ginode();
2492: filsize = dp->di_size;
2493: ckinode(dp, 1 );
2494: inum = lfdir;
2495: if((dp = ginode()) != 0 ) {
2496: dp->di_nlink++;
2497: inoblk.b_dirty = 1 ;
2498: dolncnt( dolncnt(0,1) +1 ,0) ;
2499: }
2500: inum = orphan;
2501: pwarn("DIR I=%u CONNECTED. ",orphan);
2502: printf("PARENT WAS I=%u\n",pdir);
2503: if (preen == 0)
2504: printf("\n");
2505: }
2506: return( 1 );
2507: }
2508:
2509:
2510: bread(fcp,buf,blk,size)
2511: daddr_t blk;
2512: register struct filecntl *fcp;
2513: register size;
2514: char *buf;
2515: {
2516: if(lseek(fcp->rfdes,blk<< ( (( big ) & 64) ? 12: 10) ,0) < 0)
2517: rwerr("SEEK",blk);
2518: else if(read(fcp->rfdes,buf,size) == size)
2519: return( 1 );
2520: rwerr("READ",blk);
2521: return( 0 );
2522: }
2523:
2524:
2525: bwrite(fcp,buf,blk,size)
2526: daddr_t blk;
2527: register struct filecntl *fcp;
2528: register size;
2529: char *buf;
2530: {
2531: if(fcp->wfdes < 0)
2532: return( 0 );
2533: if(lseek(fcp->wfdes,blk<< ( (( big ) & 64) ? 12: 10) ,0) < 0)
2534: rwerr("SEEK",blk);
2535: else if(write(fcp->wfdes,buf,size) == size) {
2536: fcp->mod = 1;
2537: return( 1 );
2538: }
2539: rwerr("WRITE",blk);
2540: return( 0 );
2541: }
2542:
2543: catch()
2544: {
2545: ckfini();
2546: exit(12);
2547: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.