xref: /csrg-svn/usr.sbin/quotaon/quotaon.c (revision 37983)
121518Smckusick /*
221518Smckusick  * Copyright (c) 1980 Regents of the University of California.
334365Sbostic  * All rights reserved.
434365Sbostic  *
534365Sbostic  * Redistribution and use in source and binary forms are permitted
634778Sbostic  * provided that the above copyright notice and this paragraph are
734778Sbostic  * duplicated in all such forms and that any documentation,
834778Sbostic  * advertising materials, and other materials related to such
934778Sbostic  * distribution and use acknowledge that the software was developed
1034778Sbostic  * by the University of California, Berkeley.  The name of the
1134778Sbostic  * University may not be used to endorse or promote products derived
1234778Sbostic  * from this software without specific prior written permission.
1334778Sbostic  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
1434778Sbostic  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
1534778Sbostic  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
1621518Smckusick  */
1721518Smckusick 
1812662Smckusick #ifndef lint
1921518Smckusick char copyright[] =
2021518Smckusick "@(#) Copyright (c) 1980 Regents of the University of California.\n\
2121518Smckusick  All rights reserved.\n";
2234365Sbostic #endif /* not lint */
2312809Ssam 
2421518Smckusick #ifndef lint
25*37983Sbostic static char sccsid[] = "@(#)quotaon.c	5.5 (Berkeley) 05/11/89";
2634365Sbostic #endif /* not lint */
2721518Smckusick 
2812662Smckusick /*
2912670Smckusick  * Turn quota on/off for a filesystem.
3012662Smckusick  */
3112662Smckusick #include <sys/param.h>
3212809Ssam #include <sys/file.h>
3312662Smckusick #include <stdio.h>
3412662Smckusick #include <fstab.h>
3512809Ssam #include <mtab.h>
36*37983Sbostic #include "pathnames.h"
3712662Smckusick 
3812809Ssam struct	mtab mtab[NMOUNT];
3912809Ssam 
4012662Smckusick int	vflag;		/* verbose */
4112662Smckusick int	aflag;		/* all file systems */
4212723Smckusick int	done;
4312809Ssam int	mf;
4412662Smckusick 
4512809Ssam char	*qfname = "quotas";
4612809Ssam char	quotafile[MAXPATHLEN + 1];
4712809Ssam char	*index(), *rindex();
4812670Smckusick 
4912662Smckusick main(argc, argv)
5012670Smckusick 	int argc;
5112662Smckusick 	char **argv;
5212662Smckusick {
5312662Smckusick 	register struct fstab *fs;
5412670Smckusick 	char *whoami, *rindex();
5512723Smckusick 	int offmode = 0, errs = 0, i;
5612662Smckusick 
5712670Smckusick 	whoami = rindex(*argv, '/') + 1;
5812670Smckusick 	if (whoami == (char *)1)
5912670Smckusick 		whoami = *argv;
6012670Smckusick 	if (strcmp(whoami, "quotaoff") == 0)
6112670Smckusick 		offmode++;
6212670Smckusick 	else if (strcmp(whoami, "quotaon") != 0) {
6312670Smckusick 		fprintf(stderr, "Name must be quotaon or quotaoff not %s\n",
6412670Smckusick 			whoami);
6512670Smckusick 		exit(1);
6612670Smckusick 	}
6712662Smckusick again:
6812662Smckusick 	argc--, argv++;
6912662Smckusick 	if (argc > 0 && strcmp(*argv, "-v") == 0) {
7012662Smckusick 		vflag++;
7112662Smckusick 		goto again;
7212662Smckusick 	}
7312662Smckusick 	if (argc > 0 && strcmp(*argv, "-a") == 0) {
7412662Smckusick 		aflag++;
7512662Smckusick 		goto again;
7612662Smckusick 	}
7712670Smckusick 	if (argc <= 0 && !aflag) {
7812670Smckusick 		fprintf(stderr, "Usage:\n\t%s [-v] -a\n\t%s [-v] filesys ...\n",
7912670Smckusick 			whoami, whoami);
8012662Smckusick 		exit(1);
8112662Smckusick 	}
82*37983Sbostic 	mf = open(_PATH_MTAB, O_RDONLY);
8312809Ssam 	if (mf < 0) {
84*37983Sbostic 		perror(_PATH_MTAB);
8512809Ssam 		exit(1);
8612809Ssam 	}
8712809Ssam 	(void) read(mf, (char *)mtab, sizeof (mtab));
8812809Ssam 	close(mf);
8912662Smckusick 	setfsent();
9012662Smckusick 	while ((fs = getfsent()) != NULL) {
9112723Smckusick 		if (aflag &&
9212723Smckusick 		    (fs->fs_type == 0 || strcmp(fs->fs_type, "rq") != 0))
9312662Smckusick 			continue;
9412723Smckusick 		if (!aflag &&
9512723Smckusick 		    !(oneof(fs->fs_file, argv, argc) ||
9612723Smckusick 		      oneof(fs->fs_spec, argv, argc)))
9712662Smckusick 			continue;
9812809Ssam 		errs += quotaonoff(fs, offmode);
9912662Smckusick 	}
10012662Smckusick 	endfsent();
10112723Smckusick 	for (i = 0; i < argc; i++)
10212723Smckusick 		if ((done & (1 << i)) == 0)
103*37983Sbostic 			fprintf(stderr, "%s not found in fstab\n",
10412723Smckusick 				argv[i]);
10512670Smckusick 	exit(errs);
10612662Smckusick }
10712662Smckusick 
10812809Ssam quotaonoff(fs, offmode)
10912809Ssam 	register struct fstab *fs;
11012809Ssam 	int offmode;
11112809Ssam {
11212809Ssam 
11312809Ssam 	if (strcmp(fs->fs_file, "/") && readonly(fs))
11412809Ssam 		return (1);
11512809Ssam 	if (offmode) {
11612809Ssam 		if (setquota(fs->fs_spec, NULL) < 0)
11712809Ssam 			goto bad;
11812809Ssam 		if (vflag)
11912809Ssam 			printf("%s: quotas turned off\n", fs->fs_file);
12012809Ssam 		changemtab(fs, FSTAB_RW);
12112809Ssam 		return (0);
12212809Ssam 	}
12312809Ssam 	(void) sprintf(quotafile, "%s/%s", fs->fs_file, qfname);
12412809Ssam 	if (setquota(fs->fs_spec, quotafile) < 0)
12512809Ssam 		goto bad;
12612809Ssam 	if (vflag)
12712809Ssam 		printf("%s: quotas turned on\n", fs->fs_file);
12812809Ssam 	changemtab(fs, FSTAB_RQ);
12912809Ssam 	return (0);
13012809Ssam bad:
13112809Ssam 	fprintf(stderr, "setquota: ");
13212809Ssam 	perror(fs->fs_spec);
13312809Ssam 	return (1);
13412809Ssam }
13512809Ssam 
13612662Smckusick oneof(target, list, n)
13712662Smckusick 	char *target, *list[];
13812662Smckusick 	register int n;
13912662Smckusick {
14012662Smckusick 	register int i;
14112662Smckusick 
14212662Smckusick 	for (i = 0; i < n; i++)
14312723Smckusick 		if (strcmp(target, list[i]) == 0) {
14412723Smckusick 			done |= 1 << i;
14512662Smckusick 			return (1);
14612723Smckusick 		}
14712662Smckusick 	return (0);
14812662Smckusick }
14912809Ssam 
15012809Ssam changemtab(fs, type)
15112809Ssam 	register struct fstab *fs;
15212809Ssam 	char *type;
15312809Ssam {
15412809Ssam 	register struct mtab *mp;
15512809Ssam 	register char *cp;
15612809Ssam 
15712809Ssam 	cp = index(fs->fs_spec, '\0');
15812809Ssam 	while (*--cp == '/')
15912809Ssam 		*cp = '\0';
16012809Ssam 	cp = rindex(fs->fs_spec, '/');
16112809Ssam 	if (cp)
16212809Ssam 		cp++;
16312809Ssam 	else
16412809Ssam 		cp = fs->fs_spec;
16512809Ssam 	for (mp = mtab; mp < &mtab[NMOUNT]; mp++)
16612809Ssam 		if (strcmp(mp->m_dname, cp) == 0)
16712809Ssam 			goto replace;
16812809Ssam 	for (mp = mtab; mp < &mtab[NMOUNT]; mp++)
16912809Ssam 		if (mp->m_path[0] == '\0')
17012809Ssam 			goto replace;
17112809Ssam 	return;
17212809Ssam replace:
17312809Ssam 	strcpy(mp->m_type, type);
17412809Ssam 	mp = mtab + NMOUNT - 1;
17512809Ssam 	while (mp > mtab && mp->m_path[0] == '\0')
17612809Ssam 		--mp;
177*37983Sbostic 	mf = creat(_PATH_MTAB, 0644);
17812809Ssam 	(void) write(mf, (char *)mtab, (mp - mtab + 1) * sizeof (struct mtab));
17912809Ssam 	close(mf);
18012809Ssam }
18112809Ssam 
18212809Ssam /*
18312809Ssam  * Verify file system is mounted and not readonly.
18412809Ssam  */
18512809Ssam readonly(fs)
18612809Ssam 	register struct fstab *fs;
18712809Ssam {
18812809Ssam 	register struct mtab *mp;
18912809Ssam 	register char *cp;
19012809Ssam 
19112809Ssam 	cp = index(fs->fs_spec, '\0');
19212809Ssam 	while (*--cp == '/')
19312809Ssam 		*cp = '\0';
19412809Ssam 	cp = rindex(fs->fs_spec, '/');
19512809Ssam 	if (cp)
19612809Ssam 		cp++;
19712809Ssam 	else
19812809Ssam 		cp = fs->fs_spec;
19912809Ssam 	for (mp = mtab; mp < mtab + NMOUNT; mp++) {
20012809Ssam 		if (mp->m_path[0] == '\0')
20124218Smckusick 			continue;
20212809Ssam 		if (strcmp(cp, mp->m_dname) == 0) {
20312809Ssam 			if (strcmp(mp->m_type, FSTAB_RO) == 0) {
20412809Ssam 				printf("%s: mounted read-only\n", fs->fs_file);
20512809Ssam 				return (1);
20612809Ssam 			}
20712809Ssam 			return (0);
20812809Ssam 		}
20912809Ssam 	}
21012809Ssam 	printf("%s: not mounted\n", fs->fs_file);
21112809Ssam 	return (1);
21212809Ssam }
213