/* * Check validity of held blocks in an inode, recursing through all blocks. */ int ckinode(struct ufs1_dinode *dp, struct inodesc *idesc) { ufs_daddr_t *ap, lbn; long ret, n, ndb, offset; struct ufs1_dinode dino; u_int64_t remsize, sizepb; mode_t mode; char pathbuf[MAXPATHLEN + 1]; struct uvnode *vp, *thisvp; if (idesc->id_fix != IGNORE) idesc->id_fix = DONTKNOW; idesc->id_entryno = 0; idesc->id_filesize = dp->di_size; mode = dp->di_mode & IFMT; if (mode == IFBLK || mode == IFCHR || (mode == IFLNK && (dp->di_size < fs->lfs_maxsymlinklen || (fs->lfs_maxsymlinklen == 0 && dp->di_blocks == 0)))) return (KEEPON); dino = *dp; ndb = howmany(dino.di_size, fs->lfs_bsize); thisvp = vget(fs, idesc->id_number); for (lbn = 0; lbn < NDADDR; lbn++) { ap = dino.di_db + lbn; if (thisvp) idesc->id_numfrags = numfrags(fs, VTOI(thisvp)->i_lfs_fragsize[lbn]); else { if (--ndb == 0 && (offset = blkoff(fs, dino.di_size)) != 0) { idesc->id_numfrags = numfrags(fs, fragroundup(fs, offset)); } else idesc->id_numfrags = fs->lfs_frag; } if (*ap == 0) { if (idesc->id_type == DATA && ndb >= 0) { /* An empty block in a directory XXX */ getpathname(pathbuf, sizeof(pathbuf), idesc->id_number, idesc->id_number); pfatal("DIRECTORY %s INO %lld: CONTAINS EMPTY BLOCKS [1]", pathbuf, (long long)idesc->id_number); if (reply("ADJUST LENGTH") == 1) { vp = vget(fs, idesc->id_number); dp = VTOD(vp); dp->di_size = (ap - &dino.di_db[0]) * fs->lfs_bsize; printf( "YOU MUST RERUN FSCK AFTERWARDS\n"); rerun = 1; inodirty(VTOI(vp)); } else break; } continue; } idesc->id_blkno = *ap; idesc->id_lblkno = ap - &dino.di_db[0]; if (idesc->id_type == ADDR) { ret = (*idesc->id_func) (idesc); } else ret = dirscan(idesc); if (ret & STOP) return (ret); } idesc->id_numfrags = fs->lfs_frag; remsize = dino.di_size - fs->lfs_bsize * NDADDR; sizepb = fs->lfs_bsize; for (ap = &dino.di_ib[0], n = 1; n <= NIADDR; ap++, n++) { if (*ap) { idesc->id_blkno = *ap; ret = iblock(idesc, n, remsize); if (ret & STOP) return (ret); } else { if (idesc->id_type == DATA && remsize > 0) { /* An empty block in a directory XXX */ getpathname(pathbuf, sizeof(pathbuf), idesc->id_number, idesc->id_number); pfatal("DIRECTORY %s INO %lld: CONTAINS EMPTY BLOCKS [2]", pathbuf, (long long)idesc->id_number); if (reply("ADJUST LENGTH") == 1) { vp = vget(fs, idesc->id_number); dp = VTOD(vp); dp->di_size -= remsize; remsize = 0; printf( "YOU MUST RERUN FSCK AFTERWARDS\n"); rerun = 1; inodirty(VTOI(vp)); break; } else break; } } sizepb *= NINDIR(fs); remsize -= sizepb; } return (KEEPON); }
int ckinode(struct ufs1_dinode *dp, struct inodesc *idesc) { ufs_daddr_t *ap; int ret; long n, ndb, offset; struct ufs1_dinode dino; quad_t remsize, sizepb; mode_t mode; char pathbuf[MAXPATHLEN + 1]; if (idesc->id_fix != IGNORE) idesc->id_fix = DONTKNOW; idesc->id_entryno = 0; idesc->id_filesize = dp->di_size; mode = dp->di_mode & IFMT; if (mode == IFBLK || mode == IFCHR || (mode == IFLNK && dp->di_size < (unsigned)sblock.fs_maxsymlinklen)) return (KEEPON); dino = *dp; ndb = howmany(dino.di_size, sblock.fs_bsize); for (ap = &dino.di_db[0]; ap < &dino.di_db[NDADDR]; ap++) { if (--ndb == 0 && (offset = blkoff(&sblock, dino.di_size)) != 0) idesc->id_numfrags = numfrags(&sblock, fragroundup(&sblock, offset)); else idesc->id_numfrags = sblock.fs_frag; if (*ap == 0) { if (idesc->id_type == DATA && ndb >= 0) { /* An empty block in a directory XXX */ getpathname(pathbuf, idesc->id_number, idesc->id_number); pfatal("DIRECTORY %s: CONTAINS EMPTY BLOCKS", pathbuf); if (reply("ADJUST LENGTH") == 1) { dp = ginode(idesc->id_number); dp->di_size = (ap - &dino.di_db[0]) * sblock.fs_bsize; printf( "YOU MUST RERUN FSCK AFTERWARDS\n"); rerun = 1; inodirty(); } } continue; } idesc->id_blkno = *ap; if (idesc->id_type == ADDR) ret = (*idesc->id_func)(idesc); else ret = dirscan(idesc); if (ret & STOP) return (ret); } idesc->id_numfrags = sblock.fs_frag; remsize = dino.di_size - sblock.fs_bsize * NDADDR; sizepb = sblock.fs_bsize; for (ap = &dino.di_ib[0], n = 1; n <= NIADDR; ap++, n++) { if (*ap) { idesc->id_blkno = *ap; ret = iblock(idesc, n, remsize); if (ret & STOP) return (ret); } else { if (idesc->id_type == DATA && remsize > 0) { /* An empty block in a directory XXX */ getpathname(pathbuf, idesc->id_number, idesc->id_number); pfatal("DIRECTORY %s: CONTAINS EMPTY BLOCKS", pathbuf); if (reply("ADJUST LENGTH") == 1) { dp = ginode(idesc->id_number); dp->di_size -= remsize; remsize = 0; printf( "YOU MUST RERUN FSCK AFTERWARDS\n"); rerun = 1; inodirty(); break; } } } sizepb *= NINDIR(&sblock); remsize -= sizepb; } return (KEEPON); }
int ckinode(union dinode *dp, struct inodesc *idesc) { off_t remsize, sizepb; int i, offset, ret; union dinode dino; ufs2_daddr_t ndb; mode_t mode; char pathbuf[MAXPATHLEN + 1]; if (idesc->id_fix != IGNORE) idesc->id_fix = DONTKNOW; idesc->id_lbn = -1; idesc->id_entryno = 0; idesc->id_filesize = DIP(dp, di_size); mode = DIP(dp, di_mode) & IFMT; if (mode == IFBLK || mode == IFCHR || (mode == IFLNK && DIP(dp, di_size) < (unsigned)sblock.fs_maxsymlinklen)) return (KEEPON); if (sblock.fs_magic == FS_UFS1_MAGIC) dino.dp1 = dp->dp1; else dino.dp2 = dp->dp2; ndb = howmany(DIP(&dino, di_size), sblock.fs_bsize); for (i = 0; i < NDADDR; i++) { idesc->id_lbn++; if (--ndb == 0 && (offset = blkoff(&sblock, DIP(&dino, di_size))) != 0) idesc->id_numfrags = numfrags(&sblock, fragroundup(&sblock, offset)); else idesc->id_numfrags = sblock.fs_frag; if (DIP(&dino, di_db[i]) == 0) { if (idesc->id_type == DATA && ndb >= 0) { /* An empty block in a directory XXX */ getpathname(pathbuf, idesc->id_number, idesc->id_number); pfatal("DIRECTORY %s: CONTAINS EMPTY BLOCKS", pathbuf); if (reply("ADJUST LENGTH") == 1) { dp = ginode(idesc->id_number); DIP_SET(dp, di_size, i * sblock.fs_bsize); printf( "YOU MUST RERUN FSCK AFTERWARDS\n"); rerun = 1; inodirty(); } } continue; } idesc->id_blkno = DIP(&dino, di_db[i]); if (idesc->id_type != DATA) ret = (*idesc->id_func)(idesc); else ret = dirscan(idesc); if (ret & STOP) return (ret); } idesc->id_numfrags = sblock.fs_frag; remsize = DIP(&dino, di_size) - sblock.fs_bsize * NDADDR; sizepb = sblock.fs_bsize; for (i = 0; i < NIADDR; i++) { sizepb *= NINDIR(&sblock); if (DIP(&dino, di_ib[i])) { idesc->id_blkno = DIP(&dino, di_ib[i]); ret = iblock(idesc, i + 1, remsize, BT_LEVEL1 + i); if (ret & STOP) return (ret); } else { idesc->id_lbn += sizepb / sblock.fs_bsize; if (idesc->id_type == DATA && remsize > 0) { /* An empty block in a directory XXX */ getpathname(pathbuf, idesc->id_number, idesc->id_number); pfatal("DIRECTORY %s: CONTAINS EMPTY BLOCKS", pathbuf); if (reply("ADJUST LENGTH") == 1) { dp = ginode(idesc->id_number); DIP_SET(dp, di_size, DIP(dp, di_size) - remsize); remsize = 0; printf( "YOU MUST RERUN FSCK AFTERWARDS\n"); rerun = 1; inodirty(); break; } } } remsize -= sizepb; } return (KEEPON); }
/* name: name of file/dir * dflag: T: name is for a directory */ DND *findit(char *name, const char **sp, int dflag) { register DND *p; const char *n; DND *pp,*newp; int i; char s[11]; /* crack directory and drive */ n = name; #if DBGFSDIR kprintf("findit(%s)\n", n); #endif if ((long)(p = dcrack(&n)) < 0) /* M01.01.1214.01 */ return( p ); /* * Force scan() to read from the beginning of the directory again, * since we have gone to a scheme of keeping fewer DNDs in memory. */ #if ! M0101052901 if (p->d_ofd) p->d_ofd->o_flag &= ~O_COMPLETE; #endif do { if (!(i = getpath(n,s,dflag))) break; if (i < 0) { /* path is '.' or '..' */ if (i == -2) /* go to parent (..) */ p = p->d_parent; i = -i; /* num chars is 1 or 2 */ goto scanxt; } /* ** go down a level in the path... ** save a pointer to the current DND, which will ** become the parent, and get the node on the left, ** which is the first child. */ pp = p; /* save ptr to parent dnd */ if (!(newp = p->d_left)) { /* [1] */ /* make sure children */ newp = dirscan(p,n); /* are logged in */ } if (!(p = newp)) /* If no children, exit loop */ break; /* ** check all subdirectories at this level. if we run out ** of siblings in the DND list (p->d_right == NULLPTR), then ** we should rescan the whole directory and make sure they ** are all logged in. */ while( p && (xcmps(s,p->d_name) == FALSE) ) { newp = p->d_right ; /* next sibling */ if(newp == NULLPTR) /* if no more siblings */ { p = 0; if (pp) { #if M0101052901 p = dirscan(pp,n); #else if (!(pp->d_ofd->o_flag & O_COMPLETE)) { /* M01.01.KTB.SCC.01 [1] */ pp->d_scan = 0L ; /*start*/ p = dirscan(pp,n); /*over */ } #endif } } else p = newp; } scanxt: if (*(n = n + i)) n++; else break; } while (p && i); /* p = 0 ==> not found i = 0 ==> found at p (dnd entry) n = points at filename */ *sp = n; return(p); }
int config_get_json(DB_OBJECT *object, unsigned char *s, size_t *len) { unsigned int int_val; char *ptr = (char *)s; int k; SCAN_CTX ctx; error_ptr = no_error; error_len = sizeof(no_error) - 1; if ((sizeof(form) - 1) > *len) { error_ptr = not_enough_memory; error_len = sizeof(not_enough_memory) - 1; return -1; } BLOB_RECORD *config = (BLOB_RECORD *)object->module_data; if ((config == NULL)||(object->module_data_size != sizeof(BLOB_RECORD))) config = &default_config; unsigned char *fw = (unsigned char *)strstr((char *)form, "{\"FIRMWARE\":0}"); if (fw) { size_t bytes_left = *len; unsigned char *fw_end = fw + 14; memcpy(s, form, fw - form); bytes_left -= fw - form; fw = s + (fw - form); if (bytes_left < 36) { error_ptr = not_enough_memory; error_len = sizeof(not_enough_memory) - 1; return -1; } memcpy(fw, "{\"label\": \"default\", \"id\":\"default\"}", 36); fw += 36; bytes_left -= 36; ctx.bytes_left = bytes_left; ctx.item_no = 0; ctx.ptr = fw; dirscan(fw_dir.c_str(), dirscan_callback, &ctx); size_t footer_len = form + sizeof(form) - fw_end - 1; if (footer_len > ctx.bytes_left) { error_ptr = not_enough_memory; error_len = sizeof(not_enough_memory) - 1; return -1; } memcpy(ctx.ptr, fw_end, footer_len); *len = (ctx.ptr - s) + footer_len; } else { memcpy(s, form, sizeof(form) - 1); *len = sizeof(form) - 1; } for (int i = 0; i < KEYS_COUNT; i++) { switch (fields[i].type) { case VALUE_TYPE_NUMERIC: switch (fields[i].size) { case sizeof(unsigned char): int_val = *(unsigned char *)((unsigned char*)config + fields[i].offset); break; case sizeof(unsigned short): int_val = *(unsigned short *)((unsigned char*)config + fields[i].offset); break; case sizeof(unsigned int): int_val = *(unsigned int *)((unsigned char*)config + fields[i].offset); break; default: return -1; } ptr = strstr(ptr, fields[i].tag); if (ptr == NULL) return -1; memset(ptr, ' ', fields[i].len); ptr += fields[i].len - 1; do { *--ptr = '0' + int_val % 10; int_val /= 10; } while (int_val != 0); break; case VALUE_TYPE_FLOAT: ptr = strstr(ptr, fields[i].tag); if (ptr == NULL) return -1; memset(ptr, ' ', fields[i].len); ptr[sprintf(ptr, "%f", *(float *)((unsigned char*)config + fields[i].offset))] = ' '; break; case VALUE_TYPE_BOOL: ptr = strstr(ptr, fields[i].tag); if (ptr == NULL) return -1; memset(ptr, ' ', fields[i].len); if (*(char *)((unsigned char*)config + fields[i].offset) > 0) memcpy(ptr, "true", 4); else memcpy(ptr, "false", 5); break; case VALUE_TYPE_STRING: ptr = strstr(ptr, fields[i].tag); if (ptr == NULL) return -1; memset(ptr, ' ', fields[i].len); *ptr++ = '\"'; k = 0; while (char ch = *((char*)config + fields[i].offset + k)) { *ptr++ = ch; k++; if (k == fields[i].len - 2) break; } *ptr++ = '\"'; break; default: return -1; } } return 0; }
int main(int argc, char *argv[]) { confent_t *conf; int c; int dopt = 0; int popt = 0; unsigned long bsize = 1024*1024; char *fsname = NULL; List qlist; int Fopt = 0; int ropt = 0; int sopt = 0; int Hopt = 0; int Uopt = 0; int nopt = 0; int hopt = 0; List uids = NULL; char *conf_path = _PATH_QUOTA_CONF; conf_t config; prog = basename(argv[0]); while ((c = GETOPT(argc, argv, OPTIONS, longopts)) != EOF) { switch(c) { case 'd': /* --dirscan */ dopt++; break; case 'p': /* --pwscan */ popt++; break; case 'b': /* --blocksize */ if (parse_blocksize(optarg, &bsize)) { fprintf(stderr, "%s: error parsing blocksize\n", prog); exit(1); } break; case 'u': /* --uid-range */ uids = listint_create(optarg); if (uids == NULL) { fprintf(stderr, "%s: error parsing uid-range\n", prog); exit(1); } break; case 'r': /* --reverse */ ropt++; break; case 'F': /* --files-sort */ Fopt++; break; case 's': /* --space-sort */ sopt++; break; case 'U': /* --usage-only */ Uopt++; break; case 'H': /* --suppress-heading */ Hopt++; break; case 'f': /* --config */ conf_path = optarg; break; case 'T': /* --selftest */ #ifndef NDEBUG listint_test(); exit(0); #else fprintf(stderr, "%s: not built with debugging enabled\n", prog); exit(1); #endif break; case 'D': /* --debug */ debug = 1; break; case 'n': /* --nouserlookup */ nopt = 1; break; case 'h': /* --human-readable */ hopt = 1; break; default: usage(); } } if (Fopt && sopt) { fprintf(stderr, "%s: -f and -s are mutually exclusive\n", prog); exit(1); } if (popt && dopt) { fprintf(stderr, "%s: -p and -d are mutually exclusive\n", prog); exit(1); } if (!popt && !dopt && !uids) { fprintf(stderr, "%s: need at least one of -pdu\n", prog); exit(1); } if (optind < argc) fsname = argv[optind++]; else usage(); if (optind < argc) usage(); config = conf_init(conf_path); /* exit/perror on error */ if (!(conf = conf_get_bylabel(config, fsname, 0))) { fprintf(stderr, "%s: %s: not found in quota.conf\n", prog, fsname); exit(1); } /* Scan. */ qlist = list_create((ListDelF)quota_destroy); if (popt) pwscan(conf, qlist, uids, !nopt); if (dopt) dirscan(conf, qlist, uids, !nopt); if (!dopt && !popt) uidscan(conf, qlist, uids, !nopt); /* Sort. */ if (ropt) { if (sopt) list_sort(qlist, (ListCmpF)quota_cmp_bytes_reverse); else if (Fopt) list_sort(qlist, (ListCmpF)quota_cmp_files_reverse); else list_sort(qlist, (ListCmpF)quota_cmp_uid_reverse); } else { if (sopt) list_sort(qlist, (ListCmpF)quota_cmp_bytes); else if (Fopt) list_sort(qlist, (ListCmpF)quota_cmp_files); else list_sort(qlist, (ListCmpF)quota_cmp_uid); } /* Report. */ if (!Hopt) { if (hopt) printf("Quota report for %s\n", fsname); else { char tmpstr[16]; size2str(bsize, tmpstr, sizeof(tmpstr)); printf("Quota report for %s (blocksize %s)\n", fsname, tmpstr); } } if (Uopt) { if (!Hopt) quota_report_heading_usageonly(); if (hopt) list_for_each(qlist, (ListForF)quota_report_usageonly_h, &bsize); else list_for_each(qlist, (ListForF)quota_report_usageonly, &bsize); } else { if (!Hopt) quota_report_heading(); if (hopt) list_for_each(qlist, (ListForF)quota_report_h, &bsize); else list_for_each(qlist, (ListForF)quota_report, &bsize); } if (qlist) list_destroy(qlist); if (uids) listint_destroy(uids); conf_fini(config); return 0; }