]> git.decadent.org.uk Git - nfs-utils.git/blobdiff - utils/mount/fstab.c
proper merge
[nfs-utils.git] / utils / mount / fstab.c
index ec7ab528bac720ffa251a728960d3f9552caddad..eedbddab87c63e3ea99c2a8507d7028c0d6cc2b5 100644 (file)
@@ -1,4 +1,4 @@
-/* 1999-02-22 Arkadiusz MiΒΆkiewicz <misiek@pld.ORG.PL>
+/* 1999-02-22 Arkadiusz Miskiewicz <misiek@pld.ORG.PL>
  * - added Native Language Support
  * Sun Mar 21 1999 - Arnaldo Carvalho de Melo <acme@conectiva.com.br>
  * - fixed strerr(errno) in gettext calls
@@ -46,6 +46,11 @@ get_mtab_info(void) {
        }
 }
 
+void
+reset_mtab_info(void) {
+        have_mtab_info = 0;
+}
+
 int
 mtab_does_not_exist(void) {
        get_mtab_info();
@@ -81,10 +86,13 @@ mtab_is_writable() {
 
 struct mntentchn mounttable;
 static int got_mtab = 0;
+struct mntentchn procmounts;
+static int got_procmounts = 0;
 struct mntentchn fstab;
 static int got_fstab = 0;
 
 static void read_mounttable(void);
+static void read_procmounts(void);
 static void read_fstab(void);
 
 static struct mntentchn *
@@ -95,6 +103,14 @@ mtab_head(void)
        return &mounttable;
 }
 
+static struct mntentchn *
+procmounts_head(void)
+{
+       if (!got_procmounts)
+               read_procmounts();
+       return &procmounts;
+}
+
 static struct mntentchn *
 fstab_head(void)
 {
@@ -181,6 +197,30 @@ read_mounttable() {
         read_mntentchn(mfp, fnam, mc);
 }
 
+/*
+ * Read /proc/mounts.
+ * This produces a linked list. The list head procmounts is a dummy.
+ * Return 0 on success.
+ */
+static void
+read_procmounts() {
+        mntFILE *mfp;
+        const char *fnam;
+        struct mntentchn *mc = &procmounts;
+
+        got_procmounts = 1;
+        mc->nxt = mc->prev = NULL;
+
+        fnam = PROC_MOUNTS;
+        mfp = nfs_setmntent(fnam, "r");
+        if (mfp == NULL || mfp->mntent_fp == NULL) {
+                nfs_error(_("warning: can't open %s: %s"),
+                          PROC_MOUNTS, strerror (errno));
+                return;
+        }
+        read_mntentchn(mfp, fnam, mc);
+}
+
 static void
 read_fstab()
 {
@@ -219,6 +259,23 @@ getmntdirbackward (const char *name, struct mntentchn *mcprev) {
        return NULL;
 }
 
+/*
+ * Given the directory name NAME, and the place MCPREV we found it last time,
+ * try to find more occurrences.
+ */
+struct mntentchn *
+getprocmntdirbackward (const char *name, struct mntentchn *mcprev) {
+       struct mntentchn *mc, *mc0;
+
+       mc0 = procmounts_head();
+       if (!mcprev)
+               mcprev = mc0;
+       for (mc = mcprev->prev; mc && mc != mc0; mc = mc->prev)
+               if (streq(mc->m.mnt_dir, name))
+                       return mc;
+       return NULL;
+}
+
 /*
  * Given the device name NAME, and the place MCPREV we found it last time,
  * try to find more occurrences.
@@ -280,7 +337,7 @@ handler (int sig) {
 }
 
 static void
-setlkw_timeout (int sig) {
+setlkw_timeout (__attribute__((unused)) int sig) {
      /* nothing, fcntl will fail anyway */
 }
 
