5f5270feebd28e7340b045e09c95603c34d9b661
[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.13 2005/09/30 19:13:27 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 #define scale(r,s)      ( (r) == -1? -1 : (int)((r)*(double)(s)/1024.0) )
131
132 int get_fs_stats(dir, sp)
133 char *dir;
134 generic_fs_stats_t *sp;
135 {
136     STATFS_STRUCT statbuf;
137
138     if(STATFS(dir, statbuf) == -1)
139         return -1;
140
141     /* total, avail, free: converted to kbytes, rounded down */
142
143     sp->total = scale(STATFS_TOTAL(statbuf), STATFS_SCALE(statbuf));
144     sp->avail = scale(STATFS_AVAIL(statbuf), STATFS_SCALE(statbuf));
145     sp->free  = scale(STATFS_FREE(statbuf),  STATFS_SCALE(statbuf));
146
147     /* inode stats */
148
149     sp->files  = STATFS_FILES(statbuf);
150     sp->favail = STATFS_FAVAIL(statbuf);
151     sp->ffree  = STATFS_FFREE(statbuf);
152
153     return 0;
154 }
155
156 #ifdef TEST
157 /* ----- test scaffolding ----- */
158
159 int main(argc, argv)
160 int argc;
161 char **argv;
162 {
163     generic_fs_stats_t statbuf;
164
165     safe_fd(-1, 0);
166
167     set_pname(argv[0]);
168
169     if(argc < 2) {
170         fprintf(stderr, "Usage: %s files ...\n", get_pname());
171         return 1;
172     }
173
174     printf("statfs (%s)\n",STATFS_TYP);
175     printf(
176 "name                             total    free   avail  files  ffree favail\n"
177            );
178     printf(
179 "------------------------------ ------- ------- ------- ------ ------ ------\n"
180            );
181
182     do {
183         argc--,argv++;
184         if(get_fs_stats(*argv, &statbuf) == -1) {
185             perror(*argv);
186             continue;
187         }
188         printf("%-30.30s %7ld %7ld %7ld %6ld %6ld %6ld\n", *argv,
189                statbuf.total, statbuf.free, statbuf.avail,
190                statbuf.files, statbuf.ffree, statbuf.favail);
191     } while(argc > 1);
192     return 0;
193 }
194 #endif