/* * This code is slightly modified from the procps package. */ #include #include #include #include #include #include #include #include #include #include #include #include "node.h" #include "sysinfo.h" char *xmalloc(size_t); char *fixup_null_alloc(size_t); int read_utmp(char *); int list_entries(int); int who(void); #define UPTIME_FILE "/proc/uptime" #define LOADAVG_FILE "/proc/loadavg" #define MEMINFO_FILE "/proc/meminfo" #define STRUCT_UTMP struct utmp static STRUCT_UTMP *utmp_contents; #ifndef UTMP_FILE #define UTMP_FILE "/var/run/utmp" #endif #ifndef EMAILLEN #define EMAILLEN 64 #endif #ifndef MAXHOSTNAMELEN #define MAXHOSTNAMELEN 64 #endif #ifndef S_IWGRP #define S_IWGRP 020 #endif static char buf[300]; /* This macro opens FILE only if necessary and seeks to 0 so that successive calls to the functions are more efficient. It also reads the current contents of the file into the global buf. */ #define FILE_TO_BUF(FILE) { \ static int n, fd = -1; \ if (fd == -1 && (fd = open(FILE, O_RDONLY)) == -1) { \ close(fd); \ return 0; \ } \ lseek(fd, 0L, SEEK_SET); \ if ((n = read(fd, buf, sizeof buf - 1)) < 0) { \ close(fd); \ fd = -1; \ return 0; \ } \ buf[n] = '\0'; \ } #define SET_IF_DESIRED(x,y) if (x) *(x) = (y) /* evals 'x' twice */ int uptime(double *uptime_secs, double *idle_secs) { double up=0, idle=0; FILE_TO_BUF(UPTIME_FILE) if (sscanf(buf, "%lf %lf", &up, &idle) < 2) { printf("Bad data in %s\n", UPTIME_FILE ); return 0; } SET_IF_DESIRED(uptime_secs, up); SET_IF_DESIRED(idle_secs, idle); return up; /* assume never be zero seconds in practice */ } int loadavg(double *av1, double *av5, double *av15) { double avg_1=0, avg_5=0, avg_15=0; FILE_TO_BUF(LOADAVG_FILE) if (sscanf(buf, "%lf %lf %lf", &avg_1, &avg_5, &avg_15) < 3) { printf("Bad data in %s\n", LOADAVG_FILE ); return 0; } SET_IF_DESIRED(av1, avg_1); SET_IF_DESIRED(av5, avg_5); SET_IF_DESIRED(av15, avg_15); return 1; } /* The following /proc/meminfo parsing routine assumes the following format: [