Example #1
0
/*
 * 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);
}
Example #2
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);
}