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