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 >
Wrap
C/C++ Source or Header
|
1992-12-20
|
7KB
|
289 lines
/*
* The following is a mish-mosh of code submitted to the net
* by Stan Barber <sob@bcm.tmc.edu>, Tad Guy <tadguy@cs.odu.edu>,
* Chris Jepeway <jepeway@utkcs2.cs.utk.edu>, and Tom Lane <tgl@cs.cmu.edu>.
* Modified for use in slurp by Stephen Hebditch <steveh@orbital.demon.co.uk>.
*/
#include "slurp.h"
#ifdef MINFREE
#include <sys/types.h>
#include <sys/stat.h>
#ifdef BSD_42
#ifndef sun
#ifndef ultrix
#ifndef CMU_MACH
#ifndef NeXT
#ifndef READ_SUPER
#define READ_SUPER
#endif
#endif
#endif
#endif
#endif
#endif
#ifdef BSD_43
#ifndef sun
#ifndef ultrix
#ifndef READ_SUPER
#define READ_SUPER
#endif
#endif
#endif
#endif
/*
* returns 1 if there are lots of free blocks for the nntp server to use;
* a zero value is the small number of blocks remaining (more or less).
*/
#define DFREE_OK 0
#define DFREE_INODES 1
#define DFREE_BLOCKS 2
#define DFREE_ERR 3
int
space(min_free)
int min_free;
{
int result, dfree();
result = dfree(SPOOLDIR,min_free);
if (result == DFREE_OK) return(1);
switch (result) {
case DFREE_ERR:
log_msg("dfree failed due to syscall error");
break;
case DFREE_INODES:
log_msg("no inodes on %s",SPOOLDIR);
break;
case DFREE_BLOCKS:
log_msg("no space on %s",SPOOLDIR);
break;
}
return(0);
}
/*
* Now we define the dfree() routine, which returns the free space
* on the file system containing the specified directory.
* Space is measured in kilobytes.
* A negative value is returned on error.
*/
#ifndef READ_SUPER
#if defined(sun) || defined(hpux) || defined(pyr) || defined(hp300) || defined(NeXT)
#include <sys/vfs.h>
#define statfilesys statfs /* routine to call when trying to */
/* stat a file system to get the # */
/* of free blocks available */
typedef struct statfs statfs_type; /* the data type into which statfs() */
/* wants to return useful information*/
#define bombed(call) ((call) == -1) /* boolean expression returning 1 if */
/* a call to statfs() fails */
#define blkfree(fs) ((fs).f_bfree) /* given a statfs_type, return total */
/* # of free blocks */
#define blkavail(fs) ((fs).f_bavail) /* given a statfs_type called fs, */
/* return # of blocks available to */
/* a non-privileged user */
#define filfree(fs) ((fs).f_ffree) /* given a statfs_type called fs, */
/* return number of free inodes */
#endif
#if defined(apollo)
#include <sys/types.h>
#include <sys/statfs.h>
#define statfilesys(a,b) statfs(a,b, sizeof(struct statfs), 0) /* routine to call when trying to */
/* stat a file system to get the # */
/* of free blocks available */
typedef struct statfs statfs_type; /* the data type into which statfs() */
/* wants to return useful information*/
#define bombed(call) ((call) == -1) /* boolean expression returning 1 if */
/* a call to statfs() fails */
#define blkfree(fs) ((fs).f_bfree) /* given a statfs_type, return total */
/* # of free blocks */
#define blkavail(fs) ((fs).f_bfree) /* given a statfs_type called fs, */
/* return # of blocks available to */
/* a non-privileged user */
#define filfree(fs) ((fs).f_ffree) /* given a statfs_type called fs, */
/* return number of free inodes */
#endif /* apollo */
#ifdef ultrix
#include <sys/mount.h>
typedef struct fs_data statfs_type;
#define statfilesys statfs
#define bombed(call) ((call) <= 0)
#define blkfree(fs) ((int)((fs).fd_req.bfree))
#define blkavail(fs) ((int)((fs).fd_req.bfreen))
#define filfree(fs) ((int)((fs).fd_req.gfree))
#endif
#if defined(USG) && !defined(hpux)
#include <ustat.h>
typedef struct ustat statfs_type;
/*
* You've got to make calls to 2 functions to get
* free blocks on a USG system, so statfilesys can't just be a macro.
* written by Stan Barber <sob@watson.bcm.tmc.edu>
*/
int
statfilesys(dir, fs)
char *dir;
statfs_type *fs;
{
struct stat file;
if (stat(dir,&file)) return(-1);
if (ustat(file.st_dev, fs)) return(-2);
return(0);
}
#define bombed(call) (call != 0)
#define blkfree(fs) ((fs).f_tfree)
#define blkavail(fs) ((fs).f_tfree)
/* USG doesn't reserve blocks for root */
#define filfree(fs) ((fs).f_tinode)
#endif USG
#ifdef CMU_MACH
/* This code supplied by Tom Lane <tgl@cs.cmu.edu> */
#include <sys/ioctl.h>
typedef struct fsparam statfs_type;
int
statfilesys(dir, fs)
char *dir;
statfs_type *fs;
{
int fd;
fd = open(dir, O_RDONLY);
if (fd < 0) return(-1);
if (ioctl(fd, FIOCFSPARAM, fs) < 0) {
close(fd);
return(-2);
}
close(fd);
return(0);
}
#define bombed(call) ((call) < 0)
#define blkfree(fs) ((fs).fsp_free-((fs).fsp_size*(fs).fsp_minfree+99)/100)
#define blkavail(fs) (-1)
#endif MACH
dfree(spool,free_space)
char *spool;
int free_space;
{
statfs_type fsys;
int err;
if (bombed(err = statfilesys(SPOOLDIR, &fsys)))
return(DFREE_ERR); /* can't get file system info */
# if defined(filfree) && defined(MINFILES)
if (filfree(fsys) < MINFILES )
return( DFREE_INODES );
# endif
if (blkavail(fsys) < 0L) {
/* the bavail field doesn't apply to this file system */
if(blkfree(fsys) < free_space)
return( DFREE_BLOCKS );
} else {
if (blkavail(fsys) < free_space )
return( DFREE_BLOCKS );
}
return( DFREE_OK );
}
#else READ_SUPER
/*
* This code is used if you've got to directly read the superblock
* to determine how much space you've got left. It's copied from
* patches posted by Tad Guy <tadguy@cs.odu.edu>
*/
#include <sys/fs.h>
#include <fstab.h>
/*
* return the number of free kilobytes remaining on the filesystem where
* the named file resides. returns -1 on error.
*/
off_t lseek();
dfree(name, free_space)
char *name;
int free_space;
{
struct stat namest, fsst;
struct fstab *fsp;
char lname[MAXPATHLEN];
int fd;
union {
struct fs u_fs;
char dummy[SBSIZE];
} sb;
#define sblock sb.u_fs
strcpy(lname,name);
do {
if (stat(lname,&namest)) /* if stat fails, die */
{
log_ret("dfree stat(%s) failed", lname);
return DFREE_ERR;
}
if ((namest.st_mode & S_IFMT) == S_IFLNK) { /* if symlink */
if ((fd = readlink(lname,lname,sizeof(lname))) < 0)
{
log_ret("dfree readlink() failed");
return DFREE_ERR;
}
lname[fd] = '\0';
}
} while ((namest.st_mode & S_IFMT) == S_IFLNK);
(void) setfsent();
while (fsp = getfsent()) {
if (stat(fsp->fs_spec,&fsst))
continue;
if (fsst.st_rdev == namest.st_dev)
break;
}
if (!fsp || (fd = open(fsp->fs_spec,O_RDONLY)) < 0) {
(void) endfsent();
log_ret("dfree open(%s,O_RDONLY) failed", fsp->fs_spec);
return DFREE_ERR;
}
(void) endfsent();
(void) lseek(fd,SBLOCK*DEV_BSIZE,L_SET);
if (read(fd,(char *)&sblock,SBSIZE) != SBSIZE ||
(sblock.fs_magic != FS_MAGIC))
{
log_ret("dfree read() failed");
return DFREE_ERR;
}
(void) close(fd);
# if defined(filfree) && defined(MINFILES)
if (filfree(fsys) < MINFILES )
return( DFREE_INODES );
# endif
if( ((((sblock.fs_dsize) * ( 100 - sblock.fs_minfree) / 100)
- ((sblock.fs_dsize)
- (sblock.fs_cstotal.cs_nbfree
* sblock.fs_frag + sblock.fs_cstotal.cs_nffree)))
* sblock.fs_fsize / 1024) < free_space )
return( DFREE_BLOCKS );
return( DFREE_OK );
}
#endif READ_SUPER
#endif MINFREE
/* END-OF-FILE */