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