1 /*
2  * Copyright 1994-2018 Brad Lanam, Walnut Creek, CA
3  */
4 
5 #include "config.h"
6 #include "di.h"
7 #include "dimntopt.h"
8 
9 #if _hdr_stdio
10 # include <stdio.h>
11 #endif
12 #if _hdr_stdlib
13 # include <stdlib.h>
14 #endif
15 #if _hdr_string
16 # include <string.h>
17 #endif
18 #if _hdr_strings
19 # include <strings.h>
20 #endif
21 #if _hdr_memory
22 # include <memory.h>
23 #endif
24 #if _hdr_malloc
25 # include <malloc.h>
26 #endif
27 #if _hdr_errno
28 # include <errno.h>
29 #endif
30 #if _use_mcheck
31 # include <mcheck.h>
32 #endif
33 
34 
35 /********************************************************/
36 /*
37     This module contains utility routines for conversion
38     and checking the data.
39 
40     di_initDiskInfo ()
41         initialize disk info structure
42     di_saveBlockSizes ()
43         save the block sizes in the diskinfo structure.
44     di_saveInodeSizes ()
45         save the inode sizes in the diskinfo structure.
46     convertMountOptions ()
47         converts mount options to text format.
48     convertNFSMountOptions ()
49         converts NFS mount options to text format.
50     chkMountOptions ()
51         Checks to see if the mount option is set.
52         Used if hasmntopt() is not present.
53     di_testRemoteDisk ()
54         test a disk to see if it is remote (nfs, nfs3).
55 
56 */
57 
58 void
59 #if _proto_stdc
di_initDiskInfo(diDiskInfo_t * diptr)60 di_initDiskInfo (diDiskInfo_t *diptr)
61 #else
62 di_initDiskInfo (diptr)
63     diDiskInfo_t        *diptr;
64 #endif
65 {
66     memset ((char *) diptr, '\0', sizeof (diDiskInfo_t));
67     diptr->printFlag = DI_PRNT_OK;
68     diptr->isLocal = TRUE;
69     diptr->isReadOnly = FALSE;
70     diptr->isLoopback = FALSE;
71 }
72 
73 void
74 #if _proto_stdc
di_saveBlockSizes(diDiskInfo_t * diptr,_fs_size_t block_size,_fs_size_t total_blocks,_fs_size_t free_blocks,_fs_size_t avail_blocks)75 di_saveBlockSizes (diDiskInfo_t *diptr, _fs_size_t block_size,
76         _fs_size_t total_blocks, _fs_size_t free_blocks,
77         _fs_size_t avail_blocks)
78 #else
79 di_saveBlockSizes (diptr, block_size, total_blocks, free_blocks, avail_blocks)
80     diDiskInfo_t *diptr;
81     _fs_size_t block_size;
82     _fs_size_t total_blocks;
83     _fs_size_t free_blocks;
84     _fs_size_t avail_blocks;
85 #endif
86 {
87     diptr->totalSpace = (_fs_size_t) total_blocks * (_fs_size_t) block_size;
88     diptr->freeSpace = (_fs_size_t) free_blocks * (_fs_size_t) block_size;
89     diptr->availSpace = (_fs_size_t) avail_blocks * (_fs_size_t) block_size;
90 }
91 
92 void
93 #if _proto_stdc
di_saveInodeSizes(diDiskInfo_t * diptr,_fs_size_t total_nodes,_fs_size_t free_nodes,_fs_size_t avail_nodes)94 di_saveInodeSizes (diDiskInfo_t *diptr,
95         _fs_size_t total_nodes, _fs_size_t free_nodes,
96         _fs_size_t avail_nodes)
97 #else
98 di_saveInodeSizes (diptr, total_nodes, free_nodes, avail_nodes)
99     diDiskInfo_t *diptr;
100     _fs_size_t total_nodes;
101     _fs_size_t free_nodes;
102     _fs_size_t avail_nodes;
103 #endif
104 {
105     diptr->totalInodes = total_nodes;
106     diptr->freeInodes = free_nodes;
107     diptr->availInodes = avail_nodes;
108 }
109 
110 void
111 #if _proto_stdc
convertMountOptions(unsigned long flags,diDiskInfo_t * diptr)112 convertMountOptions (unsigned long flags, diDiskInfo_t *diptr)
113 #else
114 convertMountOptions (flags, diptr)
115     unsigned long  flags;
116     diDiskInfo_t   *diptr;
117 #endif
118 {
119 #if defined (MNT_RDONLY)
120     if ((flags & MNT_RDONLY) == MNT_RDONLY)
121     {
122         strncat (diptr->options, "ro,",
123                 DI_OPT_LEN - strlen (diptr->options) - 1);
124     }
125     else
126     {
127         strncat (diptr->options, "rw,",
128                 DI_OPT_LEN - strlen (diptr->options) - 1);
129     }
130 #endif
131 #if defined (MNT_EXRDONLY)
132     if ((flags & MNT_EXRDONLY) == MNT_EXRDONLY)
133     {
134         strncat (diptr->options, "expro,",
135                 DI_OPT_LEN - strlen (diptr->options) - 1);
136     }
137 #endif
138 #if defined (MNT_DEFEXPORTED)
139     if ((flags & MNT_DEFEXPORTED) == MNT_DEFEXPORTED)
140     {
141         strncat (diptr->options, "exprwany,",
142                 DI_OPT_LEN - strlen (diptr->options) - 1);
143     }
144 #endif
145 #if defined (MNT_EXPORTANON)
146     if ((flags & MNT_EXPORTANON) == MNT_EXPORTANON)
147     {
148         strncat (diptr->options, "expanon,",
149                 DI_OPT_LEN - strlen (diptr->options) - 1);
150     }
151 #endif
152 #if defined (MNT_EXKERB)
153     if ((flags & MNT_EXKERB) == MNT_EXKERB)
154     {
155         strncat (diptr->options, "expkerb,",
156                 DI_OPT_LEN - strlen (diptr->options) - 1);
157     }
158 #endif
159 #if defined (MNT_FORCE)
160     if ((flags & MNT_FORCE) == MNT_FORCE)
161     {
162         strncat (diptr->options, "force,",
163                 DI_OPT_LEN - strlen (diptr->options) - 1);
164     }
165 #endif
166 #if defined (MNT_GRPID)
167     if ((flags & MNT_GRPID) == MNT_GRPID)
168     {
169         strncat (diptr->options, "grpid,",
170                 DI_OPT_LEN - strlen (diptr->options) - 1);
171     }
172 #endif
173 #if defined (MNT_MAGICLINKS)
174     if ((flags & MNT_MAGICLINKS) == MNT_MAGICLINKS)
175     {
176         strncat (diptr->options, "magiclinks,",
177                 DI_OPT_LEN - strlen (diptr->options) - 1);
178     }
179 #endif
180 #if defined (MNT_MLSD)
181     if ((flags & MNT_MLSD) == MNT_MLSD)
182     {
183         strncat (diptr->options, "mlsd,",
184                 DI_OPT_LEN - strlen (diptr->options) - 1);
185     }
186 #endif
187 #if defined (MNT_NOATIMES)
188     if ((flags & MNT_NOATIMES) == MNT_NOATIMES)
189     {
190         strncat (diptr->options, "noatime,",
191                 DI_OPT_LEN - strlen (diptr->options) - 1);
192     }
193 #endif
194 #if defined (MNT_NOCACHE)
195     if ((flags & MNT_NOCACHE) == MNT_NOCACHE)
196     {
197         strncat (diptr->options, "nocache,",
198                 DI_OPT_LEN - strlen (diptr->options) - 1);
199     }
200 #endif
201 #if defined (MNT_NOCOREDUMP)
202     if ((flags & MNT_NOCOREDUMP) == MNT_NOCOREDUMP)
203     {
204         strncat (diptr->options, "nocoredump,",
205                 DI_OPT_LEN - strlen (diptr->options) - 1);
206     }
207 #endif
208 #if defined (MNT_NODEV)
209     if ((flags & MNT_NODEV) == MNT_NODEV)
210     {
211         strncat (diptr->options, "nodev,",
212                 DI_OPT_LEN - strlen (diptr->options) - 1);
213     }
214 #endif
215 #if defined (MNT_NODEVMTIME)
216     if ((flags & MNT_NODEVMTIME) == MNT_NODEVMTIME)
217     {
218         strncat (diptr->options, "nodevmtime,",
219                 DI_OPT_LEN - strlen (diptr->options) - 1);
220     }
221 #endif
222 #if defined (MNT_NOEXEC)
223     if ((flags & MNT_NOEXEC) == MNT_NOEXEC)
224     {
225         strncat (diptr->options, "noexec,",
226                 DI_OPT_LEN - strlen (diptr->options) - 1);
227     }
228 #endif
229 #if defined (MNT_NOSUID)
230     if ((flags & MNT_NOSUID) == MNT_NOSUID)
231     {
232         strncat (diptr->options, "nosuid,",
233                 DI_OPT_LEN - strlen (diptr->options) - 1);
234     }
235 #endif
236 #if defined (MNT_QUOTA)
237     if ((flags & MNT_QUOTA) == MNT_QUOTA)
238     {
239         strncat (diptr->options, "quota,",
240                 DI_OPT_LEN - strlen (diptr->options) - 1);
241     }
242 #endif
243 #if defined (MNT_SECURE)
244     if ((flags & MNT_SECURE) == MNT_SECURE)
245     {
246         strncat (diptr->options, "secure,",
247                 DI_OPT_LEN - strlen (diptr->options) - 1);
248     }
249 #endif
250 #if defined (MNT_SMSYNC2)
251     if ((flags & MNT_SMSYNC2) == MNT_SMSYNC2)
252     {
253         strncat (diptr->options, "smsync2,",
254                 DI_OPT_LEN - strlen (diptr->options) - 1);
255     }
256 #endif
257 #if defined (MNT_SOFTDEP)
258     if ((flags & MNT_SOFTDEP) == MNT_SOFTDEP)
259     {
260         strncat (diptr->options, "softdep,",
261                 DI_OPT_LEN - strlen (diptr->options) - 1);
262     }
263 #endif
264 #if defined (MNT_SYMPERM)
265     if ((flags & MNT_SYMPERM) == MNT_SYMPERM)
266     {
267         strncat (diptr->options, "symperm,",
268                 DI_OPT_LEN - strlen (diptr->options) - 1);
269     }
270 #endif
271 #if defined (MNT_SYNC)
272     if ((flags & MNT_SYNC) == MNT_SYNC)
273     {
274         strncat (diptr->options, "sync,",
275                 DI_OPT_LEN - strlen (diptr->options) - 1);
276     }
277 #endif
278 #if defined (MNT_SYNCHRONOUS)
279     if ((flags & MNT_SYNCHRONOUS) == MNT_SYNCHRONOUS)
280     {
281         strncat (diptr->options, "sync,",
282                 DI_OPT_LEN - strlen (diptr->options) - 1);
283     }
284 #endif
285 #if defined (MNT_THROTTLE)
286     if ((flags & MNT_THROTTLE) == MNT_THROTTLE)
287     {
288         strncat (diptr->options, "throttle,",
289                 DI_OPT_LEN - strlen (diptr->options) - 1);
290     }
291 #endif
292 #if defined (MNT_UNION)
293     if ((flags & MNT_UNION) == MNT_UNION)
294     {
295         strncat (diptr->options, "union,",
296                 DI_OPT_LEN - strlen (diptr->options) - 1);
297     }
298 #endif
299 #if defined (MNT_UNION)
300     if ((flags & MNT_UNION) == MNT_UNION)
301     {
302         strncat (diptr->options, "union,",
303                 DI_OPT_LEN - strlen (diptr->options) - 1);
304     }
305 #endif
306 #if defined (MNT_REMOVABLE)
307     if ((flags & MNT_REMOVABLE) == MNT_REMOVABLE)
308     {
309         strncat (diptr->options, "removable,",
310                 DI_OPT_LEN - strlen (diptr->options) - 1);
311     }
312 #endif
313 #if defined (MNT_PERSISTENT)
314     if ((flags & MNT_PERSISTENT) == MNT_PERSISTENT)
315     {
316         strncat (diptr->options, "persistent,",
317                 DI_OPT_LEN - strlen (diptr->options) - 1);
318     }
319 #endif
320 #if defined (MNT_SHARED)
321     if ((flags & MNT_SHARED) == MNT_SHARED)
322     {
323         strncat (diptr->options, "shared,",
324                 DI_OPT_LEN - strlen (diptr->options) - 1);
325     }
326 #endif
327 #if defined (MNT_BLOCKBASED)
328     if ((flags & MNT_BLOCKBASED) == MNT_BLOCKBASED)
329     {
330         strncat (diptr->options, "blockbased,",
331                 DI_OPT_LEN - strlen (diptr->options) - 1);
332     }
333 #endif
334 #if defined (MNT_HAS_MIME)
335     if ((flags & MNT_HAS_MIME) == MNT_HAS_MIME)
336     {
337         strncat (diptr->options, "mime,",
338                 DI_OPT_LEN - strlen (diptr->options) - 1);
339     }
340 #endif
341 #if defined (MNT_HAS_QUERY)
342     if ((flags & MNT_HAS_QUERY) == MNT_HAS_QUERY)
343     {
344         strncat (diptr->options, "query,",
345                 DI_OPT_LEN - strlen (diptr->options) - 1);
346     }
347 #endif
348 #if defined (MNT_HAS_ATTR)
349     if ((flags & MNT_HAS_ATTR) == MNT_HAS_ATTR)
350     {
351         strncat (diptr->options, "attr,",
352                 DI_OPT_LEN - strlen (diptr->options) - 1);
353     }
354 #endif
355     return;
356 }
357 
358 void
359 #if _proto_stdc
convertNFSMountOptions(long flags,long wsize,long rsize,diDiskInfo_t * diptr)360 convertNFSMountOptions (long flags, long wsize, long rsize, diDiskInfo_t *diptr)
361 #else
362 convertNFSMountOptions (flags, wsize, rsize, diptr)
363     long          flags;
364     long          wsize;
365     long          rsize;
366     diDiskInfo_t   *diptr;
367 #endif
368 {
369 #if defined (NFSMNT_SOFT)
370     if ((flags & NFSMNT_SOFT) != NFSMNT_SOFT)
371     {
372         strncat (diptr->options, "hard,",
373                 DI_OPT_LEN - strlen (diptr->options) - 1);
374     }
375 #endif
376 #if defined (NFSMNT_WSIZE)
377     if ((flags & NFSMNT_WSIZE) == NFSMNT_WSIZE)
378     {
379         char          tmp [64];
380 
381         Snprintf1 (tmp, sizeof (tmp), "wsize=%ld,", wsize);
382         strncat (diptr->options, tmp,
383                 DI_OPT_LEN - strlen (diptr->options) - 1);
384     }
385 #endif
386 #if defined (NFSMNT_RSIZE)
387     if ((flags & NFSMNT_RSIZE) == NFSMNT_RSIZE)
388     {
389         char          tmp [64];
390 
391         Snprintf1 (tmp, sizeof (tmp), "rsize=%ld,", rsize);
392         strncat (diptr->options, tmp,
393                 DI_OPT_LEN - strlen (diptr->options) - 1);
394     }
395 #endif
396 #if defined (NFSMNT_INT) && defined (NFSMNT_SOFT)
397     if ((flags & NFSMNT_SOFT) != NFSMNT_SOFT &&
398         (flags & NFSMNT_INT) == NFSMNT_INT)
399     {
400         strncat (diptr->options, "intr,",
401                 DI_OPT_LEN - strlen (diptr->options) - 1);
402     }
403 #endif
404 #if defined (NFSMNT_TCP)
405     if ((flags & NFSMNT_TCP) != NFSMNT_TCP)
406     {
407         strncat (diptr->options, "udp,",
408                 DI_OPT_LEN - strlen (diptr->options) - 1);
409     }
410 #endif
411     return;
412 }
413 
414 
415 #if _lib_getmntent \
416     && ! _lib_getmntinfo \
417     && ! _lib_getfsstat \
418     && ! _lib_getvfsstat \
419 	&& ! _lib_mntctl \
420 	&& ! _class_os__Volumes
421 
422 char *
423 #if _proto_stdc
chkMountOptions(const char * mntopts,const char * str)424 chkMountOptions (const char *mntopts, const char *str)
425 #else
426 chkMountOptions (mntopts, str)
427     const char          *mntopts;
428     const char          *str;
429 #endif
430 {
431     char    *ptr;
432     char    *tstr;
433 
434     tstr = strdup (mntopts);
435     if (tstr == (char *) NULL)
436     {
437         fprintf (stderr, "strdup failed in chkMountOptions (1).  errno %d\n", errno);
438         exit (1);
439     }
440     ptr = strtok (tstr, ",");
441     while (ptr != (char *) NULL)
442     {
443         if (strcmp (ptr, str) == 0)
444         {
445             free (tstr);
446             return ptr;
447         }
448         ptr = strtok ((char *) NULL, ",");
449     }
450     free (tstr);
451     return (char *) NULL;
452 }
453 
454 #endif /* _lib_getmntent */
455 
456 void
457 #if _proto_stdc
di_testRemoteDisk(diDiskInfo_t * diskInfo)458 di_testRemoteDisk (diDiskInfo_t *diskInfo)
459 #else
460 di_testRemoteDisk (diskInfo)
461     diDiskInfo_t *diskInfo;
462 #endif
463 {
464   if (strncmp (diskInfo->fsType, "nfs", 3) == 0)
465   {
466     diskInfo->isLocal = FALSE;
467   }
468 }
469 
470 int
471 #if _proto_stdc
di_isPooledFs(diDiskInfo_t * diskInfo)472 di_isPooledFs (diDiskInfo_t *diskInfo)
473 #else
474 di_isPooledFs (diskInfo)
475     diDiskInfo_t *diskInfo;
476 #endif
477 {
478   if (strcmp (diskInfo->fsType, "zfs") == 0 ||
479       strcmp (diskInfo->fsType, "advfs") == 0 ||
480       strcmp (diskInfo->fsType, "apfs") == 0 ||
481       (strcmp (diskInfo->fsType, "null") == 0 &&
482        strstr (diskInfo->special, "/@@-") != (char *) NULL)) {
483     return TRUE;
484   }
485   return FALSE;
486 }
487 
488 int
489 #if _proto_stdc
di_isLoopbackFs(diDiskInfo_t * diskInfo)490 di_isLoopbackFs (diDiskInfo_t *diskInfo)
491 #else
492 di_isLoopbackFs (diskInfo)
493     diDiskInfo_t *diskInfo;
494 #endif
495 {
496   if ((strcmp (diskInfo->fsType, "lofs") == 0 && diskInfo->sp_rdev != 0) ||
497       (strcmp (diskInfo->fsType, "nullfs") == 0 &&
498        strstr (diskInfo->special, "/@@-") == (char *) NULL) ||
499       strcmp (diskInfo->fsType, "none") == 0) {
500     return TRUE;
501   }
502   return FALSE;
503 }
504 
505 Size_t
506 #if _proto_stdc
di_mungePoolName(char * poolname)507 di_mungePoolName (char *poolname)
508 #else
509 di_mungePoolName (poolname)
510   char      *poolname;
511 #endif
512 {
513   char      *ptr;
514 
515   ptr = strchr (poolname, '#');   /* advfs */
516   if (ptr != (char *) NULL) {
517     *ptr = '\0';
518   } else {
519     ptr = strchr (poolname, ':');   /* dragonflybsd */
520     if (ptr != (char *) NULL) {
521       *ptr = '\0';
522     } else {
523       if (strncmp (poolname, "/dev/disk", 9) == 0) {
524         /* apfs uses a standard /dev/diskNsN format */
525         ptr = strchr (poolname, 's');
526         if (ptr != (char *) NULL) {
527           ++ptr;
528           if (ptr != (char *) NULL) {
529             ptr = strchr (ptr, 's');
530             if (ptr != (char *) NULL) {
531               *ptr = '\0';
532             }
533           }
534         }
535       } else {
536         ptr = strchr (poolname, '/');   /* zfs */
537         if (ptr != (char *) NULL) {
538           *ptr = '\0';
539         }
540       }
541     }
542   }
543   return strlen (poolname);
544 }
545 
546