bool valid_cached_file_version(const char *cachename) { char buffer[16]; autofclose FILE *f; if (!(f = fopen(cachename, "r"))) { PERROR("Error: Could not read cache file '%s', skipping...\n", cachename); return false; } size_t res = fread(buffer, 1, 16, f); if (res < 16) { if (debug_cache) pwarn("%s: cache file '%s' invalid size\n", progname, cachename); return false; } /* 12 byte header that is always the same and then 4 byte version # */ if (memcmp(buffer, header_string, HEADER_STRING_SIZE) != 0) { if (debug_cache) pwarn("%s: cache file '%s' has wrong header\n", progname, cachename); return false; } uint32_t version = cpu_to_le32(ENCODE_VERSION(force_complain, policy_version, parser_abi_version, kernel_abi_version)); if (memcmp(buffer + 12, &version, 4) != 0) { if (debug_cache) pwarn("%s: cache file '%s' has wrong version\n", progname, cachename); return false; } return true; }
void fileerror(ino_t cwd, ino_t ino, const char *errmesg) { char pathbuf[MAXPATHLEN + 1]; struct uvnode *vp; pwarn("%s ", errmesg); pinode(ino); printf("\n"); pwarn("PARENT=%lld\n", (long long)cwd); getpathname(pathbuf, sizeof(pathbuf), cwd, ino); if (ino < ULFS_ROOTINO || ino >= maxino) { pfatal("NAME=%s\n", pathbuf); return; } vp = vget(fs, ino); if (vp == NULL) pfatal("INO is NULL\n"); else { if (ftypeok(VTOD(vp))) pfatal("%s=%s\n", (lfs_dino_getmode(fs, VTOI(vp)->i_din) & LFS_IFMT) == LFS_IFDIR ? "DIR" : "FILE", pathbuf); else pfatal("NAME=%s\n", pathbuf); } }
/* * Check a complete in-memory FAT for lost cluster chains */ int checklost(int dosfs, struct bootblock *boot, struct fatEntry *fat) { cl_t head; int mod = FSOK; int ret; for (head = CLUST_FIRST; head < boot->NumClusters; head++) { /* find next untravelled chain */ if (fat[head].head != head || fat[head].next == CLUST_FREE || (fat[head].next >= CLUST_RSRVD && fat[head].next < CLUST_EOFS) || (fat[head].flags & FAT_USED)) continue; pwarn("Lost cluster chain at cluster %u\n%d Cluster(s) lost\n", head, fat[head].length); mod |= ret = reconnect(dosfs, boot, fat, head); if (mod & FSFATAL) break; if (ret == FSERROR && ask(0, "Clear")) { clearchain(boot, fat, head); mod |= FSFATMOD; } } finishlf(); if (boot->FSInfo) { ret = 0; if (boot->FSFree != boot->NumFree) { pwarn("Free space in FSInfo block (%d) not correct (%d)\n", boot->FSFree, boot->NumFree); if (ask(1, "fix")) { boot->FSFree = boot->NumFree; ret = 1; } } if (boot->NumFree && (boot->FSNext >= boot->NumClusters || fat[boot->FSNext].next != CLUST_FREE)) { pwarn("Next free cluster in FSInfo block (%u) not free\n", boot->FSNext); if (ask(1, "fix")) for (head = CLUST_FIRST; head < boot->NumClusters; head++) if (fat[head].next == CLUST_FREE) { boot->FSNext = head; ret = 1; break; } } if (ret) mod |= writefsinfo(dosfs, boot); } return mod; }
/* * - set mount_point to NULL * - if name is mounted (search mnttab) * - if it is a device, clear rflag * - if mounted on /, /usr, or /var, set corefs * - if corefs and read-only, set hotroot and continue * - if errorlocked, continue * - if preening, bail * - ask user whether to continue, bail if not * - if it is a device and not mounted and rflag, convert * name to raw version */ static int check_mount_state(caddr_t devstr, size_t str_size) { int corefs = 0; int is_dev = 0; struct stat statb; if (stat(devstr, &statb) < 0) { exitstat = EXNOSTAT; errexit("fsck: could not stat %s: %s", devstr, strerror(errno)); } if (S_ISCHR(statb.st_mode) || S_ISBLK(statb.st_mode)) is_dev = 1; /* * mounted() will update mount_point when returning true. */ mount_point = NULL; if ((mountedfs = mounted(devstr, devstr, str_size)) != M_NOMNT) { if (is_dev) rflag = 0; corefs = which_corefs(mount_point); if (corefs && (mountedfs == M_RO)) { hotroot++; } else if (errorlocked) { goto carry_on; } else if (preen) { exitstat = EXMOUNTED; pfatal("%s IS CURRENTLY MOUNTED%s.", devstr, mountedfs == M_RW ? " READ/WRITE" : ""); } else { if (!nflag) { pwarn("%s IS CURRENTLY MOUNTED READ/%s.", devstr, mountedfs == M_RW ? "WRITE" : "ONLY"); if (reply("CONTINUE") == 0) { exitstat = EXMOUNTED; errexit("Program terminated"); } } else { pwarn("%s IS CURRENTLY MOUNTED READ/%s.\n", devstr, mountedfs == M_RW ? "WRITE" : "ONLY"); } } } else if (is_dev && rflag) { (void) strlcpy(devstr, rawname(devstr), str_size); } carry_on: return (corefs); }
static int prefix_opts(JFT_Stem *prefix, JFT_Symbol **stop, int argc, char **argv) { extern char *optarg; extern int optind, optopt; int opt, ptr, err = 0, omit = 1; static struct option options[] = { {"null", no_argument, NULL, 'n'}, {"stop", no_argument, NULL, 's'}, {"primary", no_argument, NULL, 'p'}, {"indices", no_argument, NULL, 'i'}, {} }; // default prefix->pre = JFT_SYMBOL_PRIMARY; prefix->size = 1; while ((opt = getopt_long(argc, argv, "hnspi", options, &ptr)) != -1) { switch(opt) { case 'h': return usage(0); case 'n': omit = 0; break; case 's': *stop = &null; break; case 'p': prefix->pre = JFT_SYMBOL_PRIMARY; prefix->size = 1; break; case 'i': prefix->pre = JFT_SYMBOL_INDICES; prefix->size = 1; break; case ':': pwarn("%s: option requires an argument -- %c", argv[0], optopt); err++; break; case '?': pwarn("%s: illegal option -- %c", argv[0], optopt); err++; break; } } read_prefix(prefix, omit, argc - optind, argv + optind); return err; }
void reset_maxino(ino_t len) { if (debug) pwarn("maxino reset from %lld to %lld\n", (long long)maxino, (long long)len); din_table = erealloc(din_table, len * sizeof(*din_table)); statemap = erealloc(statemap, len * sizeof(char)); typemap = erealloc(typemap, len * sizeof(char)); lncntp = erealloc(lncntp, len * sizeof(int16_t)); memset(din_table + maxino, 0, (len - maxino) * sizeof(*din_table)); memset(statemap + maxino, USTATE, (len - maxino) * sizeof(char)); memset(typemap + maxino, 0, (len - maxino) * sizeof(char)); memset(lncntp + maxino, 0, (len - maxino) * sizeof(int16_t)); maxino = len; /* * We can't roll forward after allocating new inodes in previous * phases, or thy would conflict (lost+found, for example, might * disappear to be replaced by a file found in roll-forward). */ no_roll_forward = 1; return; }
void adjust(struct inodesc *idesc, short lcnt) { union dinode *dp; dp = ginode(idesc->id_number); if (DIP(dp, di_nlink) == lcnt) { if (linkup(idesc->id_number, 0) == 0) clri(idesc, "UNREF", 0); } else { pwarn("LINK COUNT %s", (lfdir == idesc->id_number) ? lfname : ((DIP(dp, di_mode) & IFMT) == IFDIR ? "DIR" : "FILE")); pinode(idesc->id_number); printf(" COUNT %d SHOULD BE %d", DIP(dp, di_nlink), DIP(dp, di_nlink) - lcnt); if (preen || usedsoftdep) { if (lcnt < 0) { printf("\n"); pfatal("LINK COUNT INCREASING"); } if (preen) printf(" (ADJUSTED)\n"); } if (preen || reply("ADJUST") == 1) { DIP_SET(dp, di_nlink, DIP(dp, di_nlink) - lcnt); inodirty(); } } }
void clri(struct inodesc *idesc, const char *type, int flag) { union dinode *dp; dp = ginode(idesc->id_number); if (flag == 1) { pwarn("%s %s", type, (DIP(dp, di_mode) & IFMT) == IFDIR ? "DIR" : "FILE"); pinode(idesc->id_number); } if (preen || reply("CLEAR") == 1) { if (preen) printf(" (CLEARED)\n"); n_files--; if (bkgrdflag == 0) { (void)ckinode(dp, idesc); inoinfo(idesc->id_number)->ino_state = USTATE; clearinode(dp); inodirty(); } else { cmd.value = idesc->id_number; cmd.size = -DIP(dp, di_nlink); if (debug) printf("adjrefcnt ino %ld amt %lld\n", (long)cmd.value, (long long)cmd.size); if (sysctl(adjrefcnt, MIBSIZE, 0, 0, &cmd, sizeof cmd) == -1) rwerror("ADJUST INODE", cmd.value); } } }
int32_t bread(int fd, char *buf, daddr_t blk, long size) { char *cp; int i, errs; offset_t offset = ldbtob(blk); offset_t addr; if (llseek(fd, offset, 0) < 0) rwerror(gettext("SEEK"), blk); else if (read(fd, buf, (int)size) == size) return (0); rwerror(gettext("READ"), blk); if (llseek(fd, offset, 0) < 0) rwerror(gettext("SEEK"), blk); errs = 0; bzero(buf, (int)size); pwarn(gettext("THE FOLLOWING SECTORS COULD NOT BE READ:")); for (cp = buf, i = 0; i < btodb(size); i++, cp += DEV_BSIZE) { addr = ldbtob(blk + i); if (llseek(fd, addr, SEEK_CUR) < 0 || read(fd, cp, (int)secsize) < 0) { (void) printf(" %ld", blk + i); errs++; } } (void) printf("\n"); return (errs); }
void bwrite(int fd, char *buf, daddr_t blk, long size) { int i, n; char *cp; offset_t offset = ldbtob(blk); offset_t addr; if (fd < 0) return; if (llseek(fd, offset, 0) < 0) rwerror(gettext("SEEK"), blk); else if (write(fd, buf, (int)size) == size) { fsmodified = 1; return; } rwerror(gettext("WRITE"), blk); if (llseek(fd, offset, 0) < 0) rwerror(gettext("SEEK"), blk); pwarn(gettext("THE FOLLOWING SECTORS COULD NOT BE WRITTEN:")); for (cp = buf, i = 0; i < btodb(size); i++, cp += DEV_BSIZE) { n = 0; addr = ldbtob(blk + i); if (llseek(fd, addr, SEEK_CUR) < 0 || (n = write(fd, cp, DEV_BSIZE)) < 0) { (void) printf(" %ld", blk + i); } else if (n > 0) { fsmodified = 1; } } (void) printf("\n"); }
void BeetleInternal::informServicesChanged(handle_range_t range, device_t dst) { if (debug) { pdebug("informing " + std::to_string(dst) + " of service change " + range.str()); } std::lock_guard<std::recursive_mutex> handlesLg(handlesMutex); if (serviceChangedAttr->subscribersNotify.size() == 0) { return; } uint8_t cmd[7]; cmd[0] = ATT_OP_HANDLE_NOTIFY; *(uint16_t *) (cmd + 1) = htobs(serviceChangedAttr->getHandle()); *(uint16_t *) (cmd + 3) = htobs(range.start); *(uint16_t *) (cmd + 5) = htobs(range.end); if (serviceChangedAttr->subscribersNotify.find(dst) != serviceChangedAttr->subscribersNotify.end()) { if (beetle.devices.find(dst) != beetle.devices.end()) { beetle.devices[dst]->writeCommand(cmd, sizeof(cmd)); } else { pwarn("cannot inform " + std::to_string(dst) + ", does not name a device"); } } else { if (debug) { pdebug(std::to_string(dst) + " is not subscribed to service changed characteristic"); } } }
static int initial_error_state_adjust(void) { int retval = 0; /* do this right away to prevent any other fscks on this fs */ switch (sblock.fs_clean) { case FSBAD: break; case FSFIX: if (preen) errexit("ERROR-LOCKED; MARKED \"FSFIX\"\n"); if (reply("marked FSFIX, CONTINUE") == 0) { retval = -1; goto finish; } break; case FSCLEAN: if (preen) errexit("ERROR-LOCKED; MARKED \"FSCLEAN\"\n"); if (reply("marked FSCLEAN, CONTINUE") == 0) { retval = -1; goto finish; } break; default: if (preen) { if (debug) pwarn("ERRORLOCKED; NOT MARKED \"FSBAD\"\n"); else errexit("ERRORLOCKED; NOT MARKED \"FSBAD\"\n"); } else { (void) printf("error-locked but not marked \"FSBAD\";"); if (reply(" CONTINUE") == 0) { retval = -1; goto finish; } } break; } if (!do_errorlock(LOCKFS_ELOCK)) { if (preen) { retval = -1; goto finish; } if (reply("error-lock reset failed; CONTINUE") == 0) { retval = -1; goto finish; } } sblock.fs_state = FSOKAY - (long)sblock.fs_time; sblock.fs_clean = FSFIX; sbdirty(); write_altsb(fswritefd); finish: return (retval); }
/* * Check a cluster number for valid value */ static int checkclnum(struct bootblock *boot, int fat, cl_t cl, cl_t *next) { if (*next >= (CLUST_RSRVD&boot->ClustMask)) *next |= ~boot->ClustMask; if (*next == CLUST_FREE) { boot->NumFree++; return FSOK; } if (*next == CLUST_BAD) { boot->NumBad++; return FSOK; } if (*next < CLUST_FIRST || (*next >= boot->NumClusters && *next < CLUST_EOFS)) { pwarn("Cluster %u in FAT %d continues with %s cluster number %u\n", cl, fat, *next < CLUST_RSRVD ? "out of range" : "reserved", *next&boot->ClustMask); if (ask(0, "Truncate")) { *next = CLUST_EOF; return FSFATMOD; } return FSERROR; } return FSOK; }
void adjust(struct inodesc *idesc, short lcnt) { struct ext2fs_dinode *dp; dp = ginode(idesc->id_number); if (fs2h16(dp->e2di_nlink) == lcnt) { if (linkup(idesc->id_number, (ino_t)0) == 0) clri(idesc, "UNREF", 0); } else { pwarn("LINK COUNT %s", (lfdir == idesc->id_number) ? lfname : ((fs2h16(dp->e2di_mode) & IFMT) == IFDIR ? "DIR" : "FILE")); pinode(idesc->id_number); printf(" COUNT %d SHOULD BE %d", fs2h16(dp->e2di_nlink), fs2h16(dp->e2di_nlink) - lcnt); if (preen) { if (lcnt < 0) { printf("\n"); pfatal("LINK COUNT INCREASING"); } printf(" (ADJUSTED)\n"); } if (preen || reply("ADJUST") == 1) { dp->e2di_nlink = h2fs16(fs2h16(dp->e2di_nlink) - lcnt); inodirty(); } } }
/* * Should never get called. All reads and writes are serviced by the cache. */ int BeetleInternal::writeTransactionBlocking(uint8_t *buf, int len, uint8_t *&resp) { if (debug) { pwarn("Beetle received an unanticipated request"); } resp = new uint8_t[ATT_ERROR_PDU_LEN]; pack_error_pdu(buf[0], 0, ATT_ECODE_UNLIKELY, resp); return ATT_ERROR_PDU_LEN; }
boolean pthreadMayCreate(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)(void *), void *arg) /* Create a thread. Warn and return FALSE if there is a problem. */ { int err = pthread_create(thread, attr, start_routine, arg); pwarn("pthread_create", err); return err == 0; }
/* * Verify that a directory entry is valid. * This is a superset of the checks made in the kernel. */ int dircheck(struct inodesc *idesc, LFS_DIRHEADER *dp) { int size; const char *cp; u_char namlen, type; int spaceleft; spaceleft = LFS_DIRBLKSIZ - (idesc->id_loc % LFS_DIRBLKSIZ); if (lfs_dir_getino(fs, dp) >= maxino || lfs_dir_getreclen(fs, dp) == 0 || lfs_dir_getreclen(fs, dp) > spaceleft || (lfs_dir_getreclen(fs, dp) & 0x3) != 0) { pwarn("ino too large, reclen=0, reclen>space, or reclen&3!=0\n"); pwarn("dp->d_ino = 0x%jx\tdp->d_reclen = 0x%x\n", (uintmax_t)lfs_dir_getino(fs, dp), lfs_dir_getreclen(fs, dp)); pwarn("maxino = %ju\tspaceleft = 0x%x\n", (uintmax_t)maxino, spaceleft); return (0); } if (lfs_dir_getino(fs, dp) == 0) return (1); size = LFS_DIRSIZ(fs, dp); namlen = lfs_dir_getnamlen(fs, dp); type = lfs_dir_gettype(fs, dp); if (lfs_dir_getreclen(fs, dp) < size || idesc->id_filesize < size || /* namlen > MAXNAMLEN || */ type > 15) { printf("reclen<size, filesize<size, namlen too large, or type>15\n"); return (0); } cp = lfs_dir_nameptr(fs, dp); for (size = 0; size < namlen; size++) if (*cp == '\0' || (*cp++ == '/')) { printf("name contains NUL or /\n"); return (0); } if (*cp != '\0') { printf("name size misstated\n"); return (0); } return (1); }
/* * Attempt to expand the size of a directory */ static int expanddir(struct ext2fs_dinode *dp, char *name) { daddr_t lastbn, newblk; struct bufarea *bp; char *firstblk; lastbn = lblkno(&sblock, inosize(dp)); if (lastbn >= NDADDR - 1 || fs2h32(dp->e2di_blocks[lastbn]) == 0 || inosize(dp) == 0) { return (0); } if ((newblk = allocblk()) == 0) { return (0); } dp->e2di_blocks[lastbn + 1] = dp->e2di_blocks[lastbn]; dp->e2di_blocks[lastbn] = h2fs32(newblk); inossize(dp, inosize(dp) + sblock.e2fs_bsize); dp->e2di_nblock = h2fs32(fs2h32(dp->e2di_nblock) + 1); bp = getdirblk(fs2h32(dp->e2di_blocks[lastbn + 1]), sblock.e2fs_bsize); if (bp->b_errs) goto bad; if ((firstblk = malloc(sblock.e2fs_bsize)) == NULL) err(8, "cannot allocate first block"); memcpy(firstblk, bp->b_un.b_buf, sblock.e2fs_bsize); bp = getdirblk(newblk, sblock.e2fs_bsize); if (bp->b_errs) { free(firstblk); goto bad; } memcpy(bp->b_un.b_buf, firstblk, sblock.e2fs_bsize); free(firstblk); dirty(bp); bp = getdirblk(fs2h32(dp->e2di_blocks[lastbn + 1]), sblock.e2fs_bsize); if (bp->b_errs) goto bad; emptydir.dot_reclen = h2fs16(sblock.e2fs_bsize); memcpy(bp->b_un.b_buf, &emptydir, sizeof emptydir); pwarn("NO SPACE LEFT IN %s", name); if (preen) printf(" (EXPANDED)\n"); else if (reply("EXPAND") == 0) goto bad; dirty(bp); inodirty(); return (1); bad: dp->e2di_blocks[lastbn] = dp->e2di_blocks[lastbn + 1]; dp->e2di_blocks[lastbn + 1] = 0; inossize(dp, inosize(dp) - sblock.e2fs_bsize); dp->e2di_nblock = h2fs32(fs2h32(dp->e2di_nblock) - 1); freeblk(newblk); return (0); }
void adjust(struct inodesc *idesc, int lcnt) { struct ufs1_dinode *dp; int saveresolved; dp = ginode(idesc->id_number); if (dp->di_nlink == lcnt) { /* * If we have not hit any unresolved problems, are running * in preen mode, and are on a filesystem using soft updates, * then just toss any partially allocated files. */ if (resolved && preen && usedsoftdep) { clri(idesc, "UNREF", 1); return; } else { /* * The filesystem can be marked clean even if * a file is not linked up, but is cleared. * Hence, resolved should not be cleared when * linkup is answered no, but clri is answered yes. */ saveresolved = resolved; if (linkup(idesc->id_number, (ufs1_ino_t)0, NULL) == 0) { resolved = saveresolved; clri(idesc, "UNREF", 0); return; } /* * Account for the new reference created by linkup(). */ dp = ginode(idesc->id_number); lcnt--; } } if (lcnt != 0) { pwarn("LINK COUNT %s", (lfdir == idesc->id_number) ? lfname : ((dp->di_mode & IFMT) == IFDIR ? "DIR" : "FILE")); pinode(idesc->id_number); printf(" COUNT %d SHOULD BE %d", dp->di_nlink, dp->di_nlink - lcnt); if (preen || usedsoftdep) { if (lcnt < 0) { printf("\n"); pfatal("LINK COUNT INCREASING"); } if (preen) printf(" (ADJUSTED)\n"); } if (preen || reply("ADJUST") == 1) { dp->di_nlink -= lcnt; inodirty(); } } }
static void perr(char *function, int err) /* Print out error for function and abort on * non-zero error code.. */ { if (err != 0) { pwarn(function, err); noWarnAbort(); } }
static void badsb(int listerr, caddr_t s) { if (!listerr) return; if (preen) (void) printf("%s: ", devname); (void) printf("BAD SUPERBLOCK AT BLOCK %d: %s\n", bflag != 0 ? bflag : SBLOCK, s); if (preen) { pwarn( "USE AN ALTERNATE SUPERBLOCK TO SUPPLY NEEDED INFORMATION;\n"); pwarn("e.g. fsck [-F ufs] -o b=# [special ...] \n"); exitstat = EXERRFATAL; pfatal( "where # is the alternate super block. SEE fsck_ufs(1M). \n"); } /* we're expected to return if not preening */ }
void markbusy(daddr_t block, long count) { register int i; count = roundup(count, secsize) / secsize; for (i = 0; i < count; i++, block++) { if ((unsigned)block > part_len) { pwarn(gettext("Block %lx out of range\n"), block); break; } if (testbusy(block)) pwarn(gettext("Dup block %lx\n"), block); else { n_blks++; setbusy(block); } } }
/* * Attempt to expand the size of a directory */ static int expanddir(struct uvnode *vp, union lfs_dinode *dp, char *name) { daddr_t lastbn; struct ubuf *bp; char *cp, firstblk[LFS_DIRBLKSIZ]; lastbn = lfs_lblkno(fs, lfs_dino_getsize(fs, dp)); if (lastbn >= ULFS_NDADDR - 1 || lfs_dino_getdb(fs, dp, lastbn) == 0 || lfs_dino_getsize(fs, dp) == 0) return (0); lfs_dino_setdb(fs, dp, lastbn + 1, lfs_dino_getdb(fs, dp, lastbn)); lfs_dino_setdb(fs, dp, lastbn, 0); bp = getblk(vp, lastbn, lfs_sb_getbsize(fs)); VOP_BWRITE(bp); lfs_dino_setsize(fs, dp, lfs_dino_getsize(fs, dp) + lfs_sb_getbsize(fs)); lfs_dino_setblocks(fs, dp, lfs_dino_getblocks(fs, dp) + lfs_btofsb(fs, lfs_sb_getbsize(fs))); bread(vp, lfs_dino_getdb(fs, dp, lastbn + 1), (long) lfs_dblksize(fs, dp, lastbn + 1), 0, &bp); if (bp->b_flags & B_ERROR) goto bad; memcpy(firstblk, bp->b_data, LFS_DIRBLKSIZ); bread(vp, lastbn, lfs_sb_getbsize(fs), 0, &bp); if (bp->b_flags & B_ERROR) goto bad; memcpy(bp->b_data, firstblk, LFS_DIRBLKSIZ); for (cp = &bp->b_data[LFS_DIRBLKSIZ]; cp < &bp->b_data[lfs_sb_getbsize(fs)]; cp += LFS_DIRBLKSIZ) zerodirblk(cp); VOP_BWRITE(bp); bread(vp, lfs_dino_getdb(fs, dp, lastbn + 1), (long) lfs_dblksize(fs, dp, lastbn + 1), 0, &bp); if (bp->b_flags & B_ERROR) goto bad; zerodirblk(bp->b_data); pwarn("NO SPACE LEFT IN %s", name); if (preen) printf(" (EXPANDED)\n"); else if (reply("EXPAND") == 0) goto bad; VOP_BWRITE(bp); inodirty(VTOI(vp)); return (1); bad: lfs_dino_setdb(fs, dp, lastbn, lfs_dino_getdb(fs, dp, lastbn + 1)); lfs_dino_setdb(fs, dp, lastbn + 1, 0); lfs_dino_setsize(fs, dp, lfs_dino_getsize(fs, dp) - lfs_sb_getbsize(fs)); lfs_dino_setblocks(fs, dp, lfs_dino_getblocks(fs, dp) - lfs_btofsb(fs, lfs_sb_getbsize(fs))); return (0); }
/* * Do fixup for bad acl/attr references. If PARENT is -1, then * we assume we're working on a shadow, otherwise an extended attribute. * FMT must be a printf format string, with one %d directive for * the inode number. */ static void clear_attr_acl(fsck_ino_t inumber, fsck_ino_t parent, char *fmt) { fsck_ino_t victim = inumber; struct dinode *dp; if (parent != -1) victim = parent; if (fmt != NULL) { if (parent == -1) pwarn(fmt, (int)inumber); else pwarn(fmt, (int)inumber, (int)parent); } if (debug) (void) printf("parent file/dir I=%d\nvictim I=%d", (int)parent, (int)victim); if (!preen && (reply("REMOVE REFERENCE") == 0)) { iscorrupt = 1; return; } dp = ginode(victim); if (parent == -1) { /* * The file had a bad shadow/acl, so lock it down * until someone can protect it the way they need it * to be (i.e., be conservatively paranoid). */ dp->di_shadow = 0; dp->di_mode &= IFMT; } else { dp->di_oeftflag = 0; } inodirty(); if (preen) (void) printf(" (CORRECTED)\n"); }
/* * Attempt to expand the size of a directory */ static int expanddir(union dinode *dp, char *name) { ufs2_daddr_t lastbn, newblk; struct bufarea *bp; char *cp, firstblk[DIRBLKSIZ]; lastbn = lblkno(&sblock, DIP(dp, di_size)); if (lastbn >= NDADDR - 1 || DIP(dp, di_db[lastbn]) == 0 || DIP(dp, di_size) == 0) return (0); if ((newblk = allocblk(sblock.fs_frag)) == 0) return (0); DIP_SET(dp, di_db[lastbn + 1], DIP(dp, di_db[lastbn])); DIP_SET(dp, di_db[lastbn], newblk); DIP_SET(dp, di_size, DIP(dp, di_size) + sblock.fs_bsize); DIP_SET(dp, di_blocks, DIP(dp, di_blocks) + btodb(sblock.fs_bsize)); bp = getdirblk(DIP(dp, di_db[lastbn + 1]), sblksize(&sblock, DIP(dp, di_size), lastbn + 1)); if (bp->b_errs) goto bad; memmove(firstblk, bp->b_un.b_buf, DIRBLKSIZ); bp = getdirblk(newblk, sblock.fs_bsize); if (bp->b_errs) goto bad; memmove(bp->b_un.b_buf, firstblk, DIRBLKSIZ); for (cp = &bp->b_un.b_buf[DIRBLKSIZ]; cp < &bp->b_un.b_buf[sblock.fs_bsize]; cp += DIRBLKSIZ) memmove(cp, &emptydir, sizeof emptydir); dirty(bp); bp = getdirblk(DIP(dp, di_db[lastbn + 1]), sblksize(&sblock, DIP(dp, di_size), lastbn + 1)); if (bp->b_errs) goto bad; memmove(bp->b_un.b_buf, &emptydir, sizeof emptydir); pwarn("NO SPACE LEFT IN %s", name); if (preen) printf(" (EXPANDED)\n"); else if (reply("EXPAND") == 0) goto bad; dirty(bp); inodirty(); return (1); bad: DIP_SET(dp, di_db[lastbn], DIP(dp, di_db[lastbn + 1])); DIP_SET(dp, di_db[lastbn + 1], 0); DIP_SET(dp, di_size, DIP(dp, di_size) - sblock.fs_bsize); DIP_SET(dp, di_blocks, DIP(dp, di_blocks) - btodb(sblock.fs_bsize)); freeblk(newblk, sblock.fs_frag); return (0); }
static struct disklabel * getdisklabel(const char *s, int fd) { static struct disklabel lab; if (ioctl(fd, DIOCGDINFO, (char *)&lab) < 0) { if (s == NULL) return NULL; pwarn("ioctl (GCINFO): %s\n", strerror(errno)); errexit("%s: can't read disk label", s); } return &lab; }
static struct disklabel * getdisklabel(char *s, int fd) { static struct disklabel lab; if (ioctl(fd, DIOCGDINFO, (char *)&lab) < 0) { if (s == NULL) return ((struct disklabel *)NULL); pwarn("ioctl (GCINFO): %s\n", strerror(errno)); errx(EEXIT, "%s: can't read disk label", s); } return (&lab); }
/* * Attempt to expand the size of a directory */ static int expanddir(struct ufs1_dinode *dp, char *name) { ufs_daddr_t lastbn, newblk; struct bufarea *bp; char *cp, firstblk[DIRBLKSIZ]; lastbn = lblkno(&sblock, dp->di_size); if (lastbn >= NDADDR - 1 || dp->di_db[lastbn] == 0 || dp->di_size == 0) return (0); if ((newblk = allocblk(sblock.fs_frag)) == 0) return (0); dp->di_db[lastbn + 1] = dp->di_db[lastbn]; dp->di_db[lastbn] = newblk; dp->di_size += sblock.fs_bsize; dp->di_blocks += btodb(sblock.fs_bsize); bp = getdirblk(dp->di_db[lastbn + 1], (long)dblksize(&sblock, dp, lastbn + 1)); if (bp->b_errs) goto bad; memmove(firstblk, bp->b_un.b_buf, DIRBLKSIZ); bp = getdirblk(newblk, sblock.fs_bsize); if (bp->b_errs) goto bad; memmove(bp->b_un.b_buf, firstblk, DIRBLKSIZ); for (cp = &bp->b_un.b_buf[DIRBLKSIZ]; cp < &bp->b_un.b_buf[sblock.fs_bsize]; cp += DIRBLKSIZ) memmove(cp, &emptydir, sizeof emptydir); dirty(bp); bp = getdirblk(dp->di_db[lastbn + 1], (long)dblksize(&sblock, dp, lastbn + 1)); if (bp->b_errs) goto bad; memmove(bp->b_un.b_buf, &emptydir, sizeof emptydir); pwarn("NO SPACE LEFT IN %s", name); if (preen) printf(" (EXPANDED)\n"); else if (reply("EXPAND") == 0) goto bad; dirty(bp); inodirty(); return (1); bad: dp->di_db[lastbn] = dp->di_db[lastbn + 1]; dp->di_db[lastbn + 1] = 0; dp->di_size -= sblock.fs_bsize; dp->di_blocks -= btodb(sblock.fs_bsize); freeblk(newblk, sblock.fs_frag); return (0); }
void ckfini(int markclean) { struct bufarea *bp, *nbp; int cnt = 0; if (fswritefd < 0) { (void)close(fsreadfd); return; } flush(fswritefd, &sblk); if (havesb && sblk.b_bno != SBOFF / dev_bsize && !preen && reply("UPDATE STANDARD SUPERBLOCKS")) { sblk.b_bno = SBOFF / dev_bsize; sbdirty(); flush(fswritefd, &sblk); copyback_sb(&asblk); asblk.b_dirty = 1; flush(fswritefd, &asblk); } for (bp = bufhead.b_prev; bp && bp != &bufhead; bp = nbp) { cnt++; flush(fswritefd, bp); nbp = bp->b_prev; free(bp->b_un.b_buf); free((char *)bp); } if (bufhead.b_size != cnt) errexit("Panic: lost %d buffers\n", bufhead.b_size - cnt); pbp = pdirbp = (struct bufarea *)0; if (markclean && (sblock.e2fs.e2fs_state & E2FS_ISCLEAN) == 0) { /* * Mark the file system as clean, and sync the superblock. */ if (preen) pwarn("MARKING FILE SYSTEM CLEAN\n"); else if (!reply("MARK FILE SYSTEM CLEAN")) markclean = 0; if (markclean) { sblock.e2fs.e2fs_state = E2FS_ISCLEAN; sbdirty(); flush(fswritefd, &sblk); } } if (debug) printf("cache missed %ld of %ld (%d%%)\n", diskreads, totalreads, (int)(diskreads * 100 / totalreads)); (void)close(fsreadfd); (void)close(fswritefd); }
static gboolean mysql__update_blob(int id, const char* key, const guint8* d, const guint len) { char *blob = malloc((len*2+1)*sizeof(char)); mysql_real_escape_string(&mysql, blob, (char*)d, len); char *sql = malloc((strlen(blob)+33/*query string*/+20 /*int*/+strlen(key))*sizeof(char)); sprintf(sql, "UPDATE samples SET %s='%s' WHERE id=%i", key, blob, id); if(mysql_query(&mysql, sql)){ free(blob); free(sql); pwarn("update failed! sql=%s\n", sql); return false; } free(blob); free(sql); return true; }