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