and added files
[bcm963xx.git] / userapps / opensource / net-snmp / agent / mibgroup / host / hr_filesys.c
1 /*
2  *  Host Resources MIB - File System device group implementation - hr_filesys.c
3  *
4  */
5
6 #include <net-snmp/net-snmp-config.h>
7 #include "host_res.h"
8 #include "hr_filesys.h"
9 #include <net-snmp/utilities.h>
10
11 #if HAVE_MNTENT_H
12 #include <mntent.h>
13 #endif
14 #if HAVE_SYS_MNTENT_H
15 #include <sys/mntent.h>
16 #endif
17 #if HAVE_SYS_MNTTAB_H
18 #include <sys/mnttab.h>
19 #endif
20 #if HAVE_SYS_STATVFS_H
21 #include <sys/statvfs.h>
22 #endif
23 #if HAVE_SYS_VFS_H
24 #include <sys/vfs.h>
25 #endif
26 #ifdef HAVE_SYS_PARAM_H
27 #include <sys/param.h>
28 #endif
29 #ifdef HAVE_SYS_MOUNT_H
30 #include <sys/mount.h>
31 #endif
32
33 #include <ctype.h>
34 #if HAVE_STRING_H
35 #include <string.h>
36 #endif
37 #if HAVE_STDLIB_H
38 #include <stdlib.h>
39 #endif
40
41 #if defined(bsdi4) || defined(freebsd3) || defined(freebsd4) || defined(freebsd5)
42 #if HAVE_GETFSSTAT
43 #if defined(MFSNAMELEN)
44 #define MOUNT_NFS       "nfs"
45 #define MNTTYPE_UFS     "ufs"
46 #define BerkelyFS
47 #define MNTTYPE_FFS     "ffs"
48 #define MNTTYPE_NFS     "nfs"
49 #define MNTTYPE_NFS3    "nfs"
50 #define MNTTYPE_MFS     "mfs"
51 #define MNTTYPE_MSDOS   "msdos"
52 #define MNTTYPE_LFS     "lfs"
53 #define MNTTYPE_FDESC   "fdesc"
54 #define MNTTYPE_PORTAL  "portal"
55 #define MNTTYPE_NULL    "null"
56 #define MNTTYPE_UMAP    "umap"
57 #define MNTTYPE_KERNFS  "kernfs"
58 #define MNTTYPE_PROCFS  "procfs"
59 #define MNTTYPE_AFS     "afs"
60 #define MNTTYPE_CD9660  "cd9660"
61 #define MNTTYPE_UNION   "union"
62 #define MNTTYPE_ADOSFS  "adosfs"
63 #define MNTTYPE_EXT2FS  "ext2fs"
64 #define MNTTYPE_CFS     "coda"
65 #define MNTTYPE_NTFS    "ntfs"
66 #endif
67 #endif
68 #endif                          /* freebsd3 */
69
70 #define HRFS_MONOTONICALLY_INCREASING
71
72         /*********************
73          *
74          *  Kernel & interface information,
75          *   and internal forward declarations
76          *
77          *********************/
78
79 #ifdef solaris2
80
81 struct mnttab   HRFS_entry_struct;
82 struct mnttab  *HRFS_entry = &HRFS_entry_struct;
83 #define HRFS_name       mnt_special
84 #define HRFS_mount      mnt_mountp
85 #define HRFS_type       mnt_fstype
86 #define HRFS_statfs     statvfs
87
88 #elif defined(HAVE_GETFSSTAT)
89 static struct statfs *fsstats = 0;
90 static int      fscount;
91 struct statfs  *HRFS_entry;
92 #define HRFS_statfs     statfs
93 #ifdef MFSNAMELEN
94 #define HRFS_type       f_fstypename
95 #else
96 #define HRFS_type       f_type
97 #endif
98 #define HRFS_mount      f_mntonname
99 #define HRFS_name       f_mntfromname
100
101 #elif defined(dynix)
102
103 struct mntent  *HRFS_entry;
104 #define HRFS_name       mnt_fsname
105 #define HRFS_mount      mnt_dir
106 #define HRFS_type       mnt_type
107 #define HRFS_statfs     statvfs
108
109 #else
110
111 struct mntent  *HRFS_entry;
112 #define HRFS_name       mnt_fsname
113 #define HRFS_mount      mnt_dir
114 #define HRFS_type       mnt_type
115 #define HRFS_statfs     statfs
116
117 #ifdef linux
118 #define MNTTYPE_CD9660  "iso9660"
119 #define MNTTYPE_EXT2FS  "ext2"
120 #define MNTTYPE_EXT3FS  "ext3"
121 #define MNTTYPE_SMBFS   "smbfs"
122 #define MNTTYPE_MSDOS   "msdos"
123 #define MNTTYPE_FAT32   "vfat"
124 #define MNTTYPE_NTFS    "ntfs"
125 #endif  /* linux */
126
127 #endif
128
129 #define FULL_DUMP       0
130 #define PART_DUMP       1
131
132
133 extern void     Init_HR_FileSys(void);
134 extern int      Get_Next_HR_FileSys(void);
135 char           *cook_device(char *);
136 static u_char  *when_dumped(char *filesys, int level, size_t * length);
137 int             header_hrfilesys(struct variable *, oid *, size_t *, int,
138                                  size_t *, WriteMethod **);
139
140         /*********************
141          *
142          *  Initialisation & common implementation functions
143          *
144          *********************/
145
146 #define HRFSYS_INDEX            1
147 #define HRFSYS_MOUNT            2
148 #define HRFSYS_RMOUNT           3
149 #define HRFSYS_TYPE             4
150 #define HRFSYS_ACCESS           5
151 #define HRFSYS_BOOT             6
152 #define HRFSYS_STOREIDX         7
153 #define HRFSYS_FULLDUMP         8
154 #define HRFSYS_PARTDUMP         9
155
156 struct variable4 hrfsys_variables[] = {
157     {HRFSYS_INDEX, ASN_INTEGER, RONLY, var_hrfilesys, 2, {1, 1}},
158     {HRFSYS_MOUNT, ASN_OCTET_STR, RONLY, var_hrfilesys, 2, {1, 2}},
159     {HRFSYS_RMOUNT, ASN_OCTET_STR, RONLY, var_hrfilesys, 2, {1, 3}},
160     {HRFSYS_TYPE, ASN_OBJECT_ID, RONLY, var_hrfilesys, 2, {1, 4}},
161     {HRFSYS_ACCESS, ASN_INTEGER, RONLY, var_hrfilesys, 2, {1, 5}},
162     {HRFSYS_BOOT, ASN_INTEGER, RONLY, var_hrfilesys, 2, {1, 6}},
163     {HRFSYS_STOREIDX, ASN_INTEGER, RONLY, var_hrfilesys, 2, {1, 7}},
164     {HRFSYS_FULLDUMP, ASN_OCTET_STR, RONLY, var_hrfilesys, 2, {1, 8}},
165     {HRFSYS_PARTDUMP, ASN_OCTET_STR, RONLY, var_hrfilesys, 2, {1, 9}},
166 };
167 oid             hrfsys_variables_oid[] = { 1, 3, 6, 1, 2, 1, 25, 3, 8 };
168
169 void
170 init_hr_filesys(void)
171 {
172     REGISTER_MIB("host/hr_filesys", hrfsys_variables, variable4,
173                  hrfsys_variables_oid);
174 }
175
176 /*
177  * header_hrfilesys(...
178  * Arguments:
179  * vp     IN      - pointer to variable entry that points here
180  * name    IN/OUT  - IN/name requested, OUT/name found
181  * length  IN/OUT  - length of IN/OUT oid's 
182  * exact   IN      - TRUE if an exact match was requested
183  * var_len OUT     - length of variable or 0 if function returned
184  * write_method
185  * 
186  */
187
188 int
189 header_hrfilesys(struct variable *vp,
190                  oid * name,
191                  size_t * length,
192                  int exact, size_t * var_len, WriteMethod ** write_method)
193 {
194 #define HRFSYS_ENTRY_NAME_LENGTH        11
195     oid             newname[MAX_OID_LEN];
196     int             fsys_idx, LowIndex = -1;
197     int             result;
198
199     DEBUGMSGTL(("host/hr_filesys", "var_hrfilesys: "));
200     DEBUGMSGOID(("host/hr_filesys", name, *length));
201     DEBUGMSG(("host/hr_filesys", " %d\n", exact));
202
203     memcpy((char *) newname, (char *) vp->name, vp->namelen * sizeof(oid));
204     /*
205      * Find "next" file system entry 
206      */
207
208     Init_HR_FileSys();
209     for (;;) {
210         fsys_idx = Get_Next_HR_FileSys();
211         if (fsys_idx == -1)
212             break;
213         newname[HRFSYS_ENTRY_NAME_LENGTH] = fsys_idx;
214         result = snmp_oid_compare(name, *length, newname, vp->namelen + 1);
215         if (exact && (result == 0)) {
216             LowIndex = fsys_idx;
217             break;
218         }
219         if ((!exact && (result < 0)) &&
220             (LowIndex == -1 || fsys_idx < LowIndex)) {
221             LowIndex = fsys_idx;
222 #ifdef HRFS_MONOTONICALLY_INCREASING
223             break;
224 #endif
225         }
226     }
227
228     if (LowIndex == -1) {
229         DEBUGMSGTL(("host/hr_filesys", "... index out of range\n"));
230         return (MATCH_FAILED);
231     }
232
233     memcpy((char *) name, (char *) newname,
234            (vp->namelen + 1) * sizeof(oid));
235     *length = vp->namelen + 1;
236     *write_method = 0;
237     *var_len = sizeof(long);    /* default to 'long' results */
238
239     DEBUGMSGTL(("host/hr_filesys", "... get filesys stats "));
240     DEBUGMSGOID(("host/hr_filesys", name, *length));
241     DEBUGMSG(("host/hr_filesys", "\n"));
242
243     return LowIndex;
244 }
245
246
247 oid             fsys_type_id[] = { 1, 3, 6, 1, 2, 1, 25, 3, 9, 1 };     /* hrFSOther */
248 int             fsys_type_len =
249     sizeof(fsys_type_id) / sizeof(fsys_type_id[0]);
250
251         /*********************
252          *
253          *  System specific implementation functions
254          *
255          *********************/
256
257
258 u_char         *
259 var_hrfilesys(struct variable *vp,
260               oid * name,
261               size_t * length,
262               int exact, size_t * var_len, WriteMethod ** write_method)
263 {
264     int             fsys_idx;
265     static char     string[100];
266     char           *mnt_type;
267
268     fsys_idx =
269         header_hrfilesys(vp, name, length, exact, var_len, write_method);
270     if (fsys_idx == MATCH_FAILED)
271         return NULL;
272
273
274     switch (vp->magic) {
275     case HRFSYS_INDEX:
276         long_return = fsys_idx;
277         return (u_char *) & long_return;
278     case HRFSYS_MOUNT:
279         snprintf(string, sizeof(string), HRFS_entry->HRFS_mount);
280         string[ sizeof(string)-1 ] = 0;
281         *var_len = strlen(string);
282         return (u_char *) string;
283     case HRFSYS_RMOUNT:
284         if (Check_HR_FileSys_NFS()) {
285             snprintf(string, sizeof(string), HRFS_entry->HRFS_name);
286             string[ sizeof(string)-1 ] = 0;
287         } else
288             string[0] = '\0';
289         *var_len = strlen(string);
290         return (u_char *) string;
291
292     case HRFSYS_TYPE:
293         if (Check_HR_FileSys_NFS())
294             fsys_type_id[fsys_type_len - 1] = 14;
295         else {
296         /*
297          * Not sufficient to identity the file
298          *   type precisely, but it's a start.
299          */
300 #if HAVE_GETFSSTAT && !defined(MFSNAMELEN)
301         switch (HRFS_entry->HRFS_type) {
302         case MOUNT_UFS:
303             fsys_type_id[fsys_type_len - 1] = 3;
304             break;
305         case MOUNT_NFS:
306             fsys_type_id[fsys_type_len - 1] = 14;
307             break;
308         case MOUNT_MFS:
309             fsys_type_id[fsys_type_len - 1] = 8;
310             break;
311         case MOUNT_MSDOS:
312             fsys_type_id[fsys_type_len - 1] = 5;
313             break;
314         case MOUNT_LFS:
315             fsys_type_id[fsys_type_len - 1] = 1;
316             break;
317         case MOUNT_LOFS:
318             fsys_type_id[fsys_type_len - 1] = 1;
319             break;
320         case MOUNT_FDESC:
321             fsys_type_id[fsys_type_len - 1] = 1;
322             break;
323         case MOUNT_PORTAL:
324             fsys_type_id[fsys_type_len - 1] = 1;
325             break;
326         case MOUNT_NULL:
327             fsys_type_id[fsys_type_len - 1] = 1;
328             break;
329         case MOUNT_UMAP:
330             fsys_type_id[fsys_type_len - 1] = 1;
331             break;
332         case MOUNT_KERNFS:
333             fsys_type_id[fsys_type_len - 1] = 1;
334             break;
335         case MOUNT_PROCFS:
336             fsys_type_id[fsys_type_len - 1] = 1;
337             break;
338         case MOUNT_AFS:
339             fsys_type_id[fsys_type_len - 1] = 16;
340             break;
341         case MOUNT_CD9660:
342             fsys_type_id[fsys_type_len - 1] = 12;
343             break;
344         case MOUNT_UNION:
345             fsys_type_id[fsys_type_len - 1] = 1;
346             break;
347         case MOUNT_DEVFS:
348             fsys_type_id[fsys_type_len - 1] = 1;
349             break;
350 #ifdef MOUNT_EXT2FS
351         case MOUNT_EXT2FS:
352             fsys_type_id[fsys_type_len - 1] = 23;
353             break;
354 #endif
355 #ifdef MOUNT_TFS
356         case MOUNT_TFS:
357             fsys_type_id[fsys_type_len - 1] = 15;
358             break;
359 #endif
360         }
361 #else
362         mnt_type = HRFS_entry->HRFS_type;
363         if (mnt_type == NULL)
364             fsys_type_id[fsys_type_len - 1] = 2;        /* unknown */
365 #ifdef MNTTYPE_HFS
366         else if (!strcmp(mnt_type, MNTTYPE_HFS))
367 #ifdef BerkelyFS
368             fsys_type_id[fsys_type_len - 1] = 3;
369 #else                           /* SysV */
370             fsys_type_id[fsys_type_len - 1] = 4;
371 #endif
372 #endif
373 #ifdef MNTTYPE_UFS
374         else if (!strcmp(mnt_type, MNTTYPE_UFS))
375 #if defined(BerkelyFS) && !defined(MNTTYPE_HFS)
376             fsys_type_id[fsys_type_len - 1] = 3;
377 #else                           /* SysV */
378             fsys_type_id[fsys_type_len - 1] = 4;        /* or 3? XXX */
379 #endif
380 #endif
381 #ifdef MNTTYPE_SYSV
382         else if (!strcmp(mnt_type, MNTTYPE_SYSV))
383             fsys_type_id[fsys_type_len - 1] = 4;
384 #endif
385 #ifdef MNTTYPE_PC
386         else if (!strcmp(mnt_type, MNTTYPE_PC))
387             fsys_type_id[fsys_type_len - 1] = 5;
388 #endif
389 #ifdef MNTTYPE_MSDOS
390         else if (!strcmp(mnt_type, MNTTYPE_MSDOS))
391             fsys_type_id[fsys_type_len - 1] = 5;
392 #endif
393 #ifdef MNTTYPE_FAT32
394         else if (!strcmp(mnt_type, MNTTYPE_FAT32))
395             fsys_type_id[fsys_type_len - 1] = 22;
396 #endif
397 #ifdef MNTTYPE_CDFS
398         else if (!strcmp(mnt_type, MNTTYPE_CDFS))
399 #ifdef RockRidge
400             fsys_type_id[fsys_type_len - 1] = 13;
401 #else                           /* ISO 9660 */
402             fsys_type_id[fsys_type_len - 1] = 12;
403 #endif
404 #endif
405 #ifdef MNTTYPE_ISO9660
406         else if (!strcmp(mnt_type, MNTTYPE_ISO9660))
407             fsys_type_id[fsys_type_len - 1] = 12;
408 #endif
409 #ifdef MNTTYPE_CD9660
410         else if (!strcmp(mnt_type, MNTTYPE_CD9660))
411             fsys_type_id[fsys_type_len - 1] = 12;
412 #endif
413 #ifdef MNTTYPE_SMBFS
414         else if (!strcmp(mnt_type, MNTTYPE_SMBFS))
415             fsys_type_id[fsys_type_len - 1] = 1;
416 #endif
417 #ifdef MNTTYPE_NFS
418         else if (!strcmp(mnt_type, MNTTYPE_NFS))
419             fsys_type_id[fsys_type_len - 1] = 14;
420 #endif
421 #ifdef MNTTYPE_NFS3
422         else if (!strcmp(mnt_type, MNTTYPE_NFS3))
423             fsys_type_id[fsys_type_len - 1] = 14;
424 #endif
425 #ifdef MNTTYPE_MFS
426         else if (!strcmp(mnt_type, MNTTYPE_MFS))
427             fsys_type_id[fsys_type_len - 1] = 8;
428 #endif
429 #ifdef MNTTYPE_EXT2FS
430         else if (!strcmp(mnt_type, MNTTYPE_EXT2FS))
431             fsys_type_id[fsys_type_len - 1] = 23;
432 #endif
433 #ifdef MNTTYPE_EXT3FS
434         else if (!strcmp(mnt_type, MNTTYPE_EXT3FS))
435             fsys_type_id[fsys_type_len - 1] = 23;
436 #endif
437 #ifdef MNTTYPE_NTFS
438         else if (!strcmp(mnt_type, MNTTYPE_NTFS))
439             fsys_type_id[fsys_type_len - 1] = 9;
440 #endif
441         else
442             fsys_type_id[fsys_type_len - 1] = 1;        /* Other */
443 #endif                          /* HAVE_GETFSSTAT */
444         }
445
446         *var_len = sizeof(fsys_type_id);
447         return (u_char *) fsys_type_id;
448
449     case HRFSYS_ACCESS:
450 #if HAVE_GETFSSTAT
451         long_return = HRFS_entry->f_flags & MNT_RDONLY ? 2 : 1;
452 #elif defined(cygwin)
453         long_return = 1;
454 #else
455         if (hasmntopt(HRFS_entry, "ro") != NULL)
456             long_return = 2;    /* Read Only */
457         else
458             long_return = 1;    /* Read-Write */
459 #endif
460         return (u_char *) & long_return;
461     case HRFSYS_BOOT:
462         if (HRFS_entry->HRFS_mount[0] == '/' &&
463             HRFS_entry->HRFS_mount[1] == 0)
464             long_return = 1;    /* root is probably bootable! */
465         else
466             long_return = 2;    /* others probably aren't */
467         return (u_char *) & long_return;
468     case HRFSYS_STOREIDX:
469         long_return = fsys_idx; /* Use the same indices */
470         return (u_char *) & long_return;
471     case HRFSYS_FULLDUMP:
472         return when_dumped(HRFS_entry->HRFS_name, FULL_DUMP, var_len);
473     case HRFSYS_PARTDUMP:
474         return when_dumped(HRFS_entry->HRFS_name, PART_DUMP, var_len);
475     default:
476         DEBUGMSGTL(("snmpd", "unknown sub-id %d in var_hrfilesys\n",
477                     vp->magic));
478     }
479     return NULL;
480 }
481
482
483         /*********************
484          *
485          *  Internal implementation functions
486          *
487          *********************/
488
489 static int      HRFS_index;
490 #ifndef HAVE_GETFSSTAT
491 static FILE    *fp;
492 #endif
493
494 void
495 Init_HR_FileSys(void)
496 {
497 #if HAVE_GETFSSTAT
498     fscount = getfsstat(NULL, 0, MNT_NOWAIT);
499     if (fsstats)
500         free((char *) fsstats);
501     fsstats = NULL;
502     fsstats = malloc(fscount * sizeof(*fsstats));
503     getfsstat(fsstats, fscount * sizeof(*fsstats), MNT_NOWAIT);
504     HRFS_index = 0;
505 #else
506     HRFS_index = 1;
507     if (fp != NULL)
508         fclose(fp);
509     fp = fopen(ETC_MNTTAB, "r");
510 #endif
511 }
512
513 const char     *HRFS_ignores[] = {
514 #ifdef MNTTYPE_IGNORE
515     MNTTYPE_IGNORE,
516 #endif
517 #ifdef MNTTYPE_SWAP
518     MNTTYPE_SWAP,
519 #endif
520 #ifdef MNTTYPE_PROC
521     MNTTYPE_PROC,
522 #endif
523 #ifdef MNTTYPE_AUTOFS
524     MNTTYPE_AUTOFS,
525 #endif
526     "autofs",
527 #ifdef linux
528     "devpts",
529     "devfs",
530     "usbdevfs",
531     "tmpfs",
532     "shm",
533 #endif
534 #ifdef solaris2
535     "fd",
536 #endif
537     0
538 };
539
540 int
541 Get_Next_HR_FileSys(void)
542 {
543 #if HAVE_GETFSSTAT
544     if (HRFS_index >= fscount)
545         return -1;
546     HRFS_entry = fsstats + HRFS_index;
547     return ++HRFS_index;
548 #else
549     const char    **cpp;
550     /*
551      * XXX - According to RFC 1514, hrFSIndex must
552      *   "remain constant at least from one re-initialization
553      *    of the agent to the next re-initialization."
554      *
555      *  This simple-minded counter doesn't handle filesystems
556      *    being un-mounted and re-mounted.
557      *  Options for fixing this include:
558      *       - keeping a history of previous indices used
559      *       - calculating the index from filesystem
560      *              specific information
561      *
562      *  Note: this index is also used as hrStorageIndex
563      *     which is assumed to be less than HRS_TYPE_FS_MAX
564      *     This assumption may well be broken if the second
565      *     option above is followed.  Consider indexing the
566      *     non-filesystem-based storage entries first in this
567      *     case, and assume hrStorageIndex > HRS_TYPE_FS_MIN
568      *     (for file-system based storage entries)
569      *
570      *  But at least this gets us started.
571      */
572
573     if (fp == NULL)
574         return -1;
575
576 #ifdef solaris2
577     if (getmntent(fp, HRFS_entry) != 0)
578         return -1;
579 #else
580     HRFS_entry = getmntent(fp);
581     if (HRFS_entry == NULL)
582         return -1;
583 #endif                          /* solaris2 */
584
585     for (cpp = HRFS_ignores; *cpp != NULL; ++cpp)
586         if (!strcmp(HRFS_entry->HRFS_type, *cpp))
587             return Get_Next_HR_FileSys();
588
589     return HRFS_index++;
590 #endif                          /* HAVE_GETFSSTAT */
591 }
592
593 /*
594  * this function checks whether the current file system (info can be found
595  * in HRFS_entry) is a Network file system
596  * HRFS_entry must be valid prior to calling this function
597  * returns 1 if Network file system, 0 otherwise
598  */
599 int
600 Check_HR_FileSys_NFS (void)
601 {
602 #if HAVE_GETFSSTAT
603 #if defined(MFSNAMELEN)
604     if (!strcmp(HRFS_entry->HRFS_type, MOUNT_NFS))
605 #else
606     if (HRFS_entry->HRFS_type == MOUNT_NFS)
607 #endif
608 #else /* HAVE_GETFSSTAT */
609     if ( HRFS_entry->HRFS_type != NULL && (
610 #if defined(MNTTYPE_NFS)
611         !strcmp( HRFS_entry->HRFS_type, MNTTYPE_NFS) ||
612 #else
613         !strcmp( HRFS_entry->HRFS_type, "nfs") ||
614 #endif
615 #if defined(MNTTYPE_NFS3)
616             !strcmp( HRFS_entry->HRFS_type, MNTTYPE_NFS3) ||
617 #endif
618 #if defined(MNTTYPE_SMBFS)
619             !strcmp( HRFS_entry->HRFS_type, MNTTYPE_SMBFS) ||
620 #endif
621 #if defined(MNTTYPE_LOFS)
622             !strcmp( HRFS_entry->HRFS_type, MNTTYPE_LOFS) ||
623 #endif
624             /*
625              * MVFS is Rational ClearCase's view file system
626              * it is similiar to NFS file systems in that it is mounted
627              * locally or remotely from the ClearCase server
628              */
629             !strcmp( HRFS_entry->HRFS_type, "mvfs")))
630 #endif /* HAVE_GETFSSTAT */
631         return 1;       /* Network file system */
632
633     return 0;           /* no Network file system */
634 }
635
636 void
637 End_HR_FileSys(void)
638 {
639 #ifdef HAVE_GETFSSTAT
640     if (fsstats)
641         free((char *) fsstats);
642     fsstats = NULL;
643 #else
644     if (fp != NULL)
645         fclose(fp);
646     fp = NULL;
647 #endif
648 }
649
650
651 static u_char  *
652 when_dumped(char *filesys, int level, size_t * length)
653 {
654     time_t          dumpdate = 0, tmp;
655     FILE           *dump_fp;
656     char            line[100];
657     char           *cp1, *cp2, *cp3;
658
659     /*
660      * Look for the relevent entries in /etc/dumpdates
661      *
662      * This is complicated by the fact that disks are
663      *   mounted using block devices, but dumps are
664      *   done via the raw character devices.
665      * Thus the device names in /etc/dumpdates and
666      *   /etc/mnttab don't match.
667      *   These comparisons are therefore made using the
668      *   final portion of the device name only.
669      */
670
671     if (*filesys == '\0')       /* No filesystem name? */
672         return date_n_time(NULL, length);
673     cp1 = strrchr(filesys, '/');        /* Find the last element of the current FS */
674
675     if (cp1 == NULL)
676         cp1 = filesys;
677
678     if ((dump_fp = fopen("/etc/dumpdates", "r")) == NULL)
679         return date_n_time(NULL, length);
680
681     while (fgets(line, sizeof(line), dump_fp) != NULL) {
682         cp2 = strchr(line, ' ');        /* Start by looking at the device name only */
683         if (cp2 != NULL) {
684             *cp2 = '\0';
685             cp3 = strrchr(line, '/');   /* and find the last element */
686             if (cp3 == NULL)
687                 cp3 = line;
688
689             if (strcmp(cp1, cp3) != 0)  /* Wrong FS */
690                 continue;
691
692             ++cp2;
693             while (isspace(*cp2))
694                 ++cp2;          /* Now find the dump level */
695
696             if (level == FULL_DUMP) {
697                 if (*(cp2++) != '0')
698                     continue;   /* Not interested in partial dumps */
699                 while (isspace(*cp2))
700                     ++cp2;
701
702                 dumpdate = ctime_to_timet(cp2);
703                 fclose(dump_fp);
704                 return date_n_time(&dumpdate, length);
705             } else {            /* Partial Dump */
706                 if (*(cp2++) == '0')
707                     continue;   /* Not interested in full dumps */
708                 while (isspace(*cp2))
709                     ++cp2;
710
711                 tmp = ctime_to_timet(cp2);
712                 if (tmp > dumpdate)
713                     dumpdate = tmp;     /* Remember the 'latest' partial dump */
714             }
715         }
716     }
717
718     fclose(dump_fp);
719
720     return date_n_time(&dumpdate, length);
721 }
722
723
724 #define RAW_DEVICE_PREFIX       "/dev/rdsk"
725 #define COOKED_DEVICE_PREFIX    "/dev/dsk"
726
727 char           *
728 cook_device(char *dev)
729 {
730     static char     cooked_dev[SNMP_MAXPATH+1];
731
732     if (!strncmp(dev, RAW_DEVICE_PREFIX, strlen(RAW_DEVICE_PREFIX))) {
733         strncpy(cooked_dev, COOKED_DEVICE_PREFIX, sizeof(cooked_dev)-1);
734         cooked_dev[ sizeof(cooked_dev)-1 ] = 0;
735         strncat(cooked_dev, dev + strlen(RAW_DEVICE_PREFIX),
736                 sizeof(cooked_dev)-strlen(cooked_dev)-1);
737         cooked_dev[ sizeof(cooked_dev)-1 ] = 0;
738     } else {
739         strncpy(cooked_dev, dev, sizeof(cooked_dev)-1);
740         cooked_dev[ sizeof(cooked_dev)-1 ] = 0;
741     }
742
743     return (cooked_dev);
744 }
745
746
747 int
748 Get_FSIndex(char *dev)
749 {
750     int             iindex;
751
752     Init_HR_FileSys();
753
754     while ((iindex = Get_Next_HR_FileSys()) != -1)
755         if (!strcmp(HRFS_entry->HRFS_name, cook_device(dev))) {
756             End_HR_FileSys();
757             return iindex;
758         }
759
760     End_HR_FileSys();
761     return 0;
762 }
763
764 long
765 Get_FSSize(char *dev)
766 {
767     struct HRFS_statfs statfs_buf;
768
769     Init_HR_FileSys();
770
771     while (Get_Next_HR_FileSys() != -1)
772         if (!strcmp(HRFS_entry->HRFS_name, cook_device(dev))) {
773             End_HR_FileSys();
774
775             if (HRFS_statfs(HRFS_entry->HRFS_mount, &statfs_buf) != -1)
776                 /*
777                  * with large file systems the following calculation produces
778                  * an overflow:
779                  * (statfs_buf.f_blocks*statfs_buf.f_bsize)/1024
780                  *
781                  * assumption: f_bsize is either 512 or a multiple of 1024
782                  * in case of 512 (f_blocks/2) is returned
783                  * otherwise (f_blocks*(f_bsize/1024)) is returned
784                  */
785                 if (statfs_buf.f_bsize == 512)
786                     return (statfs_buf.f_blocks/2);
787                 else
788                     return (statfs_buf.f_blocks*(statfs_buf.f_bsize/1024));
789             else
790                 return -1;
791         }
792
793     End_HR_FileSys();
794     return 0;
795 }