/* * Update a specified quota file. */ int update(char *fsname, char *quotafile, int type) { struct fileusage *fup; FILE *qfi, *qfo; u_long id, lastid; off_t offset; struct ufs_dqblk dqbuf; static int warned = 0; static struct ufs_dqblk zerodqbuf; static struct fileusage zerofileusage; if ((qfo = fopen(quotafile, "r+")) == NULL) { if (errno == ENOENT) qfo = fopen(quotafile, "w+"); if (qfo) { warnx("creating quota file %s", quotafile); #define MODE (S_IRUSR|S_IWUSR|S_IRGRP) fchown(fileno(qfo), getuid(), getquotagid()); fchmod(fileno(qfo), MODE); } else { warn("%s", quotafile); return (1); } } if ((qfi = fopen(quotafile, "r")) == NULL) { warn("%s", quotafile); fclose(qfo); return (1); } if (quotactl(fsname, QCMD(Q_SYNC, type), (u_long)0, (caddr_t)0) < 0 && errno == EOPNOTSUPP && !warned && vflag) { warned++; printf("*** Warning: %s\n", "Quotas are not compiled into this kernel"); } for (lastid = highid[type], id = 0, offset = 0; id <= lastid; id++, offset += sizeof(struct ufs_dqblk)) { if (fread((char *)&dqbuf, sizeof(struct ufs_dqblk), 1, qfi) == 0) dqbuf = zerodqbuf; if ((fup = lookup(id, type)) == NULL) fup = &zerofileusage; if (dqbuf.dqb_curinodes == fup->fu_curinodes && dqbuf.dqb_curblocks == fup->fu_curblocks) { fup->fu_curinodes = 0; fup->fu_curblocks = 0; continue; } if (vflag) { if (aflag) printf("%s: ", fsname); printf("%-8s fixed:", fup->fu_name); if (dqbuf.dqb_curinodes != fup->fu_curinodes) printf("\tinodes %lu -> %lu", (u_long)dqbuf.dqb_curinodes, (u_long)fup->fu_curinodes); if (dqbuf.dqb_curblocks != fup->fu_curblocks) printf("\tblocks %lu -> %lu", (u_long)dqbuf.dqb_curblocks, (u_long)fup->fu_curblocks); printf("\n"); } /* * Reset time limit if have a soft limit and were * previously under it, but are now over it. */ if (dqbuf.dqb_bsoftlimit && dqbuf.dqb_curblocks < dqbuf.dqb_bsoftlimit && fup->fu_curblocks >= dqbuf.dqb_bsoftlimit) dqbuf.dqb_btime = 0; if (dqbuf.dqb_isoftlimit && dqbuf.dqb_curblocks < dqbuf.dqb_isoftlimit && fup->fu_curblocks >= dqbuf.dqb_isoftlimit) dqbuf.dqb_itime = 0; dqbuf.dqb_curinodes = fup->fu_curinodes; dqbuf.dqb_curblocks = fup->fu_curblocks; if (fseek(qfo, (long)offset, SEEK_SET) < 0) { warn("%s: seek failed", quotafile); return(1); } fwrite((char *)&dqbuf, sizeof(struct ufs_dqblk), 1, qfo); quotactl(fsname, QCMD(Q_SETUSE, type), id, (caddr_t)&dqbuf); fup->fu_curinodes = 0; fup->fu_curblocks = 0; } fclose(qfi); fflush(qfo); ftruncate(fileno(qfo), (off_t)((highid[type] + 1) * sizeof(struct ufs_dqblk))); fclose(qfo); return (0); }
/* * Update a specified quota file. */ int update(const char *fsname, const char *quotafile, int type) { struct fileusage *fup; FILE *qfi, *qfo; u_int32_t id, lastid; struct dqblk dqbuf; static int warned = 0; static struct dqblk zerodqbuf; static struct fileusage zerofileusage; if (flags&CHECK_DEBUG) printf("updating: %s\n", quotafile); if ((qfo = fopen(quotafile, (flags&CHECK_DEBUG)? "r" : "r+")) == NULL) { if (errno == ENOENT) qfo = fopen(quotafile, "w+"); if (qfo) { warnx("creating quota file: %s", quotafile); #define MODE (S_IRUSR|S_IWUSR|S_IRGRP) (void) fchown(fileno(qfo), getuid(), getquotagid()); (void) fchmod(fileno(qfo), MODE); } else { warn("%s", quotafile); return (1); } } if ((qfi = fopen(quotafile, "r")) == NULL) { warn("%s", quotafile); (void) fclose(qfo); return (1); } if (quotactl(fsname, QCMD(Q_SYNC, type), 0, (caddr_t)0) < 0 && errno == EOPNOTSUPP && !warned && (flags&(CHECK_DEBUG|CHECK_VERBOSE))) { warned++; (void)printf("*** Warning: %s\n", "Quotas are not compiled into this kernel"); } for (lastid = highid[type], id = 0; id <= lastid; id++) { if (fread((char *)&dqbuf, sizeof(struct dqblk), 1, qfi) == 0) dqbuf = zerodqbuf; if ((fup = lookup(id, type)) == 0) fup = &zerofileusage; if (dqbuf.dqb_curinodes == fup->fu_curinodes && dqbuf.dqb_curblocks == fup->fu_curblocks) { fup->fu_curinodes = 0; fup->fu_curblocks = 0; fseek(qfo, (long)sizeof(struct dqblk), SEEK_CUR); continue; } if (flags&(CHECK_DEBUG|CHECK_VERBOSE)) { if (flags&CHECK_PREEN) printf("%s: ", fsname); printf("%-8s fixed:", fup->fu_name); if (dqbuf.dqb_curinodes != fup->fu_curinodes) (void)printf("\tinodes %d -> %u", dqbuf.dqb_curinodes, fup->fu_curinodes); if (dqbuf.dqb_curblocks != fup->fu_curblocks) (void)printf("\tblocks %u -> %u", dqbuf.dqb_curblocks, fup->fu_curblocks); (void)printf("\n"); } /* * Reset time limit if have a soft limit and were * previously under it, but are now over it. */ if (dqbuf.dqb_bsoftlimit && dqbuf.dqb_curblocks < dqbuf.dqb_bsoftlimit && fup->fu_curblocks >= dqbuf.dqb_bsoftlimit) dqbuf.dqb_btime = 0; if (dqbuf.dqb_isoftlimit && dqbuf.dqb_curblocks < dqbuf.dqb_isoftlimit && fup->fu_curblocks >= dqbuf.dqb_isoftlimit) dqbuf.dqb_itime = 0; dqbuf.dqb_curinodes = fup->fu_curinodes; dqbuf.dqb_curblocks = fup->fu_curblocks; if (!(flags & CHECK_DEBUG)) { fwrite((char *)&dqbuf, sizeof(struct dqblk), 1, qfo); (void) quotactl(fsname, QCMD(Q_SETUSE, type), id, (caddr_t)&dqbuf); } fup->fu_curinodes = 0; fup->fu_curblocks = 0; } fclose(qfi); fflush(qfo); if (!(flags & CHECK_DEBUG)) ftruncate(fileno(qfo), (off_t)((highid[type] + 1) * sizeof(struct dqblk))); fclose(qfo); return (0); }