home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / World_Of_Computer_Software-02-387-Vol-3of3.iso / s / slurp103.zip / SPACE.C < prev    next >
C/C++ Source or Header  |  1992-12-20  |  7KB  |  289 lines

  1. /*
  2.  * The following is a mish-mosh of code submitted to the net
  3.  * by Stan Barber <sob@bcm.tmc.edu>, Tad Guy <tadguy@cs.odu.edu>,
  4.  * Chris Jepeway <jepeway@utkcs2.cs.utk.edu>, and Tom Lane <tgl@cs.cmu.edu>.
  5.  * Modified for use in slurp by Stephen Hebditch <steveh@orbital.demon.co.uk>.
  6.  */
  7.  
  8. #include "slurp.h"
  9.  
  10. #ifdef MINFREE
  11.  
  12. #include <sys/types.h>
  13. #include <sys/stat.h>
  14.  
  15. #ifdef BSD_42
  16.   #ifndef sun
  17.     #ifndef ultrix
  18.       #ifndef CMU_MACH
  19.         #ifndef NeXT
  20.           #ifndef READ_SUPER
  21.             #define READ_SUPER
  22.           #endif
  23.         #endif
  24.       #endif
  25.     #endif
  26.   #endif
  27. #endif
  28.  
  29. #ifdef BSD_43
  30.   #ifndef sun
  31.     #ifndef ultrix
  32.       #ifndef READ_SUPER
  33.         #define READ_SUPER
  34.       #endif
  35.     #endif
  36.   #endif
  37. #endif
  38.  
  39.  
  40. /*
  41.  * returns 1 if there are lots of free blocks for the nntp server to use;
  42.  * a zero value is the small number of blocks remaining (more or less).
  43.  */
  44. #define DFREE_OK    0
  45. #define DFREE_INODES    1
  46. #define DFREE_BLOCKS    2
  47. #define DFREE_ERR    3
  48.  
  49. int
  50. space(min_free)
  51. int min_free;
  52. {
  53.     int result, dfree();
  54.  
  55.     result = dfree(SPOOLDIR,min_free);
  56.     if (result == DFREE_OK) return(1);
  57.     switch (result) {
  58.     case DFREE_ERR:
  59.         log_msg("dfree failed due to syscall error");
  60.         break;
  61.     case DFREE_INODES:
  62.         log_msg("no inodes on %s",SPOOLDIR);
  63.         break;
  64.     case DFREE_BLOCKS:
  65.         log_msg("no space on %s",SPOOLDIR);
  66.         break;
  67.         }    
  68.     return(0);
  69. }
  70.  
  71. /*
  72.  * Now we define the dfree() routine, which returns the free space
  73.  * on the file system containing the specified directory.
  74.  * Space is measured in kilobytes.
  75.  * A negative value is returned on error.
  76.  */
  77. #ifndef READ_SUPER
  78. #if defined(sun) || defined(hpux) || defined(pyr) || defined(hp300) || defined(NeXT)
  79. #include <sys/vfs.h>
  80. #define statfilesys    statfs        /* routine to call when trying to  */
  81.                     /* stat a file system to get the # */
  82.                     /* of free blocks available       */
  83. typedef struct statfs statfs_type;    /* the data type into which statfs() */
  84.                     /* wants to return useful information*/
  85. #define bombed(call)    ((call) == -1)    /* boolean expression returning 1 if */
  86.                     /* a call to statfs() fails         */
  87. #define blkfree(fs)    ((fs).f_bfree)    /* given a statfs_type, return total */
  88.                     /* # of free blocks             */
  89. #define blkavail(fs)    ((fs).f_bavail)    /* given a statfs_type called fs,  */
  90.                     /* return # of blocks available to */
  91.                     /* a non-privileged user       */
  92. #define filfree(fs)    ((fs).f_ffree)    /* given a statfs_type called fs,  */
  93.                      /* return number of free inodes       */
  94. #endif 
  95.  
  96. #if defined(apollo)
  97. #include <sys/types.h>
  98. #include <sys/statfs.h>
  99. #define statfilesys(a,b)    statfs(a,b, sizeof(struct statfs), 0)        /* routine to call when trying to  */
  100.                     /* stat a file system to get the # */
  101.                     /* of free blocks available       */
  102. typedef struct statfs statfs_type;    /* the data type into which statfs() */
  103.                     /* wants to return useful information*/
  104. #define bombed(call)    ((call) == -1)    /* boolean expression returning 1 if */
  105.                     /* a call to statfs() fails         */
  106. #define blkfree(fs)    ((fs).f_bfree)    /* given a statfs_type, return total */
  107.                     /* # of free blocks             */
  108. #define blkavail(fs)    ((fs).f_bfree)    /* given a statfs_type called fs,  */
  109.                     /* return # of blocks available to */
  110.                     /* a non-privileged user       */
  111. #define filfree(fs)    ((fs).f_ffree)    /* given a statfs_type called fs,  */
  112.                      /* return number of free inodes       */
  113. #endif /* apollo */
  114.  
  115. #ifdef ultrix
  116. #include <sys/mount.h>
  117. typedef struct fs_data statfs_type;
  118. #define statfilesys    statfs
  119. #define bombed(call)    ((call) <= 0)
  120. #define blkfree(fs)    ((int)((fs).fd_req.bfree))
  121. #define blkavail(fs)    ((int)((fs).fd_req.bfreen))
  122. #define filfree(fs)    ((int)((fs).fd_req.gfree))
  123. #endif 
  124.  
  125. #if defined(USG) && !defined(hpux)
  126. #include <ustat.h>
  127. typedef struct ustat statfs_type;
  128. /*
  129.  * You've got to make calls to 2 functions to get
  130.  * free blocks on a USG system, so statfilesys can't just be a macro.
  131.  * written by Stan Barber <sob@watson.bcm.tmc.edu>
  132.  */
  133. int
  134. statfilesys(dir, fs)
  135. char *dir;
  136. statfs_type *fs;
  137. {
  138.     struct stat file;
  139.     if (stat(dir,&file)) return(-1);
  140.     if (ustat(file.st_dev, fs)) return(-2);
  141.     return(0);
  142. }
  143. #define bombed(call)    (call != 0)
  144. #define blkfree(fs)    ((fs).f_tfree)
  145. #define blkavail(fs)    ((fs).f_tfree)
  146.                 /* USG doesn't reserve blocks for root */
  147. #define filfree(fs)    ((fs).f_tinode)    
  148. #endif USG
  149.  
  150. #ifdef CMU_MACH
  151. /* This code supplied by Tom Lane <tgl@cs.cmu.edu> */
  152. #include <sys/ioctl.h>
  153. typedef struct fsparam statfs_type;
  154. int
  155. statfilesys(dir, fs)
  156. char *dir;
  157. statfs_type *fs;
  158. {
  159.     int fd;
  160.     fd = open(dir, O_RDONLY);
  161.     if (fd < 0) return(-1);
  162.     if (ioctl(fd, FIOCFSPARAM, fs) < 0) {
  163.     close(fd);
  164.     return(-2);
  165.     }
  166.     close(fd);
  167.     return(0);
  168. }
  169. #define bombed(call)    ((call) < 0)
  170. #define blkfree(fs)    ((fs).fsp_free-((fs).fsp_size*(fs).fsp_minfree+99)/100)
  171. #define blkavail(fs)    (-1)
  172. #endif MACH
  173.  
  174. dfree(spool,free_space)
  175. char *spool;
  176. int free_space;
  177. {
  178.     statfs_type fsys;
  179.     int err;
  180.  
  181.     if (bombed(err = statfilesys(SPOOLDIR, &fsys)))
  182.     return(DFREE_ERR);        /* can't get file system info */
  183. # if defined(filfree) && defined(MINFILES)
  184.      if (filfree(fsys) < MINFILES )
  185.      return( DFREE_INODES );
  186. # endif
  187.     if (blkavail(fsys) < 0L) {
  188.     /* the bavail field doesn't apply to this file system */
  189.     if(blkfree(fsys) < free_space)
  190.         return( DFREE_BLOCKS );
  191.      } else {
  192.     if (blkavail(fsys) < free_space )
  193.         return( DFREE_BLOCKS );
  194.      }
  195.     return( DFREE_OK );
  196. }
  197.  
  198. #else READ_SUPER
  199. /*
  200.  * This code is used if you've got to directly read the superblock
  201.  * to determine how much space you've got left.  It's copied from
  202.  * patches posted by Tad Guy <tadguy@cs.odu.edu>
  203.  */
  204.  
  205. #include <sys/fs.h>
  206. #include <fstab.h>
  207.  
  208. /*
  209.  * return the number of free kilobytes remaining on the filesystem where
  210.  * the named file resides.  returns -1 on error.
  211.  */
  212.  
  213. off_t lseek();
  214.  
  215. dfree(name, free_space)
  216. char *name;
  217. int free_space;
  218. {
  219.     struct stat namest, fsst;
  220.     struct fstab *fsp;
  221.     char lname[MAXPATHLEN];
  222.     int fd;
  223.     union {
  224.     struct fs u_fs;
  225.     char dummy[SBSIZE];
  226.     } sb;
  227. #define sblock sb.u_fs
  228.  
  229.     strcpy(lname,name);
  230.     do {
  231.     if (stat(lname,&namest))        /* if stat fails, die */
  232.     {
  233.       log_ret("dfree stat(%s) failed", lname);
  234.       return  DFREE_ERR;            
  235.     }
  236.     if ((namest.st_mode & S_IFMT) == S_IFLNK) { /* if symlink */
  237.         if ((fd = readlink(lname,lname,sizeof(lname))) < 0) 
  238.         {
  239.           log_ret("dfree readlink() failed");
  240.           return DFREE_ERR;
  241.         }
  242.         lname[fd] = '\0';
  243.     }
  244.     } while ((namest.st_mode & S_IFMT) == S_IFLNK);
  245.  
  246.     (void) setfsent();
  247.  
  248.     while (fsp = getfsent()) {
  249.     if (stat(fsp->fs_spec,&fsst))
  250.       continue;
  251.     if (fsst.st_rdev == namest.st_dev)
  252.       break;
  253.     }
  254.  
  255.     if (!fsp ||    (fd = open(fsp->fs_spec,O_RDONLY)) < 0) {
  256.     (void) endfsent();
  257.     log_ret("dfree open(%s,O_RDONLY) failed", fsp->fs_spec);
  258.     return DFREE_ERR;
  259.     }
  260.     (void) endfsent();
  261.  
  262.     (void) lseek(fd,SBLOCK*DEV_BSIZE,L_SET);
  263.     if (read(fd,(char *)&sblock,SBSIZE) != SBSIZE ||
  264.     (sblock.fs_magic != FS_MAGIC))
  265.     {
  266.       log_ret("dfree read() failed");
  267.       return DFREE_ERR;
  268.     }
  269.     (void) close(fd);
  270.  
  271. # if defined(filfree) && defined(MINFILES)
  272.     if (filfree(fsys) < MINFILES )
  273.     return( DFREE_INODES );
  274. # endif
  275.     if( ((((sblock.fs_dsize) * ( 100 - sblock.fs_minfree) / 100)
  276.       - ((sblock.fs_dsize) 
  277.          - (sblock.fs_cstotal.cs_nbfree 
  278.         * sblock.fs_frag + sblock.fs_cstotal.cs_nffree))) 
  279.      * sblock.fs_fsize / 1024) < free_space )
  280.     return( DFREE_BLOCKS );
  281.    return( DFREE_OK );
  282. }
  283.  
  284. #endif READ_SUPER
  285.  
  286. #endif MINFREE
  287.  
  288. /* END-OF-FILE */
  289.