eae1431e2f2fa0fe2c89399de59a509c27b3296e
[monky] / src / fs.c
1 /*
2  * Conky, a system monitor, based on torsmo
3  *
4  * This program is licensed under BSD license, read COPYING
5  *
6  *  $Id$
7  */
8
9 #include "conky.h"
10 #include <unistd.h>
11 #include <stdlib.h>
12 #include <string.h>
13 #include <errno.h>
14 #include <sys/types.h>
15 #include <fcntl.h>
16
17 /* linux */
18 #ifdef HAVE_SYS_STATFS_H
19 #include <sys/statfs.h>
20 #endif
21
22 /* freebsd && netbsd */
23 #ifdef HAVE_SYS_PARAM_H
24 #include <sys/param.h>
25 #endif
26 #ifdef HAVE_SYS_MOUNT_H
27 #include <sys/mount.h>
28 #endif
29
30 #define MAX_FS_STATS 64
31
32 static struct fs_stat fs_stats_[MAX_FS_STATS];
33 struct fs_stat *fs_stats = fs_stats_;
34
35 static void update_fs_stat(struct fs_stat* fs);
36
37 void update_fs_stats()
38 {
39         unsigned i;
40         for(i=0; i<MAX_FS_STATS; ++i)
41                 if(fs_stats[i].path)
42                         update_fs_stat(&fs_stats[i]);
43 }
44
45 void clear_fs_stats()
46 {
47         unsigned i;
48         for(i=0; i<MAX_FS_STATS; ++i)
49                 if(fs_stats[i].path) {
50                         free(fs_stats[i].path);
51                         fs_stats[i].path = 0;
52                 }
53 }
54
55 struct fs_stat *prepare_fs_stat(const char *s)
56 {
57         struct fs_stat* new = 0;
58         unsigned i;
59         /* lookup existing or get new */
60         for(i=0; i<MAX_FS_STATS; ++i) {
61                 if(fs_stats[i].path) {
62                         if(strcmp(fs_stats[i].path, s) == 0)
63                                 return &fs_stats[i];
64                 } else
65                         new = &fs_stats[i];
66         }
67         /* new path */
68         if(!new) {
69                 ERR("too many fs stats");
70                 return 0;
71         }
72         new->path = strdup(s);
73         update_fs_stat(new);
74         return new;
75 }
76
77 static
78 void update_fs_stat(struct fs_stat* fs)
79 {
80         struct statfs s;
81         if(statfs(fs->path, &s) == 0) {
82                 fs->size = (long long) s.f_blocks * s.f_bsize;
83                 /* bfree (root) or bavail (non-roots) ? */
84                 fs->avail = (long long) s.f_bavail* s.f_bsize;
85                 fs->free = (long long) s.f_bfree * s.f_bsize;;
86         } else {
87                 fs->size = 0;
88                 fs->avail = 0;
89                 fs->free = 0;
90                 ERR("statfs '%s': %s", fs->path, strerror(errno));
91         }
92 }