home *** CD-ROM | disk | FTP | other *** search
/ Fresh Fish 4 / FreshFish_May-June1994.bin / bbs / gnu / fileutils-3.9-src.lha / src / amiga / fileutils-3.9 / lib / mountlist.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-10-12  |  11.6 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. #if defined (CONFIG_BROKETS)
  20. /* We use <config.h> instead of "config.h" so that a compilation
  21.    using -I. -I$srcdir will use ./config.h rather than $srcdir/config.h
  22.    (which it would do because it found this file in $srcdir).  */
  23. #include <config.h>
  24. #else
  25. #include "config.h"
  26. #endif
  27. #endif
  28.  
  29. #include <stdio.h>
  30. #include <sys/types.h>
  31. #include "mountlist.h"
  32.  
  33. #ifdef STDC_HEADERS
  34. #include <stdlib.h>
  35. #else
  36. void free ();
  37. #endif
  38. #if defined(STDC_HEADERS) || defined(HAVE_STRING_H)
  39. #include <string.h>
  40. #else
  41. #include <strings.h>
  42. #endif
  43.  
  44. char *strstr ();
  45. char *xmalloc ();
  46. char *xrealloc ();
  47. char *xstrdup ();
  48. void error ();
  49.  
  50. #if defined (MOUNTED_GETFSSTAT)    /* __alpha running OSF_1 */
  51. #  include <sys/mount.h>
  52. #  include <sys/fs_types.h>
  53. #endif /* MOUNTED_GETFSSTAT */
  54.  
  55. #ifdef MOUNTED_GETMNTENT1    /* 4.3BSD, SunOS, HP-UX, Dynix, Irix.  */
  56. #include <mntent.h>
  57. #if !defined(MOUNTED)
  58. #  if defined(MNT_MNTTAB)    /* HP-UX.  */
  59. #    define MOUNTED MNT_MNTTAB
  60. #  endif
  61. #  if defined(MNTTABNAME)    /* Dynix.  */
  62. #    define MOUNTED MNTTABNAME
  63. #  endif
  64. #endif
  65. #endif
  66.  
  67. #ifdef MOUNTED_GETMNTINFO    /* 4.4BSD.  */
  68. #include <sys/mount.h>
  69. #endif
  70.  
  71. #ifdef MOUNTED_GETMNT        /* Ultrix.  */
  72. #include <sys/param.h>
  73. #include <sys/mount.h>
  74. #include <sys/fs_types.h>
  75. #endif
  76.  
  77. #ifdef MOUNTED_FREAD        /* SVR2.  */
  78. #include <mnttab.h>
  79. #endif
  80.  
  81. #ifdef MOUNTED_FREAD_FSTYP    /* SVR3.  */
  82. #include <mnttab.h>
  83. #include <sys/fstyp.h>
  84. #include <sys/statfs.h>
  85. #endif
  86.  
  87. #ifdef MOUNTED_GETMNTENT2    /* SVR4.  */
  88. #include <sys/mnttab.h>
  89. #endif
  90.  
  91. #ifdef MOUNTED_VMOUNT        /* AIX.  */
  92. #include <fshelp.h>
  93. #include <sys/vfs.h>
  94. #endif
  95.  
  96. #ifdef DOLPHIN
  97. /* So special that it's not worth putting this in autoconf.  */
  98. #undef MOUNTED_FREAD_FSTYP
  99. #define MOUNTED_GETMNTTBL
  100. #endif
  101.  
  102. #ifdef MOUNTED_GETMNTENT1    /* 4.3BSD, SunOS, HP-UX, Dynix, Irix.  */
  103. /* Return the value of the hexadecimal number represented by CP.
  104.    No prefix (like '0x') or suffix (like 'h') is expected to be
  105.    part of CP. */
  106.  
  107. static int
  108. xatoi (cp)
  109.      char *cp;
  110. {
  111.   int val;
  112.  
  113.   val = 0;
  114.   while (*cp)
  115.     {
  116.       if (*cp >= 'a' && *cp <= 'f')
  117.     val = val * 16 + *cp - 'a' + 10;
  118.       else if (*cp >= 'A' && *cp <= 'F')
  119.     val = val * 16 + *cp - 'A' + 10;
  120.       else if (*cp >= '0' && *cp <= '9')
  121.     val = val * 16 + *cp - '0';
  122.       else
  123.     break;
  124.       cp++;
  125.     }
  126.   return val;
  127. }
  128. #endif /* MOUNTED_GETMNTENT1.  */
  129.  
  130. #ifdef MOUNTED_GETMNTINFO    /* 4.4BSD.  */
  131. static char *
  132. fstype_to_string (t)
  133.      short t;
  134. {
  135.   switch (t)
  136.     {
  137.     case MOUNT_UFS:
  138.       return "ufs";
  139.     case MOUNT_NFS:
  140.       return "nfs";
  141. #ifdef MOUNT_PC
  142.     case MOUNT_PC:
  143.       return "pc";
  144. #endif
  145. #ifdef MOUNT_MFS
  146.     case MOUNT_MFS:
  147.       return "mfs";
  148. #endif
  149. #ifdef MOUNT_LO
  150.     case MOUNT_LO:
  151.       return "lo";
  152. #endif
  153. #ifdef MOUNT_TFS
  154.     case MOUNT_TFS:
  155.       return "tfs";
  156. #endif
  157. #ifdef MOUNT_TMP
  158.     case MOUNT_TMP:
  159.       return "tmp";
  160. #endif
  161.     default:
  162.       return "?";
  163.     }
  164. }
  165. #endif /* MOUNTED_GETMNTINFO */
  166.  
  167. #ifdef MOUNTED_VMOUNT        /* AIX.  */
  168. static char *
  169. fstype_to_string (t)
  170.      int t;
  171. {
  172.   struct vfs_ent *e;
  173.  
  174.   e = getvfsbytype (t);
  175.   if (!e || !e->vfsent_name)
  176.     return "none";
  177.   else
  178.     return e->vfsent_name;
  179. }
  180. #endif /* MOUNTED_VMOUNT */
  181.  
  182. /* Return a list of the currently mounted filesystems, or NULL on error.
  183.    Add each entry to the tail of the list so that they stay in order.
  184.    If NEED_FS_TYPE is nonzero, ensure that the filesystem type fields in
  185.    the returned list are valid.  Otherwise, they might not be.
  186.    If ALL_FS is zero, do not return entries for filesystems that
  187.    are automounter (dummy) entries.  */
  188.  
  189. struct mount_entry *
  190. read_filesystem_list (need_fs_type, all_fs)
  191.      int need_fs_type, all_fs;
  192. {
  193.   struct mount_entry *mount_list;
  194.   struct mount_entry *me;
  195.   struct mount_entry *mtail;
  196.  
  197.   /* Start the list off with a dummy entry. */
  198.   me = (struct mount_entry *) xmalloc (sizeof (struct mount_entry));
  199.   me->me_next = NULL;
  200.   mount_list = mtail = me;
  201.  
  202. #ifdef MOUNTED_GETMNTENT1    /* 4.3BSD, SunOS, HP-UX, Dynix, Irix.  */
  203.   {
  204.     struct mntent *mnt;
  205.     char *table = MOUNTED;
  206.     FILE *fp;
  207.     char *devopt;
  208.  
  209.     fp = setmntent (table, "r");
  210.     if (fp == NULL)
  211.       return NULL;
  212.  
  213.     while ((mnt = getmntent (fp)))
  214.       {
  215.     if (!all_fs && (!strcmp (mnt->mnt_type, "ignore")
  216.             || !strcmp (mnt->mnt_type, "auto")))
  217.       continue;
  218.  
  219.     me = (struct mount_entry *) xmalloc (sizeof (struct mount_entry));
  220.     me->me_devname = xstrdup (mnt->mnt_fsname);
  221.     me->me_mountdir = xstrdup (mnt->mnt_dir);
  222.     me->me_type = xstrdup (mnt->mnt_type);
  223.     devopt = strstr (mnt->mnt_opts, "dev=");
  224.     if (devopt)
  225.       {
  226.         if (devopt[4] == '0' && (devopt[5] == 'x' || devopt[5] == 'X'))
  227.           me->me_dev = xatoi (devopt + 6);
  228.         else
  229.           me->me_dev = xatoi (devopt + 4);
  230.       }
  231.     else
  232.       me->me_dev = -1;    /* Magic; means not known yet. */
  233.     me->me_next = NULL;
  234.  
  235.     /* Add to the linked list. */
  236.     mtail->me_next = me;
  237.     mtail = me;
  238.       }
  239.  
  240.     if (endmntent (fp) == 0)
  241.       return NULL;
  242.   }
  243. #endif /* MOUNTED_GETMNTENT1. */
  244.  
  245. #ifdef MOUNTED_GETMNTINFO    /* 4.4BSD.  */
  246.   {
  247.     struct statfs *fsp;
  248.     int entries;
  249.  
  250.     entries = getmntinfo (&fsp, MNT_NOWAIT);
  251.     if (entries < 0)
  252.       return NULL;
  253.     while (entries-- > 0)
  254.       {
  255.     me = (struct mount_entry *) xmalloc (sizeof (struct mount_entry));
  256.     me->me_devname = xstrdup (fsp->f_mntfromname);
  257.     me->me_mountdir = xstrdup (fsp->f_mntonname);
  258.     me->me_type = fstype_to_string (fsp->f_type);
  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.