116269Smckusick #ifndef lint 2*17931Smckusick static char version[] = "@(#)utilities.c 3.2 (Berkeley) 02/07/85"; 316269Smckusick #endif 416269Smckusick 516269Smckusick #include <stdio.h> 616269Smckusick #include <ctype.h> 716269Smckusick #include <sys/param.h> 816269Smckusick #include <sys/inode.h> 916269Smckusick #include <sys/fs.h> 1016269Smckusick #include "fsck.h" 1116269Smckusick 1216269Smckusick long lseek(); 1316269Smckusick 1416269Smckusick ftypeok(dp) 1516269Smckusick DINODE *dp; 1616269Smckusick { 1716269Smckusick switch (dp->di_mode & IFMT) { 1816269Smckusick 1916269Smckusick case IFDIR: 2016269Smckusick case IFREG: 2116269Smckusick case IFBLK: 2216269Smckusick case IFCHR: 2316269Smckusick case IFLNK: 2416269Smckusick case IFSOCK: 2516269Smckusick return (1); 2616269Smckusick 2716269Smckusick default: 2816269Smckusick if (debug) 2916269Smckusick printf("bad file type 0%o\n", dp->di_mode); 3016269Smckusick return (0); 3116269Smckusick } 3216269Smckusick } 3316269Smckusick 3416269Smckusick reply(s) 3516269Smckusick char *s; 3616269Smckusick { 3716269Smckusick char line[80]; 3816269Smckusick 3916269Smckusick if (preen) 4016269Smckusick pfatal("INTERNAL ERROR: GOT TO reply()"); 4116269Smckusick printf("\n%s? ", s); 4216269Smckusick if (nflag || dfile.wfdes < 0) { 4316269Smckusick printf(" no\n\n"); 4416269Smckusick return (0); 4516269Smckusick } 4616269Smckusick if (yflag) { 4716269Smckusick printf(" yes\n\n"); 4816269Smckusick return (1); 4916269Smckusick } 5016269Smckusick if (getline(stdin, line, sizeof(line)) == EOF) 5116269Smckusick errexit("\n"); 5216269Smckusick printf("\n"); 5316269Smckusick if (line[0] == 'y' || line[0] == 'Y') 5416269Smckusick return (1); 5516269Smckusick else 5616269Smckusick return (0); 5716269Smckusick } 5816269Smckusick 5916269Smckusick getline(fp, loc, maxlen) 6016269Smckusick FILE *fp; 6116269Smckusick char *loc; 6216269Smckusick { 6316269Smckusick register n; 6416269Smckusick register char *p, *lastloc; 6516269Smckusick 6616269Smckusick p = loc; 6716269Smckusick lastloc = &p[maxlen-1]; 6816269Smckusick while ((n = getc(fp)) != '\n') { 6916269Smckusick if (n == EOF) 7016269Smckusick return (EOF); 7116269Smckusick if (!isspace(n) && p < lastloc) 7216269Smckusick *p++ = n; 7316269Smckusick } 7416269Smckusick *p = 0; 7516269Smckusick return (p - loc); 7616269Smckusick } 7716269Smckusick 7816269Smckusick BUFAREA * 7916269Smckusick getblk(bp, blk, size) 8016269Smckusick register BUFAREA *bp; 8116269Smckusick daddr_t blk; 8216269Smckusick long size; 8316269Smckusick { 8416269Smckusick register struct filecntl *fcp; 8516269Smckusick daddr_t dblk; 8616269Smckusick 8716269Smckusick fcp = &dfile; 8816269Smckusick dblk = fsbtodb(&sblock, blk); 8916269Smckusick if (bp->b_bno == dblk) 9016269Smckusick return (bp); 9116269Smckusick flush(fcp, bp); 9216269Smckusick if (bread(fcp, bp->b_un.b_buf, dblk, size) != 0) { 9316269Smckusick bp->b_bno = dblk; 9416269Smckusick bp->b_size = size; 9516269Smckusick return (bp); 9616269Smckusick } 9716269Smckusick bp->b_bno = (daddr_t)-1; 9816269Smckusick return (NULL); 9916269Smckusick } 10016269Smckusick 10116269Smckusick flush(fcp, bp) 10216269Smckusick struct filecntl *fcp; 10316269Smckusick register BUFAREA *bp; 10416269Smckusick { 105*17931Smckusick register int i, j; 10616269Smckusick 107*17931Smckusick if (!bp->b_dirty) 108*17931Smckusick return; 10916269Smckusick bp->b_dirty = 0; 110*17931Smckusick (void)bwrite(fcp, bp->b_un.b_buf, bp->b_bno, (long)bp->b_size); 111*17931Smckusick if (bp != &sblk) 112*17931Smckusick return; 113*17931Smckusick for (i = 0, j = 0; i < sblock.fs_cssize; i += sblock.fs_bsize, j++) { 114*17931Smckusick (void)bwrite(&dfile, (char *)sblock.fs_csp[j], 115*17931Smckusick fsbtodb(&sblock, sblock.fs_csaddr + j * sblock.fs_frag), 116*17931Smckusick sblock.fs_cssize - i < sblock.fs_bsize ? 117*17931Smckusick sblock.fs_cssize - i : sblock.fs_bsize); 118*17931Smckusick } 11916269Smckusick } 12016269Smckusick 12116269Smckusick rwerr(s, blk) 12216269Smckusick char *s; 12316269Smckusick daddr_t blk; 12416269Smckusick { 12516269Smckusick 12616269Smckusick if (preen == 0) 12716269Smckusick printf("\n"); 12816269Smckusick pfatal("CANNOT %s: BLK %ld", s, blk); 12916269Smckusick if (reply("CONTINUE") == 0) 13016269Smckusick errexit("Program terminated\n"); 13116269Smckusick } 13216269Smckusick 13316269Smckusick ckfini() 13416269Smckusick { 13516269Smckusick 13616269Smckusick flush(&dfile, &fileblk); 13716269Smckusick flush(&dfile, &sblk); 13816269Smckusick if (sblk.b_bno != SBLOCK) { 13916269Smckusick sblk.b_bno = SBLOCK; 14016269Smckusick sbdirty(); 14116269Smckusick flush(&dfile, &sblk); 14216269Smckusick } 14316269Smckusick flush(&dfile, &inoblk); 14416269Smckusick (void)close(dfile.rfdes); 14516269Smckusick (void)close(dfile.wfdes); 14616269Smckusick } 14716269Smckusick 14816269Smckusick bread(fcp, buf, blk, size) 14916269Smckusick register struct filecntl *fcp; 15016269Smckusick char *buf; 15116269Smckusick daddr_t blk; 15216269Smckusick long size; 15316269Smckusick { 15416269Smckusick if (lseek(fcp->rfdes, (long)dbtob(blk), 0) < 0) 15516269Smckusick rwerr("SEEK", blk); 15616269Smckusick else if (read(fcp->rfdes, buf, (int)size) == size) 15716269Smckusick return (1); 15816269Smckusick rwerr("READ", blk); 15916269Smckusick return (0); 16016269Smckusick } 16116269Smckusick 16216269Smckusick bwrite(fcp, buf, blk, size) 16316269Smckusick register struct filecntl *fcp; 16416269Smckusick char *buf; 16516269Smckusick daddr_t blk; 16616269Smckusick long size; 16716269Smckusick { 16816269Smckusick 16916269Smckusick if (fcp->wfdes < 0) 17016269Smckusick return (0); 17116269Smckusick if (lseek(fcp->wfdes, (long)dbtob(blk), 0) < 0) 17216269Smckusick rwerr("SEEK", blk); 17316269Smckusick else if (write(fcp->wfdes, buf, (int)size) == size) { 17416269Smckusick fcp->mod = 1; 17516269Smckusick return (1); 17616269Smckusick } 17716269Smckusick rwerr("WRITE", blk); 17816269Smckusick return (0); 17916269Smckusick } 18016269Smckusick 18116269Smckusick catch() 18216269Smckusick { 18316269Smckusick 18416269Smckusick ckfini(); 18516269Smckusick exit(12); 18616269Smckusick } 18716269Smckusick 18816269Smckusick /* 18916269Smckusick * determine whether an inode should be fixed. 19016269Smckusick */ 191*17931Smckusick dofix(idesc, msg) 19216269Smckusick register struct inodesc *idesc; 193*17931Smckusick char *msg; 19416269Smckusick { 19516269Smckusick 19616269Smckusick switch (idesc->id_fix) { 19716269Smckusick 19816269Smckusick case DONTKNOW: 199*17931Smckusick if (idesc->id_type == DATA) 200*17931Smckusick direrr(idesc->id_number, msg); 201*17931Smckusick else 202*17931Smckusick pwarn(msg); 203*17931Smckusick if (preen) { 204*17931Smckusick printf(" (SALVAGED)\n"); 205*17931Smckusick idesc->id_fix = FIX; 206*17931Smckusick return (ALTERED); 207*17931Smckusick } 20816269Smckusick if (reply("SALVAGE") == 0) { 20916269Smckusick idesc->id_fix = NOFIX; 21016269Smckusick return (0); 21116269Smckusick } 21216269Smckusick idesc->id_fix = FIX; 21316269Smckusick return (ALTERED); 21416269Smckusick 21516269Smckusick case FIX: 21616269Smckusick return (ALTERED); 21716269Smckusick 21816269Smckusick case NOFIX: 21916269Smckusick return (0); 22016269Smckusick 22116269Smckusick default: 22216269Smckusick errexit("UNKNOWN INODESC FIX MODE %d\n", idesc->id_fix); 22316269Smckusick } 22416269Smckusick /* NOTREACHED */ 22516269Smckusick } 22616269Smckusick 22716269Smckusick /* VARARGS1 */ 228*17931Smckusick errexit(s1, s2, s3, s4) 22916269Smckusick char *s1; 23016269Smckusick { 23116269Smckusick printf(s1, s2, s3, s4); 23216269Smckusick exit(8); 23316269Smckusick } 23416269Smckusick 23516269Smckusick /* 23616269Smckusick * An inconsistency occured which shouldn't during normal operations. 23716269Smckusick * Die if preening, otherwise just printf. 23816269Smckusick */ 23916269Smckusick /* VARARGS1 */ 24016269Smckusick pfatal(s, a1, a2, a3) 24116269Smckusick char *s; 24216269Smckusick { 24316269Smckusick 24416269Smckusick if (preen) { 24516269Smckusick printf("%s: ", devname); 24616269Smckusick printf(s, a1, a2, a3); 24716269Smckusick printf("\n"); 248*17931Smckusick printf("%s: UNEXPECTED INCONSISTENCY; RUN fsck MANUALLY.\n", 249*17931Smckusick devname); 250*17931Smckusick exit(8); 25116269Smckusick } 25216269Smckusick printf(s, a1, a2, a3); 25316269Smckusick } 25416269Smckusick 25516269Smckusick /* 25616269Smckusick * Pwarn is like printf when not preening, 25716269Smckusick * or a warning (preceded by filename) when preening. 25816269Smckusick */ 25916269Smckusick /* VARARGS1 */ 26016269Smckusick pwarn(s, a1, a2, a3, a4, a5, a6) 26116269Smckusick char *s; 26216269Smckusick { 26316269Smckusick 26416269Smckusick if (preen) 26516269Smckusick printf("%s: ", devname); 26616269Smckusick printf(s, a1, a2, a3, a4, a5, a6); 26716269Smckusick } 26816269Smckusick 26916269Smckusick #ifndef lint 27016269Smckusick /* 27116269Smckusick * Stub for routines from kernel. 27216269Smckusick */ 27316269Smckusick panic(s) 27416269Smckusick char *s; 27516269Smckusick { 27616269Smckusick 277*17931Smckusick pfatal("INTERNAL INCONSISTENCY:"); 278*17931Smckusick errexit(s); 27916269Smckusick } 28016269Smckusick #endif 281