#include #include #include #include #include #include #include #include #include #include #include #include "info.h" static const char *os_release; static pthread_once_t once_init_openbsd; static void init_openbsd(void) { struct utsname un; if (uname(&un) == -1) return; os_release = strdup(un.release); } const char *get_os_release(void) { pthread_once(&once_init_openbsd, init_openbsd); return (os_release); } unsigned long get_cpu_speed(void) { unsigned int mhz; int mib[2], error; size_t len; mib[0] = CTL_HW; mib[1] = HW_CPUSPEED; len = sizeof(mhz); error = sysctl(mib, 2, &mhz, &len, NULL, 0); if (error == -1) return 0; return mhz; } unsigned long get_proc_total(void) { struct kinfo_proc *kp, *kpp; int mib[6], count, error; size_t len; mib[0] = CTL_KERN; mib[1] = KERN_NPROCS; len = sizeof(count); error = sysctl(mib, 2, &count, &len, NULL, 0); if (error == -1) return (0); kp = calloc(count, sizeof(*kp)); if (kp == NULL) return (0); mib[0] = CTL_KERN; mib[1] = KERN_PROC; mib[2] = KERN_PROC_ALL; mib[3] = 0; mib[4] = sizeof(*kp); mib[5] = count; len = count * sizeof(*kp); error = sysctl(mib, 6, kp, &len, NULL, 0); if (error == -1) { free(kp); return (0); } for (count = 0, kpp = kp; (char *)kpp < (char *)kp + len; kpp++) { if (kpp->p_pid == 0) continue; count++; } free(kp); return (count); } int32_t get_mem_info_bsd(struct MemInfo *mi) { struct uvmexp uv; struct bcachestats bc; struct swapent *sw; int mib[3], error, i, ns; size_t len; mib[0] = CTL_VM; mib[1] = VM_UVMEXP; len = sizeof(uv); error = sysctl(mib, 2, &uv, &len, NULL, 0); if (error == -1) goto fail; mib[0] = CTL_VFS; mib[1] = VFS_GENERIC; mib[2] = VFS_BCACHESTAT; len = sizeof(bc); error = sysctl(mib, 3, &bc, &len, NULL, 0); if (error == -1) goto fail; mi->total = (uint64_t)uv.npages * uv.pagesize / 1024; mi->avail = 0; mi->free = (uint64_t)uv.free * uv.pagesize / 1024; mi->cached = bc.numbufpages * uv.pagesize / 1024; mi->buffers = 0; mi->swap_total = 0; mi->swap_free = 0; ns = swapctl(SWAP_NSWAP, 0, 0); sw = (ns > 0) ? calloc(ns, sizeof(*sw)) : NULL; if (sw != NULL && (swapctl(SWAP_STATS, sw, ns) == ns)) { for (i = 0; i < ns; i++) { if (!(sw[i].se_flags & SWF_ENABLE)) continue; mi->swap_total += sw[i].se_nblks / (1024 / DEV_BSIZE); mi->swap_free += (sw[i].se_nblks - sw[i].se_inuse) / (1024 / DEV_BSIZE); } } free(sw); return (0); fail: return (-1); } int32_t get_disk_info_bsd(DiskInfo *di) { struct statfs *sfs, *sf; int i, nmounts; uint64_t dtotal, dfree; int32_t res; dtotal = 0; dfree = 0; sfs = NULL; res = -1; nmounts = getfsstat(NULL, 0, MNT_WAIT); if (nmounts == -1) goto fail; sfs = calloc(nmounts, sizeof(*sfs)); if (sfs == NULL) goto fail; nmounts = getfsstat(sfs, nmounts * sizeof(*sfs), MNT_WAIT); if (nmounts == -1) goto fail; for (i = 0; i < nmounts; i++) { sf = &sfs[i]; if ((sf->f_flags & MNT_LOCAL) != MNT_LOCAL) continue; dtotal += sf->f_blocks * sf->f_bsize; dfree += sf->f_bfree * sf->f_bsize; } di->total = dtotal / 1000; di->free = dfree / 1000; res = 0; fail: free(sfs); return (res); }