1/*	$NetBSD$	*/
2
3/*++
4/* NAME
5/*	fsspace 3
6/* SUMMARY
7/*	determine available file system space
8/* SYNOPSIS
9/*	#include <fsspace.h>
10/*
11/*	struct fsspace {
12/* .in +4
13/*		unsigned long block_size;
14/*		unsigned long block_free;
15/* .in -4
16/*	};
17/*
18/*	void	fsspace(path, sp)
19/*	const char *path;
20/*	struct fsspace *sp;
21/* DESCRIPTION
22/*	fsspace() returns the amount of available space in the file
23/*	system specified in \fIpath\fR, in terms of the block size and
24/*	of the number of available blocks.
25/* DIAGNOSTICS
26/*	All errors are fatal.
27/* BUGS
28/*	Use caution when doing computations with the result from fsspace().
29/*	It is easy to cause overflow (by multiplying large numbers) or to
30/*	cause underflow (by subtracting unsigned numbers).
31/* LICENSE
32/* .ad
33/* .fi
34/*	The Secure Mailer license must be distributed with this software.
35/* AUTHOR(S)
36/*	Wietse Venema
37/*	IBM T.J. Watson Research
38/*	P.O. Box 704
39/*	Yorktown Heights, NY 10598, USA
40/*--*/
41
42/* System library. */
43
44#include <sys_defs.h>
45
46#if defined(STATFS_IN_SYS_MOUNT_H)
47#include <sys/param.h>
48#include <sys/mount.h>
49#elif defined(STATFS_IN_SYS_VFS_H)
50#include <sys/vfs.h>
51#elif defined(STATVFS_IN_SYS_STATVFS_H)
52#include <sys/statvfs.h>
53#elif defined(STATFS_IN_SYS_STATFS_H)
54#include <sys/statfs.h>
55#else
56#ifdef USE_STATFS
57#error "please specify the include file with `struct statfs'"
58#else
59#error "please specify the include file with `struct statvfs'"
60#endif
61#endif
62
63/* Utility library. */
64
65#include <msg.h>
66#include <fsspace.h>
67
68/* fsspace - find amount of available file system space */
69
70void    fsspace(const char *path, struct fsspace * sp)
71{
72    const char *myname = "fsspace";
73
74#ifdef USE_STATFS
75#ifdef USE_STRUCT_FS_DATA			/* Ultrix */
76    struct fs_data fsbuf;
77
78    if (statfs(path, &fsbuf) < 0)
79	msg_fatal("statfs %s: %m", path);
80    sp->block_size = 1024;
81    sp->block_free = fsbuf.fd_bfreen;
82#else
83    struct statfs fsbuf;
84
85    if (statfs(path, &fsbuf) < 0)
86	msg_fatal("statfs %s: %m", path);
87    sp->block_size = fsbuf.f_bsize;
88    sp->block_free = fsbuf.f_bavail;
89#endif
90#endif
91#ifdef USE_STATVFS
92    struct statvfs fsbuf;
93
94    if (statvfs(path, &fsbuf) < 0)
95	msg_fatal("statvfs %s: %m", path);
96    sp->block_size = fsbuf.f_frsize;
97    sp->block_free = fsbuf.f_bavail;
98#endif
99    if (msg_verbose)
100	msg_info("%s: %s: block size %lu, blocks free %lu",
101		 myname, path, sp->block_size, sp->block_free);
102}
103
104#ifdef TEST
105
106 /*
107  * Proof-of-concept test program: print free space unit and count for all
108  * listed file systems.
109  */
110
111#include <vstream.h>
112
113int     main(int argc, char **argv)
114{
115    struct fsspace sp;
116
117    if (argc == 1)
118	msg_fatal("usage: %s filesystem...", argv[0]);
119
120    while (--argc && *++argv) {
121	fsspace(*argv, &sp);
122	vstream_printf("%10s: block size %lu, blocks free %lu\n",
123		       *argv, sp.block_size, sp.block_free);
124	vstream_fflush(VSTREAM_OUT);
125    }
126    return (0);
127}
128
129#endif
130