edquota.c (28431) | edquota.c (29529) |
---|---|
1/* 2 * Copyright (c) 1980, 1990, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * This code is derived from software contributed to Berkeley by 6 * Robert Elz at The University of Melbourne. 7 * 8 * Redistribution and use in source and binary forms, with or without --- 21 unchanged lines hidden (view full) --- 30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 34 * SUCH DAMAGE. 35 */ 36 37#ifndef lint | 1/* 2 * Copyright (c) 1980, 1990, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * This code is derived from software contributed to Berkeley by 6 * Robert Elz at The University of Melbourne. 7 * 8 * Redistribution and use in source and binary forms, with or without --- 21 unchanged lines hidden (view full) --- 30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 34 * SUCH DAMAGE. 35 */ 36 37#ifndef lint |
38static char copyright[] = | 38static const char copyright[] = |
39"@(#) Copyright (c) 1980, 1990, 1993\n\ 40 The Regents of the University of California. All rights reserved.\n"; 41#endif /* not lint */ 42 43#ifndef lint | 39"@(#) Copyright (c) 1980, 1990, 1993\n\ 40 The Regents of the University of California. All rights reserved.\n"; 41#endif /* not lint */ 42 43#ifndef lint |
44#if 0 |
|
44static char sccsid[] = "@(#)edquota.c 8.1 (Berkeley) 6/6/93"; | 45static char sccsid[] = "@(#)edquota.c 8.1 (Berkeley) 6/6/93"; |
46#endif 47static const char rcsid[] = 48 "$Id$"; |
|
45#endif /* not lint */ 46 47/* 48 * Disk quota editor. 49 */ 50#include <sys/param.h> 51#include <sys/stat.h> 52#include <sys/file.h> 53#include <sys/wait.h> 54#include <ufs/ufs/quota.h> | 49#endif /* not lint */ 50 51/* 52 * Disk quota editor. 53 */ 54#include <sys/param.h> 55#include <sys/stat.h> 56#include <sys/file.h> 57#include <sys/wait.h> 58#include <ufs/ufs/quota.h> |
59#include <ctype.h> 60#include <err.h> |
|
55#include <errno.h> 56#include <fstab.h> | 61#include <errno.h> 62#include <fstab.h> |
57#include <pwd.h> | |
58#include <grp.h> | 63#include <grp.h> |
59#include <ctype.h> | 64#include <pwd.h> 65#include <signal.h> |
60#include <stdio.h> | 66#include <stdio.h> |
67#include <stdlib.h> |
|
61#include <string.h> 62#include <unistd.h> 63#include "pathnames.h" 64 65char *qfname = QUOTAFILENAME; 66char *qfextension[] = INITQFNAMES; 67char *quotagroup = QUOTAGROUP; 68char tmpfil[] = _PATH_TMP; 69 70struct quotause { 71 struct quotause *next; 72 long flags; 73 struct dqblk dqblk; 74 char fsname[MAXPATHLEN + 1]; 75 char qfname[1]; /* actually longer */ | 68#include <string.h> 69#include <unistd.h> 70#include "pathnames.h" 71 72char *qfname = QUOTAFILENAME; 73char *qfextension[] = INITQFNAMES; 74char *quotagroup = QUOTAGROUP; 75char tmpfil[] = _PATH_TMP; 76 77struct quotause { 78 struct quotause *next; 79 long flags; 80 struct dqblk dqblk; 81 char fsname[MAXPATHLEN + 1]; 82 char qfname[1]; /* actually longer */ |
76} *getprivs(); | 83}; |
77#define FOUND 0x01 78 | 84#define FOUND 0x01 85 |
86int alldigits __P((char *s)); 87int cvtatos __P((time_t, char *, time_t *)); 88char *cvtstoa __P((time_t)); 89int editit __P((char *)); 90void freeprivs __P((struct quotause *)); 91int getentry __P((char *, int)); 92struct quotause *getprivs __P((long, int)); 93int hasquota __P((struct fstab *, int, char **)); 94void putprivs __P((long, int, struct quotause *)); 95int readprivs __P((struct quotause *, char *)); 96int readtimes __P((struct quotause *, char *)); 97static void usage __P((void)); 98int writetimes __P((struct quotause *, int, int)); 99int writeprivs __P((struct quotause *, int, char *, int)); 100 101int |
|
79main(argc, argv) 80 register char **argv; 81 int argc; 82{ 83 register struct quotause *qup, *protoprivs, *curprivs; | 102main(argc, argv) 103 register char **argv; 104 int argc; 105{ 106 register struct quotause *qup, *protoprivs, *curprivs; |
84 extern char *optarg; 85 extern int optind; | |
86 register long id, protoid; 87 register int quotatype, tmpfd; 88 register uid_t startuid, enduid; 89 char *protoname, *cp, ch; 90 int tflag = 0, pflag = 0; 91 char buf[30]; 92 93 if (argc < 2) 94 usage(); | 107 register long id, protoid; 108 register int quotatype, tmpfd; 109 register uid_t startuid, enduid; 110 char *protoname, *cp, ch; 111 int tflag = 0, pflag = 0; 112 char buf[30]; 113 114 if (argc < 2) 115 usage(); |
95 if (getuid()) { 96 fprintf(stderr, "edquota: permission denied\n"); 97 exit(1); 98 } | 116 if (getuid()) 117 errx(1, "permission denied"); |
99 quotatype = USRQUOTA; 100 while ((ch = getopt(argc, argv, "ugtp:")) != -1) { 101 switch(ch) { 102 case 'p': 103 protoname = optarg; 104 pflag++; 105 break; 106 case 'g': --- 20 unchanged lines hidden (view full) --- 127 qup->dqblk.dqb_itime = 0; 128 } 129 while (argc-- > 0) { 130 if (isdigit(*argv[0]) && 131 (cp = strchr(*argv, '-')) != NULL) { 132 *cp++ = '\0'; 133 startuid = atoi(*argv); 134 enduid = atoi(cp); | 118 quotatype = USRQUOTA; 119 while ((ch = getopt(argc, argv, "ugtp:")) != -1) { 120 switch(ch) { 121 case 'p': 122 protoname = optarg; 123 pflag++; 124 break; 125 case 'g': --- 20 unchanged lines hidden (view full) --- 146 qup->dqblk.dqb_itime = 0; 147 } 148 while (argc-- > 0) { 149 if (isdigit(*argv[0]) && 150 (cp = strchr(*argv, '-')) != NULL) { 151 *cp++ = '\0'; 152 startuid = atoi(*argv); 153 enduid = atoi(cp); |
135 if (enduid < startuid) { 136 fprintf(stderr, "edquota: ending uid (%d) must be >= starting uid (%d) when using uid ranges\n", | 154 if (enduid < startuid) 155 errx(1, 156 "ending uid (%d) must be >= starting uid (%d) when using uid ranges", |
137 enduid, startuid); | 157 enduid, startuid); |
138 exit(1); 139 } | |
140 for ( ; startuid <= enduid; startuid++) { 141 snprintf(buf, sizeof(buf), "%d", 142 startuid); 143 if ((id = getentry(buf, quotatype)) < 0) 144 continue; 145 putprivs(id, quotatype, protoprivs); 146 } 147 continue; --- 27 unchanged lines hidden (view full) --- 175 putprivs(id, quotatype, curprivs); 176 freeprivs(curprivs); 177 } 178 close(tmpfd); 179 unlink(tmpfil); 180 exit(0); 181} 182 | 158 for ( ; startuid <= enduid; startuid++) { 159 snprintf(buf, sizeof(buf), "%d", 160 startuid); 161 if ((id = getentry(buf, quotatype)) < 0) 162 continue; 163 putprivs(id, quotatype, protoprivs); 164 } 165 continue; --- 27 unchanged lines hidden (view full) --- 193 putprivs(id, quotatype, curprivs); 194 freeprivs(curprivs); 195 } 196 close(tmpfd); 197 unlink(tmpfil); 198 exit(0); 199} 200 |
201static void |
|
183usage() 184{ | 202usage() 203{ |
185 fprintf(stderr, "%s%s%s%s", 186 "Usage: edquota [-u] [-p username] username ...\n", 187 "\tedquota -g [-p groupname] groupname ...\n", 188 "\tedquota [-u] -t\n", "\tedquota -g -t\n"); | 204 fprintf(stderr, "%s\n%s\n%s\n%s\n", 205 "usage: edquota [-u] [-p username] username ...", 206 " edquota -g [-p groupname] groupname ...", 207 " edquota [-u] -t", 208 " edquota -g -t"); |
189 exit(1); 190} 191 192/* 193 * This routine converts a name for a particular quota type to 194 * an identifier. This routine must agree with the kernel routine 195 * getinoquota as to the interpretation of quota types. 196 */ | 209 exit(1); 210} 211 212/* 213 * This routine converts a name for a particular quota type to 214 * an identifier. This routine must agree with the kernel routine 215 * getinoquota as to the interpretation of quota types. 216 */ |
217int |
|
197getentry(name, quotatype) 198 char *name; 199 int quotatype; 200{ 201 struct passwd *pw; 202 struct group *gr; 203 204 if (alldigits(name)) 205 return (atoi(name)); 206 switch(quotatype) { 207 case USRQUOTA: | 218getentry(name, quotatype) 219 char *name; 220 int quotatype; 221{ 222 struct passwd *pw; 223 struct group *gr; 224 225 if (alldigits(name)) 226 return (atoi(name)); 227 switch(quotatype) { 228 case USRQUOTA: |
208 if (pw = getpwnam(name)) | 229 if ((pw = getpwnam(name))) |
209 return (pw->pw_uid); | 230 return (pw->pw_uid); |
210 fprintf(stderr, "%s: no such user\n", name); | 231 warnx("%s: no such user", name); |
211 break; 212 case GRPQUOTA: | 232 break; 233 case GRPQUOTA: |
213 if (gr = getgrnam(name)) | 234 if ((gr = getgrnam(name))) |
214 return (gr->gr_gid); | 235 return (gr->gr_gid); |
215 fprintf(stderr, "%s: no such group\n", name); | 236 warnx("%s: no such group", name); |
216 break; 217 default: | 237 break; 238 default: |
218 fprintf(stderr, "%d: unknown quota type\n", quotatype); | 239 warnx("%d: unknown quota type", quotatype); |
219 break; 220 } 221 sleep(1); 222 return (-1); 223} 224 225/* 226 * Collect the requested quota information. --- 4 unchanged lines hidden (view full) --- 231 int quotatype; 232{ 233 register struct fstab *fs; 234 register struct quotause *qup, *quptail; 235 struct quotause *quphead; 236 int qcmd, qupsize, fd; 237 char *qfpathname; 238 static int warned = 0; | 240 break; 241 } 242 sleep(1); 243 return (-1); 244} 245 246/* 247 * Collect the requested quota information. --- 4 unchanged lines hidden (view full) --- 252 int quotatype; 253{ 254 register struct fstab *fs; 255 register struct quotause *qup, *quptail; 256 struct quotause *quphead; 257 int qcmd, qupsize, fd; 258 char *qfpathname; 259 static int warned = 0; |
239 extern int errno; | |
240 241 setfsent(); 242 quphead = (struct quotause *)0; 243 qcmd = QCMD(Q_GETQUOTA, quotatype); | 260 261 setfsent(); 262 quphead = (struct quotause *)0; 263 qcmd = QCMD(Q_GETQUOTA, quotatype); |
244 while (fs = getfsent()) { | 264 while ((fs = getfsent())) { |
245 if (strcmp(fs->fs_vfstype, "ufs")) 246 continue; 247 if (!hasquota(fs, quotatype, &qfpathname)) 248 continue; 249 qupsize = sizeof(*qup) + strlen(qfpathname); | 265 if (strcmp(fs->fs_vfstype, "ufs")) 266 continue; 267 if (!hasquota(fs, quotatype, &qfpathname)) 268 continue; 269 qupsize = sizeof(*qup) + strlen(qfpathname); |
250 if ((qup = (struct quotause *)malloc(qupsize)) == NULL) { 251 fprintf(stderr, "edquota: out of memory\n"); 252 exit(2); 253 } | 270 if ((qup = (struct quotause *)malloc(qupsize)) == NULL) 271 errx(2, "out of memory"); |
254 if (quotactl(fs->fs_file, qcmd, id, &qup->dqblk) != 0) { 255 if (errno == EOPNOTSUPP && !warned) { 256 warned++; | 272 if (quotactl(fs->fs_file, qcmd, id, &qup->dqblk) != 0) { 273 if (errno == EOPNOTSUPP && !warned) { 274 warned++; |
257 fprintf(stderr, "Warning: %s\n", 258 "Quotas are not compiled into this kernel"); | 275 warnx("warning: quotas are not compiled into this kernel"); |
259 sleep(3); 260 } 261 if ((fd = open(qfpathname, O_RDONLY)) < 0) { 262 fd = open(qfpathname, O_RDWR|O_CREAT, 0640); 263 if (fd < 0 && errno != ENOENT) { | 276 sleep(3); 277 } 278 if ((fd = open(qfpathname, O_RDONLY)) < 0) { 279 fd = open(qfpathname, O_RDWR|O_CREAT, 0640); 280 if (fd < 0 && errno != ENOENT) { |
264 perror(qfpathname); | 281 warn("%s", qfpathname); |
265 free(qup); 266 continue; 267 } | 282 free(qup); 283 continue; 284 } |
268 fprintf(stderr, "Creating quota file %s\n", 269 qfpathname); | 285 warnx("creating quota file %s", qfpathname); |
270 sleep(3); 271 (void) fchown(fd, getuid(), 272 getentry(quotagroup, GRPQUOTA)); 273 (void) fchmod(fd, 0640); 274 } 275 lseek(fd, (long)(id * sizeof(struct dqblk)), L_SET); 276 switch (read(fd, &qup->dqblk, sizeof(struct dqblk))) { 277 case 0: /* EOF */ --- 4 unchanged lines hidden (view full) --- 282 bzero((caddr_t)&qup->dqblk, 283 sizeof(struct dqblk)); 284 break; 285 286 case sizeof(struct dqblk): /* OK */ 287 break; 288 289 default: /* ERROR */ | 286 sleep(3); 287 (void) fchown(fd, getuid(), 288 getentry(quotagroup, GRPQUOTA)); 289 (void) fchmod(fd, 0640); 290 } 291 lseek(fd, (long)(id * sizeof(struct dqblk)), L_SET); 292 switch (read(fd, &qup->dqblk, sizeof(struct dqblk))) { 293 case 0: /* EOF */ --- 4 unchanged lines hidden (view full) --- 298 bzero((caddr_t)&qup->dqblk, 299 sizeof(struct dqblk)); 300 break; 301 302 case sizeof(struct dqblk): /* OK */ 303 break; 304 305 default: /* ERROR */ |
290 fprintf(stderr, "edquota: read error in "); 291 perror(qfpathname); | 306 warn("read error in %s", qfpathname); |
292 close(fd); 293 free(qup); 294 continue; 295 } 296 close(fd); 297 } 298 strcpy(qup->qfname, qfpathname); 299 strcpy(qup->fsname, fs->fs_file); --- 6 unchanged lines hidden (view full) --- 306 } 307 endfsent(); 308 return (quphead); 309} 310 311/* 312 * Store the requested quota information. 313 */ | 307 close(fd); 308 free(qup); 309 continue; 310 } 311 close(fd); 312 } 313 strcpy(qup->qfname, qfpathname); 314 strcpy(qup->fsname, fs->fs_file); --- 6 unchanged lines hidden (view full) --- 321 } 322 endfsent(); 323 return (quphead); 324} 325 326/* 327 * Store the requested quota information. 328 */ |
329void |
|
314putprivs(id, quotatype, quplist) 315 long id; 316 int quotatype; 317 struct quotause *quplist; 318{ 319 register struct quotause *qup; 320 int qcmd, fd; 321 322 qcmd = QCMD(Q_SETQUOTA, quotatype); 323 for (qup = quplist; qup; qup = qup->next) { 324 if (quotactl(qup->fsname, qcmd, id, &qup->dqblk) == 0) 325 continue; 326 if ((fd = open(qup->qfname, O_WRONLY)) < 0) { | 330putprivs(id, quotatype, quplist) 331 long id; 332 int quotatype; 333 struct quotause *quplist; 334{ 335 register struct quotause *qup; 336 int qcmd, fd; 337 338 qcmd = QCMD(Q_SETQUOTA, quotatype); 339 for (qup = quplist; qup; qup = qup->next) { 340 if (quotactl(qup->fsname, qcmd, id, &qup->dqblk) == 0) 341 continue; 342 if ((fd = open(qup->qfname, O_WRONLY)) < 0) { |
327 perror(qup->qfname); | 343 warn("%s", qup->qfname); |
328 } else { 329 lseek(fd, (long)id * (long)sizeof (struct dqblk), 0); 330 if (write(fd, &qup->dqblk, sizeof (struct dqblk)) != 331 sizeof (struct dqblk)) { | 344 } else { 345 lseek(fd, (long)id * (long)sizeof (struct dqblk), 0); 346 if (write(fd, &qup->dqblk, sizeof (struct dqblk)) != 347 sizeof (struct dqblk)) { |
332 fprintf(stderr, "edquota: "); 333 perror(qup->qfname); | 348 warn("%s", qup->qfname); |
334 } 335 close(fd); 336 } 337 } 338} 339 340/* 341 * Take a list of priviledges and get it edited. 342 */ | 349 } 350 close(fd); 351 } 352 } 353} 354 355/* 356 * Take a list of priviledges and get it edited. 357 */ |
358int |
|
343editit(tmpfile) 344 char *tmpfile; 345{ 346 long omask; 347 int pid, stat; | 359editit(tmpfile) 360 char *tmpfile; 361{ 362 long omask; 363 int pid, stat; |
348 extern char *getenv(); | |
349 350 omask = sigblock(sigmask(SIGINT)|sigmask(SIGQUIT)|sigmask(SIGHUP)); 351 top: 352 if ((pid = fork()) < 0) { | 364 365 omask = sigblock(sigmask(SIGINT)|sigmask(SIGQUIT)|sigmask(SIGHUP)); 366 top: 367 if ((pid = fork()) < 0) { |
353 extern errno; | |
354 355 if (errno == EPROCLIM) { | 368 369 if (errno == EPROCLIM) { |
356 fprintf(stderr, "You have too many processes\n"); | 370 warnx("you have too many processes"); |
357 return(0); 358 } 359 if (errno == EAGAIN) { 360 sleep(1); 361 goto top; 362 } | 371 return(0); 372 } 373 if (errno == EAGAIN) { 374 sleep(1); 375 goto top; 376 } |
363 perror("fork"); | 377 warn("fork"); |
364 return (0); 365 } 366 if (pid == 0) { 367 register char *ed; 368 369 sigsetmask(omask); 370 setgid(getgid()); 371 setuid(getuid()); 372 if ((ed = getenv("EDITOR")) == (char *)0) 373 ed = _PATH_VI; 374 execlp(ed, ed, tmpfile, 0); | 378 return (0); 379 } 380 if (pid == 0) { 381 register char *ed; 382 383 sigsetmask(omask); 384 setgid(getgid()); 385 setuid(getuid()); 386 if ((ed = getenv("EDITOR")) == (char *)0) 387 ed = _PATH_VI; 388 execlp(ed, ed, tmpfile, 0); |
375 perror(ed); 376 exit(1); | 389 err(1, "%s", ed); |
377 } 378 waitpid(pid, &stat, 0); 379 sigsetmask(omask); 380 if (!WIFEXITED(stat) || WEXITSTATUS(stat) != 0) 381 return (0); 382 return (1); 383} 384 385/* 386 * Convert a quotause list to an ASCII file. 387 */ | 390 } 391 waitpid(pid, &stat, 0); 392 sigsetmask(omask); 393 if (!WIFEXITED(stat) || WEXITSTATUS(stat) != 0) 394 return (0); 395 return (1); 396} 397 398/* 399 * Convert a quotause list to an ASCII file. 400 */ |
401int |
|
388writeprivs(quplist, outfd, name, quotatype) 389 struct quotause *quplist; 390 int outfd; 391 char *name; 392 int quotatype; 393{ 394 register struct quotause *qup; 395 FILE *fd; 396 397 ftruncate(outfd, 0); 398 lseek(outfd, 0, L_SET); | 402writeprivs(quplist, outfd, name, quotatype) 403 struct quotause *quplist; 404 int outfd; 405 char *name; 406 int quotatype; 407{ 408 register struct quotause *qup; 409 FILE *fd; 410 411 ftruncate(outfd, 0); 412 lseek(outfd, 0, L_SET); |
399 if ((fd = fdopen(dup(outfd), "w")) == NULL) { 400 fprintf(stderr, "edquota: "); 401 perror(tmpfil); 402 exit(1); 403 } | 413 if ((fd = fdopen(dup(outfd), "w")) == NULL) 414 err(1, "%s", tmpfil); |
404 fprintf(fd, "Quotas for %s %s:\n", qfextension[quotatype], name); 405 for (qup = quplist; qup; qup = qup->next) { 406 fprintf(fd, "%s: %s %lu, limits (soft = %lu, hard = %lu)\n", 407 qup->fsname, "blocks in use:", 408 (unsigned long)(dbtob(qup->dqblk.dqb_curblocks) / 1024), 409 (unsigned long)(dbtob(qup->dqblk.dqb_bsoftlimit) / 1024), 410 (unsigned long)(dbtob(qup->dqblk.dqb_bhardlimit) / 1024)); 411 fprintf(fd, "%s %lu, limits (soft = %lu, hard = %lu)\n", 412 "\tinodes in use:", qup->dqblk.dqb_curinodes, 413 qup->dqblk.dqb_isoftlimit, qup->dqblk.dqb_ihardlimit); 414 } 415 fclose(fd); 416 return (1); 417} 418 419/* 420 * Merge changes to an ASCII file into a quotause list. 421 */ | 415 fprintf(fd, "Quotas for %s %s:\n", qfextension[quotatype], name); 416 for (qup = quplist; qup; qup = qup->next) { 417 fprintf(fd, "%s: %s %lu, limits (soft = %lu, hard = %lu)\n", 418 qup->fsname, "blocks in use:", 419 (unsigned long)(dbtob(qup->dqblk.dqb_curblocks) / 1024), 420 (unsigned long)(dbtob(qup->dqblk.dqb_bsoftlimit) / 1024), 421 (unsigned long)(dbtob(qup->dqblk.dqb_bhardlimit) / 1024)); 422 fprintf(fd, "%s %lu, limits (soft = %lu, hard = %lu)\n", 423 "\tinodes in use:", qup->dqblk.dqb_curinodes, 424 qup->dqblk.dqb_isoftlimit, qup->dqblk.dqb_ihardlimit); 425 } 426 fclose(fd); 427 return (1); 428} 429 430/* 431 * Merge changes to an ASCII file into a quotause list. 432 */ |
433int |
|
422readprivs(quplist, inname) 423 struct quotause *quplist; 424 char *inname; 425{ 426 register struct quotause *qup; 427 FILE *fd; 428 int cnt; 429 register char *cp; 430 struct dqblk dqblk; 431 char *fsp, line1[BUFSIZ], line2[BUFSIZ]; 432 433 fd = fopen(inname, "r"); 434 if (fd == NULL) { | 434readprivs(quplist, inname) 435 struct quotause *quplist; 436 char *inname; 437{ 438 register struct quotause *qup; 439 FILE *fd; 440 int cnt; 441 register char *cp; 442 struct dqblk dqblk; 443 char *fsp, line1[BUFSIZ], line2[BUFSIZ]; 444 445 fd = fopen(inname, "r"); 446 if (fd == NULL) { |
435 fprintf(stderr, "Can't re-read temp file!!\n"); | 447 warnx("can't re-read temp file!!"); |
436 return (0); 437 } 438 /* 439 * Discard title line, then read pairs of lines to process. 440 */ 441 (void) fgets(line1, sizeof (line1), fd); 442 while (fgets(line1, sizeof (line1), fd) != NULL && 443 fgets(line2, sizeof (line2), fd) != NULL) { 444 if ((fsp = strtok(line1, " \t:")) == NULL) { | 448 return (0); 449 } 450 /* 451 * Discard title line, then read pairs of lines to process. 452 */ 453 (void) fgets(line1, sizeof (line1), fd); 454 while (fgets(line1, sizeof (line1), fd) != NULL && 455 fgets(line2, sizeof (line2), fd) != NULL) { 456 if ((fsp = strtok(line1, " \t:")) == NULL) { |
445 fprintf(stderr, "%s: bad format\n", line1); | 457 warnx("%s: bad format", line1); |
446 return (0); 447 } 448 if ((cp = strtok((char *)0, "\n")) == NULL) { | 458 return (0); 459 } 460 if ((cp = strtok((char *)0, "\n")) == NULL) { |
449 fprintf(stderr, "%s: %s: bad format\n", fsp, 450 &fsp[strlen(fsp) + 1]); | 461 warnx("%s: %s: bad format", fsp, &fsp[strlen(fsp) + 1]); |
451 return (0); 452 } 453 cnt = sscanf(cp, 454 " blocks in use: %lu, limits (soft = %lu, hard = %lu)", 455 &dqblk.dqb_curblocks, &dqblk.dqb_bsoftlimit, 456 &dqblk.dqb_bhardlimit); 457 if (cnt != 3) { | 462 return (0); 463 } 464 cnt = sscanf(cp, 465 " blocks in use: %lu, limits (soft = %lu, hard = %lu)", 466 &dqblk.dqb_curblocks, &dqblk.dqb_bsoftlimit, 467 &dqblk.dqb_bhardlimit); 468 if (cnt != 3) { |
458 fprintf(stderr, "%s:%s: bad format\n", fsp, cp); | 469 warnx("%s:%s: bad format", fsp, cp); |
459 return (0); 460 } 461 dqblk.dqb_curblocks = btodb(dqblk.dqb_curblocks * 1024); 462 dqblk.dqb_bsoftlimit = btodb(dqblk.dqb_bsoftlimit * 1024); 463 dqblk.dqb_bhardlimit = btodb(dqblk.dqb_bhardlimit * 1024); 464 if ((cp = strtok(line2, "\n")) == NULL) { | 470 return (0); 471 } 472 dqblk.dqb_curblocks = btodb(dqblk.dqb_curblocks * 1024); 473 dqblk.dqb_bsoftlimit = btodb(dqblk.dqb_bsoftlimit * 1024); 474 dqblk.dqb_bhardlimit = btodb(dqblk.dqb_bhardlimit * 1024); 475 if ((cp = strtok(line2, "\n")) == NULL) { |
465 fprintf(stderr, "%s: %s: bad format\n", fsp, line2); | 476 warnx("%s: %s: bad format", fsp, line2); |
466 return (0); 467 } 468 cnt = sscanf(cp, 469 "\tinodes in use: %lu, limits (soft = %lu, hard = %lu)", 470 &dqblk.dqb_curinodes, &dqblk.dqb_isoftlimit, 471 &dqblk.dqb_ihardlimit); 472 if (cnt != 3) { | 477 return (0); 478 } 479 cnt = sscanf(cp, 480 "\tinodes in use: %lu, limits (soft = %lu, hard = %lu)", 481 &dqblk.dqb_curinodes, &dqblk.dqb_isoftlimit, 482 &dqblk.dqb_ihardlimit); 483 if (cnt != 3) { |
473 fprintf(stderr, "%s: %s: bad format\n", fsp, line2); | 484 warnx("%s: %s: bad format", fsp, line2); |
474 return (0); 475 } 476 for (qup = quplist; qup; qup = qup->next) { 477 if (strcmp(fsp, qup->fsname)) 478 continue; 479 /* 480 * Cause time limit to be reset when the quota 481 * is next used if previously had no soft limit --- 15 unchanged lines hidden (view full) --- 497 qup->dqblk.dqb_bsoftlimit = dqblk.dqb_bsoftlimit; 498 qup->dqblk.dqb_bhardlimit = dqblk.dqb_bhardlimit; 499 qup->dqblk.dqb_isoftlimit = dqblk.dqb_isoftlimit; 500 qup->dqblk.dqb_ihardlimit = dqblk.dqb_ihardlimit; 501 qup->flags |= FOUND; 502 if (dqblk.dqb_curblocks == qup->dqblk.dqb_curblocks && 503 dqblk.dqb_curinodes == qup->dqblk.dqb_curinodes) 504 break; | 485 return (0); 486 } 487 for (qup = quplist; qup; qup = qup->next) { 488 if (strcmp(fsp, qup->fsname)) 489 continue; 490 /* 491 * Cause time limit to be reset when the quota 492 * is next used if previously had no soft limit --- 15 unchanged lines hidden (view full) --- 508 qup->dqblk.dqb_bsoftlimit = dqblk.dqb_bsoftlimit; 509 qup->dqblk.dqb_bhardlimit = dqblk.dqb_bhardlimit; 510 qup->dqblk.dqb_isoftlimit = dqblk.dqb_isoftlimit; 511 qup->dqblk.dqb_ihardlimit = dqblk.dqb_ihardlimit; 512 qup->flags |= FOUND; 513 if (dqblk.dqb_curblocks == qup->dqblk.dqb_curblocks && 514 dqblk.dqb_curinodes == qup->dqblk.dqb_curinodes) 515 break; |
505 fprintf(stderr, 506 "%s: cannot change current allocation\n", fsp); | 516 warnx("%s: cannot change current allocation", fsp); |
507 break; 508 } 509 } 510 fclose(fd); 511 /* 512 * Disable quotas for any filesystems that have not been found. 513 */ 514 for (qup = quplist; qup; qup = qup->next) { --- 7 unchanged lines hidden (view full) --- 522 qup->dqblk.dqb_ihardlimit = 0; 523 } 524 return (1); 525} 526 527/* 528 * Convert a quotause list to an ASCII file of grace times. 529 */ | 517 break; 518 } 519 } 520 fclose(fd); 521 /* 522 * Disable quotas for any filesystems that have not been found. 523 */ 524 for (qup = quplist; qup; qup = qup->next) { --- 7 unchanged lines hidden (view full) --- 532 qup->dqblk.dqb_ihardlimit = 0; 533 } 534 return (1); 535} 536 537/* 538 * Convert a quotause list to an ASCII file of grace times. 539 */ |
540int |
|
530writetimes(quplist, outfd, quotatype) 531 struct quotause *quplist; 532 int outfd; 533 int quotatype; 534{ 535 register struct quotause *qup; | 541writetimes(quplist, outfd, quotatype) 542 struct quotause *quplist; 543 int outfd; 544 int quotatype; 545{ 546 register struct quotause *qup; |
536 char *cvtstoa(); | |
537 FILE *fd; 538 539 ftruncate(outfd, 0); 540 lseek(outfd, 0, L_SET); | 547 FILE *fd; 548 549 ftruncate(outfd, 0); 550 lseek(outfd, 0, L_SET); |
541 if ((fd = fdopen(dup(outfd), "w")) == NULL) { 542 fprintf(stderr, "edquota: "); 543 perror(tmpfil); 544 exit(1); 545 } | 551 if ((fd = fdopen(dup(outfd), "w")) == NULL) 552 err(1, "%s", tmpfil); |
546 fprintf(fd, "Time units may be: days, hours, minutes, or seconds\n"); 547 fprintf(fd, "Grace period before enforcing soft limits for %ss:\n", 548 qfextension[quotatype]); 549 for (qup = quplist; qup; qup = qup->next) { 550 fprintf(fd, "%s: block grace period: %s, ", 551 qup->fsname, cvtstoa(qup->dqblk.dqb_btime)); 552 fprintf(fd, "file grace period: %s\n", 553 cvtstoa(qup->dqblk.dqb_itime)); 554 } 555 fclose(fd); 556 return (1); 557} 558 559/* 560 * Merge changes of grace times in an ASCII file into a quotause list. 561 */ | 553 fprintf(fd, "Time units may be: days, hours, minutes, or seconds\n"); 554 fprintf(fd, "Grace period before enforcing soft limits for %ss:\n", 555 qfextension[quotatype]); 556 for (qup = quplist; qup; qup = qup->next) { 557 fprintf(fd, "%s: block grace period: %s, ", 558 qup->fsname, cvtstoa(qup->dqblk.dqb_btime)); 559 fprintf(fd, "file grace period: %s\n", 560 cvtstoa(qup->dqblk.dqb_itime)); 561 } 562 fclose(fd); 563 return (1); 564} 565 566/* 567 * Merge changes of grace times in an ASCII file into a quotause list. 568 */ |
569int |
|
562readtimes(quplist, inname) 563 struct quotause *quplist; 564 char *inname; 565{ 566 register struct quotause *qup; 567 FILE *fd; 568 int cnt; 569 register char *cp; 570 time_t itime, btime, iseconds, bseconds; 571 char *fsp, bunits[10], iunits[10], line1[BUFSIZ]; 572 573 fd = fopen(inname, "r"); 574 if (fd == NULL) { | 570readtimes(quplist, inname) 571 struct quotause *quplist; 572 char *inname; 573{ 574 register struct quotause *qup; 575 FILE *fd; 576 int cnt; 577 register char *cp; 578 time_t itime, btime, iseconds, bseconds; 579 char *fsp, bunits[10], iunits[10], line1[BUFSIZ]; 580 581 fd = fopen(inname, "r"); 582 if (fd == NULL) { |
575 fprintf(stderr, "Can't re-read temp file!!\n"); | 583 warnx("can't re-read temp file!!"); |
576 return (0); 577 } 578 /* 579 * Discard two title lines, then read lines to process. 580 */ 581 (void) fgets(line1, sizeof (line1), fd); 582 (void) fgets(line1, sizeof (line1), fd); 583 while (fgets(line1, sizeof (line1), fd) != NULL) { 584 if ((fsp = strtok(line1, " \t:")) == NULL) { | 584 return (0); 585 } 586 /* 587 * Discard two title lines, then read lines to process. 588 */ 589 (void) fgets(line1, sizeof (line1), fd); 590 (void) fgets(line1, sizeof (line1), fd); 591 while (fgets(line1, sizeof (line1), fd) != NULL) { 592 if ((fsp = strtok(line1, " \t:")) == NULL) { |
585 fprintf(stderr, "%s: bad format\n", line1); | 593 warnx("%s: bad format", line1); |
586 return (0); 587 } 588 if ((cp = strtok((char *)0, "\n")) == NULL) { | 594 return (0); 595 } 596 if ((cp = strtok((char *)0, "\n")) == NULL) { |
589 fprintf(stderr, "%s: %s: bad format\n", fsp, 590 &fsp[strlen(fsp) + 1]); | 597 warnx("%s: %s: bad format", fsp, &fsp[strlen(fsp) + 1]); |
591 return (0); 592 } 593 cnt = sscanf(cp, 594 " block grace period: %ld %s file grace period: %ld %s", 595 &btime, bunits, &itime, iunits); 596 if (cnt != 4) { | 598 return (0); 599 } 600 cnt = sscanf(cp, 601 " block grace period: %ld %s file grace period: %ld %s", 602 &btime, bunits, &itime, iunits); 603 if (cnt != 4) { |
597 fprintf(stderr, "%s:%s: bad format\n", fsp, cp); | 604 warnx("%s:%s: bad format", fsp, cp); |
598 return (0); 599 } 600 if (cvtatos(btime, bunits, &bseconds) == 0) 601 return (0); 602 if (cvtatos(itime, iunits, &iseconds) == 0) 603 return (0); 604 for (qup = quplist; qup; qup = qup->next) { 605 if (strcmp(fsp, qup->fsname)) --- 41 unchanged lines hidden (view full) --- 647 } else 648 sprintf(buf, "%ld second%s", time, time == 1 ? "" : "s"); 649 return (buf); 650} 651 652/* 653 * Convert ASCII input times to seconds. 654 */ | 605 return (0); 606 } 607 if (cvtatos(btime, bunits, &bseconds) == 0) 608 return (0); 609 if (cvtatos(itime, iunits, &iseconds) == 0) 610 return (0); 611 for (qup = quplist; qup; qup = qup->next) { 612 if (strcmp(fsp, qup->fsname)) --- 41 unchanged lines hidden (view full) --- 654 } else 655 sprintf(buf, "%ld second%s", time, time == 1 ? "" : "s"); 656 return (buf); 657} 658 659/* 660 * Convert ASCII input times to seconds. 661 */ |
662int |
|
655cvtatos(time, units, seconds) 656 time_t time; 657 char *units; 658 time_t *seconds; 659{ 660 661 if (bcmp(units, "second", 6) == 0) 662 *seconds = time; --- 9 unchanged lines hidden (view full) --- 672 return (0); 673 } 674 return (1); 675} 676 677/* 678 * Free a list of quotause structures. 679 */ | 663cvtatos(time, units, seconds) 664 time_t time; 665 char *units; 666 time_t *seconds; 667{ 668 669 if (bcmp(units, "second", 6) == 0) 670 *seconds = time; --- 9 unchanged lines hidden (view full) --- 680 return (0); 681 } 682 return (1); 683} 684 685/* 686 * Free a list of quotause structures. 687 */ |
688void |
|
680freeprivs(quplist) 681 struct quotause *quplist; 682{ 683 register struct quotause *qup, *nextqup; 684 685 for (qup = quplist; qup; qup = nextqup) { 686 nextqup = qup->next; 687 free(qup); 688 } 689} 690 691/* 692 * Check whether a string is completely composed of digits. 693 */ | 689freeprivs(quplist) 690 struct quotause *quplist; 691{ 692 register struct quotause *qup, *nextqup; 693 694 for (qup = quplist; qup; qup = nextqup) { 695 nextqup = qup->next; 696 free(qup); 697 } 698} 699 700/* 701 * Check whether a string is completely composed of digits. 702 */ |
703int |
|
694alldigits(s) 695 register char *s; 696{ 697 register c; 698 699 c = *s++; 700 do { 701 if (!isdigit(c)) 702 return (0); | 704alldigits(s) 705 register char *s; 706{ 707 register c; 708 709 c = *s++; 710 do { 711 if (!isdigit(c)) 712 return (0); |
703 } while (c = *s++); | 713 } while ((c = *s++)); |
704 return (1); 705} 706 707/* 708 * Check to see if a particular quota is to be enabled. 709 */ | 714 return (1); 715} 716 717/* 718 * Check to see if a particular quota is to be enabled. 719 */ |
720int |
|
710hasquota(fs, type, qfnamep) 711 register struct fstab *fs; 712 int type; 713 char **qfnamep; 714{ 715 register char *opt; | 721hasquota(fs, type, qfnamep) 722 register struct fstab *fs; 723 int type; 724 char **qfnamep; 725{ 726 register char *opt; |
716 char *cp, *index(), *strtok(); | 727 char *cp; |
717 static char initname, usrname[100], grpname[100]; 718 static char buf[BUFSIZ]; 719 720 if (!initname) { 721 sprintf(usrname, "%s%s", qfextension[USRQUOTA], qfname); 722 sprintf(grpname, "%s%s", qfextension[GRPQUOTA], qfname); 723 initname = 1; 724 } 725 strcpy(buf, fs->fs_mntops); 726 for (opt = strtok(buf, ","); opt; opt = strtok(NULL, ",")) { | 728 static char initname, usrname[100], grpname[100]; 729 static char buf[BUFSIZ]; 730 731 if (!initname) { 732 sprintf(usrname, "%s%s", qfextension[USRQUOTA], qfname); 733 sprintf(grpname, "%s%s", qfextension[GRPQUOTA], qfname); 734 initname = 1; 735 } 736 strcpy(buf, fs->fs_mntops); 737 for (opt = strtok(buf, ","); opt; opt = strtok(NULL, ",")) { |
727 if (cp = index(opt, '=')) | 738 if ((cp = index(opt, '='))) |
728 *cp++ = '\0'; 729 if (type == USRQUOTA && strcmp(opt, usrname) == 0) 730 break; 731 if (type == GRPQUOTA && strcmp(opt, grpname) == 0) 732 break; 733 } 734 if (!opt) 735 return (0); 736 if (cp) { 737 *qfnamep = cp; 738 return (1); 739 } 740 (void) sprintf(buf, "%s/%s.%s", fs->fs_file, qfname, qfextension[type]); 741 *qfnamep = buf; 742 return (1); 743} | 739 *cp++ = '\0'; 740 if (type == USRQUOTA && strcmp(opt, usrname) == 0) 741 break; 742 if (type == GRPQUOTA && strcmp(opt, grpname) == 0) 743 break; 744 } 745 if (!opt) 746 return (0); 747 if (cp) { 748 *qfnamep = cp; 749 return (1); 750 } 751 (void) sprintf(buf, "%s/%s.%s", fs->fs_file, qfname, qfextension[type]); 752 *qfnamep = buf; 753 return (1); 754} |