1*16269Smckusick #ifndef lint 2*16269Smckusick static char version[] = "@(#)utilities.c 3.1 (Berkeley) 03/31/84"; 3*16269Smckusick #endif 4*16269Smckusick 5*16269Smckusick #include <stdio.h> 6*16269Smckusick #include <ctype.h> 7*16269Smckusick #include <sys/param.h> 8*16269Smckusick #include <sys/inode.h> 9*16269Smckusick #include <sys/fs.h> 10*16269Smckusick #include "fsck.h" 11*16269Smckusick 12*16269Smckusick long lseek(); 13*16269Smckusick 14*16269Smckusick ftypeok(dp) 15*16269Smckusick DINODE *dp; 16*16269Smckusick { 17*16269Smckusick switch (dp->di_mode & IFMT) { 18*16269Smckusick 19*16269Smckusick case IFDIR: 20*16269Smckusick case IFREG: 21*16269Smckusick case IFBLK: 22*16269Smckusick case IFCHR: 23*16269Smckusick case IFLNK: 24*16269Smckusick case IFSOCK: 25*16269Smckusick return (1); 26*16269Smckusick 27*16269Smckusick default: 28*16269Smckusick if (debug) 29*16269Smckusick printf("bad file type 0%o\n", dp->di_mode); 30*16269Smckusick return (0); 31*16269Smckusick } 32*16269Smckusick } 33*16269Smckusick 34*16269Smckusick reply(s) 35*16269Smckusick char *s; 36*16269Smckusick { 37*16269Smckusick char line[80]; 38*16269Smckusick 39*16269Smckusick if (preen) 40*16269Smckusick pfatal("INTERNAL ERROR: GOT TO reply()"); 41*16269Smckusick rplyflag = 1; 42*16269Smckusick printf("\n%s? ", s); 43*16269Smckusick if (nflag || dfile.wfdes < 0) { 44*16269Smckusick printf(" no\n\n"); 45*16269Smckusick return (0); 46*16269Smckusick } 47*16269Smckusick if (yflag) { 48*16269Smckusick printf(" yes\n\n"); 49*16269Smckusick return (1); 50*16269Smckusick } 51*16269Smckusick if (getline(stdin, line, sizeof(line)) == EOF) 52*16269Smckusick errexit("\n"); 53*16269Smckusick printf("\n"); 54*16269Smckusick if (line[0] == 'y' || line[0] == 'Y') 55*16269Smckusick return (1); 56*16269Smckusick else 57*16269Smckusick return (0); 58*16269Smckusick } 59*16269Smckusick 60*16269Smckusick getline(fp, loc, maxlen) 61*16269Smckusick FILE *fp; 62*16269Smckusick char *loc; 63*16269Smckusick { 64*16269Smckusick register n; 65*16269Smckusick register char *p, *lastloc; 66*16269Smckusick 67*16269Smckusick p = loc; 68*16269Smckusick lastloc = &p[maxlen-1]; 69*16269Smckusick while ((n = getc(fp)) != '\n') { 70*16269Smckusick if (n == EOF) 71*16269Smckusick return (EOF); 72*16269Smckusick if (!isspace(n) && p < lastloc) 73*16269Smckusick *p++ = n; 74*16269Smckusick } 75*16269Smckusick *p = 0; 76*16269Smckusick return (p - loc); 77*16269Smckusick } 78*16269Smckusick 79*16269Smckusick BUFAREA * 80*16269Smckusick getblk(bp, blk, size) 81*16269Smckusick register BUFAREA *bp; 82*16269Smckusick daddr_t blk; 83*16269Smckusick long size; 84*16269Smckusick { 85*16269Smckusick register struct filecntl *fcp; 86*16269Smckusick daddr_t dblk; 87*16269Smckusick 88*16269Smckusick fcp = &dfile; 89*16269Smckusick dblk = fsbtodb(&sblock, blk); 90*16269Smckusick if (bp->b_bno == dblk) 91*16269Smckusick return (bp); 92*16269Smckusick flush(fcp, bp); 93*16269Smckusick if (bread(fcp, bp->b_un.b_buf, dblk, size) != 0) { 94*16269Smckusick bp->b_bno = dblk; 95*16269Smckusick bp->b_size = size; 96*16269Smckusick return (bp); 97*16269Smckusick } 98*16269Smckusick bp->b_bno = (daddr_t)-1; 99*16269Smckusick return (NULL); 100*16269Smckusick } 101*16269Smckusick 102*16269Smckusick flush(fcp, bp) 103*16269Smckusick struct filecntl *fcp; 104*16269Smckusick register BUFAREA *bp; 105*16269Smckusick { 106*16269Smckusick 107*16269Smckusick if (bp->b_dirty) 108*16269Smckusick (void)bwrite(fcp, bp->b_un.b_buf, bp->b_bno, (long)bp->b_size); 109*16269Smckusick bp->b_dirty = 0; 110*16269Smckusick } 111*16269Smckusick 112*16269Smckusick rwerr(s, blk) 113*16269Smckusick char *s; 114*16269Smckusick daddr_t blk; 115*16269Smckusick { 116*16269Smckusick 117*16269Smckusick if (preen == 0) 118*16269Smckusick printf("\n"); 119*16269Smckusick pfatal("CANNOT %s: BLK %ld", s, blk); 120*16269Smckusick if (reply("CONTINUE") == 0) 121*16269Smckusick errexit("Program terminated\n"); 122*16269Smckusick } 123*16269Smckusick 124*16269Smckusick ckfini() 125*16269Smckusick { 126*16269Smckusick 127*16269Smckusick flush(&dfile, &fileblk); 128*16269Smckusick flush(&dfile, &sblk); 129*16269Smckusick if (sblk.b_bno != SBLOCK) { 130*16269Smckusick sblk.b_bno = SBLOCK; 131*16269Smckusick sbdirty(); 132*16269Smckusick flush(&dfile, &sblk); 133*16269Smckusick } 134*16269Smckusick flush(&dfile, &inoblk); 135*16269Smckusick (void)close(dfile.rfdes); 136*16269Smckusick (void)close(dfile.wfdes); 137*16269Smckusick } 138*16269Smckusick 139*16269Smckusick bread(fcp, buf, blk, size) 140*16269Smckusick register struct filecntl *fcp; 141*16269Smckusick char *buf; 142*16269Smckusick daddr_t blk; 143*16269Smckusick long size; 144*16269Smckusick { 145*16269Smckusick if (lseek(fcp->rfdes, (long)dbtob(blk), 0) < 0) 146*16269Smckusick rwerr("SEEK", blk); 147*16269Smckusick else if (read(fcp->rfdes, buf, (int)size) == size) 148*16269Smckusick return (1); 149*16269Smckusick rwerr("READ", blk); 150*16269Smckusick return (0); 151*16269Smckusick } 152*16269Smckusick 153*16269Smckusick bwrite(fcp, buf, blk, size) 154*16269Smckusick register struct filecntl *fcp; 155*16269Smckusick char *buf; 156*16269Smckusick daddr_t blk; 157*16269Smckusick long size; 158*16269Smckusick { 159*16269Smckusick 160*16269Smckusick if (fcp->wfdes < 0) 161*16269Smckusick return (0); 162*16269Smckusick if (lseek(fcp->wfdes, (long)dbtob(blk), 0) < 0) 163*16269Smckusick rwerr("SEEK", blk); 164*16269Smckusick else if (write(fcp->wfdes, buf, (int)size) == size) { 165*16269Smckusick fcp->mod = 1; 166*16269Smckusick return (1); 167*16269Smckusick } 168*16269Smckusick rwerr("WRITE", blk); 169*16269Smckusick return (0); 170*16269Smckusick } 171*16269Smckusick 172*16269Smckusick catch() 173*16269Smckusick { 174*16269Smckusick 175*16269Smckusick ckfini(); 176*16269Smckusick exit(12); 177*16269Smckusick } 178*16269Smckusick 179*16269Smckusick /* 180*16269Smckusick * determine whether an inode should be fixed. 181*16269Smckusick */ 182*16269Smckusick dofix(idesc) 183*16269Smckusick register struct inodesc *idesc; 184*16269Smckusick { 185*16269Smckusick 186*16269Smckusick switch (idesc->id_fix) { 187*16269Smckusick 188*16269Smckusick case DONTKNOW: 189*16269Smckusick direrr(idesc->id_number, "DIRECTORY CORRUPTED"); 190*16269Smckusick if (reply("SALVAGE") == 0) { 191*16269Smckusick idesc->id_fix = NOFIX; 192*16269Smckusick return (0); 193*16269Smckusick } 194*16269Smckusick idesc->id_fix = FIX; 195*16269Smckusick return (ALTERED); 196*16269Smckusick 197*16269Smckusick case FIX: 198*16269Smckusick return (ALTERED); 199*16269Smckusick 200*16269Smckusick case NOFIX: 201*16269Smckusick return (0); 202*16269Smckusick 203*16269Smckusick default: 204*16269Smckusick errexit("UNKNOWN INODESC FIX MODE %d\n", idesc->id_fix); 205*16269Smckusick } 206*16269Smckusick /* NOTREACHED */ 207*16269Smckusick } 208*16269Smckusick 209*16269Smckusick /* VARARGS1 */ 210*16269Smckusick error(s1, s2, s3, s4) 211*16269Smckusick char *s1; 212*16269Smckusick { 213*16269Smckusick 214*16269Smckusick printf(s1, s2, s3, s4); 215*16269Smckusick } 216*16269Smckusick 217*16269Smckusick /* VARARGS1 */ 218*16269Smckusick errexit(s1, s2, s3, s4) 219*16269Smckusick char *s1; 220*16269Smckusick { 221*16269Smckusick error(s1, s2, s3, s4); 222*16269Smckusick exit(8); 223*16269Smckusick } 224*16269Smckusick 225*16269Smckusick /* 226*16269Smckusick * An inconsistency occured which shouldn't during normal operations. 227*16269Smckusick * Die if preening, otherwise just printf. 228*16269Smckusick */ 229*16269Smckusick /* VARARGS1 */ 230*16269Smckusick pfatal(s, a1, a2, a3) 231*16269Smckusick char *s; 232*16269Smckusick { 233*16269Smckusick 234*16269Smckusick if (preen) { 235*16269Smckusick printf("%s: ", devname); 236*16269Smckusick printf(s, a1, a2, a3); 237*16269Smckusick printf("\n"); 238*16269Smckusick preendie(); 239*16269Smckusick } 240*16269Smckusick printf(s, a1, a2, a3); 241*16269Smckusick } 242*16269Smckusick 243*16269Smckusick preendie() 244*16269Smckusick { 245*16269Smckusick 246*16269Smckusick printf("%s: UNEXPECTED INCONSISTENCY; RUN fsck MANUALLY.\n", devname); 247*16269Smckusick exit(8); 248*16269Smckusick } 249*16269Smckusick 250*16269Smckusick /* 251*16269Smckusick * Pwarn is like printf when not preening, 252*16269Smckusick * or a warning (preceded by filename) when preening. 253*16269Smckusick */ 254*16269Smckusick /* VARARGS1 */ 255*16269Smckusick pwarn(s, a1, a2, a3, a4, a5, a6) 256*16269Smckusick char *s; 257*16269Smckusick { 258*16269Smckusick 259*16269Smckusick if (preen) 260*16269Smckusick printf("%s: ", devname); 261*16269Smckusick printf(s, a1, a2, a3, a4, a5, a6); 262*16269Smckusick } 263*16269Smckusick 264*16269Smckusick #ifndef lint 265*16269Smckusick /* 266*16269Smckusick * Stub for routines from kernel. 267*16269Smckusick */ 268*16269Smckusick panic(s) 269*16269Smckusick char *s; 270*16269Smckusick { 271*16269Smckusick 272*16269Smckusick pfatal("INTERNAL INCONSISTENCY: %s\n", s); 273*16269Smckusick exit(12); 274*16269Smckusick } 275*16269Smckusick #endif 276