@@ -326,16 +383,43 @@ lock_mtab (void) {
                int sig = 0;
                struct sigaction sa;
 
-               sa.sa_handler = handler;
                sa.sa_flags = 0;
                sigfillset (&sa.sa_mask);
   
-               while (sigismember (&sa.sa_mask, ++sig) != -1
-                      && sig != SIGCHLD) {
-                       if (sig == SIGALRM)
+               while (sigismember (&sa.sa_mask, ++sig) != -1) {
+                       switch(sig) {
+                       case SIGCHLD:
+                       case SIGKILL:
+                       case SIGCONT:
+                       case SIGSTOP:
+                               /* The cannot be caught, or should not,
+                                * so don't even try.
+                                */
+                               continue;
+                       case SIGALRM:
                                sa.sa_handler = setlkw_timeout;
-                       else
+                               break;
+                       case SIGHUP:
+                       case SIGINT:
+                       case SIGQUIT:
+                       case SIGWINCH:
+                       case SIGTSTP:
+                       case SIGTTIN:
+                       case SIGTTOU:
+                       case SIGPIPE:
+                       case SIGXFSZ:
+                       case SIGXCPU:
+                               /* non-priv user can cause these to be
+                                * generated, so ignore them.
+                                */
+                               sa.sa_handler = SIG_IGN;
+                               break;
+                       default:
+                               /* The rest should not be possible, so just
+                                * print a message and unlock mtab.
+                                */
                                sa.sa_handler = handler;
+                       }
                        sigaction (sig, &sa, (struct sigaction *) 0);
                }
                signals_have_been_setup = 1;
@@ -359,19 +443,22 @@ lock_mtab (void) {
        /* Repeat until it was us who made the link */
        while (!we_created_lockfile) {
                struct flock flock;
-               int errsv, j;
+               int j;
 
                j = link(linktargetfile, MOUNTED_LOCK);
-               errsv = errno;
 
-               if (j == 0)
-                       we_created_lockfile = 1;
+               {
+                       int errsv = errno;
 
-               if (j < 0 && errsv != EEXIST) {
-                       (void) unlink(linktargetfile);
-                       die (EX_FILEIO, _("can't link lock file %s: %s "
-                            "(use -n flag to override)"),
-                            MOUNTED_LOCK, strerror (errsv));
+                       if (j == 0)
+                               we_created_lockfile = 1;
+
+                       if (j < 0 && errsv != EEXIST) {
+                               (void) unlink(linktargetfile);
+                               die (EX_FILEIO, _("can't link lock file %s: %s "
+                                    "(use -n flag to override)"),
+                                    MOUNTED_LOCK, strerror (errsv));
+                       }
                }
 
                lockfile_fd = open (MOUNTED_LOCK, O_WRONLY);
@@ -409,7 +496,7 @@ lock_mtab (void) {
                        }
                        (void) unlink(linktargetfile);
                } else {
-                       static int tries = 0;
+                       static int retries = 0;
 
                        /* Someone else made the link. Wait. */
                        alarm(LOCK_TIMEOUT);
@@ -423,10 +510,10 @@ lock_mtab (void) {
                        alarm(0);
                        /* Limit the number of iterations - maybe there
                           still is some old /etc/mtab~ */
-                       ++tries;
-                       if (tries % 200 == 0)
+                       ++retries;
+                       if (retries % 200 == 0)
                           usleep(30);
-                       if (tries > 100000) {
+                       if (retries > 100000) {
                                (void) unlink(linktargetfile);
                                close(lockfile_fd);
                                die (EX_FILEIO, _("Cannot create link %s\n"
@@ -541,8 +628,12 @@ update_mtab (const char *dir, struct mntent *instead)
           * from the present mtab before renaming.
           */
            struct stat sbuf;
-           if (stat (MOUNTED, &sbuf) == 0)
-               chown (MOUNTED_TEMP, sbuf.st_uid, sbuf.st_gid);
+           if (stat (MOUNTED, &sbuf) == 0) {
+                       if (chown (MOUNTED_TEMP, sbuf.st_uid, sbuf.st_gid) < 0) {
+                               nfs_error(_("%s: error changing owner of %s: %s"),
+                                       progname, MOUNTED_TEMP, strerror (errno));
+                       }
+               }
        }
 
        /* rename mtemp to mtab */