⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 edquota.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Copyright (c) 1980, 1990, 1993 *	The Regents of the University of California.  All rights reserved. * * This code is derived from software contributed to Berkeley by * Robert Elz at The University of Melbourne. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in the *    documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software *    must display the following acknowledgement: *	This product includes software developed by the University of *	California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors *    may be used to endorse or promote products derived from this software *    without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */#ifndef lintstatic char copyright[] ="@(#) Copyright (c) 1980, 1990, 1993\n\	The Regents of the University of California.  All rights reserved.\n";#endif /* not lint */#ifndef lintstatic char sccsid[] = "@(#)edquota.c	8.1 (Berkeley) 6/6/93";#endif /* not lint *//* * Disk quota editor. */#include <sys/param.h>#include <sys/stat.h>#include <sys/file.h>#include <sys/wait.h>#include <ufs/ufs/quota.h>#include <errno.h>#include <fstab.h>#include <pwd.h>#include <grp.h>#include <ctype.h>#include <stdio.h>#include <string.h>#include <unistd.h>#include "pathnames.h"char *qfname = QUOTAFILENAME;char *qfextension[] = INITQFNAMES;char *quotagroup = QUOTAGROUP;char tmpfil[] = _PATH_TMP;struct quotause {	struct	quotause *next;	long	flags;	struct	dqblk dqblk;	char	fsname[MAXPATHLEN + 1];	char	qfname[1];	/* actually longer */} *getprivs();#define	FOUND	0x01main(argc, argv)	register char **argv;	int argc;{	register struct quotause *qup, *protoprivs, *curprivs;	extern char *optarg;	extern int optind;	register long id, protoid;	register int quotatype, tmpfd;	char *protoname, ch;	int tflag = 0, pflag = 0;	if (argc < 2)		usage();	if (getuid()) {		fprintf(stderr, "edquota: permission denied\n");		exit(1);	}	quotatype = USRQUOTA;	while ((ch = getopt(argc, argv, "ugtp:")) != EOF) {		switch(ch) {		case 'p':			protoname = optarg;			pflag++;			break;		case 'g':			quotatype = GRPQUOTA;			break;		case 'u':			quotatype = USRQUOTA;			break;		case 't':			tflag++;			break;		default:			usage();		}	}	argc -= optind;	argv += optind;	if (pflag) {		if ((protoid = getentry(protoname, quotatype)) == -1)			exit(1);		protoprivs = getprivs(protoid, quotatype);		for (qup = protoprivs; qup; qup = qup->next) {			qup->dqblk.dqb_btime = 0;			qup->dqblk.dqb_itime = 0;		}		while (argc-- > 0) {			if ((id = getentry(*argv++, quotatype)) < 0)				continue;			putprivs(id, quotatype, protoprivs);		}		exit(0);	}	tmpfd = mkstemp(tmpfil);	fchown(tmpfd, getuid(), getgid());	if (tflag) {		protoprivs = getprivs(0, quotatype);		if (writetimes(protoprivs, tmpfd, quotatype) == 0)			exit(1);		if (editit(tmpfil) && readtimes(protoprivs, tmpfd))			putprivs(0, quotatype, protoprivs);		freeprivs(protoprivs);		exit(0);	}	for ( ; argc > 0; argc--, argv++) {		if ((id = getentry(*argv, quotatype)) == -1)			continue;		curprivs = getprivs(id, quotatype);		if (writeprivs(curprivs, tmpfd, *argv, quotatype) == 0)			continue;		if (editit(tmpfil) && readprivs(curprivs, tmpfd))			putprivs(id, quotatype, curprivs);		freeprivs(curprivs);	}	close(tmpfd);	unlink(tmpfil);	exit(0);}usage(){	fprintf(stderr, "%s%s%s%s",		"Usage: edquota [-u] [-p username] username ...\n",		"\tedquota -g [-p groupname] groupname ...\n",		"\tedquota [-u] -t\n", "\tedquota -g -t\n");	exit(1);}/* * This routine converts a name for a particular quota type to * an identifier. This routine must agree with the kernel routine * getinoquota as to the interpretation of quota types. */getentry(name, quotatype)	char *name;	int quotatype;{	struct passwd *pw;	struct group *gr;	if (alldigits(name))		return (atoi(name));	switch(quotatype) {	case USRQUOTA:		if (pw = getpwnam(name))			return (pw->pw_uid);		fprintf(stderr, "%s: no such user\n", name);		break;	case GRPQUOTA:		if (gr = getgrnam(name))			return (gr->gr_gid);		fprintf(stderr, "%s: no such group\n", name);		break;	default:		fprintf(stderr, "%d: unknown quota type\n", quotatype);		break;	}	sleep(1);	return (-1);}/* * Collect the requested quota information. */struct quotause *getprivs(id, quotatype)	register long id;	int quotatype;{	register struct fstab *fs;	register struct quotause *qup, *quptail;	struct quotause *quphead;	int qcmd, qupsize, fd;	char *qfpathname;	static int warned = 0;	extern int errno;	setfsent();	quphead = (struct quotause *)0;	qcmd = QCMD(Q_GETQUOTA, quotatype);	while (fs = getfsent()) {		if (strcmp(fs->fs_vfstype, "ufs"))			continue;		if (!hasquota(fs, quotatype, &qfpathname))			continue;		qupsize = sizeof(*qup) + strlen(qfpathname);		if ((qup = (struct quotause *)malloc(qupsize)) == NULL) {			fprintf(stderr, "edquota: out of memory\n");			exit(2);		}		if (quotactl(fs->fs_file, qcmd, id, &qup->dqblk) != 0) {	    		if (errno == EOPNOTSUPP && !warned) {				warned++;				fprintf(stderr, "Warning: %s\n",				    "Quotas are not compiled into this kernel");				sleep(3);			}			if ((fd = open(qfpathname, O_RDONLY)) < 0) {				fd = open(qfpathname, O_RDWR|O_CREAT, 0640);				if (fd < 0 && errno != ENOENT) {					perror(qfpathname);					free(qup);					continue;				}				fprintf(stderr, "Creating quota file %s\n",				    qfpathname);				sleep(3);				(void) fchown(fd, getuid(),				    getentry(quotagroup, GRPQUOTA));				(void) fchmod(fd, 0640);			}			lseek(fd, (long)(id * sizeof(struct dqblk)), L_SET);			switch (read(fd, &qup->dqblk, sizeof(struct dqblk))) {			case 0:			/* EOF */				/*				 * Convert implicit 0 quota (EOF)				 * into an explicit one (zero'ed dqblk)				 */				bzero((caddr_t)&qup->dqblk,				    sizeof(struct dqblk));				break;			case sizeof(struct dqblk):	/* OK */				break;			default:		/* ERROR */				fprintf(stderr, "edquota: read error in ");				perror(qfpathname);				close(fd);				free(qup);				continue;			}			close(fd);		}		strcpy(qup->qfname, qfpathname);		strcpy(qup->fsname, fs->fs_file);		if (quphead == NULL)			quphead = qup;		else			quptail->next = qup;		quptail = qup;		qup->next = 0;	}	endfsent();	return (quphead);}/* * Store the requested quota information. */putprivs(id, quotatype, quplist)	long id;	int quotatype;	struct quotause *quplist;{	register struct quotause *qup;	int qcmd, fd;	qcmd = QCMD(Q_SETQUOTA, quotatype);	for (qup = quplist; qup; qup = qup->next) {		if (quotactl(qup->fsname, qcmd, id, &qup->dqblk) == 0)			continue;		if ((fd = open(qup->qfname, O_WRONLY)) < 0) {			perror(qup->qfname);		} else {			lseek(fd, (long)id * (long)sizeof (struct dqblk), 0);			if (write(fd, &qup->dqblk, sizeof (struct dqblk)) !=			    sizeof (struct dqblk)) {				fprintf(stderr, "edquota: ");				perror(qup->qfname);			}			close(fd);		}	}}/* * Take a list of priviledges and get it edited. */editit(tmpfile)	char *tmpfile;{	long omask;	int pid, stat;	extern char *getenv();	omask = sigblock(sigmask(SIGINT)|sigmask(SIGQUIT)|sigmask(SIGHUP)); top:	if ((pid = fork()) < 0) {		extern errno;		if (errno == EPROCLIM) {			fprintf(stderr, "You have too many processes\n");			return(0);		}		if (errno == EAGAIN) {			sleep(1);			goto top;		}		perror("fork");		return (0);	}	if (pid == 0) {		register char *ed;		sigsetmask(omask);		setgid(getgid());		setuid(getuid());		if ((ed = getenv("EDITOR")) == (char *)0)			ed = _PATH_VI;		execlp(ed, ed, tmpfile, 0);		perror(ed);		exit(1);	}	waitpid(pid, &stat, 0);	sigsetmask(omask);	if (!WIFEXITED(stat) || WEXITSTATUS(stat) != 0)		return (0);	return (1);}/*

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -