9e1d3cd1932cd190f5a3bc766093c558a9745f83
[debian/amanda] / common-src / statfs.c
1 /*
2  * Amanda, The Advanced Maryland Automatic Network Disk Archiver
3  * Copyright (c) 1991-1998 University of Maryland at College Park
4  * All Rights Reserved.
5  *
6  * Permission to use, copy, modify, distribute, and sell this software and its
7  * documentation for any purpose is hereby granted without fee, provided that
8  * the above copyright notice appear in all copies and that both that
9  * copyright notice and this permission notice appear in supporting
10  * documentation, and that the name of U.M. not be used in advertising or
11  * publicity pertaining to distribution of the software without specific,
12  * written prior permission.  U.M. makes no representations about the
13  * suitability of this software for any purpose.  It is provided "as is"
14  * without express or implied warranty.
15  *
16  * U.M. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL U.M.
18  * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
19  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
20  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
21  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
22  *
23  * Authors: the Amanda Development Team.  Its members are listed in a
24  * file named AUTHORS, in the root directory of this distribution.
25  */
26 /*
27  * $Id: statfs.c,v 1.16 2006/08/24 17:05:35 martinea Exp $
28  *
29  * a generic statfs-like routine
30  */
31 #include "amanda.h"
32 #include "statfs.h"
33
34 /*
35  * You are in a maze of twisty passages, all alike.
36  * Begin retching now.
37  */
38
39 #ifdef STATFS_ULTRIX
40 # include <sys/param.h>
41 # include <sys/mount.h>
42 # define STATFS_STRUCT  struct fs_data
43 # define STATFS_TOTAL(buf)      (buf).fd_btot
44 # define STATFS_AVAIL(buf)      (buf).fd_bfreen
45 # define STATFS_FREE(buf)       (buf).fd_bfree
46 # define STATFS_FILES(buf)      (buf).fd_gtot
47 # define STATFS_FAVAIL(buf)     (buf).fd_gfree
48 # define STATFS_FFREE(buf)      (buf).fd_gfree
49 # define STATFS_SCALE(buf)      1024
50 # define STATFS(path, buffer)   statfs(path, &buffer)
51 #else
52 # if defined(HAVE_SYS_STATVFS_H) && !defined(STATFS_SCO_OS5)
53 /*
54 ** System V.4 (STATFS_SVR4)
55 */
56 #  include <sys/statvfs.h>
57 #  define STATFS_TYP            "SVR4 (Irix-5+, Solaris-2, Linux glibc 2.1)"
58 #  define STATFS_STRUCT struct statvfs
59 #  define STATFS_TOTAL(buf)     (buf).f_blocks
60 #  define STATFS_AVAIL(buf)     (buf).f_bavail
61 #  define STATFS_FREE(buf)      (buf).f_bfree
62 #  define STATFS_FILES(buf)     (buf).f_files
63 #  define STATFS_FAVAIL(buf)    (buf).f_favail
64 #  define STATFS_FFREE(buf)     (buf).f_ffree
65 #  define STATFS_SCALE(buf)     ((buf).f_frsize?(buf).f_frsize:(buf).f_bsize)
66 #  define STATFS(path, buffer)  statvfs(path, &buffer)
67 # else
68 #  if HAVE_SYS_VFS_H
69 /*
70 ** (STATFS_AIX, STATFS_VFS, STATFS_NEXT)
71 */
72 #   ifdef HAVE_SYS_STATFS_H /* AIX */
73 #    include <sys/statfs.h>
74 #   endif
75 #   include <sys/vfs.h>
76 #   define STATFS_TYP           "Posix (NeXTstep, AIX, Linux, HP-UX)"
77 #   define STATFS_STRUCT        struct statfs
78 #   define STATFS_TOTAL(buf)    (buf).f_blocks
79 #   define STATFS_AVAIL(buf)    (buf).f_bavail
80 #   define STATFS_FREE(buf)     (buf).f_bfree
81 #   define STATFS_FILES(buf)    (buf).f_files
82 #   define STATFS_FAVAIL(buf)   (buf).f_ffree
83 #   define STATFS_FFREE(buf)    (buf).f_ffree
84 #   define STATFS_SCALE(buf)    (buf).f_bsize
85 #   define STATFS(path, buffer) statfs(path, &buffer)
86 #  else
87 #   if HAVE_SYS_STATFS_H
88 /*
89 ** System V.3 (STATFS_SVR3)
90 */
91 #    include <sys/statfs.h>
92 #    define STATFS_TYP          "SVR3 (Irix-3, Irix-4)"
93 #    define STATFS_STRUCT       struct statfs
94 #    define STATFS_TOTAL(buf)   (buf).f_blocks
95 #    define STATFS_AVAIL(buf)   (buf).f_bfree
96 #    define STATFS_FREE(buf)    (buf).f_bfree
97 #    define STATFS_FILES(buf)   (buf).f_files
98 #    define STATFS_FAVAIL(buf)  (buf).f_ffree
99 #    define STATFS_FFREE(buf)   (buf).f_ffree
100 #    define STATFS_SCALE(buf)   (buf).f_bsize
101 #    define STATFS(path, buffer)        statfs(path, &buffer, SIZEOF(STATFS_STRUCT), 0)
102 #   else
103 #    if HAVE_SYS_MOUNT_H
104 /*
105 ** BSD (STATFS_BSD43, STATFS_BSD44)
106 */
107 #     ifdef HAVE_SYS_PARAM_H /* BSD-4.4 */
108 #      include <sys/param.h>
109 #     endif
110 #     include <sys/mount.h>
111 #     define STATFS_TYP         "BSD43/44"
112 #     define STATFS_STRUCT      struct statfs
113 #     define STATFS_TOTAL(buf)  (buf).f_blocks
114 #     define STATFS_AVAIL(buf)  (buf).f_bavail
115 #     define STATFS_FREE(buf)   (buf).f_bfree
116 #     define STATFS_FILES(buf)  (buf).f_files
117 #     define STATFS_FAVAIL(buf) (buf).f_ffree
118 #     define STATFS_FFREE(buf)  (buf).f_ffree
119 #     define STATFS_SCALE(buf)  (buf).f_bsize
120 #     define STATFS(path, buffer)       statfs(path, &buffer)
121 #     ifdef STATFS_OSF1
122 #      define STATFS(path, buffer)      statfs(path, &buffer, SIZEOF(STATFS_STRUCT))
123 #     endif
124 #    endif
125 #   endif
126 #  endif
127 # endif
128 #endif
129
130
131 off_t scale(off_t r, off_t s);
132
133 off_t
134 scale(
135     off_t r,
136     off_t s)
137 {
138     if (r == (off_t)-1)
139         return (off_t)-1;
140     return r*(s/(off_t)1024);
141 }
142
143 int
144 get_fs_stats(
145     char *              dir,
146     generic_fs_stats_t *sp)
147 {
148     STATFS_STRUCT statbuf;
149
150     if(STATFS(dir, statbuf) == -1)
151         return -1;
152
153     /* total, avail, free: converted to kbytes, rounded down */
154
155     sp->total = scale((off_t)STATFS_TOTAL(statbuf),
156                       (off_t)STATFS_SCALE(statbuf));
157     sp->avail = scale((off_t)STATFS_AVAIL(statbuf),
158                       (off_t)STATFS_SCALE(statbuf));
159     sp->free  = scale((off_t)STATFS_FREE(statbuf),
160                       (off_t)STATFS_SCALE(statbuf));
161
162     /* inode stats */
163
164     sp->files  = (off_t)STATFS_FILES(statbuf);
165     sp->favail = (off_t)STATFS_FAVAIL(statbuf);
166     sp->ffree  = (off_t)STATFS_FFREE(statbuf);
167
168     return 0;
169 }
170
171 #ifdef TEST
172 /* ----- test scaffolding ----- */
173
174 int
175 main(
176     int         argc,
177     char **     argv)
178 {
179     generic_fs_stats_t statbuf;
180
181     safe_fd(-1, 0);
182
183     set_pname(argv[0]);
184
185     dbopen(NULL);
186
187     if(argc < 2) {
188         fprintf(stderr, "Usage: %s files ...\n", get_pname());
189         return 1;
190     }
191
192     printf("statfs (%s)\n",STATFS_TYP);
193     printf(
194 "name                             total    free   avail  files  ffree favail\n"
195            );
196     printf(
197 "------------------------------ ------- ------- ------- ------ ------ ------\n"
198            );
199
200     do {
201         argc--,argv++;
202         if(get_fs_stats(*argv, &statbuf) == -1) {
203             perror(*argv);
204             continue;
205         }
206         printf("%-30.30s %7ld %7ld %7ld %6ld %6ld %6ld\n", *argv,
207                statbuf.total, statbuf.free, statbuf.avail,
208                statbuf.files, statbuf.ffree, statbuf.favail);
209     } while(argc > 1);
210     return 0;
211 }
212 #endif