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.4 (Berkeley) 06/18/88"; 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 37 struct mtab mtab[NMOUNT]; 38 39 int vflag; /* verbose */ 40 int aflag; /* all file systems */ 41 int done; 42 int mf; 43 44 char *qfname = "quotas"; 45 char quotafile[MAXPATHLEN + 1]; 46 char *index(), *rindex(); 47 48 main(argc, argv) 49 int argc; 50 char **argv; 51 { 52 register struct fstab *fs; 53 char *whoami, *rindex(); 54 int offmode = 0, errs = 0, i; 55 56 whoami = rindex(*argv, '/') + 1; 57 if (whoami == (char *)1) 58 whoami = *argv; 59 if (strcmp(whoami, "quotaoff") == 0) 60 offmode++; 61 else if (strcmp(whoami, "quotaon") != 0) { 62 fprintf(stderr, "Name must be quotaon or quotaoff not %s\n", 63 whoami); 64 exit(1); 65 } 66 again: 67 argc--, argv++; 68 if (argc > 0 && strcmp(*argv, "-v") == 0) { 69 vflag++; 70 goto again; 71 } 72 if (argc > 0 && strcmp(*argv, "-a") == 0) { 73 aflag++; 74 goto again; 75 } 76 if (argc <= 0 && !aflag) { 77 fprintf(stderr, "Usage:\n\t%s [-v] -a\n\t%s [-v] filesys ...\n", 78 whoami, whoami); 79 exit(1); 80 } 81 mf = open("/etc/mtab", O_RDONLY); 82 if (mf < 0) { 83 perror("/etc/mtab"); 84 exit(1); 85 } 86 (void) read(mf, (char *)mtab, sizeof (mtab)); 87 close(mf); 88 setfsent(); 89 while ((fs = getfsent()) != NULL) { 90 if (aflag && 91 (fs->fs_type == 0 || strcmp(fs->fs_type, "rq") != 0)) 92 continue; 93 if (!aflag && 94 !(oneof(fs->fs_file, argv, argc) || 95 oneof(fs->fs_spec, argv, argc))) 96 continue; 97 errs += quotaonoff(fs, offmode); 98 } 99 endfsent(); 100 for (i = 0; i < argc; i++) 101 if ((done & (1 << i)) == 0) 102 fprintf(stderr, "%s not found in /etc/fstab\n", 103 argv[i]); 104 exit(errs); 105 } 106 107 quotaonoff(fs, offmode) 108 register struct fstab *fs; 109 int offmode; 110 { 111 112 if (strcmp(fs->fs_file, "/") && readonly(fs)) 113 return (1); 114 if (offmode) { 115 if (setquota(fs->fs_spec, NULL) < 0) 116 goto bad; 117 if (vflag) 118 printf("%s: quotas turned off\n", fs->fs_file); 119 changemtab(fs, FSTAB_RW); 120 return (0); 121 } 122 (void) sprintf(quotafile, "%s/%s", fs->fs_file, qfname); 123 if (setquota(fs->fs_spec, quotafile) < 0) 124 goto bad; 125 if (vflag) 126 printf("%s: quotas turned on\n", fs->fs_file); 127 changemtab(fs, FSTAB_RQ); 128 return (0); 129 bad: 130 fprintf(stderr, "setquota: "); 131 perror(fs->fs_spec); 132 return (1); 133 } 134 135 oneof(target, list, n) 136 char *target, *list[]; 137 register int n; 138 { 139 register int i; 140 141 for (i = 0; i < n; i++) 142 if (strcmp(target, list[i]) == 0) { 143 done |= 1 << i; 144 return (1); 145 } 146 return (0); 147 } 148 149 changemtab(fs, type) 150 register struct fstab *fs; 151 char *type; 152 { 153 register struct mtab *mp; 154 register char *cp; 155 156 cp = index(fs->fs_spec, '\0'); 157 while (*--cp == '/') 158 *cp = '\0'; 159 cp = rindex(fs->fs_spec, '/'); 160 if (cp) 161 cp++; 162 else 163 cp = fs->fs_spec; 164 for (mp = mtab; mp < &mtab[NMOUNT]; mp++) 165 if (strcmp(mp->m_dname, cp) == 0) 166 goto replace; 167 for (mp = mtab; mp < &mtab[NMOUNT]; mp++) 168 if (mp->m_path[0] == '\0') 169 goto replace; 170 return; 171 replace: 172 strcpy(mp->m_type, type); 173 mp = mtab + NMOUNT - 1; 174 while (mp > mtab && mp->m_path[0] == '\0') 175 --mp; 176 mf = creat("/etc/mtab", 0644); 177 (void) write(mf, (char *)mtab, (mp - mtab + 1) * sizeof (struct mtab)); 178 close(mf); 179 } 180 181 /* 182 * Verify file system is mounted and not readonly. 183 */ 184 readonly(fs) 185 register struct fstab *fs; 186 { 187 register struct mtab *mp; 188 register char *cp; 189 190 cp = index(fs->fs_spec, '\0'); 191 while (*--cp == '/') 192 *cp = '\0'; 193 cp = rindex(fs->fs_spec, '/'); 194 if (cp) 195 cp++; 196 else 197 cp = fs->fs_spec; 198 for (mp = mtab; mp < mtab + NMOUNT; mp++) { 199 if (mp->m_path[0] == '\0') 200 continue; 201 if (strcmp(cp, mp->m_dname) == 0) { 202 if (strcmp(mp->m_type, FSTAB_RO) == 0) { 203 printf("%s: mounted read-only\n", fs->fs_file); 204 return (1); 205 } 206 return (0); 207 } 208 } 209 printf("%s: not mounted\n", fs->fs_file); 210 return (1); 211 } 212