quotacheck.c (175678) | quotacheck.c (180187) |
---|---|
1/* 2 * Copyright (c) 1980, 1990, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * This code is derived from software contributed to Berkeley by 6 * Robert Elz at The University of Melbourne. 7 * 8 * Redistribution and use in source and binary forms, with or without --- 28 unchanged lines hidden (view full) --- 37 The Regents of the University of California. All rights reserved.\n"; 38#endif /* not lint */ 39 40#ifndef lint 41static char sccsid[] = "@(#)quotacheck.c 8.3 (Berkeley) 1/29/94"; 42#endif /* not lint */ 43#endif 44#include <sys/cdefs.h> | 1/* 2 * Copyright (c) 1980, 1990, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * This code is derived from software contributed to Berkeley by 6 * Robert Elz at The University of Melbourne. 7 * 8 * Redistribution and use in source and binary forms, with or without --- 28 unchanged lines hidden (view full) --- 37 The Regents of the University of California. All rights reserved.\n"; 38#endif /* not lint */ 39 40#ifndef lint 41static char sccsid[] = "@(#)quotacheck.c 8.3 (Berkeley) 1/29/94"; 42#endif /* not lint */ 43#endif 44#include <sys/cdefs.h> |
45__FBSDID("$FreeBSD: head/sbin/quotacheck/quotacheck.c 175678 2008-01-26 12:03:26Z mpp $"); | 45__FBSDID("$FreeBSD: head/sbin/quotacheck/quotacheck.c 180187 2008-07-02 15:51:59Z des $"); |
46 47/* 48 * Fix up / report on disk quotas & usage 49 */ 50#include <sys/param.h> 51#include <sys/disklabel.h> 52#include <sys/mount.h> 53#include <sys/stat.h> --- 74 unchanged lines hidden (view full) --- 128struct quotaname *needchk(struct fstab *); 129int oneof(char *, char*[], int); 130void printchanges(char *, int, struct dqblk *, struct fileusage *, u_long); 131void setinodebuf(ino_t); 132int update(char *, char *, int); 133void usage(void); 134 135int | 46 47/* 48 * Fix up / report on disk quotas & usage 49 */ 50#include <sys/param.h> 51#include <sys/disklabel.h> 52#include <sys/mount.h> 53#include <sys/stat.h> --- 74 unchanged lines hidden (view full) --- 128struct quotaname *needchk(struct fstab *); 129int oneof(char *, char*[], int); 130void printchanges(char *, int, struct dqblk *, struct fileusage *, u_long); 131void setinodebuf(ino_t); 132int update(char *, char *, int); 133void usage(void); 134 135int |
136main(argc, argv) 137 int argc; 138 char *argv[]; | 136main(int argc, char *argv[]) |
139{ 140 struct fstab *fs; 141 struct passwd *pw; 142 struct group *gr; 143 struct quotaname *qnp; 144 int i, argnum, maxrun, errs, ch; 145 long done = 0; 146 char *name; --- 64 unchanged lines hidden (view full) --- 211 for (i = 0; i < argc; i++) 212 if ((done & (1 << i)) == 0) 213 fprintf(stderr, "%s not found in %s\n", 214 argv[i], FSTAB); 215 exit(errs); 216} 217 218void | 137{ 138 struct fstab *fs; 139 struct passwd *pw; 140 struct group *gr; 141 struct quotaname *qnp; 142 int i, argnum, maxrun, errs, ch; 143 long done = 0; 144 char *name; --- 64 unchanged lines hidden (view full) --- 209 for (i = 0; i < argc; i++) 210 if ((done & (1 << i)) == 0) 211 fprintf(stderr, "%s not found in %s\n", 212 argv[i], FSTAB); 213 exit(errs); 214} 215 216void |
219usage() | 217usage(void) |
220{ | 218{ |
221 (void)fprintf(stderr, "%s\n%s\n", | 219 (void)fprintf(stderr, "%s\n%s\n", |
222 "usage: quotacheck [-guv] [-l maxrun] -a", 223 " quotacheck [-guv] filesystem ..."); 224 exit(1); 225} 226 227struct quotaname * | 220 "usage: quotacheck [-guv] [-l maxrun] -a", 221 " quotacheck [-guv] filesystem ..."); 222 exit(1); 223} 224 225struct quotaname * |
228needchk(fs) 229 struct fstab *fs; | 226needchk(struct fstab *fs) |
230{ 231 struct quotaname *qnp; 232 char *qfnp; 233 234 if (strcmp(fs->fs_vfstype, "ufs") || 235 strcmp(fs->fs_type, FSTAB_RW)) 236 return (NULL); 237 if ((qnp = malloc(sizeof(*qnp))) == NULL) --- 17 unchanged lines hidden (view full) --- 255 * Possible superblock locations ordered from most to least likely. 256 */ 257static int sblock_try[] = SBLOCKSEARCH; 258 259/* 260 * Scan the specified file system to check quota(s) present on it. 261 */ 262int | 227{ 228 struct quotaname *qnp; 229 char *qfnp; 230 231 if (strcmp(fs->fs_vfstype, "ufs") || 232 strcmp(fs->fs_type, FSTAB_RW)) 233 return (NULL); 234 if ((qnp = malloc(sizeof(*qnp))) == NULL) --- 17 unchanged lines hidden (view full) --- 252 * Possible superblock locations ordered from most to least likely. 253 */ 254static int sblock_try[] = SBLOCKSEARCH; 255 256/* 257 * Scan the specified file system to check quota(s) present on it. 258 */ 259int |
263chkquota(fsname, mntpt, qnp) 264 char *fsname, *mntpt; 265 struct quotaname *qnp; | 260chkquota(char *fsname, char *mntpt, struct quotaname *qnp) |
266{ 267 struct fileusage *fup; 268 union dinode *dp; 269 int cg, i, mode, errs = 0; 270 ino_t ino, inosused, userino = 0, groupino = 0; 271 dev_t dev, userdev = 0, groupdev = 0; 272 char *cp; 273 struct stat sb; --- 84 unchanged lines hidden (view full) --- 358 if ((dp = getnextinode(ino)) == NULL || ino < ROOTINO || 359 (mode = DIP(dp, di_mode) & IFMT) == 0) 360 continue; 361 /* 362 * XXX: Do not account for UIDs or GIDs that appear 363 * to be negative to prevent generating 100GB+ 364 * quota files. 365 */ | 261{ 262 struct fileusage *fup; 263 union dinode *dp; 264 int cg, i, mode, errs = 0; 265 ino_t ino, inosused, userino = 0, groupino = 0; 266 dev_t dev, userdev = 0, groupdev = 0; 267 char *cp; 268 struct stat sb; --- 84 unchanged lines hidden (view full) --- 353 if ((dp = getnextinode(ino)) == NULL || ino < ROOTINO || 354 (mode = DIP(dp, di_mode) & IFMT) == 0) 355 continue; 356 /* 357 * XXX: Do not account for UIDs or GIDs that appear 358 * to be negative to prevent generating 100GB+ 359 * quota files. 360 */ |
366 if ((int)DIP(dp, di_uid) < 0 || | 361 if ((int)DIP(dp, di_uid) < 0 || |
367 (int)DIP(dp, di_gid) < 0) { 368 if (vflag) { 369 if (aflag) 370 (void)printf("%s: ", mntpt); 371 (void)printf("out of range UID/GID (%u/%u) ino=%u\n", 372 DIP(dp, di_uid), DIP(dp,di_gid), 373 ino); 374 } 375 continue; 376 } 377 | 362 (int)DIP(dp, di_gid) < 0) { 363 if (vflag) { 364 if (aflag) 365 (void)printf("%s: ", mntpt); 366 (void)printf("out of range UID/GID (%u/%u) ino=%u\n", 367 DIP(dp, di_uid), DIP(dp,di_gid), 368 ino); 369 } 370 continue; 371 } 372 |
378 /* | 373 /* |
379 * Do not account for file system snapshot files 380 * or the actual quota data files to be consistent 381 * with how they are handled inside the kernel. 382 */ 383#ifdef SF_SNAPSHOT 384 if (DIP(dp, di_flags) & SF_SNAPSHOT) 385 continue; 386#endif --- 27 unchanged lines hidden (view full) --- 414 (void)fflush(stdout); 415 return (errs); 416} 417 418/* 419 * Update a specified quota file. 420 */ 421int | 374 * Do not account for file system snapshot files 375 * or the actual quota data files to be consistent 376 * with how they are handled inside the kernel. 377 */ 378#ifdef SF_SNAPSHOT 379 if (DIP(dp, di_flags) & SF_SNAPSHOT) 380 continue; 381#endif --- 27 unchanged lines hidden (view full) --- 409 (void)fflush(stdout); 410 return (errs); 411} 412 413/* 414 * Update a specified quota file. 415 */ 416int |
422update(fsname, quotafile, type) 423 char *fsname, *quotafile; 424 int type; | 417update(char *fsname, char *quotafile, int type) |
425{ 426 struct fileusage *fup; 427 FILE *qfi, *qfo; 428 u_long id, lastid, highid = 0; 429 off_t offset; 430 int i; 431 struct dqblk dqbuf; 432 struct stat sb; --- 37 unchanged lines hidden (view full) --- 470 /* 471 * Scan the on-disk quota file and record any usage changes. 472 */ 473 474 if (sb.st_size != 0) 475 lastid = (sb.st_size / sizeof(struct dqblk)) - 1; 476 else 477 lastid = 0; | 418{ 419 struct fileusage *fup; 420 FILE *qfi, *qfo; 421 u_long id, lastid, highid = 0; 422 off_t offset; 423 int i; 424 struct dqblk dqbuf; 425 struct stat sb; --- 37 unchanged lines hidden (view full) --- 463 /* 464 * Scan the on-disk quota file and record any usage changes. 465 */ 466 467 if (sb.st_size != 0) 468 lastid = (sb.st_size / sizeof(struct dqblk)) - 1; 469 else 470 lastid = 0; |
478 for (id = 0, offset = 0; id <= lastid; | 471 for (id = 0, offset = 0; id <= lastid; |
479 id++, offset += sizeof(struct dqblk)) { 480 if (fread((char *)&dqbuf, sizeof(struct dqblk), 1, qfi) == 0) 481 dqbuf = zerodqbuf; 482 if ((fup = lookup(id, type)) == NULL) 483 fup = &zerofileusage; 484 if (fup->fu_curinodes || fup->fu_curblocks || 485 dqbuf.dqb_bsoftlimit || dqbuf.dqb_bhardlimit || 486 dqbuf.dqb_isoftlimit || dqbuf.dqb_ihardlimit) --- 50 unchanged lines hidden (view full) --- 537 dqbuf.dqb_curblocks = fup->fu_curblocks; 538 offset = (off_t)fup->fu_id * sizeof(struct dqblk); 539 if (fseeko(qfo, offset, SEEK_SET) < 0) { 540 warn("%s: seek failed", quotafile); 541 return(1); 542 } 543 fwrite((char *)&dqbuf, sizeof(struct dqblk), 1, qfo); 544 (void) quotactl(fsname, QCMD(Q_SETUSE, type), id, | 472 id++, offset += sizeof(struct dqblk)) { 473 if (fread((char *)&dqbuf, sizeof(struct dqblk), 1, qfi) == 0) 474 dqbuf = zerodqbuf; 475 if ((fup = lookup(id, type)) == NULL) 476 fup = &zerofileusage; 477 if (fup->fu_curinodes || fup->fu_curblocks || 478 dqbuf.dqb_bsoftlimit || dqbuf.dqb_bhardlimit || 479 dqbuf.dqb_isoftlimit || dqbuf.dqb_ihardlimit) --- 50 unchanged lines hidden (view full) --- 530 dqbuf.dqb_curblocks = fup->fu_curblocks; 531 offset = (off_t)fup->fu_id * sizeof(struct dqblk); 532 if (fseeko(qfo, offset, SEEK_SET) < 0) { 533 warn("%s: seek failed", quotafile); 534 return(1); 535 } 536 fwrite((char *)&dqbuf, sizeof(struct dqblk), 1, qfo); 537 (void) quotactl(fsname, QCMD(Q_SETUSE, type), id, |
545 (caddr_t)&dqbuf); | 538 (caddr_t)&dqbuf); |
546 fup->fu_curinodes = 0; 547 fup->fu_curblocks = 0; 548 } 549 } 550 fclose(qfi); 551 fflush(qfo); 552 ftruncate(fileno(qfo), 553 (((off_t)highid + 1) * sizeof(struct dqblk))); 554 fclose(qfo); 555 return (0); 556} 557 558/* 559 * Check to see if target appears in list of size cnt. 560 */ 561int | 539 fup->fu_curinodes = 0; 540 fup->fu_curblocks = 0; 541 } 542 } 543 fclose(qfi); 544 fflush(qfo); 545 ftruncate(fileno(qfo), 546 (((off_t)highid + 1) * sizeof(struct dqblk))); 547 fclose(qfo); 548 return (0); 549} 550 551/* 552 * Check to see if target appears in list of size cnt. 553 */ 554int |
562oneof(target, list, cnt) 563 char *target, *list[]; 564 int cnt; | 555oneof(char *target, char *list[], int cnt) |
565{ 566 int i; 567 568 for (i = 0; i < cnt; i++) 569 if (strcmp(target, list[i]) == 0) 570 return (i); 571 return (-1); 572} 573 574/* 575 * Determine the group identifier for quota files. 576 */ 577int | 556{ 557 int i; 558 559 for (i = 0; i < cnt; i++) 560 if (strcmp(target, list[i]) == 0) 561 return (i); 562 return (-1); 563} 564 565/* 566 * Determine the group identifier for quota files. 567 */ 568int |
578getquotagid() | 569getquotagid(void) |
579{ 580 struct group *gr; 581 582 if ((gr = getgrnam(quotagroup)) != NULL) 583 return (gr->gr_gid); 584 return (-1); 585} 586 587/* 588 * Check to see if a particular quota is to be enabled. 589 */ 590int | 570{ 571 struct group *gr; 572 573 if ((gr = getgrnam(quotagroup)) != NULL) 574 return (gr->gr_gid); 575 return (-1); 576} 577 578/* 579 * Check to see if a particular quota is to be enabled. 580 */ 581int |
591hasquota(fs, type, qfnamep) 592 struct fstab *fs; 593 int type; 594 char **qfnamep; | 582hasquota(struct fstab *fs, int type, char **qfnamep) |
595{ 596 char *opt; 597 char *cp; 598 struct statfs sfb; 599 static char initname, usrname[100], grpname[100]; 600 static char buf[BUFSIZ]; 601 602 if (!initname) { --- 34 unchanged lines hidden (view full) --- 637} 638 639/* 640 * Routines to manage the file usage table. 641 * 642 * Lookup an id of a specific type. 643 */ 644struct fileusage * | 583{ 584 char *opt; 585 char *cp; 586 struct statfs sfb; 587 static char initname, usrname[100], grpname[100]; 588 static char buf[BUFSIZ]; 589 590 if (!initname) { --- 34 unchanged lines hidden (view full) --- 625} 626 627/* 628 * Routines to manage the file usage table. 629 * 630 * Lookup an id of a specific type. 631 */ 632struct fileusage * |
645lookup(id, type) 646 u_long id; 647 int type; | 633lookup(u_long id, int type) |
648{ 649 struct fileusage *fup; 650 651 for (fup = fuhead[type][id & (FUHASH-1)]; fup != 0; fup = fup->fu_next) 652 if (fup->fu_id == id) 653 return (fup); 654 return (NULL); 655} 656 657/* 658 * Add a new file usage id if it does not already exist. 659 */ 660struct fileusage * | 634{ 635 struct fileusage *fup; 636 637 for (fup = fuhead[type][id & (FUHASH-1)]; fup != 0; fup = fup->fu_next) 638 if (fup->fu_id == id) 639 return (fup); 640 return (NULL); 641} 642 643/* 644 * Add a new file usage id if it does not already exist. 645 */ 646struct fileusage * |
661addid(id, type, name, fsname) 662 u_long id; 663 int type; 664 char *name; 665 char *fsname; | 647addid(u_long id, int type, char *name, char *fsname) |
666{ 667 struct fileusage *fup, **fhp; 668 int len; 669 670 if ((fup = lookup(id, type)) != NULL) 671 return (fup); 672 if (name) 673 len = strlen(name); --- 7 unchanged lines hidden (view full) --- 681 fup->fu_id = id; 682 if (name) 683 bcopy(name, fup->fu_name, len + 1); 684 else { 685 (void)sprintf(fup->fu_name, "%lu", id); 686 if (vflag) { 687 if (aflag && fsname != NULL) 688 (void)printf("%s: ", fsname); | 648{ 649 struct fileusage *fup, **fhp; 650 int len; 651 652 if ((fup = lookup(id, type)) != NULL) 653 return (fup); 654 if (name) 655 len = strlen(name); --- 7 unchanged lines hidden (view full) --- 663 fup->fu_id = id; 664 if (name) 665 bcopy(name, fup->fu_name, len + 1); 666 else { 667 (void)sprintf(fup->fu_name, "%lu", id); 668 if (vflag) { 669 if (aflag && fsname != NULL) 670 (void)printf("%s: ", fsname); |
689 printf("unknown %cid: %lu\n", | 671 printf("unknown %cid: %lu\n", |
690 type == USRQUOTA ? 'u' : 'g', id); 691 } 692 } 693 return (fup); 694} 695 696/* 697 * Special purpose version of ginode used to optimize pass --- 70 unchanged lines hidden (view full) --- 768 if ((inodebuf = malloc((unsigned)inobufsize)) == NULL) 769 errx(1, "cannot allocate space for inode buffer"); 770} 771 772/* 773 * Free up data structures used to scan inodes. 774 */ 775void | 672 type == USRQUOTA ? 'u' : 'g', id); 673 } 674 } 675 return (fup); 676} 677 678/* 679 * Special purpose version of ginode used to optimize pass --- 70 unchanged lines hidden (view full) --- 750 if ((inodebuf = malloc((unsigned)inobufsize)) == NULL) 751 errx(1, "cannot allocate space for inode buffer"); 752} 753 754/* 755 * Free up data structures used to scan inodes. 756 */ 757void |
776freeinodebuf() | 758freeinodebuf(void) |
777{ 778 779 if (inodebuf != NULL) 780 free(inodebuf); 781 inodebuf = NULL; 782} 783 784/* 785 * Read specified disk blocks. 786 */ 787void | 759{ 760 761 if (inodebuf != NULL) 762 free(inodebuf); 763 inodebuf = NULL; 764} 765 766/* 767 * Read specified disk blocks. 768 */ 769void |
788bread(bno, buf, cnt) 789 ufs2_daddr_t bno; 790 char *buf; 791 long cnt; | 770bread(ufs2_daddr_t bno, char *buf, long cnt) |
792{ 793 794 if (lseek(fi, (off_t)bno * dev_bsize, SEEK_SET) < 0 || 795 read(fi, buf, cnt) != cnt) 796 errx(1, "bread failed on block %ld", (long)bno); 797} 798 799/* 800 * Display updated block and i-node counts. 801 */ 802void | 771{ 772 773 if (lseek(fi, (off_t)bno * dev_bsize, SEEK_SET) < 0 || 774 read(fi, buf, cnt) != cnt) 775 errx(1, "bread failed on block %ld", (long)bno); 776} 777 778/* 779 * Display updated block and i-node counts. 780 */ 781void |
803printchanges(fsname, type, dp, fup, id) 804 char *fsname; 805 int type; 806 struct dqblk *dp; 807 struct fileusage *fup; 808 u_long id; | 782printchanges(char *fsname, int type, struct dqblk *dp, 783 struct fileusage *fup, u_long id) |
809{ 810 if (!vflag) 811 return; 812 if (aflag) 813 (void)printf("%s: ", fsname); 814 if (fup->fu_name[0] == '\0') 815 (void)printf("%-8lu fixed ", id); 816 else --- 11 unchanged lines hidden (view full) --- 828 default: 829 (void)printf("(unknown quota type %d)", type); 830 break; 831 } 832 if (dp->dqb_curinodes != fup->fu_curinodes) 833 (void)printf("\tinodes %lu -> %lu", (u_long)dp->dqb_curinodes, 834 (u_long)fup->fu_curinodes); 835 if (dp->dqb_curblocks != fup->fu_curblocks) | 784{ 785 if (!vflag) 786 return; 787 if (aflag) 788 (void)printf("%s: ", fsname); 789 if (fup->fu_name[0] == '\0') 790 (void)printf("%-8lu fixed ", id); 791 else --- 11 unchanged lines hidden (view full) --- 803 default: 804 (void)printf("(unknown quota type %d)", type); 805 break; 806 } 807 if (dp->dqb_curinodes != fup->fu_curinodes) 808 (void)printf("\tinodes %lu -> %lu", (u_long)dp->dqb_curinodes, 809 (u_long)fup->fu_curinodes); 810 if (dp->dqb_curblocks != fup->fu_curblocks) |
836 (void)printf("\tblocks %lu -> %lu", | 811 (void)printf("\tblocks %lu -> %lu", |
837 (u_long)dp->dqb_curblocks, 838 (u_long)fup->fu_curblocks); 839 (void)printf("\n"); 840} | 812 (u_long)dp->dqb_curblocks, 813 (u_long)fup->fu_curblocks); 814 (void)printf("\n"); 815} |