install correct aliases file
[unix-history] / usr / src / usr.sbin / edquota / edquota.c
index 64e0652..f37fe82 100644 (file)
@@ -1,6 +1,29 @@
+/*
+ * Copyright (c) 1980 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms are permitted
+ * provided that the above copyright notice and this paragraph are
+ * duplicated in all such forms and that any documentation,
+ * advertising materials, and other materials related to such
+ * distribution and use acknowledge that the software was developed
+ * by the University of California, Berkeley.  The name of the
+ * University may not be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef lint
+char copyright[] =
+"@(#) Copyright (c) 1980 Regents of the University of California.\n\
+ All rights reserved.\n";
+#endif /* not lint */
+
 #ifndef lint
 #ifndef lint
-static char sccsid[] = "@(#)edquota.c  4.1 (Berkeley, from Melbourne) %G%";
-#endif
+static char sccsid[] = "@(#)edquota.c  5.6 (Berkeley) %G%";
+#endif /* not lint */
 
 /*
  * Disk quota editor.
 
 /*
  * Disk quota editor.
@@ -13,16 +36,11 @@ static char sccsid[] = "@(#)edquota.c       4.1 (Berkeley, from Melbourne) %G%";
 #include <fstab.h>
 
 #include <sys/param.h>
 #include <fstab.h>
 
 #include <sys/param.h>
-#define        QUOTA
-#include <sys/quota.h>
 #include <sys/stat.h>
 #include <sys/file.h>
 #include <sys/stat.h>
 #include <sys/file.h>
+#include <sys/quota.h>
 
 
-#ifdef MELBOURNE
-#define        DEFEDITOR       "/bin/ed"
-#else
 #define        DEFEDITOR       "/usr/ucb/vi"
 #define        DEFEDITOR       "/usr/ucb/vi"
-#endif
 
 struct dquot dq[NMOUNT];
 struct dquot odq[NMOUNT];
 
 struct dquot dq[NMOUNT];
 struct dquot odq[NMOUNT];
@@ -30,19 +48,21 @@ char        dqf[NMOUNT][MAXPATHLEN + 1];
 char   odqf[NMOUNT][MAXPATHLEN + 1];
 
 char   tmpfil[] = "/tmp/EdP.aXXXXX";
 char   odqf[NMOUNT][MAXPATHLEN + 1];
 
 char   tmpfil[] = "/tmp/EdP.aXXXXX";
-char   *arg0;
+char   *qfname = "quotas";
 char   *getenv();
 
 main(argc, argv)
        char **argv;
 {
 char   *getenv();
 
 main(argc, argv)
        char **argv;
 {
+       int uid;
+       char *arg0;
 
        mktemp(tmpfil);
        close(creat(tmpfil, 0600));
        chown(tmpfil, getuid(), getgid());
        arg0 = *argv++;
        if (argc < 2) {
 
        mktemp(tmpfil);
        close(creat(tmpfil, 0600));
        chown(tmpfil, getuid(), getgid());
        arg0 = *argv++;
        if (argc < 2) {
-               fprintf(stderr, "Usage: %s username ...\n", arg0);
+               fprintf(stderr, "Usage: %s [-p username] username ...\n", arg0);
                unlink(tmpfil);
                exit(1);
        }
                unlink(tmpfil);
                exit(1);
        }
@@ -52,41 +72,62 @@ main(argc, argv)
                unlink(tmpfil);
                exit(1);
        }
                unlink(tmpfil);
                exit(1);
        }
-       while (--argc >= 0)
-               doedit(*argv++);
+       if (argc > 2 && strcmp(*argv, "-p") == 0) {
+               argc--, argv++;
+               uid = getentry(*argv++);
+               if (uid < 0) {
+                       unlink(tmpfil);
+                       exit(1);
+               }
+               getprivs(uid);
+               argc--;
+               while (argc-- > 0) {
+                       uid = getentry(*argv++);
+                       if (uid < 0)
+                               continue;
+                       getdiscq(uid, odq, odqf);
+                       putprivs(uid);
+               }
+               unlink(tmpfil);
+               exit(0);
+       }
+       while (--argc >= 0) {
+               uid = getentry(*argv++);
+               if (uid < 0)
+                       continue;
+               getprivs(uid);
+               if (editit())
+                       putprivs(uid);
+       }
        unlink(tmpfil);
        exit(0);
 }
 
        unlink(tmpfil);
        exit(0);
 }
 
-doedit(name)
-       register char *name;
+getentry(name)
+       char *name;
 {
 {
-       register uid;
-       register struct passwd *pw;
+       struct passwd *pw;
+       int uid;
 
        if (alldigits(name))
                uid = atoi(name);
        else if (pw = getpwnam(name))
                uid = pw->pw_uid;
        else {
 
        if (alldigits(name))
                uid = atoi(name);
        else if (pw = getpwnam(name))
                uid = pw->pw_uid;
        else {
-               fprintf(stderr, "%s: no such user\n");
+               fprintf(stderr, "%s: no such user\n", name);
                sleep(1);
                sleep(1);
-               return;
+               return (-1);
        }
        }
-       getprivs(uid);
-       if (editit())
-               putprivs(uid);
+       return (uid);
 }
 
 editit()
 {
 }
 
 editit()
 {
-       register pid, xpid;
+       register int pid, xpid;
+       long omask;
        int stat;
 
        int stat;
 
-       sighold(SIGINT);
-       sighold(SIGQUIT);
-       sighold(SIGHUP);
-
+       omask = sigblock(sigmask(SIGINT)|sigmask(SIGQUIT)|sigmask(SIGHUP));
  top:
        if ((pid = fork()) < 0) {
                extern errno;
  top:
        if ((pid = fork()) < 0) {
                extern errno;
@@ -105,12 +146,9 @@ editit()
        if (pid == 0) {
                register char *ed;
 
        if (pid == 0) {
                register char *ed;
 
-               sigrelse(SIGINT);
-               sigrelse(SIGQUIT);
-               sigrelse(SIGHUP);
+               sigsetmask(omask);
                setgid(getgid());
                setuid(getuid());
                setgid(getgid());
                setuid(getuid());
-
                if ((ed = getenv("EDITOR")) == (char *)0)
                        ed = DEFEDITOR;
                execlp(ed, ed, tmpfil, 0);
                if ((ed = getenv("EDITOR")) == (char *)0)
                        ed = DEFEDITOR;
                execlp(ed, ed, tmpfil, 0);
@@ -120,9 +158,7 @@ editit()
        while ((xpid = wait(&stat)) >= 0)
                if (xpid == pid)
                        break;
        while ((xpid = wait(&stat)) >= 0)
                if (xpid == pid)
                        break;
-       sigrelse(SIGINT);
-       sigrelse(SIGQUIT);
-       sigrelse(SIGHUP);
+       sigsetmask(omask);
        return (!stat);
 }
 
        return (!stat);
 }
 
@@ -148,8 +184,8 @@ getprivs(uid)
                fprintf(fd,
 "fs %s blocks (soft = %d, hard = %d) inodes (soft = %d, hard = %d)\n"
                        , dqf[i]
                fprintf(fd,
 "fs %s blocks (soft = %d, hard = %d) inodes (soft = %d, hard = %d)\n"
                        , dqf[i]
-                       , dq[i].dq_bsoftlimit
-                       , dq[i].dq_bhardlimit
+                       , dbtob(dq[i].dq_bsoftlimit) / 1024
+                       , dbtob(dq[i].dq_bhardlimit) / 1024
                        , dq[i].dq_isoftlimit
                        , dq[i].dq_ihardlimit
                );
                        , dq[i].dq_isoftlimit
                        , dq[i].dq_ihardlimit
                );
@@ -195,8 +231,12 @@ putprivs(uid)
                        , &dq[i].dq_isoftlimit
                        , &dq[i].dq_ihardlimit
                );
                        , &dq[i].dq_isoftlimit
                        , &dq[i].dq_ihardlimit
                );
-               if (n != 4)
-                       break;
+               if (n != 4) {
+                       fprintf(stderr, "%s: bad format\n", cp);
+                       continue;
+               }
+               dq[i].dq_bsoftlimit = btodb(dq[i].dq_bsoftlimit * 1024);
+               dq[i].dq_bhardlimit = btodb(dq[i].dq_bhardlimit * 1024);
        }
        fclose(fd);
        n = i;
        }
        fclose(fd);
        n = i;
@@ -210,18 +250,6 @@ putprivs(uid)
                if (j >= NMOUNT)
                        continue;
                *odqf[j] = '\0';
                if (j >= NMOUNT)
                        continue;
                *odqf[j] = '\0';
-               if (dq[i].dq_isoftlimit == odq[j].dq_isoftlimit &&
-                   dq[i].dq_ihardlimit == odq[j].dq_ihardlimit &&
-                   dq[i].dq_bsoftlimit == odq[j].dq_bsoftlimit &&
-                   dq[i].dq_bhardlimit == odq[j].dq_bhardlimit) {
-                       for (j = i; j < 15; j++) {
-                               dq[j] = dq[j+1];
-                               strcpy(dqf[j], dqf[j+1]);
-                       }
-                       *dqf[j] = '\0';
-                       i--;
-                       continue;
-               }
                /*
                 * This isn't really good enough, it is quite likely
                 * to have changed while we have been away editing,
                /*
                 * This isn't really good enough, it is quite likely
                 * to have changed while we have been away editing,
@@ -300,37 +328,52 @@ getdiscq(uid, dq, dqf)
        register char (*dqf)[MAXPATHLEN + 1];
 {
        register struct fstab *fs;
        register char (*dqf)[MAXPATHLEN + 1];
 {
        register struct fstab *fs;
-       char qfname[MAXPATHLEN + 1];
+       char qfilename[MAXPATHLEN + 1];
+       struct stat statb;
+       struct dqblk dqblk;
+       dev_t fsdev;
+       int fd;
+       static int warned = 0;
+       extern int errno;
 
        setfsent();
        while (fs = getfsent()) {
 
        setfsent();
        while (fs = getfsent()) {
-               struct  stat statb;
-               struct  dqblk dqblk;
-               dev_t   fsdev;
-
                if (stat(fs->fs_spec, &statb) < 0)
                        continue;
                fsdev = statb.st_rdev;
                if (stat(fs->fs_spec, &statb) < 0)
                        continue;
                fsdev = statb.st_rdev;
-               if (fs->fs_quotafile == 0 || *fs->fs_quotafile == '\0')
-                       continue;
-               sprintf(qfname, "%s/%s", fs->fs_file, fs->fs_quotafile);
-               if (stat(qfname, &statb) < 0 || statb.st_dev != fsdev)
+               sprintf(qfilename, "%s/%s", fs->fs_file, qfname);
+               if (stat(qfilename, &statb) < 0 || statb.st_dev != fsdev)
                        continue;
                if (quota(Q_GETDLIM, uid, fsdev, &dqblk) != 0) {
                        continue;
                if (quota(Q_GETDLIM, uid, fsdev, &dqblk) != 0) {
-                       register fd = open(qfname, FRDONLY);
-
+                       if (errno == EINVAL && !warned) {
+                               warned++;
+                               fprintf(stderr, "Warning: %s\n",
+                                   "Quotas are not compiled into this kernel");
+                               sleep(3);
+                       }
+                       fd = open(qfilename, O_RDONLY);
                        if (fd < 0)
                                continue;
                        if (fd < 0)
                                continue;
-                       lseek(fd, (long)(uid * sizeof dqblk), FSEEK_ABSOLUTE);
-                       if (read(fd, &dqblk, sizeof dqblk) != sizeof (dqblk)) {
+                       lseek(fd, (long)(uid * sizeof dqblk), L_SET);
+                       switch (read(fd, &dqblk, sizeof dqblk)) {
+                       case 0:                 /* EOF */
+                               /*
+                                * Convert implicit 0 quota (EOF)
+                                * into an explicit one (zero'ed dqblk)
+                                */
+                               bzero((caddr_t)&dqblk, sizeof dqblk);
+                               break;
+
+                       case sizeof dqblk:      /* OK */
+                               break;
+
+                       default:                /* ERROR */
+                               fprintf(stderr, "edquota: read error in ");
+                               perror(qfilename);
                                close(fd);
                                continue;
                        }
                        close(fd);
                                close(fd);
                                continue;
                        }
                        close(fd);
