From 39888c630c7e25c0f45df3c7db6018315db7920f Mon Sep 17 00:00:00 2001 From: Adrien Destugues Date: Mon, 9 Nov 2015 15:39:29 +0100 Subject: picolcd: C89 fixes. diff --git a/server/drivers/picolcd.c b/server/drivers/picolcd.c index 401f593..e7b2a8b 100644 --- a/server/drivers/picolcd.c +++ b/server/drivers/picolcd.c @@ -1874,6 +1874,7 @@ picolcd_send(USB_DEVICE_HANDLE * lcd, unsigned char *data, int size) if ((lcd == NULL) && (data == NULL)) return; #ifdef HAVE_LIBUSB_1_0 +{ int error = 0; int transferred = 0; unsigned int timeout = 1000; /* milliseconds */ @@ -1882,6 +1883,7 @@ picolcd_send(USB_DEVICE_HANDLE * lcd, unsigned char *data, int size) report(RPT_WARNING, "libusb_interrupt_transfer error %d, sent %d of %d bytes\n", error, transferred, size); } +} #else usb_interrupt_write(lcd, USB_ENDPOINT_OUT + 1, (char *)data, size, 1000); #endif @@ -2008,11 +2010,6 @@ picolcd_20x4_set_char(Driver *drvthis, int n, unsigned char *dat) { PrivateData *p = drvthis->private_data; - if ((n < 0) || (n >= NUM_CCs)) - return; - if (dat == NULL) - return; - unsigned char command[6] = { OUT_REPORT_CMD, 0x00, 0x01, 0x00, 0x64, 0x40 + 8 * n }; /* 0x94 */ @@ -2022,6 +2019,11 @@ picolcd_20x4_set_char(Driver *drvthis, int n, unsigned char *dat) dat[4], dat[5], dat[6], dat[7] }; /* 0x95 */ + if ((n < 0) || (n >= NUM_CCs)) + return; + if (dat == NULL) + return; + picolcd_send(p->lcd, command, 6); picolcd_send(p->lcd, data, 13); } -- 2.13.1 From a0bc10ba8ad19ba630c2b0cb83947942d6dabd79 Mon Sep 17 00:00:00 2001 From: Adrien Destugues Date: Mon, 9 Nov 2015 15:40:03 +0100 Subject: Add "machine" implementation for Haiku * Incomplete, trying to look for /proc, except for the filesystem listing. diff --git a/clients/lcdproc/Makefile.am b/clients/lcdproc/Makefile.am index 1141367..1be39f8 100644 --- a/clients/lcdproc/Makefile.am +++ b/clients/lcdproc/Makefile.am @@ -4,7 +4,7 @@ sysconf_DATA = lcdproc.conf bin_PROGRAMS = lcdproc -lcdproc_SOURCES = main.c main.h mode.c mode.h batt.c batt.h chrono.c chrono.h cpu.c cpu.h cpu_smp.c cpu_smp.h disk.c disk.h load.c load.h mem.c mem.h eyebox.c eyebox.h machine.h machine_Linux.c machine_OpenBSD.c machine_FreeBSD.c machine_NetBSD.c machine_Darwin.c machine_SunOS.c util.c util.h iface.c iface.h +lcdproc_SOURCES = main.c main.h mode.c mode.h batt.c batt.h chrono.c chrono.h cpu.c cpu.h cpu_smp.c cpu_smp.h disk.c disk.h load.c load.h mem.c mem.h eyebox.c eyebox.h machine.h machine_Linux.c machine_OpenBSD.c machine_FreeBSD.c machine_NetBSD.c machine_Darwin.c machine_SunOS.c machine_Haiku.c util.c util.h iface.c iface.h lcdproc_LDADD = ../../shared/libLCDstuff.a diff --git a/clients/lcdproc/machine_Haiku.c b/clients/lcdproc/machine_Haiku.c new file mode 100644 index 0000000..3803b6d --- /dev/null +++ b/clients/lcdproc/machine_Haiku.c @@ -0,0 +1,590 @@ +/** \file clients/lcdproc/machine_Linux.c + * Collects system information on Linux. + */ + +/*- + * This file is part of lcdproc, the lcdproc client. + * + * This file is released under the GNU General Public License. + * Refer to the COPYING file distributed with this package. + */ + +#ifdef __HAIKU__ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#if TIME_WITH_SYS_TIME +# include +# include +#else +# if HAVE_SYS_TIME_H +# include +# else +# include +# endif +#endif + +#ifdef HAVE_GETLOADAVG +# define USE_GETLOADAVG +#endif + +#ifdef USE_GETLOADAVG +# ifdef HAVE_SYS_LOADAVG_H +# include +# endif +#endif + +#ifdef HAVE_PROCFS_H +# include +#endif + +#ifdef HAVE_SYS_PROCFS_H +# include +#endif + +#include "main.h" +#include "mode.h" +#include "machine.h" +#include "shared/LL.h" + + +static int batt_fd; +static int load_fd; +static int loadavg_fd; +static int meminfo_fd; +static int uptime_fd; + +static char procbuf[1024]; /* TODO ugly hack! */ + +int +machine_init(void) +{ + uptime_fd = -1; + batt_fd = -1; + load_fd = -1; + loadavg_fd = -1; + meminfo_fd = -1; + + if (uptime_fd < 0) { + uptime_fd = open("/proc/uptime", O_RDONLY); + if (uptime_fd < 0) { + perror("open /proc/uptime"); + return (FALSE); + } + } + + if (load_fd < 0) { + load_fd = open("/proc/stat", O_RDONLY); + if (load_fd < 0) { + perror("open /proc/stat"); + return (FALSE); + } + } + +#ifndef USE_GETLOADAVG + if (loadavg_fd < 0) { + loadavg_fd = open("/proc/loadavg", O_RDONLY); + if (loadavg_fd < 0) { + perror("open /proc/loadavg"); + return (FALSE); + } + } +#endif + + if (meminfo_fd < 0) { + meminfo_fd = open("/proc/meminfo", O_RDONLY); + if (meminfo_fd < 0) { + perror("open /proc/meminfo"); + return (FALSE); + } + } + + if (batt_fd < 0) { + batt_fd = open("/proc/apm", O_RDONLY); + if (batt_fd < 0) { + /* allow opening /proc/apm to fail */ + batt_fd = -1; + } + } + + return (TRUE); +} + +int +machine_close(void) +{ + if (batt_fd >= 0) + close(batt_fd); + batt_fd = -1; + + if (load_fd >= 0) + close(load_fd); + load_fd = -1; + +#ifndef USE_GETLOADAVG + if (loadavg_fd >= 0) + close(loadavg_fd); + loadavg_fd = -1; +#endif + + if (meminfo_fd >= 0) + close(meminfo_fd); + meminfo_fd = -1; + + if (uptime_fd >= 0) + close(uptime_fd); + uptime_fd = -1; + + return (TRUE); +} + +static void +reread(int f, char *errmsg) +{ + if (lseek(f, 0L, 0) == 0 && read(f, procbuf, sizeof(procbuf) - 1) > 0) + return; + perror(errmsg); + exit(1); +} + +static int +getentry(const char *tag, const char *bufptr, long *value) +{ + char *tail; + int len = strlen(tag); + long val; + + while (bufptr != NULL) { + if (*bufptr == '\n') + bufptr++; + if (!strncmp(tag, bufptr, len)) { + errno = 0; + val = strtol(bufptr + len, &tail, 10); + if ((errno == 0) && (tail != bufptr + len)) { + *value = val; + return TRUE; + } + else + return FALSE; + } + bufptr = strchr(bufptr, '\n'); + } + return FALSE; +} + +int +machine_get_battstat(int *acstat, int *battflag, int *percent) +{ + char str[64]; + int battstat; + + /* no battery status available: fake one ;-) */ + if (batt_fd < 0) { + *acstat = LCDP_AC_ON; + *battflag = LCDP_BATT_ABSENT; + *percent = 100; + return (TRUE); + } + + if (lseek(batt_fd, 0, 0) != 0) + return (FALSE); + + if (read(batt_fd, str, sizeof(str) - 1) < 0) + return (FALSE); + + if (3 > sscanf(str + 13, "0x%x 0x%x 0x%x %d", acstat, &battstat, battflag, percent)) + return (FALSE); + + if (*battflag == 0xff) + *battflag = LCDP_BATT_UNKNOWN; + else { + if (*battflag & 1) + *battflag = LCDP_BATT_HIGH; + if (*battflag & 2) + *battflag = LCDP_BATT_LOW; + if (*battflag & 4) + *battflag = LCDP_BATT_CRITICAL; + if (*battflag & 8 || battstat == 3) + *battflag = LCDP_BATT_CHARGING; + if (*battflag & 128) + *battflag = LCDP_BATT_ABSENT; + } + + switch (*acstat) { + case 0: + *acstat = LCDP_AC_OFF; + break; + case 1: + *acstat = LCDP_AC_ON; + break; + case 2: + *acstat = LCDP_AC_BACKUP; + break; + default: + *acstat = LCDP_AC_UNKNOWN; + break; + } + + return (TRUE); +} + +int +machine_get_fs(mounts_type fs[], int *cnt) +{ + dev_t dev; + int32_t idx = 0; + + while(dev = next_dev(&idx) > 0) { + fs_info info; + fs_stat_dev(dev, &info); + + strcpy(fs[idx - 1].dev, info.device_name); + strcpy(fs[idx - 1].type, info.fsh_name); + strcpy(fs[idx - 1].mpoint, info.volume_name); + fs[idx - 1].bsize = info.block_size; + fs[idx - 1].blocks = info.total_blocks; + fs[idx - 1].bfree = info.free_blocks; + fs[idx - 1].files = info.total_nodes; + fs[idx - 1].ffree = info.free_nodes; + } + *cnt = idx - 1; + return (TRUE); +} + +int +machine_get_load(load_type * curr_load) +{ + static load_type last_load = {0, 0, 0, 0, 0}; + load_type load; + int ret; + unsigned long load_iowait, load_irq, load_softirq; + + reread(load_fd, "get_load"); + + ret = sscanf(procbuf, "cpu %lu %lu %lu %lu %lu %lu %lu", + &load.user, &load.nice, &load.system, &load.idle, + &load_iowait, &load_irq, &load_softirq); + + if (ret >= 5) + load.idle += load_iowait; + if (ret >= 6) + load.system += load_irq; + if (ret >= 7) + load.system += load_softirq; + + load.total = load.user + load.nice + load.system + load.idle; + + curr_load->user = load.user - last_load.user; + curr_load->nice = load.nice - last_load.nice; + curr_load->system = load.system - last_load.system; + curr_load->idle = load.idle - last_load.idle; + curr_load->total = load.total - last_load.total; + + /* struct assignment is legal in C89 */ + last_load = load; + + return (TRUE); +} + +int +machine_get_loadavg(double *load) +{ +#ifdef USE_GETLOADAVG + double loadavg[LOADAVG_NSTATS]; + + if (getloadavg(loadavg, LOADAVG_NSTATS) <= LOADAVG_1MIN) { + perror("getloadavg"); /* ToDo: correct error reporting */ + return (FALSE); + } + *load = loadavg[LOADAVG_1MIN]; +#else + reread(loadavg_fd, "get_loadavg"); + sscanf(procbuf, "%lf", load); +#endif + return (TRUE); +} + +int +machine_get_meminfo(meminfo_type * result) +{ + long tmp; + + reread(meminfo_fd, "get_meminfo"); + result[0].total = (getentry("MemTotal:", procbuf, &tmp) == TRUE) ? tmp : 0L; + result[0].free = (getentry("MemFree:", procbuf, &tmp) == TRUE) ? tmp : 0L; + result[0].shared = (getentry("MemShared:", procbuf, &tmp) == TRUE) ? tmp : 0L; + result[0].buffers = (getentry("Buffers:", procbuf, &tmp) == TRUE) ? tmp : 0L; + result[0].cache = (getentry("Cached:", procbuf, &tmp) == TRUE) ? tmp : 0L; + result[1].total = (getentry("SwapTotal:", procbuf, &tmp) == TRUE) ? tmp : 0L; + result[1].free = (getentry("SwapFree:", procbuf, &tmp) == TRUE) ? tmp : 0L; + + return (TRUE); +} + +int +machine_get_procs(LinkedList * procs) +{ + /* Much of this code was ripped from "gmemusage" */ + DIR *proc; + FILE *StatusFile; + struct dirent *procdir; + + char procName[16]; + int procSize, procRSS, procData, procStk, procExe; + const char + *NameLine = "Name:", + *VmSizeLine = "VmSize:", + *VmRSSLine = "VmRSS", + *VmDataLine = "VmData", + *VmStkLine = "VmStk", + *VmExeLine = "VmExe"; + const int + NameLineLen = strlen(NameLine), + VmSizeLineLen = strlen(VmSizeLine), + VmDataLineLen = strlen(VmDataLine), + VmStkLineLen = strlen(VmStkLine), + VmExeLineLen = strlen(VmExeLine), + VmRSSLineLen = strlen(VmRSSLine); + int threshold = 400, unique; + + if ((proc = opendir("/proc")) == NULL) { + /* ToDo: correct error reporting */ + perror("mem_top_screen: unable to open /proc"); + return (FALSE); + } + + while ((procdir = readdir(proc))) { + char buf[128]; + + /* ignore everything in proc except process ids */ + if (!strchr("1234567890", procdir->d_name[0])) + continue; + + sprintf(buf, "/proc/%s/status", procdir->d_name); + if ((StatusFile = fopen(buf, "r")) == NULL) { + /* + * Not a serious error; process has finished before + * we could examine it: + */ + continue; + } + + procRSS = procSize = procData = procStk = procExe = 0; + while (fgets(buf, sizeof(buf), StatusFile)) { + if (!strncmp(buf, NameLine, NameLineLen)) { + /* Name: procName */ + sscanf(buf, "%*s %s", procName); + } + else if (!strncmp(buf, VmSizeLine, VmSizeLineLen)) { + /* VmSize: procSize kB */ + sscanf(buf, "%*s %d", &procSize); + } + else if (!strncmp(buf, VmRSSLine, VmRSSLineLen)) { + /* VmRSS: procRSS kB */ + sscanf(buf, "%*s %d", &procRSS); + } + else if (!strncmp(buf, VmDataLine, VmDataLineLen)) { + /* VmData: procData kB */ + sscanf(buf, "%*s %d", &procData); + } + else if (!strncmp(buf, VmStkLine, VmStkLineLen)) { + /* VmStk: procStk kB */ + sscanf(buf, "%*s %d", &procStk); + } + else if (!strncmp(buf, VmExeLine, VmExeLineLen)) { + /* VmExe: procExe kB */ + sscanf(buf, "%*s %d", &procExe); + } + } + fclose(StatusFile); + + if (procSize > threshold) { + /* Figure out if it's sharing any memory... */ + unique = 1; + LL_Rewind(procs); + do { + procinfo_type *p = LL_Get(procs); + + if ((p != NULL) && (0 == strcmp(p->name, procName))) { + unique = 0; + p->number++; + p->totl += procData + procStk + procExe; + } + } while (LL_Next(procs) == 0); + + /* If this is the first one by this name... */ + if (unique) { + procinfo_type *p = malloc(sizeof(procinfo_type)); + if (p == NULL) { + perror("mem_top_screen: Error allocating process entry"); + break; + } + strcpy(p->name, procName); + p->totl = procData + procStk + procExe; + p->number = 1; + /* TODO: Check for errors here? */ + LL_Push(procs, (void *)p); + } + } + } + closedir(proc); + + return (TRUE); +} + +int +machine_get_smpload(load_type * result, int *numcpus) +{ + char *token; + static load_type last_load[MAX_CPUS]; + load_type curr_load[MAX_CPUS]; + int ncpu = 0; + int ret; + unsigned long load_iowait, load_irq, load_softirq; + + reread(load_fd, "get_load"); + + /* Look for lines starting with "cpu0", "cpu1", etc. */ + token = strtok(procbuf, "\n"); + while (token != NULL) { + if ((strlen(token) > 3) && (!strncmp(token, "cpu", 3)) && isdigit(token[3])) { + ret = sscanf(token, "cpu%*d %lu %lu %lu %lu %lu %lu %lu", + &curr_load[ncpu].user, &curr_load[ncpu].nice, &curr_load[ncpu].system, + &curr_load[ncpu].idle, &load_iowait, &load_irq, &load_softirq); + + if (ret >= 5) + curr_load[ncpu].idle += load_iowait; + if (ret >= 6) + curr_load[ncpu].system += load_irq; + if (ret >= 7) + curr_load[ncpu].system += load_softirq; + + curr_load[ncpu].total = curr_load[ncpu].user + curr_load[ncpu].nice + + curr_load[ncpu].system + curr_load[ncpu].idle; + + result[ncpu].total = curr_load[ncpu].total - last_load[ncpu].total; + result[ncpu].user = curr_load[ncpu].user - last_load[ncpu].user; + result[ncpu].nice = curr_load[ncpu].nice - last_load[ncpu].nice; + result[ncpu].system = curr_load[ncpu].system - last_load[ncpu].system; + result[ncpu].idle = curr_load[ncpu].idle - last_load[ncpu].idle; + + /* struct assignment is legal in C89 */ + last_load[ncpu] = curr_load[ncpu]; + + /* restrict # CPUs to min(*numcpus, MAX_CPUS) */ + ncpu++; + if ((ncpu >= *numcpus) || (ncpu >= MAX_CPUS)) + break; + } + token = strtok(NULL, "\n"); + } + *numcpus = ncpu; + + return (TRUE); +} + +int +machine_get_uptime(double *up, double *idle) +{ + double local_up, local_idle; + + reread(uptime_fd, "get_uptime"); + sscanf(procbuf, "%lf %lf", &local_up, &local_idle); + if (up != NULL) + *up = local_up; + if (idle != NULL) + *idle = (local_up != 0) + ? 100 * local_idle / local_up + : 100; + + return (TRUE); +} + + +int +machine_get_iface_stats(IfaceInfo * interface) +{ + FILE *file; /* file handler */ + char buffer[1024]; /* buffer to work with the file */ + static int first_time = 1; /* is it first time we call this + * function? */ + char *ch_pointer = NULL;/* pointer to where interface values are in + * file */ + + /* Open the file in read-only mode and parse */ + if ((file = fopen("/proc/net/dev", "r")) != NULL) { + /* Skip first 2 header lines of file */ + fgets(buffer, sizeof(buffer), file); + fgets(buffer, sizeof(buffer), file); + + /* By default, treat interface as down */ + interface->status = down; + + /* Search iface_name and scan values */ + while ((fgets(buffer, sizeof(buffer), file) != NULL)) { + if (strstr(buffer, interface->name)) { + /* interface exists */ + interface->status = up; /* is up */ + interface->last_online = time(NULL); /* save actual time */ + + /* search ':' and skip over it */ + ch_pointer = strchr(buffer, ':'); + ch_pointer++; + + /* + * Now ch_pointer points to values of + * iface_name + */ + /* Scan values from here */ + sscanf(ch_pointer, "%lf %lf %*s %*s %*s %*s %*s %*s %lf %lf", + &interface->rc_byte, + &interface->rc_pkt, + &interface->tr_byte, + &interface->tr_pkt); + + /* + * if is the first time we call this + * function, old values are the same as new + * so we don't get big speeds when + * calculating + */ + if (first_time) { + interface->rc_byte_old = interface->rc_byte; + interface->tr_byte_old = interface->tr_byte; + interface->rc_pkt_old = interface->rc_pkt; + interface->tr_pkt_old = interface->tr_pkt; + first_time = 0; /* now it isn't first + * time */ + } + } + } + + fclose(file); + return (TRUE); + } + else { /* error when opening the file */ + perror("Error: Could not open DEVFILE"); + return (FALSE); + } +} + +#endif /* __HAIKU__ */ + -- 2.13.1 From 89326917be2fc8f0e93338fe39a6815f34edfdd6 Mon Sep 17 00:00:00 2001 From: Jerome Duval Date: Thu, 28 Sep 2017 21:08:00 +0200 Subject: Haiku: link against libnetwork. don't use rdynamic. diff --git a/configure.ac b/configure.ac index 0c37b60..0a83923 100644 --- a/configure.ac +++ b/configure.ac @@ -33,11 +33,17 @@ case "$host" in AC_DEFINE([DARWIN],[1],[Define if you're using Darwin/Mac OS X.]) ac_system_host=Darwin ;; +*-*-*haiku*) + AC_DEFINE([HAIKU],[1],[Define if you're using Haiku.]) + ac_system_host=Haiku + ;; esac AC_DEFINE_UNQUOTED([SYSTEM_HOST], [$ac_system_host], [Set this to your system host (Linux, Solaris, OpenBSD, NetBSD, FreeBSD or Darwin)]) dnl treat Darwin special in Makefiles AM_CONDITIONAL(DARWIN, test x$ac_system_host = xDarwin) +dnl treat Haiku special in Makefiles +AM_CONDITIONAL(HAIKU, test x$ac_system_host = xHaiku) AC_MSG_CHECKING([whether to enable debugging]) AC_ARG_ENABLE(debug, @@ -82,10 +88,10 @@ AX_CFLAGS_GCC_OPTION(-Wno-unused-function) AX_CFLAGS_GCC_OPTION(-ftrampolines) export CFLAGS -dnl Solaris -AC_CHECK_FUNC(gethostbyname,,[AC_CHECK_LIB(nsl,gethostbyname)]) -AC_CHECK_FUNC(connect,,[AC_CHECK_LIB(socket,connect)]) -AC_CHECK_FUNC(inet_aton,,[AC_CHECK_LIB(resolv,inet_aton)]) +dnl Solaris and Haiku +AC_CHECK_FUNC(gethostbyname,,[AC_SEARCH_LIBS(gethostbyname, nsl network)]) +AC_CHECK_FUNC(connect,,[AC_SEARCH_LIBS(connect, socket network)]) +AC_CHECK_FUNC(inet_aton,,[AC_SEARCH_LIBS(inet_aton, resolv network)]) AC_CHECK_LIB(kstat, kstat_open) AC_CHECK_LIB(posix4, nanosleep) AC_CHECK_FUNCS(getloadavg swapctl) diff --git a/server/Makefile.am b/server/Makefile.am index 849ab92..fef2e11 100644 --- a/server/Makefile.am +++ b/server/Makefile.am @@ -9,8 +9,10 @@ LCDd_SOURCES= client.c client.h clients.c clients.h input.c input.h main.c main. LDADD = ../shared/libLCDstuff.a commands/libLCDcommands.a @LIBPTHREAD_LIBS@ if !DARWIN +if !HAIKU AM_LDFLAGS = -rdynamic endif +endif AM_CPPFLAGS = -I$(top_srcdir) -I$(top_srcdir)/shared -DSYSCONFDIR=\"$(sysconfdir)\" -- 2.13.1