Imported Upstream version 2.5.2p1
[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     if (s % 1024 == 0)
141         return r*(s/(off_t)1024);
142     return (off_t)(r*((double)s/1024.0));
143 }
144
145 int
146 get_fs_stats(
147     char *              dir,
148     generic_fs_stats_t *sp)
149 {
150     STATFS_STRUCT statbuf;
151
152     if(STATFS(dir, statbuf) == -1)
153         return -1;
154
155     /* total, avail, free: converted to kbytes, rounded down */
156
157     sp->total = scale((off_t)STATFS_TOTAL(statbuf),
158                       (off_t)STATFS_SCALE(statbuf));
159     sp->avail = scale((off_t)STATFS_AVAIL(statbuf),
160                       (off_t)STATFS_SCALE(statbuf));
161     sp->free  = scale((off_t)STATFS_FREE(statbuf),
162                       (off_t)STATFS_SCALE(statbuf));
163
164     /* inode stats */
165
166     sp->files  = (off_t)STATFS_FILES(statbuf);
167     sp->favail = (off_t)STATFS_FAVAIL(statbuf);
168     sp->ffree  = (off_t)STATFS_FFREE(statbuf);
169
170     return 0;
171 }
172
173 #ifdef TEST
174 /* ----- test scaffolding ----- */
175
176 int
177 main(
178     int         argc,
179     char **     argv)
180 {
181     generic_fs_stats_t statbuf;
182
183     safe_fd(-1, 0);
184
185     set_pname(argv[0]);
186
187     dbopen(NULL);
188
189     if(argc < 2) {
190         fprintf(stderr, "Usage: %s files ...\n", get_pname());
191         return 1;
192     }
193
194     printf("statfs (%s)\n",STATFS_TYP);
195     printf(
196 "name                            total     free    avail   files   ffree  favail\n"
197            );
198     printf(
199 "---------------------------- -------- -------- -------- ------- ------- -------\n"
200            );
201
202     do {
203         argc--,argv++;
204         if(get_fs_stats(*argv, &statbuf) == -1) {
205             perror(*argv);
206             continue;
207         }
208         printf("%-28.28s %8ld %8ld %8ld %7ld %7ld %7ld\n", *argv,
209                statbuf.total, statbuf.free, statbuf.avail,
210                statbuf.files, statbuf.ffree, statbuf.favail);
211     } while(argc > 1);
212     return 0;
213 }
214 #endif