home *** CD-ROM | disk | FTP | other *** search
/ Fresh Fish 8 / FreshFishVol8-CD1.bin / gnu / src / amiga / fileutils-3.12-src.lha / fileutils-3.12 / lib / mountlist.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-10-08  |  11.4 KB  |  484 lines

  1. /* mountlist.c -- return a list of mounted filesystems
  2.    Copyright (C) 1991, 1992 Free Software Foundation, Inc.
  3.  
  4.    This program is free software; you can redistribute it and/or modify
  5.    it under the terms of the GNU General Public License as published by
  6.    the Free Software Foundation; either version 2, or (at your option)
  7.    any later version.
  8.  
  9.    This program is distributed in the hope that it will be useful,
  10.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  11.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12.    GNU General Public License for more details.
  13.  
  14.    You should have received a copy of the GNU General Public License
  15.    along with this program; if not, write to the Free Software
  16.    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
  17.  
  18. #ifdef HAVE_CONFIG_H
  19. #include <config.h>
  20. #endif
  21.  
  22. #include <stdio.h>
  23. #include <sys/types.h>
  24. #include "mountlist.h"
  25.  
  26. #ifdef STDC_HEADERS
  27. #include <stdlib.h>
  28. #else
  29. void free ();
  30. #endif
  31. #if defined(STDC_HEADERS) || defined(HAVE_STRING_H)
  32. #include <string.h>
  33. #else
  34. #include <strings.h>
  35. #endif
  36.  
  37. char *strstr ();
  38. char *xmalloc ();
  39. char *xrealloc ();
  40. char *xstrdup ();
  41. void error ();
  42.  
  43. #ifdef HAVE_SYS_PARAM_H
  44. #include <sys/param.h>
  45. #endif
  46.  
  47. #if defined (MOUNTED_GETFSSTAT)    /* __alpha running OSF_1 */
  48. #  include <sys/mount.h>
  49. #  include <sys/fs_types.h>
  50. #endif /* MOUNTED_GETFSSTAT */
  51.  
  52. #ifdef MOUNTED_GETMNTENT1    /* 4.3BSD, SunOS, HP-UX, Dynix, Irix.  */
  53. #include <mntent.h>
  54. #if !defined(MOUNTED)
  55. #  if defined(MNT_MNTTAB)    /* HP-UX.  */
  56. #    define MOUNTED MNT_MNTTAB
  57. #  endif
  58. #  if defined(MNTTABNAME)    /* Dynix.  */
  59. #    define MOUNTED MNTTABNAME
  60. #  endif
  61. #endif
  62. #endif
  63.  
  64. #ifdef MOUNTED_GETMNTINFO    /* 4.4BSD.  */
  65. #include <sys/mount.h>
  66. #endif
  67.  
  68. #ifdef MOUNTED_GETMNT        /* Ultrix.  */
  69. #include <sys/mount.h>
  70. #include <sys/fs_types.h>
  71. #endif
  72.  
  73. #ifdef MOUNTED_FREAD        /* SVR2.  */
  74. #include <mnttab.h>
  75. #endif
  76.  
  77. #ifdef MOUNTED_FREAD_FSTYP    /* SVR3.  */
  78. #include <mnttab.h>
  79. #include <sys/fstyp.h>
  80. #include <sys/statfs.h>
  81. #endif
  82.  
  83. #ifdef MOUNTED_GETMNTENT2    /* SVR4.  */
  84. #include <sys/mnttab.h>
  85. #endif
  86.  
  87. #ifdef MOUNTED_VMOUNT        /* AIX.  */
  88. #include <fshelp.h>
  89. #include <sys/vfs.h>
  90. #endif
  91.  
  92. #ifdef DOLPHIN
  93. /* So special that it's not worth putting this in autoconf.  */
  94. #undef MOUNTED_FREAD_FSTYP
  95. #define MOUNTED_GETMNTTBL
  96. #endif
  97.  
  98. #ifdef MOUNTED_GETMNTENT1    /* 4.3BSD, SunOS, HP-UX, Dynix, Irix.  */
  99. /* Return the value of the hexadecimal number represented by CP.
  100.    No prefix (like '0x') or suffix (like 'h') is expected to be
  101.    part of CP. */
  102.  
  103. static int
  104. xatoi (cp)
  105.      char *cp;
  106. {
  107.   int val;
  108.  
  109.   val = 0;
  110.   while (*cp)
  111.     {
  112.       if (*cp >= 'a' && *cp <= 'f')
  113.     val = val * 16 + *cp - 'a' + 10;
  114.       else if (*cp >= 'A' && *cp <= 'F')
  115.     val = val * 16 + *cp - 'A' + 10;
  116.       else if (*cp >= '0' && *cp <= '9')
  117.     val = val * 16 + *cp - '0';
  118.       else
  119.     break;
  120.       cp++;
  121.     }
  122.   return val;
  123. }
  124. #endif /* MOUNTED_GETMNTENT1.  */
  125.  
  126. #if defined (MOUNTED_GETMNTINFO) && !defined (__NetBSD__)
  127. static char *
  128. fstype_to_string (t)
  129.      short t;
  130. {
  131.   switch (t)
  132.     {
  133.     case MOUNT_UFS:
  134.       return "ufs";
  135.     case MOUNT_NFS:
  136.       return "nfs";
  137. #ifdef MOUNT_PC
  138.     case MOUNT_PC:
  139.       return "pc";
  140. #endif
  141. #ifdef MOUNT_MFS
  142.     case MOUNT_MFS:
  143.       return "mfs";
  144. #endif
  145. #ifdef MOUNT_LO
  146.     case MOUNT_LO:
  147.       return "lo";
  148. #endif
  149. #ifdef MOUNT_TFS
  150.     case MOUNT_TFS:
  151.       return "tfs";
  152. #endif
  153. #ifdef MOUNT_TMP
  154.     case MOUNT_TMP:
  155.       return "tmp";
  156. #endif
  157.     default:
  158.       return "?";
  159.     }
  160. }
  161. #endif /* MOUNTED_GETMNTINFO */
  162.  
  163. #ifdef MOUNTED_VMOUNT        /* AIX.  */
  164. static char *
  165. fstype_to_string (t)
  166.      int t;
  167. {
  168.   struct vfs_ent *e;
  169.  
  170.   e = getvfsbytype (t);
  171.   if (!e || !e->vfsent_name)
  172.     return "none";
  173.   else
  174.     return e->vfsent_name;
  175. }
  176. #endif /* MOUNTED_VMOUNT */
  177.  
  178. /* Return a list of the currently mounted filesystems, or NULL on error.
  179.    Add each entry to the tail of the list so that they stay in order.
  180.    If NEED_FS_TYPE is nonzero, ensure that the filesystem type fields in
  181.    the returned list are valid.  Otherwise, they might not be.
  182.    If ALL_FS is zero, do not return entries for filesystems that
  183.    are automounter (dummy) entries.  */
  184.  
  185. struct mount_entry *
  186. read_filesystem_list (need_fs_type, all_fs)
  187.      int need_fs_type, all_fs;
  188. {
  189.   struct mount_entry *mount_list;
  190.   struct mount_entry *me;
  191.   struct mount_entry *mtail;
  192.  
  193.   /* Start the list off with a dummy entry. */
  194.   me = (struct mount_entry *) xmalloc (sizeof (struct mount_entry));
  195.   me->me_next = NULL;
  196.   mount_list = mtail = me;
  197.  
  198. #ifdef MOUNTED_GETMNTENT1    /* 4.3BSD, SunOS, HP-UX, Dynix, Irix.  */
  199.   {
  200.     struct mntent *mnt;
  201.     char *table = MOUNTED;
  202.     FILE *fp;
  203.     char *devopt;
  204.  
  205.     fp = setmntent (table, "r");
  206.     if (fp == NULL)
  207.       return NULL;
  208.  
  209.     while ((mnt = getmntent (fp)))
  210.       {
  211.     if (!all_fs && (!strcmp (mnt->mnt_type, "ignore")
  212.             || !strcmp (mnt->mnt_type, "auto")))
  213.       continue;
  214.  
  215.     me = (struct mount_entry *) xmalloc (sizeof (struct mount_entry));
  216.     me->me_devname = xstrdup (mnt->mnt_fsname);
  217.     me->me_mountdir = xstrdup (mnt->mnt_dir);
  218.     me->me_type = xstrdup (mnt->mnt_type);
  219.     devopt = strstr (mnt->mnt_opts, "dev=");
  220.     if (devopt)
  221.       {
  222.         if (devopt[4] == '0' && (devopt[5] == 'x' || devopt[5] == 'X'))
  223.           me->me_dev = xatoi (devopt + 6);
  224.         else
  225.           me->me_dev = xatoi (devopt + 4);
  226.       }
  227.     else
  228.       me->me_dev = -1;    /* Magic; means not known yet. */
  229.     me->me_next = NULL;
  230.  
  231.     /* Add to the linked list. */
  232.     mtail->me_next = me;
  233.     mtail = me;
  234.       }
  235.  
  236.     if (endmntent (fp) == 0)
  237.       return NULL;
  238.   }
  239. #endif /* MOUNTED_GETMNTENT1. */
  240.  
  241. #ifdef MOUNTED_GETMNTINFO    /* 4.4BSD.  */
  242.   {
  243.     struct statfs *fsp;
  244.     int entries;
  245.  
  246.     entries = getmntinfo (&fsp, MNT_NOWAIT);
  247.     if (entries < 0)
  248.       return NULL;
  249.     while (entries-- > 0)
  250.       {
  251.     me = (struct mount_entry *) xmalloc (sizeof (struct mount_entry));
  252.     me->me_devname = xstrdup (fsp->f_mntfromname);
  253.     me->me_mountdir = xstrdup (fsp->f_mntonname);
  254. #ifdef __NetBSD__
  255.     me->me_type = xstrdup (fsp->f_fstypename);
  256. #else
  257.     me->me_type = fstype_to_string (fsp->f_type);
  258. #endif
  259.     me->me_dev = -1;    /* Magic; means not known yet. */
  260.     me->me_next = NULL;
  261.  
  262.     /* Add to the linked list. */
  263.     mtail->me_next = me;
  264.     mtail = me;
  265.     fsp++;
  266.       }
  267.   }
  268. #endif /* MOUNTED_GETMNTINFO */
  269.  
  270. #ifdef MOUNTED_GETMNT        /* Ultrix.  */
  271.   {
  272.     int offset = 0;
  273.     int val;
  274.     struct fs_data fsd;
  275.  
  276.     while ((val = getmnt (&offset, &fsd, sizeof (fsd), NOSTAT_MANY,
  277.               (char *) 0)) > 0)
  278.       {
  279.     me = (struct mount_entry *) xmalloc (sizeof (struct mount_entry));
  280.     me->me_devname = xstrdup (fsd.fd_req.devname);
  281.     me->me_mountdir = xstrdup (fsd.fd_req.path);
  282.     me->me_type = gt_names[fsd.fd_req.fstype];
  283.     me->me_dev = fsd.fd_req.dev;
  284.     me->me_next = NULL;
  285.  
  286.     /* Add to the linked list. */
  287.     mtail->me_next = me;
  288.     mtail = me;
  289.       }
  290.     if (val < 0)
  291.       return NULL;
  292.   }
  293. #endif /* MOUNTED_GETMNT. */
  294.  
  295. #if defined (MOUNTED_GETFSSTAT)    /* __alpha running OSF_1 */
  296.   {
  297.     int numsys, counter, bufsize;
  298.     struct statfs *stats;
  299.  
  300.     numsys = getfsstat ((struct statfs *)0, 0L, MNT_WAIT);
  301.     if (numsys < 0)
  302.       return (NULL);
  303.  
  304.     bufsize = (1 + numsys) * sizeof (struct statfs);
  305.     stats = (struct statfs *)xmalloc (bufsize);
  306.     numsys = getfsstat (stats, bufsize, MNT_WAIT);
  307.  
  308.     if (numsys < 0)
  309.       {
  310.     free (stats);
  311.     return (NULL);
  312.       }
  313.  
  314.     for (counter = 0; counter < numsys; counter++)
  315.       {
  316.     me = (struct mount_entry *) xmalloc (sizeof (struct mount_entry));
  317.     me->me_devname = xstrdup (stats[counter].f_mntfromname);
  318.     me->me_mountdir = xstrdup (stats[counter].f_mntonname);
  319.     me->me_type = mnt_names[stats[counter].f_type];
  320.     me->me_dev = -1;    /* Magic; means not known yet. */
  321.     me->me_next = NULL;
  322.  
  323.     /* Add to the linked list. */
  324.     mtail->me_next = me;
  325.     mtail = me;
  326.       }
  327.  
  328.     free (stats);
  329.   }
  330. #endif /* MOUNTED_GETFSSTAT */
  331.  
  332. #if defined (MOUNTED_FREAD) || defined (MOUNTED_FREAD_FSTYP) /* SVR[23].  */
  333.   {
  334.     struct mnttab mnt;
  335.     char *table = "/etc/mnttab";
  336.     FILE *fp;
  337.  
  338.     fp = fopen (table, "r");
  339.     if (fp == NULL)
  340.       return NULL;
  341.  
  342.     while (fread (&mnt, sizeof mnt, 1, fp) > 0)
  343.       {
  344.     me = (struct mount_entry *) xmalloc (sizeof (struct mount_entry));
  345. #ifdef GETFSTYP            /* SVR3.  */
  346.     me->me_devname = xstrdup (mnt.mt_dev);
  347. #else
  348.     me->me_devname = xmalloc (strlen (mnt.mt_dev) + 6);
  349.     strcpy (me->me_devname, "/dev/");
  350.     strcpy (me->me_devname + 5, mnt.mt_dev);
  351. #endif
  352.     me->me_mountdir = xstrdup (mnt.mt_filsys);
  353.     me->me_dev = -1;    /* Magic; means not known yet. */
  354.     me->me_type = "";
  355. #ifdef GETFSTYP            /* SVR3.  */
  356.     if (need_fs_type)
  357.       {
  358.         struct statfs fsd;
  359.         char typebuf[FSTYPSZ];
  360.  
  361.         if (statfs (me->me_mountdir, &fsd, sizeof fsd, 0) != -1
  362.         && sysfs (GETFSTYP, fsd.f_fstyp, typebuf) != -1)
  363.           me->me_type = xstrdup (typebuf);
  364.       }
  365. #endif
  366.     me->me_next = NULL;
  367.  
  368.     /* Add to the linked list. */
  369.     mtail->me_next = me;
  370.     mtail = me;
  371.       }
  372.  
  373.     if (fclose (fp) == EOF)
  374.       return NULL;
  375.   }
  376. #endif /* MOUNTED_FREAD || MOUNTED_FREAD_FSTYP.  */
  377.  
  378. #ifdef MOUNTED_GETMNTTBL    /* DolphinOS goes it's own way */
  379.   {
  380.     struct mntent **mnttbl=getmnttbl(),**ent;
  381.     for (ent=mnttbl;*ent;ent++)
  382.       {
  383.     me = (struct mount_entry *) xmalloc (sizeof (struct mount_entry));
  384.     me->me_devname = xstrdup ( (*ent)->mt_resource);
  385.     me->me_mountdir = xstrdup( (*ent)->mt_directory);
  386.     me->me_type =  xstrdup ((*ent)->mt_fstype);
  387.     me->me_dev = -1;    /* Magic; means not known yet. */
  388.     me->me_next = NULL;
  389.  
  390.     /* Add to the linked list. */
  391.     mtail->me_next = me;
  392.     mtail = me;
  393.       }
  394.     endmnttbl();
  395.   }
  396. #endif
  397.  
  398. #ifdef MOUNTED_GETMNTENT2    /* SVR4.  */
  399.   {
  400.     struct mnttab mnt;
  401.     char *table = MNTTAB;
  402.     FILE *fp;
  403.     int ret;
  404.  
  405.     fp = fopen (table, "r");
  406.     if (fp == NULL)
  407.       return NULL;
  408.  
  409.     while ((ret = getmntent (fp, &mnt)) == 0)
  410.       {
  411.     me = (struct mount_entry *) xmalloc (sizeof (struct mount_entry));
  412.     me->me_devname = xstrdup (mnt.mnt_special);
  413.     me->me_mountdir = xstrdup (mnt.mnt_mountp);
  414.     me->me_type = xstrdup (mnt.mnt_fstype);
  415.     me->me_dev = -1;    /* Magic; means not known yet. */
  416.     me->me_next = NULL;
  417.  
  418.     /* Add to the linked list. */
  419.     mtail->me_next = me;
  420.     mtail = me;
  421.       }
  422.  
  423.     if (ret > 0)
  424.       return NULL;
  425.    if (fclose (fp) == EOF)
  426.       return NULL;
  427.   }
  428. #endif /* MOUNTED_GETMNTENT2.  */
  429.  
  430. #ifdef MOUNTED_VMOUNT        /* AIX.  */
  431.   {
  432.     int bufsize;
  433.     char *entries, *thisent;
  434.     struct vmount *vmp;
  435.  
  436.     /* Ask how many bytes to allocate for the mounted filesystem info.  */
  437.     mntctl (MCTL_QUERY, sizeof bufsize, (struct vmount *) &bufsize);
  438.     entries = xmalloc (bufsize);
  439.  
  440.     /* Get the list of mounted filesystems.  */
  441.     mntctl (MCTL_QUERY, bufsize, (struct vmount *) entries);
  442.  
  443.     for (thisent = entries; thisent < entries + bufsize;
  444.      thisent += vmp->vmt_length)
  445.       {
  446.     vmp = (struct vmount *) thisent;
  447.     me = (struct mount_entry *) xmalloc (sizeof (struct mount_entry));
  448.     if (vmp->vmt_flags & MNT_REMOTE)
  449.       {
  450.         char *host, *path;
  451.  
  452.         /* Prepend the remote pathname.  */
  453.         host = thisent + vmp->vmt_data[VMT_HOSTNAME].vmt_off;
  454.         path = thisent + vmp->vmt_data[VMT_OBJECT].vmt_off;
  455.         me->me_devname = xmalloc (strlen (host) + strlen (path) + 2);
  456.         strcpy (me->me_devname, host);
  457.         strcat (me->me_devname, ":");
  458.         strcat (me->me_devname, path);
  459.       }
  460.     else
  461.       {
  462.         me->me_devname = xstrdup (thisent +
  463.                       vmp->vmt_data[VMT_OBJECT].vmt_off);
  464.       }
  465.     me->me_mountdir = xstrdup (thisent + vmp->vmt_data[VMT_STUB].vmt_off);
  466.     me->me_type = xstrdup (fstype_to_string (vmp->vmt_gfstype));
  467.     me->me_dev = -1;    /* vmt_fsid might be the info we want.  */
  468.     me->me_next = NULL;
  469.  
  470.     /* Add to the linked list. */
  471.     mtail->me_next = me;
  472.     mtail = me;
  473.       }
  474.     free (entries);
  475.   }
  476. #endif /* MOUNTED_VMOUNT. */
  477.  
  478.   /* Free the dummy head. */
  479.   me = mount_list;
  480.   mount_list = mount_list->me_next;
  481.   free (me);
  482.   return mount_list;
  483. }
  484.