-#ifdef notdef
-                       if (dqblk.dqb_isoftlimit == 0 && dqblk.dqb_bsoftlimit == 0)
-                               continue;
-#endif
                }
                dq->dq_dqb = dqblk;
                dq->dq_dev = fsdev;
                }
                dq->dq_dqb = dqblk;
                dq->dq_dev = fsdev;
@@ -353,10 +396,17 @@ putdiscq(uid, dq, dqf)
        cnt = 0;
        for (cnt = 0; ++cnt <= NMOUNT && **dqf; dq++, dqf++) {
                fs = getfsfile(*dqf);
        cnt = 0;
        for (cnt = 0; ++cnt <= NMOUNT && **dqf; dq++, dqf++) {
                fs = getfsfile(*dqf);
-               if (fs == NULL)
-                       goto nofile;
-               strcat(*dqf, fs->fs_quotafile);
-               if (stat(*dqf, &sb) >= 0 && (fd = open(*dqf, 1)) >= 0) {
+               if (fs == NULL) {
+                       fprintf(stderr, "%s: not in /etc/fstab\n", *dqf);
+                       continue;
+               }
+               strcat(*dqf, "/");
+               strcat(*dqf, qfname);
+               if (stat(*dqf, &sb) >= 0)
+                       quota(Q_SETDLIM, uid, sb.st_dev, &dq->dq_dqb);
+               if ((fd = open(*dqf, 1)) < 0) {
+                       perror(*dqf);
+               } else {
                        lseek(fd, (long)uid * (long)sizeof (struct dqblk), 0);
                        if (write(fd, &dq->dq_dqb, sizeof (struct dqblk)) !=
                            sizeof (struct dqblk)) {
                        lseek(fd, (long)uid * (long)sizeof (struct dqblk), 0);
                        if (write(fd, &dq->dq_dqb, sizeof (struct dqblk)) !=
                            sizeof (struct dqblk)) {
@@ -365,7 +415,5 @@ putdiscq(uid, dq, dqf)
                        }
                        close(fd);
                }
                        }
                        close(fd);
                }
-nofile:
-               quota(Q_SETDLIM, uid, sb.st_dev, &dq->dq_dqb);
        }
 }
        }
 }