1 /*
2 * Copyright (c) 2016-2017, Robin Hahling
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 *
8 * * Redistributions of source code must retain the above copyright notice, this
9 * list of conditions and the following disclaimer.
10 *
11 * * Redistributions in binary form must reproduce the above copyright notice,
12 * this list of conditions and the following disclaimer in the documentation
13 * and/or other materials provided with the distribution.
14 *
15 * * Neither the name of the author nor the names of its contributors may be
16 * used to endorse or promote products derived from this software without
17 * specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
23 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
30 */
31
32 /*
33 * services-solaris.c
34 *
35 * Solaris implemention of services.
36 */
37 #ifdef __sun
38
39 #include <stdio.h>
40 #include <stdlib.h>
41 #include <string.h>
42 #include <unistd.h>
43
44 #ifdef NLS_ENABLED
45 #include <locale.h>
46 #include <libintl.h>
47 #endif /* NLS_ENABLED */
48
49 #include <sys/mnttab.h>
50 #include <sys/statvfs.h>
51
52 #include "extern.h"
53 #include "services.h"
54 #include "util.h"
55
56 int
is_mnt_ignore(const struct fsmntinfo * fs)57 is_mnt_ignore(const struct fsmntinfo *fs)
58 {
59 /* if the size is zero, it is most likely a fs that we want to ignore */
60 if (fs->blocks == 0)
61 return 1;
62
63 /* treat tmpfs/devtmpfs/... as a special case */
64 if (fs->fstype && strstr(fs->fstype, "tmpfs"))
65 return 0;
66
67 /* libc is dynamically mounted into /lib, treat it as a special case */
68 if (fs->mntdir && (strncmp(fs->mntdir, "/lib/", 5) == 0))
69 return 1;
70
71 return is_pseudofs(fs->fstype);
72 }
73
74 int
is_remote(const struct fsmntinfo * fs)75 is_remote(const struct fsmntinfo *fs)
76 {
77 return is_remotefs(fs->fstype);
78 }
79
80 void
fetch_info(struct list * lst)81 fetch_info(struct list *lst)
82 {
83 struct fsmntinfo *fmi;
84 FILE *mnttab;
85 struct mnttab mnttabbuf;
86 struct statvfs vfsbuf;
87 int ret;
88
89 /* init fsmntinfo */
90 if ((fmi = malloc(sizeof(struct fsmntinfo))) == NULL) {
91 (void)fputs("Error while allocating memory to fmi", stderr);
92 exit(EXIT_FAILURE);
93 /* NOTREACHED */
94 }
95 *fmi = fmi_init();
96
97 /* open mnttab file */
98 if ((mnttab = fopen("/etc/mnttab", "r")) == NULL) {
99 perror("Error while opening mnttab file ");
100 exit(EXIT_FAILURE);
101 /* NOTREACHED */
102 }
103
104 /* loop to get infos from all the mounted fs */
105 while ((ret = getmntent(mnttab, &mnttabbuf)) == 0) {
106 if (statvfs(mnttabbuf.mnt_mountp, &vfsbuf) == -1) {
107 (void)fprintf(stderr, _("WARNING: %s was skipped "
108 "because it could not be stated"),
109 mnttabbuf.mnt_mountp);
110 perror(" ");
111 continue;
112 }
113 if ((fmi->fsnameog = strdup(mnttabbuf.mnt_special)) == NULL)
114 fmi->fsnameog = g_unknown_str;
115 if ((fmi->mntdirog = strdup(mnttabbuf.mnt_mountp))== NULL)
116 fmi->mntdirog = g_unknown_str;
117 if ((fmi->fstypeog = strdup(mnttabbuf.mnt_fstype)) == NULL)
118 fmi->fstypeog = g_unknown_str;
119 if (Wflag) { /* Wflag to avoid name truncation */
120 fmi->fsname = fmi->fsnameog;
121 fmi->mntdir = fmi->mntdirog;
122 fmi->fstype = fmi->fstypeog;
123 } else {
124 if ((fmi->fsname = strdup(shortenstr(
125 mnttabbuf.mnt_special, STRMAXLEN))) == NULL) {
126 fmi->fsname = g_unknown_str;
127 }
128 if ((fmi->mntdir = strdup(shortenstr
129 (mnttabbuf.mnt_mountp, STRMAXLEN))) == NULL) {
130 fmi->mntdir = g_unknown_str;
131 }
132 if ((fmi->fstype = strdup(shortenstr(
133 mnttabbuf.mnt_fstype, STRMAXLEN))) == NULL) {
134 fmi->fstype = g_unknown_str;
135 }
136 }
137
138 if ((fmi->mntopts = strdup(mnttabbuf.mnt_mntopts)) == NULL)
139 fmi->mntopts = g_none_str;
140
141 fmi->bsize = vfsbuf.f_bsize;
142 fmi->frsize = vfsbuf.f_frsize;
143 fmi->blocks = vfsbuf.f_blocks;
144 fmi->bfree = vfsbuf.f_bfree;
145 fmi->bavail = vfsbuf.f_bavail;
146 fmi->files = vfsbuf.f_files;
147 fmi->ffree = vfsbuf.f_ffree;
148 fmi->favail = vfsbuf.f_favail;
149
150 compute_fs_stats(fmi);
151
152 fmi->next = NULL;
153 enqueue(lst, *fmi);
154
155 update_maxwidth(fmi);
156 }
157 if (ret > 0) {
158 (void)fprintf(stderr, "An error occured while reading the "
159 "mnttab file\n");
160 }
161
162 /* we need to close the mnttab file now */
163 if (fclose(mnttab) == EOF)
164 perror("Could not close mnttab file ");
165 free(fmi);
166 }
167
168 void
compute_fs_stats(struct fsmntinfo * fmi)169 compute_fs_stats(struct fsmntinfo *fmi)
170 {
171 fmi->total = (double)fmi->frsize * (double)fmi->blocks;
172 fmi->avail = (double)fmi->frsize * (double)fmi->bavail;
173 fmi->used = (double)fmi->frsize * ((double)fmi->blocks - (double)fmi->bfree);
174 if ((int)fmi->total == 0)
175 fmi->perctused = 100.0;
176 else
177 fmi->perctused = 100.0 -
178 ((double)fmi->bavail / (double)fmi->blocks) * 100.0;
179 }
180
181 #endif /* __sun */
182