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