home *** CD-ROM | disk | FTP | other *** search
/ Chip 1995 March / CHIP3.mdf / slackwar / a / util / util-lin.2 / util-lin / util-linux-2.2 / mount / sundries.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-02-22  |  6.1 KB  |  284 lines

  1. /*
  2.  * Support functions.  Exported functions are prototyped in sundries.h.
  3.  * sundries.c,v 1.1.1.1 1993/11/18 08:40:51 jrs Exp
  4.  */
  5.  
  6. #include "sundries.h"
  7.  
  8. /* File pointer for /etc/mtab.  */
  9. FILE *F_mtab = NULL;
  10.  
  11. /* File pointer for temp mtab.  */
  12. FILE *F_temp = NULL;
  13.  
  14. /* File descriptor for lock.  Value tested in unlock_mtab() to remove race.  */
  15. static int lock = -1;
  16.  
  17. /* String list constructor.  (car() and cdr() are defined in "sundries.h").  */
  18. string_list
  19. cons (char *a, const string_list b)
  20. {
  21.   string_list p;
  22.  
  23.   p = xmalloc (sizeof *p);
  24.  
  25.   car (p) = a;
  26.   cdr (p) = b;
  27.   return p;
  28. }
  29.  
  30. void *
  31. xmalloc (size_t size)
  32. {
  33.   void *t;
  34.  
  35.   if (size == 0)
  36.     return NULL;
  37.  
  38.   t = malloc (size);
  39.   if (t == NULL)
  40.     die (2, "not enough memory");
  41.   
  42.   return t;
  43. }
  44.  
  45. char *
  46. xstrdup (const char *s)
  47. {
  48.   char *t;
  49.  
  50.   if (s == NULL)
  51.     return NULL;
  52.  
  53.   t = strdup (s);
  54.  
  55.   if (t == NULL)
  56.     die (2, "not enough memory");
  57.  
  58.   return t;
  59. }
  60.  
  61. /* Call this with SIG_BLOCK to block and SIG_UNBLOCK to unblock.  */
  62. void
  63. block_signals (int how)
  64. {
  65.   sigset_t sigs;
  66.  
  67.   sigfillset (&sigs);
  68.   sigprocmask (how, &sigs, (sigset_t *) 0);
  69. }
  70.  
  71.  
  72. /* Non-fatal error.  Print message and return.  */
  73. void
  74. error (const char *fmt, ...)
  75. {
  76.   va_list args;
  77.  
  78.   va_start (args, fmt);
  79.   vfprintf (stderr, fmt, args);
  80.   fprintf (stderr, "\n");
  81.   va_end (args);
  82. }
  83.  
  84. /* Fatal error.  Print message and exit.  */
  85. void
  86. die (int err, const char *fmt, ...)
  87. {
  88.   va_list args;
  89.  
  90.   va_start (args, fmt);
  91.   vfprintf (stderr, fmt, args);
  92.   fprintf (stderr, "\n");
  93.   va_end (args);
  94.  
  95.   unlock_mtab ();
  96.   exit (err);
  97. }
  98.  
  99. /* Ensure that the lock is released if we are interrupted.  */
  100. static void
  101. handler (int sig)
  102. {
  103.   die (2, "%s", sys_siglist[sig]);
  104. }
  105.  
  106. /* Create the lock file.  The lock file will be removed if we catch a signal
  107.    or when we exit.  The value of lock is tested to remove the race.  */
  108. void
  109. lock_mtab (void)
  110. {
  111.   int sig = 0;
  112.   struct sigaction sa;
  113.  
  114.   /* If this is the first time, ensure that the lock will be removed.  */
  115.   if (lock < 0)
  116.     {
  117.       sa.sa_handler = handler;
  118.       sa.sa_flags = 0;
  119.       sigfillset (&sa.sa_mask);
  120.   
  121.       while (sigismember (&sa.sa_mask, ++sig) != -1)
  122.     sigaction (sig, &sa, (struct sigaction *) 0);
  123.  
  124.       if ((lock = open (MOUNTED_LOCK, O_WRONLY|O_CREAT|O_EXCL, 0)) < 0)
  125.     die (2, "can't create lock file %s: %s",
  126.          MOUNTED_LOCK, strerror (errno));
  127.     }
  128. }
  129.  
  130. /* Remove lock file.  */
  131. void
  132. unlock_mtab (void)
  133. {
  134.   if (lock != -1)
  135.     {
  136.       close( lock );
  137.       unlink (MOUNTED_LOCK);
  138.     }
  139. }
  140.  
  141. /* Open mtab.  */
  142. void
  143. open_mtab (const char *mode)
  144. {
  145.   if ((F_mtab = setmntent (MOUNTED, mode)) == NULL)
  146.     die (2, "can't open %s: %s", MOUNTED, strerror (errno));
  147. }
  148.  
  149. /* Close mtab.  */
  150. void
  151. close_mtab (void)
  152. {
  153.   if (fchmod (fileno (F_mtab), S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH) < 0)
  154.     die (1, "mount: error changing mode of %s: %s", MOUNTED, strerror (errno));
  155.   endmntent (F_mtab);
  156. }
  157.  
  158. /* Update the mtab by removing any DIR entries and replace it with INSTEAD.  */
  159. void
  160. update_mtab (const char *dir, struct mntent *instead)
  161. {
  162.   struct mntent *mnt;
  163.   struct mntent *next;
  164.   int added = 0;
  165.  
  166.   open_mtab ("r");
  167.  
  168.   if ((F_temp = setmntent (MOUNTED_TEMP, "w")) == NULL)
  169.     die (2, "can't open %s: %s", MOUNTED_TEMP, strerror (errno));
  170.   
  171.   while ((mnt = getmntent (F_mtab)))
  172.     {
  173.       next = streq (mnt->mnt_dir, dir) ? (added++, instead) : mnt;
  174.       if (next && addmntent(F_temp, next) == 1)
  175.     die (1, "error writing %s: %s", MOUNTED_TEMP, strerror (errno));
  176.     }
  177.   if (instead && !added)
  178.     addmntent(F_temp, instead);
  179.  
  180.   endmntent (F_mtab);
  181.   if (fchmod (fileno (F_temp), S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH) < 0)
  182.     die (1, "error changing mode of %s: %s", MOUNTED_TEMP, strerror (errno));
  183.   endmntent (F_temp);
  184.  
  185.   if (rename (MOUNTED_TEMP, MOUNTED) < 0)
  186.     die (1, "can't rename %s to %s: %s",
  187.      MOUNTED_TEMP, MOUNTED, strerror(errno));
  188. }
  189.  
  190. /* Given the name FILE, try to find it in mtab.  */ 
  191. struct mntent *
  192. getmntfile (const char *file)
  193. {
  194.   struct mntent *mnt;
  195.  
  196.   if (!F_mtab)
  197.      return NULL;
  198.  
  199.   rewind(F_mtab);
  200.  
  201.   while ((mnt = getmntent (F_mtab)) != NULL)
  202.     {
  203.       if (streq (mnt->mnt_dir, file))
  204.     break;
  205.       if (streq (mnt->mnt_fsname, file))
  206.     break;
  207.     }
  208.  
  209.   return mnt;
  210. }
  211.  
  212. /* Parse a list of strings like str[,str]... into a string list.  */
  213. string_list
  214. parse_list (char *strings)
  215. {
  216.   string_list list;
  217.   char *t;
  218.  
  219.   if (strings == NULL)
  220.     return NULL;
  221.  
  222.   list = cons (strtok (strings, ","), NULL);
  223.  
  224.   while ((t = strtok (NULL, ",")) != NULL)
  225.     list = cons (t, list);
  226.  
  227.   return list;
  228. }
  229.  
  230. /* True if fstypes match.  Null *TYPES means match anything,
  231.    except that swap types always return false.  This routine
  232.    has some ugliness to deal with ``no'' types.  */
  233. int
  234. matching_type (const char *type, string_list types)
  235. {
  236.   char *notype;
  237.   int no;            /* true if a "no" type match, ie -t nominix */
  238.  
  239.   if (streq (type, MNTTYPE_SWAP))
  240.     return 0;
  241.   if (types == NULL)
  242.     return 1;
  243.  
  244.   if ((notype = alloca (strlen (type) + 3)) == NULL)
  245.     die (2, "mount: out of memory");
  246.   sprintf (notype, "no%s", type);
  247.   no = (car (types)[0] == 'n') && (car (types)[1] == 'o');
  248.  
  249.   /* If we get a match and the user specified a positive match type (e.g.
  250.      "minix") we return true.  If we match and a negative match type (e.g.
  251.      "nominix") was specified we return false.  */
  252.   while (types != NULL)
  253.     if (streq (type, car (types)))
  254.       return !no;
  255.     else if (streq (notype, car (types)))
  256.       return 0;            /* match with "nofoo" always returns false */
  257.     else
  258.       types = cdr (types);
  259.  
  260.   /* No matches, so if the user specified a positive match type return false,
  261.      if a negative match type was specified, return true.  */
  262.   return no;
  263. }
  264.  
  265. /* Make a canonical pathname from PATH.  Returns a freshly malloced string.
  266.    It is up the *caller* to ensure that the PATH is sensible.  i.e.
  267.    canonicalize ("/dev/fd0/.") returns "/dev/fd0" even though ``/dev/fd0/.''
  268.    is not a legal pathname for ``/dev/fd0.''  Anything we cannot parse
  269.    we return unmodified.   */
  270. char *
  271. canonicalize (const char *path)
  272. {
  273.   char *canonical = xmalloc (PATH_MAX + 1);
  274.   
  275.   if (path == NULL)
  276.     return NULL;
  277.   
  278.   if (realpath (path, canonical))
  279.     return canonical;
  280.  
  281.   strcpy (canonical, path);
  282.   return canonical;
  283. }
  284.