diff options
-rw-r--r-- | sbin/fsck_msdos/check.c | 82 | ||||
-rw-r--r-- | sbin/fsck_msdos/dir.c | 360 | ||||
-rw-r--r-- | sbin/fsck_msdos/dosfs.h | 6 | ||||
-rw-r--r-- | sbin/fsck_msdos/ext.h | 26 | ||||
-rw-r--r-- | sbin/fsck_msdos/fat.c | 27 | ||||
-rw-r--r-- | sbin/fsck_msdos/main.c | 24 |
6 files changed, 318 insertions, 207 deletions
diff --git a/sbin/fsck_msdos/check.c b/sbin/fsck_msdos/check.c index adf41300c79..940157a0bd7 100644 --- a/sbin/fsck_msdos/check.c +++ b/sbin/fsck_msdos/check.c @@ -1,4 +1,4 @@ -/* $NetBSD: check.c,v 1.1 1996/05/14 17:39:29 ws Exp $ */ +/* $NetBSD: check.c,v 1.1.4.1 1996/05/31 18:41:33 jtc Exp $ */ /* * Copyright (C) 1995, 1996 Wolfgang Solfrank @@ -34,7 +34,7 @@ #ifndef lint -static char rcsid[] = "$NetBSD: check.c,v 1.1 1996/05/14 17:39:29 ws Exp $"; +static char rcsid[] = "$NetBSD: check.c,v 1.1.4.1 1996/05/31 18:41:33 jtc Exp $"; #endif /* not lint */ #include <stdlib.h> @@ -51,7 +51,6 @@ checkfilesys(fname) const char *fname; { int dosfs; - struct dosDirEntry *rootDir; struct bootblock boot; struct fatEntry * fat = NULL; int i; @@ -90,7 +89,9 @@ checkfilesys(fname) mod |= readfat(dosfs, &boot, i, ¤tFat); - if (mod&FSFATAL) { + if (mod & FSFATAL) { + if (fat) + free(fat); close(dosfs); return 8; } @@ -99,7 +100,9 @@ checkfilesys(fname) fat = currentFat; else { mod |= comparefat(&boot, fat, currentFat, i + 1); - if (mod&FSFATAL) { + free(currentFat); + if (mod & FSFATAL) { + free(fat); close(dosfs); return 8; } @@ -110,83 +113,50 @@ checkfilesys(fname) printf("** Phase 2 - Check Cluster Chains\n"); mod |= checkfat(&boot, fat); - if (mod&FSFATAL) { + if (mod & FSFATAL) { + free(fat); close(dosfs); return 8; } - if (mod&FSFATMOD) + if (mod & FSFATMOD) mod |= writefat(dosfs, &boot, fat); /* delay writing fats? XXX */ - if (mod&FSFATAL) { + if (mod & FSFATAL) { + free(fat); close(dosfs); return 8; } if (!preen) printf("** Phase 3 - Checking Directories\n"); - - rootDir = malloc(sizeof(struct dosDirEntry)); - memset(rootDir, 0, sizeof(struct dosDirEntry)); - rootDir->fullpath = strdup("/"); - if (resetDosDirSection(&boot)&FSFATAL) { - close(dosfs); - return 8; - } - - mod = readDosDirSection(dosfs, &boot, fat, rootDir); - if (mod&FSFATAL) { + + if (resetDosDirSection(&boot) & FSFATAL) { + free(fat); close(dosfs); return 8; } - - if (mod&FSFATMOD) - mod |= writefat(dosfs, &boot, fat); /* delay writing fats? XXX */ - if (mod&FSFATAL) { + + mod |= handleDirTree(dosfs, &boot, fat); + if (mod & FSFATAL) { + finishDosDirSection(); + free(fat); close(dosfs); return 8; } - /* - * process the directory todo list - */ - while (pendingDirectories) { - struct dosDirEntry *dir = pendingDirectories->dir; - struct dirTodoNode *n = pendingDirectories->next; - - /* - * remove TODO entry now, the list might change during - * directory reads - */ - free(pendingDirectories); - pendingDirectories = n; - - /* - * handle subdirectory - */ - mod |= readDosDirSection(dosfs, &boot, fat, dir); - if (mod&FSFATAL) { - close(dosfs); - return 8; - } - if (mod&FSFATMOD) - mod |= writefat(dosfs, &boot, fat); /* delay writing fats? XXX */ - if (mod&FSFATAL) { - close(dosfs); - return 8; - } - } - finishDosDirSection(); - if (!preen) printf("** Phase 4 - Checking for Lost Files\n"); - mod |= checklost(dosfs, &boot, fat, rootDir); + mod |= checklost(dosfs, &boot, fat); + finishDosDirSection(); + free(fat); close(dosfs); + pwarn("%d files, %d free (%d clusters)\n", boot.NumFiles, boot.NumFree * boot.ClusterSize / 1024, boot.NumFree); - if (mod&(FSFATAL|FSERROR)) + if (mod & (FSFATAL | FSERROR)) return 8; if (mod) { pwarn("\n***** FILE SYSTEM WAS MODIFIED *****\n"); diff --git a/sbin/fsck_msdos/dir.c b/sbin/fsck_msdos/dir.c index d0b205cf98f..6b06737747b 100644 --- a/sbin/fsck_msdos/dir.c +++ b/sbin/fsck_msdos/dir.c @@ -1,4 +1,4 @@ -/* $NetBSD: dir.c,v 1.1 1996/05/14 17:39:30 ws Exp $ */ +/* $NetBSD: dir.c,v 1.1.4.1 1996/05/31 18:41:38 jtc Exp $ */ /* * Copyright (C) 1995, 1996 Wolfgang Solfrank @@ -36,7 +36,7 @@ #ifndef lint -static char rcsid[] = "$NetBSD: dir.c,v 1.1 1996/05/14 17:39:30 ws Exp $"; +static char rcsid[] = "$NetBSD: dir.c,v 1.1.4.1 1996/05/31 18:41:38 jtc Exp $"; #endif /* not lint */ #include <stdio.h> @@ -47,6 +47,8 @@ static char rcsid[] = "$NetBSD: dir.c,v 1.1 1996/05/14 17:39:30 ws Exp $"; #include <unistd.h> #include <time.h> +#include <sys/param.h> + #include "ext.h" #define SLOT_EMPTY 0x00 /* slot has never been used */ @@ -88,6 +90,89 @@ static char rcsid[] = "$NetBSD: dir.c,v 1.1 1996/05/14 17:39:30 ws Exp $"; #define DD_YEAR_SHIFT 9 /* + * Manage free dosDirEntry structures. + */ +static struct dosDirEntry *freede; + +static struct dosDirEntry * +newDosDirEntry() +{ + struct dosDirEntry *de; + + if (!(de = freede)) { + if (!(de = (struct dosDirEntry *)malloc(sizeof *de))) + return 0; + } else + freede = de->next; + return de; +} + +static void +freeDosDirEntry(de) + struct dosDirEntry *de; +{ + de->next = freede; + freede = de; +} + +/* + * The same for dirTodoNode structures. + */ +static struct dirTodoNode *freedt; + +static struct dirTodoNode * +newDirTodo() +{ + struct dirTodoNode *dt; + + if (!(dt = freedt)) { + if (!(dt = (struct dirTodoNode *)malloc(sizeof *dt))) + return 0; + } else + freedt = dt->next; + return dt; +} + +static void +freeDirTodo(dt) + struct dirTodoNode *dt; +{ + dt->next = freedt; + freedt = dt; +} + +/* + * The stack of unread directories + */ +struct dirTodoNode *pendingDirectories = NULL; + +/* + * Return the full pathname for a directory entry. + */ +static char * +fullpath(dir) + struct dosDirEntry *dir; +{ + static char namebuf[MAXPATHLEN + 1]; + char *cp, *np; + int nl; + + cp = namebuf + sizeof namebuf - 1; + *cp = '\0'; + do { + np = dir->lname[0] ? dir->lname : dir->name; + nl = strlen(np); + if ((cp -= nl) <= namebuf + 1) + break; + memcpy(cp, np, nl); + *--cp = '/'; + } while (dir = dir->parent); + if (dir->parent) + *--cp = '?'; + return cp; +} + +/* * Calculate a checksum over an 8.3 alias name */ static u_char @@ -112,6 +197,9 @@ static char longName[DOSLONGNAMELEN] = ""; static u_char *buffer = NULL; static u_char *delbuf = NULL; +struct dosDirEntry *rootDir; +static struct dosDirEntry *lostDir; + /* * Init internal state for a new directory scan. */ @@ -125,10 +213,12 @@ resetDosDirSection(boot) b2 = boot->SecPerClust * boot->BytesPerSec; if (!(buffer = malloc(b1 > b2 ? b1 : b2)) - || !(delbuf = malloc(b2))) { + || !(delbuf = malloc(b2)) + || !(rootDir = newDosDirEntry())) { perror("No space for directory"); return FSFATAL; } + memset(rootDir, 0, sizeof *rootDir); return FSOK; } @@ -138,6 +228,24 @@ resetDosDirSection(boot) void finishDosDirSection() { + struct dirTodoNode *p, *np; + struct dosDirEntry *d, *nd; + + for (p = pendingDirectories; p; p = np) { + np = p->next; + freeDirTodo(p); + } + pendingDirectories = 0; + for (d = rootDir; d; d = nd) { + if (nd = d->child) { + d->child = 0; + continue; + } + if (!(nd = d->next)) + nd = d->parent; + freeDosDirEntry(d); + } + rootDir = lostDir = NULL; free(buffer); free(delbuf); buffer = NULL; @@ -195,7 +303,7 @@ delete(f, boot, fat, startcl, startoff, endcl, endoff, notlast) } static int -removede(f, boot, fat, start, end, startcl, endcl, curcl, path, eof) +removede(f, boot, fat, start, end, startcl, endcl, curcl, path, type) int f; struct bootblock *boot; struct fatEntry *fat; @@ -205,12 +313,19 @@ removede(f, boot, fat, start, end, startcl, endcl, curcl, path, eof) cl_t endcl; cl_t curcl; char *path; - int eof; + int type; { - if (!eof) + switch (type) { + case 0: pwarn("Invalid long filename entry for %s\n", path); - else + break; + case 1: pwarn("Invalid long filename entry at end of directory %s\n", path); + break; + case 2: + pwarn("Invalid long filename entry for volume label\n"); + break; + } if (ask(0, "Remove")) { if (startcl != curcl) { if (delete(f, boot, fat, @@ -241,14 +356,18 @@ checksize(boot, fat, p, dir) /* * Check size on ordinary files */ - u_int32_t physicalSize; + int32_t physicalSize; - if (dir->head < CLUST_FIRST || dir->head >= boot->NumClusters) - return FSERROR; - physicalSize = fat[dir->head].length * boot->ClusterSize; + if (dir->head == CLUST_FREE) + physicalSize = 0; + else { + if (dir->head < CLUST_FIRST || dir->head >= boot->NumClusters) + return FSERROR; + physicalSize = fat[dir->head].length * boot->ClusterSize; + } if (physicalSize < dir->size) { pwarn("size of %s is %lu, should at most be %lu\n", - dir->fullpath, dir->size, physicalSize); + fullpath(dir), dir->size, physicalSize); if (ask(1, "Truncate")) { dir->size = physicalSize; p[28] = (u_char)physicalSize; @@ -260,7 +379,7 @@ checksize(boot, fat, p, dir) return FSERROR; } else if (physicalSize - dir->size >= boot->ClusterSize) { pwarn("%s has too many clusters allocated\n", - dir->fullpath); + fullpath(dir)); if (ask(1, "Drop superfluous clusters")) { cl_t cl; u_int32_t sz = 0; @@ -277,17 +396,12 @@ checksize(boot, fat, p, dir) } /* - * The stack of unread directories - */ -struct dirTodoNode *pendingDirectories = NULL; - -/* * Read a directory and * - resolve long name records * - enter file and directory records into the parent's list * - push directories onto the todo-stack */ -int +static int readDosDirSection(f, boot, fat, dir) int f; struct bootblock *boot; @@ -306,7 +420,7 @@ readDosDirSection(f, boot, fat, dir) #define THISMOD 0x8000 /* Only used within this routine */ cl = dir->head; - if (dir->fullpath[1] && (cl < CLUST_FIRST || cl >= boot->NumClusters)) { + if (dir->parent && (cl < CLUST_FIRST || cl >= boot->NumClusters)) { /* * Already handled somewhere else. */ @@ -315,7 +429,7 @@ readDosDirSection(f, boot, fat, dir) shortSum = -1; vallfn = invlfn = empty = NULL; do { - if (!dir->fullpath[1]) { + if (!dir->parent) { last = boot->RootDirEnts * 32; off = boot->ResSectors + boot->FATs * boot->FATsecs; } else { @@ -351,7 +465,7 @@ readDosDirSection(f, boot, fat, dir) if (dir->fsckflags & DIREMPTY) { if (!(dir->fsckflags & DIREMPWARN)) { pwarn("%s has entries after end of directory\n", - dir->fullpath); + fullpath(dir)); if (ask(1, "Extend")) { dir->fsckflags &= ~DIREMPTY; if (delete(f, boot, fat, @@ -465,10 +579,20 @@ readDosDirSection(f, boot, fat, dir) k++; if (dirent.name[0] == SLOT_E5) dirent.name[0] = 0xe5; - /* - * What about volume names with extensions? XXX - */ - if ((dirent.flags & ATTR_VOLUME) == 0 && p[8] != ' ') + + if (dirent.flags & ATTR_VOLUME) { + if (vallfn || invlfn) { + mod |= removede(f, boot, fat, + invlfn ? invlfn : vallfn, p, + invlfn ? invcl : valcl, -1, 0, + fullpath(dir), 2); + vallfn = NULL; + invlfn = NULL; + } + continue; + } + + if (p[8] != ' ') dirent.name[k++] = '.'; for (j = 0; j < 3; j++) dirent.name[k++] = p[j+8]; @@ -490,20 +614,12 @@ readDosDirSection(f, boot, fat, dir) longName[0] = '\0'; shortSum = -1; } - - k = strlen(dirent.lname[0] ? dirent.lname : dirent.name); - k += strlen(dir->fullpath) + 2; - dirent.fullpath = malloc(k); - strcpy(dirent.fullpath, dir->fullpath); - if (dir->fullpath[1]) - strcat(dirent.fullpath, "/"); - strcat(dirent.fullpath, - dirent.lname[0] ? dirent.lname : dirent.name); + if (invlfn) { mod |= k = removede(f, boot, fat, invlfn, vallfn ? vallfn : p, invcl, vallfn ? valcl : cl, cl, - dirent.fullpath, 0); + fullpath(&dirent), 0); if (mod & FSFATAL) return FSFATAL; if (vallfn @@ -518,7 +634,7 @@ readDosDirSection(f, boot, fat, dir) if (dirent.size == 0 && !(dirent.flags & ATTR_DIRECTORY)) { if (dirent.head != 0) { pwarn("%s has clusters, but size 0\n", - dirent.fullpath); + fullpath(&dirent)); if (ask(1, "Drop allocated clusters")) { p[26] = p[27] = 0; clearchain(boot, fat, dirent.head); @@ -529,7 +645,8 @@ readDosDirSection(f, boot, fat, dir) } } else if (dirent.head == 0 && !strcmp(dirent.name, "..") - && !strcmp(dir->parent->fullpath, "/")) { + && dir->parent /* XXX */ + && !dir->parent->parent) { /* * Do nothing, the parent is the root */ @@ -541,22 +658,22 @@ readDosDirSection(f, boot, fat, dir) || fat[dirent.head].head != dirent.head) { if (dirent.head == 0) pwarn("%s has no clusters\n", - dirent.fullpath); + fullpath(&dirent)); else if (dirent.head < CLUST_FIRST || dirent.head >= boot->NumClusters) pwarn("%s starts with cluster out of range(%d)\n", - dirent.fullpath, + fullpath(&dirent), dirent.head); else if (fat[dirent.head].next == CLUST_FREE) pwarn("%s starts with free cluster\n", - dirent.fullpath); + fullpath(&dirent)); else if (fat[dirent.head].next >= CLUST_RSRVD) pwarn("%s starts with %s cluster\n", - dirent.fullpath, + fullpath(&dirent), rsrvdcltype(fat[dirent.head].next)); else pwarn("%s doesn't start a cluster chain\n", - dirent.fullpath); + fullpath(&dirent)); if (dirent.flags & ATTR_DIRECTORY) { if (ask(0, "Remove")) { *p = SLOT_DELETED; @@ -574,28 +691,23 @@ readDosDirSection(f, boot, fat, dir) } } - /* create directory tree node */ - d = malloc(sizeof(struct dosDirEntry)); - memcpy(d, &dirent, sizeof(struct dosDirEntry)); - /* link it into the directory tree */ - d->parent = dir; - d->next = dir->child; - dir->child = d; - if (d->head >= CLUST_FIRST && d->head < boot->NumClusters) - fat[d->head].dirp = d; + dirent.parent = dir; + dirent.next = dir->child; + if (dirent.head >= CLUST_FIRST && dirent.head < boot->NumClusters) + fat[dirent.head].flags |= FAT_USED; - if (d->flags & ATTR_DIRECTORY) { + if (dirent.flags & ATTR_DIRECTORY) { /* * gather more info for directories */ struct dirTodoNode * n; - if (d->size) { + if (dirent.size) { pwarn("Directory %s has size != 0\n", - d->fullpath); + fullpath(&dirent)); if (ask(1, "Correct")) { p[28] = p[29] = p[30] = p[31] = 0; - d->size = 0; + dirent.size = 0; mod |= THISMOD|FSDIRMOD; } else mod |= FSERROR; @@ -603,28 +715,29 @@ readDosDirSection(f, boot, fat, dir) /* * handle `.' and `..' specially */ - if (strcmp(d->name, ".") == 0) { - if (d->head != dir->head) { + if (strcmp(dirent.name, ".") == 0) { + if (dirent.head != dir->head) { pwarn("`.' entry in %s has incorrect start cluster\n", - dir->fullpath); + fullpath(dir)); if (ask(1, "Correct")) { - d->head = dir->head; - p[26] = (u_char)d->head; - p[27] = (u_char)(d->head >> 8); + dirent.head = dir->head; + p[26] = (u_char)dirent.head; + p[27] = (u_char)(dirent.head >> 8); mod |= THISMOD|FSDIRMOD; } else mod |= FSERROR; } continue; } - if (strcmp(d->name, "..") == 0) { - if (d->head != dir->parent->head) { + if (strcmp(dirent.name, "..") == 0) { + if (dir->parent /* XXX */ + && dirent.head != dir->parent->head) { pwarn("`..' entry in %s has incorrect start cluster\n", - dir->fullpath); + fullpath(dir)); if (ask(1, "Correct")) { - d->head = dir->parent->head; - p[26] = (u_char)d->head; - p[27] = (u_char)(d->head >> 8); + dirent.head = dir->parent->head; + p[26] = (u_char)dirent.head; + p[27] = (u_char)(dirent.head >> 8); mod |= THISMOD|FSDIRMOD; } else mod |= FSERROR; @@ -633,13 +746,27 @@ readDosDirSection(f, boot, fat, dir) } boot->NumFiles++; + + /* create directory tree node */ + if (!(d = newDosDirEntry())) { + perror("No space for directory"); + return FSFATAL; + } + + memcpy(d, &dirent, sizeof(struct dosDirEntry)); + /* link it into the tree */ + dir->child = d; + /* Enter this directory into the todo list */ - n = malloc(sizeof(struct dirTodoNode)); + if (!(n = newDirTodo())) { + perror("No space for todo list"); + return FSFATAL; + } n->next = pendingDirectories; n->dir = d; pendingDirectories = n; } else { - mod |= k = checksize(boot, fat, p, d); + mod |= k = checksize(boot, fat, p, &dirent); if (k & FSDIRMOD) mod |= THISMOD; boot->NumFiles++; @@ -659,10 +786,60 @@ readDosDirSection(f, boot, fat, dir) mod |= removede(f, boot, fat, invlfn ? invlfn : vallfn, p, invlfn ? invcl : valcl, -1, 0, - dir->fullpath, 1); + fullpath(dir), 1); return mod & ~THISMOD; } +int +handleDirTree(dosfs, boot, fat) + int dosfs; + struct bootblock *boot; + struct fatEntry *fat; +{ + int mod; + + mod = readDosDirSection(dosfs, boot, fat, rootDir); + if (mod & FSFATAL) + return FSFATAL; + + if (mod & FSFATMOD) { + mod &= ~FSFATMOD; + mod |= writefat(dosfs, boot, fat); /* delay writing fats? XXX */ + } + + if (mod & FSFATAL) + return FSFATAL; + + /* + * process the directory todo list + */ + while (pendingDirectories) { + struct dosDirEntry *dir = pendingDirectories->dir; + struct dirTodoNode *n = pendingDirectories->next; + + /* + * remove TODO entry now, the list might change during + * directory reads + */ + freeDirTodo(pendingDirectories); + pendingDirectories = n; + + /* + * handle subdirectory + */ + mod |= readDosDirSection(dosfs, boot, fat, dir); + if (mod & FSFATAL) + return FSFATAL; + if (mod & FSFATMOD) { + mod &= ~FSFATMOD; + mod |= writefat(dosfs, boot, fat); /* delay writing fats? XXX */ + } + if (mod & FSFATAL) + return FSFATAL; + } + return mod; +} + /* * Try to reconnect a FAT chain into dir */ @@ -671,18 +848,25 @@ static cl_t lfcl; static off_t lfoff; int -reconnect(dosfs, boot, fat, head, dir) +reconnect(dosfs, boot, fat, head) int dosfs; struct bootblock *boot; struct fatEntry *fat; cl_t head; - struct dosDirEntry *dir; { struct dosDirEntry d; u_char *p; - if (!dir) /* Create lfdir? XXX */ - return FSERROR; + if (!lostDir) { + for (lostDir = rootDir->child; lostDir; lostDir = lostDir->next) { + if (!strcmp(lostDir->name, LOSTDIR)) + break; + } + if (!lostDir) { /* Create LOSTDIR? XXX */ + pwarn("No %s directory\n", LOSTDIR); + return FSERROR; + } + } if (!lfbuf) { lfbuf = malloc(boot->ClusterSize); if (!lfbuf) { @@ -700,9 +884,9 @@ reconnect(dosfs, boot, fat, head, dir) break; if (p && p < lfbuf + boot->ClusterSize) break; - lfcl = p ? fat[lfcl].next : dir->head; + lfcl = p ? fat[lfcl].next : lostDir->head; if (lfcl < CLUST_FIRST || lfcl >= boot->NumClusters) { - /* Extend lfdir? XXX */ + /* Extend LOSTDIR? XXX */ pwarn("No space in %s\n", LOSTDIR); return FSERROR; } @@ -723,26 +907,20 @@ reconnect(dosfs, boot, fat, head, dir) /* Ensure uniqueness of entry here! XXX */ memset(&d, 0, sizeof d); sprintf(d.name, "%d", head); - d.fullpath = malloc(strlen(dir->fullpath) + strlen(d.name) + 2); - sprintf(d.fullpath, "%s/%s", dir->fullpath, d.name); d.flags = 0; d.head = head; d.size = fat[head].length * boot->ClusterSize; - d.parent = dir; - d.next = dir->child; - dir->child = malloc(sizeof(struct dosDirEntry)); - memcpy(dir->child, &d, sizeof(struct dosDirEntry)); memset(p, 0, 32); memset(p, ' ', 11); - memcpy(p, dir->name, strlen(dir->name)); - p[26] = (u_char)dir->head; - p[27] = (u_char)(dir->head >> 8); - p[28] = (u_char)dir->size; - p[29] = (u_char)(dir->size >> 8); - p[30] = (u_char)(dir->size >> 16); - p[31] = (u_char)(dir->size >> 24); - fat[head].dirp = dir; + memcpy(p, d.name, strlen(d.name)); + p[26] = (u_char)d.head; + p[27] = (u_char)(d.head >> 8); + p[28] = (u_char)d.size; + p[29] = (u_char)(d.size >> 8); + p[30] = (u_char)(d.size >> 16); + p[31] = (u_char)(d.size >> 24); + fat[head].flags |= FAT_USED; if (lseek(dosfs, lfoff, SEEK_SET) != lfoff || write(dosfs, buffer, boot->ClusterSize) != boot->ClusterSize) { perror("could not write LOST.DIR"); diff --git a/sbin/fsck_msdos/dosfs.h b/sbin/fsck_msdos/dosfs.h index c0295bc7b10..e94bb8b0a60 100644 --- a/sbin/fsck_msdos/dosfs.h +++ b/sbin/fsck_msdos/dosfs.h @@ -1,3 +1,4 @@ +/* $NetBSD: dosfs.h,v 1.1.4.1 1996/05/31 18:41:42 jtc Exp $ */ /* * Copyright (C) 1995, 1996 Wolfgang Solfrank @@ -77,7 +78,7 @@ struct fatEntry { cl_t next; /* pointer to next cluster */ cl_t head; /* pointer to start of chain */ u_int32_t length; /* number of clusters on chain */ - struct dosDirEntry *dirp; /* corresponding file name */ + int flags; /* see below */ }; #define CLUST_FREE 0 /* 0 means cluster is free */ @@ -87,6 +88,8 @@ struct fatEntry { #define CLUST_EOFS 0xfff8 /* start of EOF indicators */ #define CLUST_EOF 0xffff /* standard value for last cluster */ +#define FAT_USED 1 /* This fat chain is used in a file */ + #define DOSLONGNAMELEN 256 /* long name maximal length */ #define LRFIRST 0x40 /* first long name record */ #define LRNOMASK 0x1f /* mask to extract long record @@ -100,7 +103,6 @@ struct dosDirEntry { *parent, /* previous tree level */ *next, /* next brother */ *child; /* if this is a directory */ - char *fullpath; /* path name from root to this directory */ char name[8+1+3+1]; /* alias name first part */ char lname[DOSLONGNAMELEN]; /* real name */ uint flags; /* attributes */ diff --git a/sbin/fsck_msdos/ext.h b/sbin/fsck_msdos/ext.h index 63615e8e195..ae019457ed4 100644 --- a/sbin/fsck_msdos/ext.h +++ b/sbin/fsck_msdos/ext.h @@ -1,3 +1,5 @@ +/* $NetBSD: ext.h,v 1.1.4.1 1996/05/31 18:41:45 jtc Exp $ */ + /* * Copyright (C) 1995, 1996 Wolfgang Solfrank * Copyright (c) 1995 Martin Husemann @@ -35,17 +37,6 @@ #include <sys/types.h> -#if sun -#define __P(a) a - -typedef char int8_t; -typedef unsigned char u_int8_t; -typedef short int16_t; -typedef unsigned short u_int16_t; -typedef long int32_t; -typedef unsigned long u_int32_t; -#endif - #include "dosfs.h" #define LOSTDIR "LOST.DIR" @@ -60,6 +51,8 @@ extern int rdonly; /* device is opened read only (supersedes above) */ extern char *fname; /* filesystem currently checked */ +extern struct dosDirEntry *rootDir; + /* * function declarations */ @@ -117,12 +110,7 @@ int writefat __P((int, struct bootblock *, struct fatEntry *)); */ int resetDosDirSection __P((struct bootblock *)); void finishDosDirSection __P((void)); -int readDosDirSection __P((int, struct bootblock *, struct fatEntry *, struct dosDirEntry *)); - -/* - * A stack of directories which should be examined later - */ -extern struct dirTodoNode *pendingDirectories; +int handleDirTree __P((int, struct bootblock *, struct fatEntry *)); /* * Cross-check routines run after everything is completely in memory @@ -130,11 +118,11 @@ extern struct dirTodoNode *pendingDirectories; /* * Check for lost cluster chains */ -int checklost __P((int, struct bootblock *, struct fatEntry *, struct dosDirEntry *)); +int checklost __P((int, struct bootblock *, struct fatEntry *)); /* * Try to reconnect a lost cluster chain */ -int reconnect __P((int, struct bootblock *, struct fatEntry *, cl_t, struct dosDirEntry *)); +int reconnect __P((int, struct bootblock *, struct fatEntry *, cl_t)); void finishlf __P((void)); /* diff --git a/sbin/fsck_msdos/fat.c b/sbin/fsck_msdos/fat.c index 6ebb99e529d..830f5d44d48 100644 --- a/sbin/fsck_msdos/fat.c +++ b/sbin/fsck_msdos/fat.c @@ -1,4 +1,4 @@ -/* $NetBSD: fat.c,v 1.1 1996/05/14 17:39:34 ws Exp $ */ +/* $NetBSD: fat.c,v 1.1.4.1 1996/05/31 18:41:50 jtc Exp $ */ /* * Copyright (C) 1995, 1996 Wolfgang Solfrank @@ -34,7 +34,7 @@ #ifndef lint -static char rcsid[] = "$NetBSD: fat.c,v 1.1 1996/05/14 17:39:34 ws Exp $"; +static char rcsid[] = "$NetBSD: fat.c,v 1.1.4.1 1996/05/31 18:41:50 jtc Exp $"; #endif /* not lint */ #include <stdlib.h> @@ -478,35 +478,28 @@ writefat(fs, boot, fat) * Check a complete in-memory FAT for lost cluster chains */ int -checklost(dosfs, boot, fat, rootDir) +checklost(dosfs, boot, fat) int dosfs; struct bootblock *boot; struct fatEntry *fat; - struct dosDirEntry *rootDir; { cl_t head; - struct dosDirEntry *lfdir; int mod = FSOK; - for (lfdir = rootDir->child; lfdir; lfdir = lfdir->next) { - if (!strcmp(lfdir->name, LOSTDIR)) - break; - } for (head = CLUST_FIRST; head < boot->NumClusters; head++) { /* find next untraveled chain */ if (fat[head].head != head || fat[head].next == CLUST_FREE || (fat[head].next >= CLUST_RSRVD - && fat[head].next < CLUST_EOFS)) + && fat[head].next < CLUST_EOFS) + || (fat[head].flags & FAT_USED)) continue; - if (fat[head].dirp == NULL) { - pwarn("Lost cluster chain at cluster 0x%04x\n%d Cluster(s) lost\n", - head, fat[head].length); - mod |= reconnect(dosfs, boot, fat, head, lfdir); - if (mod&FSFATAL) - break; - } + pwarn("Lost cluster chain at cluster 0x%04x\n%d Cluster(s) lost\n", + head, fat[head].length); + mod |= reconnect(dosfs, boot, fat, head); + if (mod & FSFATAL) + break; } finishlf(); diff --git a/sbin/fsck_msdos/main.c b/sbin/fsck_msdos/main.c index 67634aa278f..e786a9d76a3 100644 --- a/sbin/fsck_msdos/main.c +++ b/sbin/fsck_msdos/main.c @@ -1,4 +1,4 @@ -/* $NetBSD: main.c,v 1.1 1996/05/14 17:39:36 ws Exp $ */ +/* $NetBSD: main.c,v 1.1.4.1 1996/05/31 18:41:54 jtc Exp $ */ /* * Copyright (C) 1995 Wolfgang Solfrank @@ -34,7 +34,7 @@ #ifndef lint -static char rcsid[] = "$NetBSD: main.c,v 1.1 1996/05/14 17:39:36 ws Exp $"; +static char rcsid[] = "$NetBSD: main.c,v 1.1.4.1 1996/05/31 18:41:54 jtc Exp $"; #endif /* not lint */ #include <stdlib.h> @@ -179,22 +179,6 @@ pwarn(fmt, va_alist) va_end(ap); } -#if sun -char * -strerror(n) - int n; -{ - extern int sys_nerr; - extern char *sys_errlist[]; - static char alt[80]; - - if (n < sys_nerr) - return sys_errlist[n]; - sprintf(alt, "Unknown error %d", n); - return alt; -} -#endif - void perror(s) const char *s; @@ -231,11 +215,7 @@ ask(def, fmt, va_alist) #else va_start(ap); #endif -#if sun - vsprintf(prompt, fmt, ap); -#else vsnprintf(prompt, sizeof(prompt), fmt, ap); -#endif if (alwaysyes || rdonly) { printf("%s? %s\n", prompt, rdonly ? "no" : "yes"); return !rdonly; |