home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / World_Of_Computer_Software-02-385-Vol-1of3.iso / f / find37.zip / find-3.7 / find / fstype.c < prev    next >
C/C++ Source or Header  |  1992-04-18  |  6KB  |  309 lines

  1. /* fstype.c -- determine type of filesystems that files are on
  2.    Copyright (C) 1990, 1991 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. /* Written by David MacKenzie (djm@gnu.ai.mit.edu). */
  19.  
  20. #include <stdio.h>
  21. #include <sys/types.h>
  22. #include <sys/stat.h>
  23. #include "modetype.h"
  24. #include <errno.h>
  25. #ifndef STDC_HEADERS
  26. extern int errno;
  27. #endif
  28.  
  29. #if defined(USG) || defined(STDC_HEADERS)
  30. #include <string.h>
  31. #else
  32. #include <strings.h>
  33. #endif
  34.  
  35. char *strdup ();
  36. char *strstr ();
  37.  
  38. int xatoi ();
  39. char *xmalloc ();
  40. char *xstrdup ();
  41. void error ();
  42.  
  43. #ifdef FSTYPE_MNTENT        /* 4.3BSD, SunOS, HP-UX, Dynix, Irix.  */
  44. #include <mntent.h>
  45. #if !defined(MOUNTED)
  46. #  if defined(MNT_MNTTAB)    /* HP-UX.  */
  47. #    define MOUNTED MNT_MNTTAB
  48. #  endif
  49. #  if defined(MNTTABNAME)    /* Dynix.  */
  50. #    define MOUNTED MNTTABNAME
  51. #  endif
  52. #endif
  53. #endif
  54.  
  55. #ifdef FSTYPE_GETMNT        /* Ultrix.  */
  56. #include <sys/param.h>
  57. #include <sys/mount.h>
  58. #include <sys/fs_types.h>
  59. #endif
  60.  
  61. #ifdef FSTYPE_USG_STATFS    /* SVR3.  */
  62. #include <sys/statfs.h>
  63. #include <sys/fstyp.h>
  64. #endif
  65.  
  66. #ifdef FSTYPE_STATVFS        /* SVR4.  */
  67. #include <sys/statvfs.h>
  68. #include <sys/fstyp.h>
  69. #endif
  70.  
  71. #ifdef FSTYPE_STATFS        /* 4.4BSD.  */
  72. #include <sys/mount.h>
  73.  
  74. char *dirname ();
  75.  
  76. static char *
  77. fstype_to_string (t)
  78.      short t;
  79. {
  80.   switch (t)
  81.     {
  82.     case MOUNT_UFS:
  83.       return "ufs";
  84.     case MOUNT_NFS:
  85.       return "nfs";
  86.     case MOUNT_PC:
  87.       return "pc";
  88. #ifdef MOUNT_MFS
  89.     case MOUNT_MFS:
  90.       return "mfs";
  91. #endif
  92. #ifdef MOUNT_LO
  93.     case MOUNT_LO:
  94.       return "lo";
  95. #endif
  96. #ifdef MOUNT_TFS
  97.     case MOUNT_TFS:
  98.       return "tfs";
  99. #endif
  100. #ifdef MOUNT_TMP
  101.     case MOUNT_TMP:
  102.       return "tmp";
  103. #endif
  104.     default:
  105.       return "?";
  106.     }
  107. }
  108. #endif
  109.  
  110. #ifdef FSTYPE_AIX_STATFS    /* AIX.  */
  111. #include <sys/vmount.h>
  112. #include <sys/statfs.h>
  113.  
  114. #define FSTYPE_STATFS        /* Otherwise like 4.4BSD.  */
  115. #define f_type f_vfstype
  116.  
  117. char *dirname ();
  118.  
  119. static char *
  120. fstype_to_string (t)
  121.      short t;
  122. {
  123.   switch (t)
  124.     {
  125.     case MNT_AIX:
  126. #if 0                /* NFS filesystems are actually MNT_AIX. */
  127.       return "aix";
  128. #endif
  129.     case MNT_NFS:
  130.       return "nfs";
  131.     case MNT_JFS:
  132.       return "jfs";
  133.     case MNT_CDROM:
  134.       return "cdrom";
  135.     default:
  136.       return "?";
  137.     }
  138. }
  139. #endif
  140.  
  141. /* Return the type of filesystem that the file PATH, described by STATP,
  142.    is on in a newly allocated string.
  143.    Return "unknown" if its filesystem type is unknown.  */
  144.  
  145. char *
  146. filesystem_type (path, statp)
  147.      char *path;
  148.      struct stat *statp;
  149. {
  150.   char *type = NULL;
  151.  
  152. #ifdef FSTYPE_MNTENT        /* 4.3BSD, SunOS, HP-UX, Dynix, Irix.  */
  153.   char *table = MOUNTED;
  154.   FILE *mfp;
  155.   struct mntent *mnt;
  156.  
  157.   mfp = setmntent (table, "r");
  158.   if (mfp == NULL)
  159.     {
  160.       fflush (stdout);
  161.       error (1, errno, "%s", table);
  162.     }
  163.  
  164.   /* Find the entry with the same device number as STATP, and return
  165.      that entry's fstype. */
  166.   while (type == NULL && (mnt = getmntent (mfp)))
  167.     {
  168.       char *devopt;
  169.       dev_t dev;
  170.       struct stat disk_stats;
  171.  
  172. #ifdef MNTTYPE_IGNORE
  173.       if (!strcmp (mnt->mnt_type, MNTTYPE_IGNORE))
  174.     continue;
  175. #endif
  176.  
  177.       /* Newer systems like SunOS 4.1 keep the dev number in the mtab,
  178.      in the options string.     For older systems, we need to stat the
  179.      directory that the filesystem is mounted on to get it. */
  180.       devopt = strstr (mnt->mnt_opts, "dev=");
  181.       if (devopt)
  182.     {
  183.       if (devopt[4] == '0' && (devopt[5] == 'x' || devopt[5] == 'X'))
  184.         dev = xatoi (devopt + 6);
  185.       else
  186.         dev = xatoi (devopt + 4);
  187.     }
  188.       else
  189.     {
  190.       if (stat (mnt->mnt_dir, &disk_stats) == -1)
  191.         {
  192.           fflush (stdout);
  193.           error (1, errno, "error in %s: %s", table, mnt->mnt_dir);
  194.         }
  195.       dev = disk_stats.st_dev;
  196.     }
  197.  
  198.       if (dev == statp->st_dev)
  199.     type = mnt->mnt_type;
  200.     }
  201.  
  202.   if (endmntent (mfp) == 0)
  203.     {
  204.       fflush (stdout);
  205.       error (0, errno, "%s", table);
  206.     }
  207. #endif
  208.  
  209. #ifdef FSTYPE_GETMNT        /* Ultrix.  */
  210.   int offset = 0;
  211.   struct fs_data fsd;
  212.  
  213.   while (type == NULL
  214.      && getmnt (&offset, &fsd, sizeof (fsd), NOSTAT_MANY, 0) > 0)
  215.     {
  216.       if (fsd.fd_req.dev == statp->st_dev)
  217.     type = gt_names[fsd.fd_req.fstype];
  218.     }
  219. #endif
  220.  
  221. #ifdef FSTYPE_USG_STATFS    /* SVR3.  */
  222.   struct statfs fss;
  223.   char typebuf[FSTYPSZ];
  224.  
  225.   if (statfs (path, &fss, sizeof (struct statfs), 0) == -1)
  226.     {
  227.       /* Don't die if a file was just removed. */
  228.       if (errno != ENOENT)
  229.     {
  230.       fflush (stdout);
  231.       error (1, errno, "%s", path);
  232.     }
  233.     }
  234.   else if (!sysfs (GETFSTYP, fss.f_fstyp, typebuf))
  235.     type = typebuf;
  236. #endif
  237.  
  238. #ifdef FSTYPE_STATVFS        /* SVR4.  */
  239.   struct statvfs fss;
  240.  
  241.   if (statvfs (path, &fss) == -1)
  242.     {
  243.       /* Don't die if a file was just removed. */
  244.       if (errno != ENOENT)
  245.     {
  246.       fflush (stdout);
  247.       error (1, errno, "%s", path);
  248.     }
  249.     }
  250.   else
  251.     type = fss.f_basetype;
  252. #endif
  253.  
  254. #ifdef FSTYPE_STATFS        /* 4.4BSD.  */
  255.   struct statfs fss;
  256.   char *p;
  257.  
  258.   if (S_ISLNK (statp->st_mode))
  259.     p = dirname (path);
  260.   else
  261.     p = path;
  262.  
  263.   if (statfs (p, &fss) == -1)
  264.     {
  265.       /* Don't die if symlink to nonexisting file, or a file that was
  266.      just removed. */
  267.       if (errno != ENOENT)
  268.     {
  269.       fflush (stdout);
  270.       error (1, errno, "%s", path);
  271.     }
  272.     }
  273.   else
  274.     type = fstype_to_string (fss.f_type);
  275.   if (p != path)
  276.     free (p);
  277. #endif
  278.  
  279.   return xstrdup (type ? type : "unknown");
  280. }
  281.  
  282. #ifdef FSTYPE_MNTENT        /* 4.3BSD etc.  */
  283. /* Return the value of the hexadecimal number represented by CP.
  284.    No prefix (like '0x') or suffix (like 'h') is expected to be
  285.    part of CP. */
  286.  
  287. int
  288. xatoi (cp)
  289.      char *cp;
  290. {
  291.   int val;
  292.   
  293.   val = 0;
  294.   while (*cp)
  295.     {
  296.       if (*cp >= 'a' && *cp <= 'f')
  297.     val = val * 16 + *cp - 'a' + 10;
  298.       else if (*cp >= 'A' && *cp <= 'F')
  299.     val = val * 16 + *cp - 'A' + 10;
  300.       else if (*cp >= '0' && *cp <= '9')
  301.     val = val * 16 + *cp - '0';
  302.       else
  303.     break;
  304.       cp++;
  305.     }
  306.   return val;
  307. }
  308. #endif
  309.