xref: /csrg-svn/usr.sbin/quotaon/quotaon.c (revision 34365)
121518Smckusick /*
221518Smckusick  * Copyright (c) 1980 Regents of the University of California.
3*34365Sbostic  * All rights reserved.
4*34365Sbostic  *
5*34365Sbostic  * Redistribution and use in source and binary forms are permitted
6*34365Sbostic  * provided that this notice is preserved and that due credit is given
7*34365Sbostic  * to the University of California at Berkeley. The name of the University
8*34365Sbostic  * may not be used to endorse or promote products derived from this
9*34365Sbostic  * software without specific prior written permission. This software
10*34365Sbostic  * is provided ``as is'' without express or implied warranty.
1121518Smckusick  */
1221518Smckusick 
1312662Smckusick #ifndef lint
1421518Smckusick char copyright[] =
1521518Smckusick "@(#) Copyright (c) 1980 Regents of the University of California.\n\
1621518Smckusick  All rights reserved.\n";
17*34365Sbostic #endif /* not lint */
1812809Ssam 
1921518Smckusick #ifndef lint
20*34365Sbostic static char sccsid[] = "@(#)quotaon.c	5.3 (Berkeley) 05/20/88";
21*34365Sbostic #endif /* not lint */
2221518Smckusick 
2312662Smckusick /*
2412670Smckusick  * Turn quota on/off for a filesystem.
2512662Smckusick  */
2612662Smckusick #include <sys/param.h>
2712809Ssam #include <sys/file.h>
2812662Smckusick #include <stdio.h>
2912662Smckusick #include <fstab.h>
3012809Ssam #include <mtab.h>
3112662Smckusick 
3212809Ssam struct	mtab mtab[NMOUNT];
3312809Ssam 
3412662Smckusick int	vflag;		/* verbose */
3512662Smckusick int	aflag;		/* all file systems */
3612723Smckusick int	done;
3712809Ssam int	mf;
3812662Smckusick 
3912809Ssam char	*qfname = "quotas";
4012809Ssam char	quotafile[MAXPATHLEN + 1];
4112809Ssam char	*index(), *rindex();
4212670Smckusick 
4312662Smckusick main(argc, argv)
4412670Smckusick 	int argc;
4512662Smckusick 	char **argv;
4612662Smckusick {
4712662Smckusick 	register struct fstab *fs;
4812670Smckusick 	char *whoami, *rindex();
4912723Smckusick 	int offmode = 0, errs = 0, i;
5012662Smckusick 
5112670Smckusick 	whoami = rindex(*argv, '/') + 1;
5212670Smckusick 	if (whoami == (char *)1)
5312670Smckusick 		whoami = *argv;
5412670Smckusick 	if (strcmp(whoami, "quotaoff") == 0)
5512670Smckusick 		offmode++;
5612670Smckusick 	else if (strcmp(whoami, "quotaon") != 0) {
5712670Smckusick 		fprintf(stderr, "Name must be quotaon or quotaoff not %s\n",
5812670Smckusick 			whoami);
5912670Smckusick 		exit(1);
6012670Smckusick 	}
6112662Smckusick again:
6212662Smckusick 	argc--, argv++;
6312662Smckusick 	if (argc > 0 && strcmp(*argv, "-v") == 0) {
6412662Smckusick 		vflag++;
6512662Smckusick 		goto again;
6612662Smckusick 	}
6712662Smckusick 	if (argc > 0 && strcmp(*argv, "-a") == 0) {
6812662Smckusick 		aflag++;
6912662Smckusick 		goto again;
7012662Smckusick 	}
7112670Smckusick 	if (argc <= 0 && !aflag) {
7212670Smckusick 		fprintf(stderr, "Usage:\n\t%s [-v] -a\n\t%s [-v] filesys ...\n",
7312670Smckusick 			whoami, whoami);
7412662Smckusick 		exit(1);
7512662Smckusick 	}
7612809Ssam 	mf = open("/etc/mtab", O_RDONLY);
7712809Ssam 	if (mf < 0) {
7812809Ssam 		perror("/etc/mtab");
7912809Ssam 		exit(1);
8012809Ssam 	}
8112809Ssam 	(void) read(mf, (char *)mtab, sizeof (mtab));
8212809Ssam 	close(mf);
8312662Smckusick 	setfsent();
8412662Smckusick 	while ((fs = getfsent()) != NULL) {
8512723Smckusick 		if (aflag &&
8612723Smckusick 		    (fs->fs_type == 0 || strcmp(fs->fs_type, "rq") != 0))
8712662Smckusick 			continue;
8812723Smckusick 		if (!aflag &&
8912723Smckusick 		    !(oneof(fs->fs_file, argv, argc) ||
9012723Smckusick 		      oneof(fs->fs_spec, argv, argc)))
9112662Smckusick 			continue;
9212809Ssam 		errs += quotaonoff(fs, offmode);
9312662Smckusick 	}
9412662Smckusick 	endfsent();
9512723Smckusick 	for (i = 0; i < argc; i++)
9612723Smckusick 		if ((done & (1 << i)) == 0)
9712723Smckusick 			fprintf(stderr, "%s not found in /etc/fstab\n",
9812723Smckusick 				argv[i]);
9912670Smckusick 	exit(errs);
10012662Smckusick }
10112662Smckusick 
10212809Ssam quotaonoff(fs, offmode)
10312809Ssam 	register struct fstab *fs;
10412809Ssam 	int offmode;
10512809Ssam {
10612809Ssam 
10712809Ssam 	if (strcmp(fs->fs_file, "/") && readonly(fs))
10812809Ssam 		return (1);
10912809Ssam 	if (offmode) {
11012809Ssam 		if (setquota(fs->fs_spec, NULL) < 0)
11112809Ssam 			goto bad;
11212809Ssam 		if (vflag)
11312809Ssam 			printf("%s: quotas turned off\n", fs->fs_file);
11412809Ssam 		changemtab(fs, FSTAB_RW);
11512809Ssam 		return (0);
11612809Ssam 	}
11712809Ssam 	(void) sprintf(quotafile, "%s/%s", fs->fs_file, qfname);
11812809Ssam 	if (setquota(fs->fs_spec, quotafile) < 0)
11912809Ssam 		goto bad;
12012809Ssam 	if (vflag)
12112809Ssam 		printf("%s: quotas turned on\n", fs->fs_file);
12212809Ssam 	changemtab(fs, FSTAB_RQ);
12312809Ssam 	return (0);
12412809Ssam bad:
12512809Ssam 	fprintf(stderr, "setquota: ");
12612809Ssam 	perror(fs->fs_spec);
12712809Ssam 	return (1);
12812809Ssam }
12912809Ssam 
13012662Smckusick oneof(target, list, n)
13112662Smckusick 	char *target, *list[];
13212662Smckusick 	register int n;
13312662Smckusick {
13412662Smckusick 	register int i;
13512662Smckusick 
13612662Smckusick 	for (i = 0; i < n; i++)
13712723Smckusick 		if (strcmp(target, list[i]) == 0) {
13812723Smckusick 			done |= 1 << i;
13912662Smckusick 			return (1);
14012723Smckusick 		}
14112662Smckusick 	return (0);
14212662Smckusick }
14312809Ssam 
14412809Ssam changemtab(fs, type)
14512809Ssam 	register struct fstab *fs;
14612809Ssam 	char *type;
14712809Ssam {
14812809Ssam 	register struct mtab *mp;
14912809Ssam 	register char *cp;
15012809Ssam 
15112809Ssam 	cp = index(fs->fs_spec, '\0');
15212809Ssam 	while (*--cp == '/')
15312809Ssam 		*cp = '\0';
15412809Ssam 	cp = rindex(fs->fs_spec, '/');
15512809Ssam 	if (cp)
15612809Ssam 		cp++;
15712809Ssam 	else
15812809Ssam 		cp = fs->fs_spec;
15912809Ssam 	for (mp = mtab; mp < &mtab[NMOUNT]; mp++)
16012809Ssam 		if (strcmp(mp->m_dname, cp) == 0)
16112809Ssam 			goto replace;
16212809Ssam 	for (mp = mtab; mp < &mtab[NMOUNT]; mp++)
16312809Ssam 		if (mp->m_path[0] == '\0')
16412809Ssam 			goto replace;
16512809Ssam 	return;
16612809Ssam replace:
16712809Ssam 	strcpy(mp->m_type, type);
16812809Ssam 	mp = mtab + NMOUNT - 1;
16912809Ssam 	while (mp > mtab && mp->m_path[0] == '\0')
17012809Ssam 		--mp;
17112809Ssam 	mf = creat("/etc/mtab", 0644);
17212809Ssam 	(void) write(mf, (char *)mtab, (mp - mtab + 1) * sizeof (struct mtab));
17312809Ssam 	close(mf);
17412809Ssam }
17512809Ssam 
17612809Ssam /*
17712809Ssam  * Verify file system is mounted and not readonly.
17812809Ssam  */
17912809Ssam readonly(fs)
18012809Ssam 	register struct fstab *fs;
18112809Ssam {
18212809Ssam 	register struct mtab *mp;
18312809Ssam 	register char *cp;
18412809Ssam 
18512809Ssam 	cp = index(fs->fs_spec, '\0');
18612809Ssam 	while (*--cp == '/')
18712809Ssam 		*cp = '\0';
18812809Ssam 	cp = rindex(fs->fs_spec, '/');
18912809Ssam 	if (cp)
19012809Ssam 		cp++;
19112809Ssam 	else
19212809Ssam 		cp = fs->fs_spec;
19312809Ssam 	for (mp = mtab; mp < mtab + NMOUNT; mp++) {
19412809Ssam 		if (mp->m_path[0] == '\0')
19524218Smckusick 			continue;
19612809Ssam 		if (strcmp(cp, mp->m_dname) == 0) {
19712809Ssam 			if (strcmp(mp->m_type, FSTAB_RO) == 0) {
19812809Ssam 				printf("%s: mounted read-only\n", fs->fs_file);
19912809Ssam 				return (1);
20012809Ssam 			}
20112809Ssam 			return (0);
20212809Ssam 		}
20312809Ssam 	}
20412809Ssam 	printf("%s: not mounted\n", fs->fs_file);
20512809Ssam 	return (1);
20612809Ssam }
207