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