1 /* 2 * Copyright (c) 1980 Regents of the University of California. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms are permitted 6 * provided that the above copyright notice and this paragraph are 7 * duplicated in all such forms and that any documentation, 8 * advertising materials, and other materials related to such 9 * distribution and use acknowledge that the software was developed 10 * by the University of California, Berkeley. The name of the 11 * University may not be used to endorse or promote products derived 12 * from this software without specific prior written permission. 13 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 14 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 15 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. 16 */ 17 18 #ifndef lint 19 char copyright[] = 20 "@(#) Copyright (c) 1980 Regents of the University of California.\n\ 21 All rights reserved.\n"; 22 #endif /* not lint */ 23 24 #ifndef lint 25 static char sccsid[] = "@(#)quotaon.c 5.5 (Berkeley) 05/11/89"; 26 #endif /* not lint */ 27 28 /* 29 * Turn quota on/off for a filesystem. 30 */ 31 #include <sys/param.h> 32 #include <sys/file.h> 33 #include <stdio.h> 34 #include <fstab.h> 35 #include <mtab.h> 36 #include "pathnames.h" 37 38 struct mtab mtab[NMOUNT]; 39 40 int vflag; /* verbose */ 41 int aflag; /* all file systems */ 42 int done; 43 int mf; 44 45 char *qfname = "quotas"; 46 char quotafile[MAXPATHLEN + 1]; 47 char *index(), *rindex(); 48 49 main(argc, argv) 50 int argc; 51 char **argv; 52 { 53 register struct fstab *fs; 54 char *whoami, *rindex(); 55 int offmode = 0, errs = 0, i; 56 57 whoami = rindex(*argv, '/') + 1; 58 if (whoami == (char *)1) 59 whoami = *argv; 60 if (strcmp(whoami, "quotaoff") == 0) 61 offmode++; 62 else if (strcmp(whoami, "quotaon") != 0) { 63 fprintf(stderr, "Name must be quotaon or quotaoff not %s\n", 64 whoami); 65 exit(1); 66 } 67 again: 68 argc--, argv++; 69 if (argc > 0 && strcmp(*argv, "-v") == 0) { 70 vflag++; 71 goto again; 72 } 73 if (argc > 0 && strcmp(*argv, "-a") == 0) { 74 aflag++; 75 goto again; 76 } 77 if (argc <= 0 && !aflag) { 78 fprintf(stderr, "Usage:\n\t%s [-v] -a\n\t%s [-v] filesys ...\n", 79 whoami, whoami); 80 exit(1); 81 } 82 mf = open(_PATH_MTAB, O_RDONLY); 83 if (mf < 0) { 84 perror(_PATH_MTAB); 85 exit(1); 86 } 87 (void) read(mf, (char *)mtab, sizeof (mtab)); 88 close(mf); 89 setfsent(); 90 while ((fs = getfsent()) != NULL) { 91 if (aflag && 92 (fs->fs_type == 0 || strcmp(fs->fs_type, "rq") != 0)) 93 continue; 94 if (!aflag && 95 !(oneof(fs->fs_file, argv, argc) || 96 oneof(fs->fs_spec, argv, argc))) 97 continue; 98 errs += quotaonoff(fs, offmode); 99 } 100 endfsent(); 101 for (i = 0; i < argc; i++) 102 if ((done & (1 << i)) == 0) 103 fprintf(stderr, "%s not found in fstab\n", 104 argv[i]); 105 exit(errs); 106 } 107 108 quotaonoff(fs, offmode) 109 register struct fstab *fs; 110 int offmode; 111 { 112 113 if (strcmp(fs->fs_file, "/") && readonly(fs)) 114 return (1); 115 if (offmode) { 116 if (setquota(fs->fs_spec, NULL) < 0) 117 goto bad; 118 if (vflag) 119 printf("%s: quotas turned off\n", fs->fs_file); 120 changemtab(fs, FSTAB_RW); 121 return (0); 122 } 123 (void) sprintf(quotafile, "%s/%s", fs->fs_file, qfname); 124 if (setquota(fs->fs_spec, quotafile) < 0) 125 goto bad; 126 if (vflag) 127 printf("%s: quotas turned on\n", fs->fs_file); 128 changemtab(fs, FSTAB_RQ); 129 return (0); 130 bad: 131 fprintf(stderr, "setquota: "); 132 perror(fs->fs_spec); 133 return (1); 134 } 135 136 oneof(target, list, n) 137 char *target, *list[]; 138 register int n; 139 { 140 register int i; 141 142 for (i = 0; i < n; i++) 143 if (strcmp(target, list[i]) == 0) { 144 done |= 1 << i; 145 return (1); 146 } 147 return (0); 148 } 149 150 changemtab(fs, type) 151 register struct fstab *fs; 152 char *type; 153 { 154 register struct mtab *mp; 155 register char *cp; 156 157 cp = index(fs->fs_spec, '\0'); 158 while (*--cp == '/') 159 *cp = '\0'; 160 cp = rindex(fs->fs_spec, '/'); 161 if (cp) 162 cp++; 163 else 164 cp = fs->fs_spec; 165 for (mp = mtab; mp < &mtab[NMOUNT]; mp++) 166 if (strcmp(mp->m_dname, cp) == 0) 167 goto replace; 168 for (mp = mtab; mp < &mtab[NMOUNT]; mp++) 169 if (mp->m_path[0] == '\0') 170 goto replace; 171 return; 172 replace: 173 strcpy(mp->m_type, type); 174 mp = mtab + NMOUNT - 1; 175 while (mp > mtab && mp->m_path[0] == '\0') 176 --mp; 177 mf = creat(_PATH_MTAB, 0644); 178 (void) write(mf, (char *)mtab, (mp - mtab + 1) * sizeof (struct mtab)); 179 close(mf); 180 } 181 182 /* 183 * Verify file system is mounted and not readonly. 184 */ 185 readonly(fs) 186 register struct fstab *fs; 187 { 188 register struct mtab *mp; 189 register char *cp; 190 191 cp = index(fs->fs_spec, '\0'); 192 while (*--cp == '/') 193 *cp = '\0'; 194 cp = rindex(fs->fs_spec, '/'); 195 if (cp) 196 cp++; 197 else 198 cp = fs->fs_spec; 199 for (mp = mtab; mp < mtab + NMOUNT; mp++) { 200 if (mp->m_path[0] == '\0') 201 continue; 202 if (strcmp(cp, mp->m_dname) == 0) { 203 if (strcmp(mp->m_type, FSTAB_RO) == 0) { 204 printf("%s: mounted read-only\n", fs->fs_file); 205 return (1); 206 } 207 return (0); 208 } 209 } 210 printf("%s: not mounted\n", fs->fs_file); 211 return (1); 212 } 213