xref: /csrg-svn/usr.sbin/quotaon/quotaon.c (revision 21518)
1*21518Smckusick /*
2*21518Smckusick  * Copyright (c) 1980 Regents of the University of California.
3*21518Smckusick  * All rights reserved.  The Berkeley software License Agreement
4*21518Smckusick  * specifies the terms and conditions for redistribution.
5*21518Smckusick  */
6*21518Smckusick 
712662Smckusick #ifndef lint
8*21518Smckusick char copyright[] =
9*21518Smckusick "@(#) Copyright (c) 1980 Regents of the University of California.\n\
10*21518Smckusick  All rights reserved.\n";
11*21518Smckusick #endif not lint
1212809Ssam 
13*21518Smckusick #ifndef lint
14*21518Smckusick static char sccsid[] = "@(#)quotaon.c	5.1 (Berkeley) 05/30/85";
15*21518Smckusick #endif not lint
16*21518Smckusick 
1712662Smckusick /*
1812670Smckusick  * Turn quota on/off for a filesystem.
1912662Smckusick  */
2012662Smckusick #include <sys/param.h>
2112809Ssam #include <sys/file.h>
2212662Smckusick #include <stdio.h>
2312662Smckusick #include <fstab.h>
2412809Ssam #include <mtab.h>
2512662Smckusick 
2612809Ssam struct	mtab mtab[NMOUNT];
2712809Ssam 
2812662Smckusick int	vflag;		/* verbose */
2912662Smckusick int	aflag;		/* all file systems */
3012723Smckusick int	done;
3112809Ssam int	mf;
3212662Smckusick 
3312809Ssam char	*qfname = "quotas";
3412809Ssam char	quotafile[MAXPATHLEN + 1];
3512809Ssam char	*index(), *rindex();
3612670Smckusick 
3712662Smckusick main(argc, argv)
3812670Smckusick 	int argc;
3912662Smckusick 	char **argv;
4012662Smckusick {
4112662Smckusick 	register struct fstab *fs;
4212670Smckusick 	char *whoami, *rindex();
4312723Smckusick 	int offmode = 0, errs = 0, i;
4412662Smckusick 
4512670Smckusick 	whoami = rindex(*argv, '/') + 1;
4612670Smckusick 	if (whoami == (char *)1)
4712670Smckusick 		whoami = *argv;
4812670Smckusick 	if (strcmp(whoami, "quotaoff") == 0)
4912670Smckusick 		offmode++;
5012670Smckusick 	else if (strcmp(whoami, "quotaon") != 0) {
5112670Smckusick 		fprintf(stderr, "Name must be quotaon or quotaoff not %s\n",
5212670Smckusick 			whoami);
5312670Smckusick 		exit(1);
5412670Smckusick 	}
5512662Smckusick again:
5612662Smckusick 	argc--, argv++;
5712662Smckusick 	if (argc > 0 && strcmp(*argv, "-v") == 0) {
5812662Smckusick 		vflag++;
5912662Smckusick 		goto again;
6012662Smckusick 	}
6112662Smckusick 	if (argc > 0 && strcmp(*argv, "-a") == 0) {
6212662Smckusick 		aflag++;
6312662Smckusick 		goto again;
6412662Smckusick 	}
6512670Smckusick 	if (argc <= 0 && !aflag) {
6612670Smckusick 		fprintf(stderr, "Usage:\n\t%s [-v] -a\n\t%s [-v] filesys ...\n",
6712670Smckusick 			whoami, whoami);
6812662Smckusick 		exit(1);
6912662Smckusick 	}
7012809Ssam 	mf = open("/etc/mtab", O_RDONLY);
7112809Ssam 	if (mf < 0) {
7212809Ssam 		perror("/etc/mtab");
7312809Ssam 		exit(1);
7412809Ssam 	}
7512809Ssam 	(void) read(mf, (char *)mtab, sizeof (mtab));
7612809Ssam 	close(mf);
7712662Smckusick 	setfsent();
7812662Smckusick 	while ((fs = getfsent()) != NULL) {
7912723Smckusick 		if (aflag &&
8012723Smckusick 		    (fs->fs_type == 0 || strcmp(fs->fs_type, "rq") != 0))
8112662Smckusick 			continue;
8212723Smckusick 		if (!aflag &&
8312723Smckusick 		    !(oneof(fs->fs_file, argv, argc) ||
8412723Smckusick 		      oneof(fs->fs_spec, argv, argc)))
8512662Smckusick 			continue;
8612809Ssam 		errs += quotaonoff(fs, offmode);
8712662Smckusick 	}
8812662Smckusick 	endfsent();
8912723Smckusick 	for (i = 0; i < argc; i++)
9012723Smckusick 		if ((done & (1 << i)) == 0)
9112723Smckusick 			fprintf(stderr, "%s not found in /etc/fstab\n",
9212723Smckusick 				argv[i]);
9312670Smckusick 	exit(errs);
9412662Smckusick }
9512662Smckusick 
9612809Ssam quotaonoff(fs, offmode)
9712809Ssam 	register struct fstab *fs;
9812809Ssam 	int offmode;
9912809Ssam {
10012809Ssam 
10112809Ssam 	if (strcmp(fs->fs_file, "/") && readonly(fs))
10212809Ssam 		return (1);
10312809Ssam 	if (offmode) {
10412809Ssam 		if (setquota(fs->fs_spec, NULL) < 0)
10512809Ssam 			goto bad;
10612809Ssam 		if (vflag)
10712809Ssam 			printf("%s: quotas turned off\n", fs->fs_file);
10812809Ssam 		changemtab(fs, FSTAB_RW);
10912809Ssam 		return (0);
11012809Ssam 	}
11112809Ssam 	(void) sprintf(quotafile, "%s/%s", fs->fs_file, qfname);
11212809Ssam 	if (setquota(fs->fs_spec, quotafile) < 0)
11312809Ssam 		goto bad;
11412809Ssam 	if (vflag)
11512809Ssam 		printf("%s: quotas turned on\n", fs->fs_file);
11612809Ssam 	changemtab(fs, FSTAB_RQ);
11712809Ssam 	return (0);
11812809Ssam bad:
11912809Ssam 	fprintf(stderr, "setquota: ");
12012809Ssam 	perror(fs->fs_spec);
12112809Ssam 	return (1);
12212809Ssam }
12312809Ssam 
12412662Smckusick oneof(target, list, n)
12512662Smckusick 	char *target, *list[];
12612662Smckusick 	register int n;
12712662Smckusick {
12812662Smckusick 	register int i;
12912662Smckusick 
13012662Smckusick 	for (i = 0; i < n; i++)
13112723Smckusick 		if (strcmp(target, list[i]) == 0) {
13212723Smckusick 			done |= 1 << i;
13312662Smckusick 			return (1);
13412723Smckusick 		}
13512662Smckusick 	return (0);
13612662Smckusick }
13712809Ssam 
13812809Ssam changemtab(fs, type)
13912809Ssam 	register struct fstab *fs;
14012809Ssam 	char *type;
14112809Ssam {
14212809Ssam 	register struct mtab *mp;
14312809Ssam 	register char *cp;
14412809Ssam 
14512809Ssam 	cp = index(fs->fs_spec, '\0');
14612809Ssam 	while (*--cp == '/')
14712809Ssam 		*cp = '\0';
14812809Ssam 	cp = rindex(fs->fs_spec, '/');
14912809Ssam 	if (cp)
15012809Ssam 		cp++;
15112809Ssam 	else
15212809Ssam 		cp = fs->fs_spec;
15312809Ssam 	for (mp = mtab; mp < &mtab[NMOUNT]; mp++)
15412809Ssam 		if (strcmp(mp->m_dname, cp) == 0)
15512809Ssam 			goto replace;
15612809Ssam 	for (mp = mtab; mp < &mtab[NMOUNT]; mp++)
15712809Ssam 		if (mp->m_path[0] == '\0')
15812809Ssam 			goto replace;
15912809Ssam 	return;
16012809Ssam replace:
16112809Ssam 	strcpy(mp->m_type, type);
16212809Ssam 	mp = mtab + NMOUNT - 1;
16312809Ssam 	while (mp > mtab && mp->m_path[0] == '\0')
16412809Ssam 		--mp;
16512809Ssam 	mf = creat("/etc/mtab", 0644);
16612809Ssam 	(void) write(mf, (char *)mtab, (mp - mtab + 1) * sizeof (struct mtab));
16712809Ssam 	close(mf);
16812809Ssam }
16912809Ssam 
17012809Ssam /*
17112809Ssam  * Verify file system is mounted and not readonly.
17212809Ssam  */
17312809Ssam readonly(fs)
17412809Ssam 	register struct fstab *fs;
17512809Ssam {
17612809Ssam 	register struct mtab *mp;
17712809Ssam 	register char *cp;
17812809Ssam 
17912809Ssam 	cp = index(fs->fs_spec, '\0');
18012809Ssam 	while (*--cp == '/')
18112809Ssam 		*cp = '\0';
18212809Ssam 	cp = rindex(fs->fs_spec, '/');
18312809Ssam 	if (cp)
18412809Ssam 		cp++;
18512809Ssam 	else
18612809Ssam 		cp = fs->fs_spec;
18712809Ssam 	for (mp = mtab; mp < mtab + NMOUNT; mp++) {
18812809Ssam 		if (mp->m_path[0] == '\0')
18912809Ssam 			break;
19012809Ssam 		if (strcmp(cp, mp->m_dname) == 0) {
19112809Ssam 			if (strcmp(mp->m_type, FSTAB_RO) == 0) {
19212809Ssam 				printf("%s: mounted read-only\n", fs->fs_file);
19312809Ssam 				return (1);
19412809Ssam 			}
19512809Ssam 			return (0);
19612809Ssam 		}
19712809Ssam 	}
19812809Ssam 	printf("%s: not mounted\n", fs->fs_file);
19912809Ssam 	return (1);
20012809Ssam }
201