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