1 /* GKrellM
2 |  Copyright (C) 1999-2019 Bill Wilson
3 |
4 |  Author:  Bill Wilson    billw@gkrellm.net
5 |  Latest versions might be found at:  http://gkrellm.net
6 |
7 |  bsd-common.c code is Copyright (C):
8 |            Hajimu UMEMOTO <ume@FreeBSD.org>
9 |            Anthony Mallet <anthony.mallet@useless-ficus.net>
10 |
11 |
12 |  GKrellM is free software: you can redistribute it and/or modify it
13 |  under the terms of the GNU General Public License as published by
14 |  the Free Software Foundation, either version 3 of the License, or
15 |  (at your option) any later version.
16 |
17 |  GKrellM is distributed in the hope that it will be useful, but WITHOUT
18 |  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
19 |  or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
20 |  License for more details.
21 |
22 |  You should have received a copy of the GNU General Public License
23 |  along with this program. If not, see http://www.gnu.org/licenses/
24 |
25 |
26 |  Additional permission under GNU GPL version 3 section 7
27 |
28 |  If you modify this program, or any covered work, by linking or
29 |  combining it with the OpenSSL project's OpenSSL library (or a
30 |  modified version of that library), containing parts covered by
31 |  the terms of the OpenSSL or SSLeay licenses, you are granted
32 |  additional permission to convey the resulting work.
33 |  Corresponding Source for a non-source form of such a combination
34 |  shall include the source code for the parts of OpenSSL used as well
35 |  as that of the covered work.
36 */
37 
38 #if !(defined(__FreeBSD__) && __FreeBSD_version < 410000) && \
39     !(defined(__NetBSD__) && __NetBSD_version < 105000000) && \
40     !(defined(__OpenBSD__) && OpenBSD < 200006) && \
41     !defined(__APPLE__)
42 #define HAVE_GETIFADDRS	1
43 #endif
44 
45 #if defined(HAVE_GETIFADDRS)
46 
47 #include <sys/types.h>
48 #include <sys/socket.h>
49 #include <net/if.h>
50 #include <ifaddrs.h>
51 
52 void
gkrellm_sys_net_read_data(void)53 gkrellm_sys_net_read_data(void)
54 	{
55 	struct ifaddrs		*ifap, *ifa;
56 	struct if_data		*ifd;
57 
58 	if (getifaddrs(&ifap) < 0)
59 		return;
60 
61 	for (ifa = ifap; ifa; ifa = ifa->ifa_next)
62 		{
63 		if (ifa->ifa_flags & IFF_UP)
64 			{
65 			if (ifa->ifa_addr->sa_family != AF_LINK)
66 				continue;
67 #ifdef IFF_CANTCONFIG
68 			if ((ifa->ifa_flags & IFF_CANTCONFIG) != 0)
69 				continue;
70 #endif
71 			ifd = (struct if_data *)ifa->ifa_data;
72 			gkrellm_net_assign_data(ifa->ifa_name,
73 					ifd->ifi_ibytes, ifd->ifi_obytes);
74 			}
75 		}
76 
77 	freeifaddrs(ifap);
78 	}
79 
80 #else /* HAVE_GETIFADDRS */
81 
82 #include <sys/sysctl.h>
83 #include <sys/socket.h> // For PF_ROUTE, etc
84 #include <net/if.h>
85 #include <net/if_dl.h>
86 #include <net/route.h>
87 
88 
89 static int	mib_net[] = { CTL_NET, PF_ROUTE, 0, 0, NET_RT_IFLIST, 0 };
90 static char	*buf;
91 static int	alloc;
92 
93 void
gkrellm_sys_net_read_data(void)94 gkrellm_sys_net_read_data(void)
95 	{
96 	struct if_msghdr	*ifm, *nextifm;
97 	struct sockaddr_dl	*sdl;
98 	char			*lim, *next;
99 	size_t			needed;
100 	gchar			s[32];
101 
102 	if (sysctl(mib_net, 6, NULL, &needed, NULL, 0) < 0)
103 		return;
104 	if (alloc < needed)
105 		{
106 		if (buf != NULL)
107 			free(buf);
108 		buf = malloc(needed);
109 		if (buf == NULL)
110 			return;
111 		alloc = needed;
112 		}
113 
114 	if (sysctl(mib_net, 6, buf, &needed, NULL, 0) < 0)
115 		return;
116 	lim = buf + needed;
117 
118 	next = buf;
119 	while (next < lim)
120 		{
121 		ifm = (struct if_msghdr *)next;
122 		if (ifm->ifm_type != RTM_IFINFO)
123 			return;
124 		next += ifm->ifm_msglen;
125 
126 		while (next < lim)
127 			{
128 			nextifm = (struct if_msghdr *)next;
129 			if (nextifm->ifm_type != RTM_NEWADDR)
130 				break;
131 			next += nextifm->ifm_msglen;
132 			}
133 
134 		if (ifm->ifm_flags & IFF_UP)
135 			{
136 			sdl = (struct sockaddr_dl *)(ifm + 1);
137 			if (sdl->sdl_family != AF_LINK)
138 				continue;
139 			strncpy(s, sdl->sdl_data, sdl->sdl_nlen);
140 			s[sdl->sdl_nlen] = '\0';
141 			gkrellm_net_assign_data(s,
142 					ifm->ifm_data.ifi_ibytes, ifm->ifm_data.ifi_obytes);
143 			}
144 		}
145 	}
146 
147 #endif /* HAVE_GETIFADDRS */
148 
149   /* This would be needed only if net up (or routed) state is available in
150   |  a different way than for reading net stats.
151   */
152 void
gkrellm_sys_net_check_routes(void)153 gkrellm_sys_net_check_routes(void)
154 	{
155 	return;
156 	}
157 
158 gboolean
gkrellm_sys_net_isdn_online(void)159 gkrellm_sys_net_isdn_online(void)
160 	{
161 	return FALSE;
162 	}
163 
164 gboolean
gkrellm_sys_net_init(void)165 gkrellm_sys_net_init(void)
166 	{
167 	gkrellm_net_set_lock_directory("/var/spool/lock");
168 	gkrellm_net_add_timer_type_ppp("tun0");
169 	gkrellm_net_add_timer_type_ppp("ppp0");
170 	return TRUE;
171 	}
172 
173 
174 /* ===================================================================== */
175 /* FS monitor interface */
176 
177 #include <sys/mount.h>
178 #if !defined(__APPLE__)
179 #include <sys/cdio.h>
180 #endif
181 #include <sys/wait.h>
182 
183 #if defined(__FreeBSD__)
184 #include <osreldate.h>
185 #if __FreeBSD_version < 300000
186 static char	*mnttype[] = INITMOUNTNAMES;
187 #endif
188 #endif
189 
190 static void
fix_fstab_name(gchar * buf)191 fix_fstab_name(gchar *buf)
192 	{
193 	gchar	*rp,
194 			*wp;
195 
196 	if (buf[0] == '\0')
197 		return;
198 	rp = buf;
199 	wp = buf;
200 	do	/* This loop same as in libc6 getmntent()	*/
201 		if (rp[0] == '\\' && rp[1] == '0' && rp[2] == '4' && rp[3] == '0')
202 			{
203 			*wp++ = ' ';		/* \040 is a SPACE.  */
204 			rp += 3;
205 			}
206 		else if (rp[0] == '\\' && rp[1] == '0' && rp[2] == '1' && rp[3] == '2')
207 			{
208 			*wp++ = '\t';		/* \012 is a TAB.  */
209 			rp += 3;
210 			}
211 		else if (rp[0] == '\\' && rp[1] == '\\')
212 			{
213 			*wp++ = '\\';		/* \\ is a \	*/
214 			rp += 1;
215 			}
216 		else
217 			*wp++ = *rp;
218 	while (*rp++ != '\0');
219 	}
220 
221 gboolean
gkrellm_sys_fs_fstab_modified(void)222 gkrellm_sys_fs_fstab_modified(void)
223 	{
224 	struct stat		s;
225 	static time_t	fstab_mtime;
226 	gint			modified = FALSE;
227 
228 	if (stat("/etc/fstab", &s) == 0 && s.st_mtime != fstab_mtime)
229 		modified = TRUE;
230 	fstab_mtime = s.st_mtime;
231 	return modified;
232 	}
233 
234 void
gkrellm_sys_fs_get_fstab_list(void)235 gkrellm_sys_fs_get_fstab_list(void)
236 	{
237 	FILE			*f;
238 	gchar			buf[1024], *s;
239 	gchar			dev[65], dir[129], type[65], opt[129];
240 
241 	if ((f = fopen("/etc/fstab", "r")) == NULL)
242 		return;
243 	while (fgets(buf, sizeof(buf), f))
244 		{
245 		s = buf;
246 		while (*s == ' ' || *s == '\t')
247 			++s;
248 		if (*s == '\0' || *s == '#' || *s == '\n')
249 			continue;
250 		dev[0] = dir[0] = type[0] = opt[0] = '\0';
251 		sscanf(s, "%64s %128s %64s %128s", dev, dir, type, opt);
252 		fix_fstab_name(dev);
253 		fix_fstab_name(dir);
254 		fix_fstab_name(type);
255 		fix_fstab_name(opt);
256 
257 		if (   type[0] == '\0'
258 			|| !strcmp(type, "devpts")
259 			|| !strcmp(type, "swap")
260 			|| !strcmp(type, "proc")
261 			|| !strcmp(type, "usbdevfs")
262 			|| !strcmp(type, "ignore")
263 		   )
264 			continue;
265 		gkrellm_fs_add_to_fstab_list(dir, dev, type, opt);
266 		}
267 	fclose(f);
268 	}
269 
270 
271 void
gkrellm_sys_fs_get_mounts_list(void)272 gkrellm_sys_fs_get_mounts_list(void)
273 	{
274 	gchar		*s, *dev, *dir, *type;
275 #if (defined(__NetBSD__) && __NetBSD_Version__ >= 299000900) /* NetBSD 2.99.9 */
276 	struct statvfs	*mntbuf;
277 #else
278 	struct statfs	*mntbuf;
279 #endif
280 	gint		mntsize, i;
281 
282 	if ((mntsize = getmntinfo(&mntbuf, MNT_NOWAIT)) == 0)
283 		return;
284 	for (i = 0; i < mntsize; i++)
285 		{
286 #if defined(__FreeBSD__) && __FreeBSD_version < 300000
287 		type = mnttype[mntbuf[i].f_type];
288 #else
289 		type = mntbuf[i].f_fstypename;
290 #endif
291 		dir = mntbuf[i].f_mntonname;
292 		dev = mntbuf[i].f_mntfromname;
293 		/* Strip trailing / from the directory.
294 		*/
295 		s = strrchr(dir, (int) '/');
296 		if (s && s != dir && *(s+1) == '\0')
297 			*s = '\0';
298 		gkrellm_fs_add_to_mounts_list(dir, dev, type);
299 		}
300 	}
301 
302 void
gkrellm_sys_fs_get_fsusage(gpointer fs,gchar * dir)303 gkrellm_sys_fs_get_fsusage(gpointer fs, gchar *dir)
304 	{
305 #if (defined(__NetBSD__) && __NetBSD_Version__ >= 299000900) /* NetBSD 2.99.9 */
306 	struct statvfs	st;
307 #else
308 	struct statfs	st;
309 #endif
310 
311 #if (defined(__NetBSD__) && __NetBSD_Version__ >= 299000900) /* NetBSD 2.99.9 */
312 	if (!statvfs(dir, &st))
313 #else
314 	if (!statfs(dir, &st))
315 #endif
316 		gkrellm_fs_assign_fsusage_data(fs,
317 					(gint64) st.f_blocks, (gint64) st.f_bavail,
318 #if (defined(__NetBSD__) && __NetBSD_Version__ >= 299000900) /* NetBSD 2.99.9 */
319 					(gint64) st.f_bfree, (gint64) st.f_frsize);
320 #else
321 					(gint64) st.f_bfree, (gint64) st.f_bsize);
322 #endif
323 	else
324 		gkrellm_fs_assign_fsusage_data(fs, 0, 0, 0, 0);
325 	}
326 
327 
328 #if defined(__APPLE__)
329 #include <IOKit/storage/IOMediaBSDClient.h>
330 
331 static void
eject_darwin_cdrom(gchar * device)332 eject_darwin_cdrom(gchar *device)
333 	{
334     gint    d;
335 
336     if ((d = open(device, O_RDONLY)) >= 0)
337             {
338             ioctl(d, DKIOCEJECT);
339             close(d);
340             }
341 	}
342 #else	/* FreeBSD || NetBSD || OpenBSD */
343 static void
eject_bsd_cdrom(gchar * device)344 eject_bsd_cdrom(gchar *device)
345 	{
346 	gint	d;
347 
348 	if ((d = open(device, O_RDONLY)) >= 0)
349 		{
350 		(void) ioctl(d, CDIOCALLOW);
351 		ioctl(d, CDIOCEJECT);
352 		close(d);
353 		}
354 	}
355 #endif
356 
357 
358 #if defined(__APPLE__)
359 gboolean
gkrellm_sys_fs_init(void)360 gkrellm_sys_fs_init(void)
361 	{
362 	gchar	*eject_command = NULL,
363 			*close_command = NULL;
364 
365 #if defined(WEXITSTATUS)
366 	gint    n;
367 
368 	n = system("hdiutil info > /dev/null 2>&1");
369 	if (WEXITSTATUS(n) == 0)
370 		{
371         eject_command = "hdiutil eject %s";
372         close_command = "disktool -o %s";
373 		}
374 #endif
375 	gkrellm_fs_setup_eject(eject_command, close_command,
376 				eject_darwin_cdrom, NULL);
377 	return TRUE;
378 	}
379 #endif
380 
381 #if defined(__FreeBSD__) || defined(__DragonFly__)
382 gboolean
gkrellm_sys_fs_init(void)383 gkrellm_sys_fs_init(void)
384 	{
385 	gchar	*eject_command = NULL,
386 			*close_command = NULL;
387 
388 #if defined(WEXITSTATUS)
389 	gint	n;
390 
391 	n = system("cdcontrol quit > /dev/null 2>&1");
392 	if (WEXITSTATUS(n) == 0)
393 		{
394 		eject_command = "cdcontrol -f %s eject";
395 		close_command = "cdcontrol -f %s close";
396 		}
397 #endif
398 	gkrellm_fs_setup_eject(eject_command, close_command,
399 				eject_bsd_cdrom, NULL);
400 	return TRUE;
401 	}
402 #endif	/* __FreeBSD__ */
403 
404 
405 #if defined(__NetBSD__)
406 gboolean
gkrellm_sys_fs_init(void)407 gkrellm_sys_fs_init(void)
408 	{
409 	gchar	*eject_command = NULL,
410 			*close_command = NULL;
411 
412 #if defined(WEXITSTATUS)
413 	gint	n;
414 
415 	n = system("eject -n > /dev/null 2>&1");
416 	if (WEXITSTATUS(n) == 0)
417 		{
418 		eject_command = "eject %s";
419 		close_command = "eject -l %s";
420 		}
421 #endif
422 	gkrellm_fs_setup_eject(eject_command, close_command,
423 				eject_bsd_cdrom, NULL);
424 	return TRUE;
425 	}
426 #endif /* __NetBSD__ */
427 
428 
429 #if defined(__OpenBSD__)
430 gboolean
gkrellm_sys_fs_init(void)431 gkrellm_sys_fs_init(void)
432 	{
433 	gkrellm_fs_setup_eject(NULL, NULL, eject_bsd_cdrom, NULL);
434 	return TRUE;
435 	}
436 #endif /* __OpenBSD__ */
437 
438 
439 /* ===================================================================== */
440 /* Uptime monitor interface */
441 
442 #include <sys/sysctl.h>
443 
444 time_t
gkrellm_sys_uptime_read_uptime(void)445 gkrellm_sys_uptime_read_uptime(void)
446 	{
447 	return (time_t) 0;	/* Will calculate using base_uptime */
448 	}
449 
450 gboolean
gkrellm_sys_uptime_init(void)451 gkrellm_sys_uptime_init(void)
452 	{
453 	static int		mib[] = { CTL_KERN, KERN_BOOTTIME };
454 	struct timeval		boottime;
455 	size_t			size = sizeof(boottime);
456 	time_t			base_uptime, now;
457 
458 	base_uptime = (time_t) 0;
459 	if (sysctl(mib, 2, &boottime, &size, NULL, 0) != -1 &&
460 	    boottime.tv_sec != 0)
461 		{
462 		(void)time(&now);
463 		base_uptime = now - boottime.tv_sec;
464 		base_uptime += 30;
465 		}
466 	gkrellm_uptime_set_base_uptime(base_uptime);
467 
468 	return (base_uptime == (time_t) 0) ? FALSE : TRUE;
469 	}
470 
471