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