1 #include <net-snmp/net-snmp-config.h>
2 #include <net-snmp/net-snmp-includes.h>
3 #include <net-snmp/agent/net-snmp-agent-includes.h>
4 #include <net-snmp/agent/hardware/fsys.h>
5 #include "hardware/fsys/hw_fsys.h"
6 #include "hardware/fsys/hw_fsys_private.h"
7 
8 #if HAVE_SYS_PARAM_H
9 #include <sys/param.h>
10 #endif
11 #if HAVE_SYS_MOUNT_H
12 #include <sys/mount.h>
13 #endif
14 #if HAVE_SYS_STATVFS_H
15 #include <sys/statvfs.h>
16 #endif
17 
18 
19     /*
20      * Handle minor naming differences between statfs/statvfs
21      */
22 #if defined(_VFS_NAMELEN)
23 #define NSFS_NAMELEN  _VFS_NAMELEN
24 #else
25 #define NSFS_NAMELEN  MNAMELEN
26 #endif
27 
28 #if defined(HAVE_GETVFSSTAT) && defined(__NetBSD__)
29 #define NSFS_GETFSSTAT  getvfsstat
30 #define NSFS_STATFS     statvfs
31 #define NSFS_FLAGS      f_flag
32 #else
33 #define NSFS_GETFSSTAT  getfsstat
34 #define NSFS_STATFS     statfs
35 #define NSFS_FLAGS      f_flags
36 #endif
37 
38 int
_fs_type(char * typename)39 _fs_type( char *typename )
40 {
41     DEBUGMSGTL(("fsys:type", "Classifying %s\n", typename));
42 
43     if ( !typename || *typename=='\0' )
44        return NETSNMP_FS_TYPE_UNKNOWN;
45 
46 #include "mounts.h"
47 
48        /*
49         * List of mount types from <sys/mount.h>
50         */
51     else if ( !strcmp(typename, MOUNT_FFS) ||
52               !strcmp(typename, MOUNT_UFS) )
53        return NETSNMP_FS_TYPE_BERKELEY;
54     else if ( !strcmp(typename, MOUNT_NFS) )
55        return NETSNMP_FS_TYPE_NFS;
56     else if ( !strcmp(typename, MOUNT_MFS) )
57        return NETSNMP_FS_TYPE_MFS;
58     else if ( !strcmp(typename, MOUNT_MSDOS) ||
59               !strcmp(typename, MOUNT_MSDOSFS) )
60        return NETSNMP_FS_TYPE_FAT;
61     else if ( !strcmp(typename, MOUNT_AFS) )
62        return NETSNMP_FS_TYPE_AFS;
63     else if ( !strcmp(typename, MOUNT_CD9660) )
64        return NETSNMP_FS_TYPE_ISO9660;
65     else if ( !strcmp(typename, MOUNT_EXT2FS) )
66        return NETSNMP_FS_TYPE_EXT2;
67     else if ( !strcmp(typename, MOUNT_NTFS) )
68        return NETSNMP_FS_TYPE_NTFS;
69     else if ( !strcmp(typename, MOUNT_ZFS) )
70        return NETSNMP_FS_TYPE_OTHER;
71     else if ( !strcmp(typename, MOUNT_NVMFS) )
72        return NETSNMP_FS_TYPE_OTHER;
73     else if ( !strcmp(typename, MOUNT_ACFS) )
74        return NETSNMP_FS_TYPE_OTHER;
75 
76        /*
77         * NetBSD also recognises the following filesystem types:
78         *     MOUNT_NULL
79         *     MOUNT_OVERLAY
80         *     MOUNT_UMAP
81         *     MOUNT_UNION
82         *     MOUNT_CFS/CODA
83         *     MOUNT_FILECORE
84         *     MOUNT_SMBFS
85         *     MOUNT_PTYFS
86         * OpenBSD also recognises the following filesystem types:
87         *     MOUNT_LOFS
88         *     MOUNT_NCPFS
89         *     MOUNT_XFS
90         *     MOUNT_UDF
91         * Both of them recognise the following filesystem types:
92         *     MOUNT_LFS
93         *     MOUNT_FDESC
94         *     MOUNT_PORTAL
95         *     MOUNT_KERNFS
96         *     MOUNT_PROCFS
97         *     MOUNT_ADOSFS
98         *
99         * All of these filesystems are mapped to NETSNMP_FS_TYPE_OTHER
100         *   so will be picked up by the following default branch.
101         */
102     else
103        return NETSNMP_FS_TYPE_OTHER;
104 }
105 
106 void
netsnmp_fsys_arch_init(void)107 netsnmp_fsys_arch_init( void )
108 {
109     return;
110 }
111 
112 void
netsnmp_fsys_arch_load(void)113 netsnmp_fsys_arch_load( void )
114 {
115     int n, i;
116     struct NSFS_STATFS *stats;
117     netsnmp_fsys_info *entry;
118 
119     /*
120      * Retrieve information about the currently mounted filesystems...
121      */
122     n = NSFS_GETFSSTAT( NULL, 0, MNT_NOWAIT );
123     if ( n==0 )
124         return;
125     stats = (struct NSFS_STATFS *)malloc( n * sizeof( struct NSFS_STATFS ));
126     n = NSFS_GETFSSTAT( stats, n * sizeof( struct NSFS_STATFS ), MNT_NOWAIT );
127 
128     /*
129      * ... and insert this into the filesystem container.
130      */
131     for ( i=0; i<n; i++ ) {
132         entry = netsnmp_fsys_by_path( stats[i].f_mntonname,
133                                       NETSNMP_FS_FIND_CREATE );
134         if (!entry)
135             continue;
136 
137         strlcpy( entry->path,   stats[i].f_mntonname,   sizeof(entry->path));
138         entry->path[sizeof(entry->path)-1] = '\0';
139         strlcpy( entry->device, stats[i].f_mntfromname, sizeof(entry->device));
140         entry->device[sizeof(entry->device)-1] = '\0';
141         entry->units = stats[i].f_bsize;    /* or f_frsize */
142         entry->size  = stats[i].f_blocks;
143         entry->used  = (stats[i].f_blocks - stats[i].f_bfree);
144         /* entry->avail is currently unsigned, so protect against negative
145          * values!
146          * This should be changed to a signed field.
147          */
148         if (stats[i].f_bavail < 0)
149             entry->avail = 0;
150         else
151             entry->avail = stats[i].f_bavail;
152         entry->inums_total = stats[i].f_files;
153         entry->inums_avail = stats[i].f_ffree;
154 
155         entry->type = _fs_type( stats[i].f_fstypename );
156         entry->flags |= NETSNMP_FS_FLAG_ACTIVE;
157 
158         if (! (stats[i].NSFS_FLAGS & MNT_LOCAL )) {
159             entry->flags |= NETSNMP_FS_FLAG_REMOTE;
160         }
161         if (  stats[i].NSFS_FLAGS & MNT_RDONLY ) {
162             entry->flags |= NETSNMP_FS_FLAG_RONLY;
163         }
164         if (  stats[i].NSFS_FLAGS & MNT_ROOTFS ) {
165             entry->flags |= NETSNMP_FS_FLAG_BOOTABLE;
166         }
167         netsnmp_fsys_calculate32(entry);
168     }
169 
170     free(stats);
171 }
172