From 0cc9b20c15460213e488bf5e70963b941482f628 Mon Sep 17 00:00:00 2001 From: William Harrington Date: Tue, 14 Jan 2025 16:06:02 -0600 Subject: Add source. --- utils/vmon.c | 442 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 442 insertions(+) create mode 100644 utils/vmon.c (limited to 'utils/vmon.c') diff --git a/utils/vmon.c b/utils/vmon.c new file mode 100644 index 0000000..e1015b4 --- /dev/null +++ b/utils/vmon.c @@ -0,0 +1,442 @@ +/* Verbal monitor system status. + * $Id: vmon.c 1.2 Mon, 24 Mar 1997 12:25:37 -0500 dyfet $ + * Copyright (c) 1997 by Tycho Softworks. + * For conditions on distribution and reuse see product license. + * + * Abstract: + * Monitor system status in background. This service is normally + * started with the speech server. It may also be ran as 'vstat' + * to perform immediate notification. + */ + +#include +#include +#include +#include +#include +#include + +/* For systems that use statfs! */ + +#ifdef __linux__ +#include +#define __statfs__ +#endif + +typedef struct _MAILBOX +{ + struct _MAILBOX *next; + time_t update; + ulong size; + char name[0]; +} MAILBOX; + +static int freq = 3600; +static int timer = 3600; +static int interval = 300; +static int iter; +static int orig_timer; +static int alert = 90; /* warn on 90% full */ +static char alertmsg[] = "emergency alert emergency alert \r\n"; +static char **fs; +static char host[128] = "localhost"; +static int mute[2] = {24, 0}; + +static char *vmailbox(MAILBOX *mbox) +{ + struct stat ino; + static char buf[80]; + + if(stat(mbox->name, &ino)) + return NULL; + + if(!ino.st_size) + { + mbox->size = 0; + return NULL; + } + + if(ino.st_size == mbox->size) + return NULL; + + if(mbox->size == -1) + { + mbox->size = ino.st_size; + return NULL; + } + + mbox->size = ino.st_size; + sprintf(buf, "User %s has new mail\n", mbox->name); + return buf; +} + +static void vmbox(MAILBOX *box, int port) +{ + STREAM fp = NULL; + char *p; + time_t now; + struct tm *dt; + char buf[128]; + + time(&now); + dt = localtime(&now); + if(dt->tm_hour > mute[0] || dt->tm_hour < mute[1]) + return; + + while(box) + { + p = vmailbox(box); + if(!p) + { + box = box->next; + continue; + } + if(!fp) + { + fp = opentcp(host, port); + if(!fp) + return; + + gettcp(buf, sizeof(buf) - 1, fp); + } + puttcp(p, fp); + box = box->next; + } + if(fp) + closetcp(fp); +} + +static int vstat(int port) +{ + int i = 0; + char *f; + long btotal = 0; + long bfree = 0; + bool failed = FALSE; + STREAM fp = NULL; +#ifdef __statfs__ + struct statfs fnode; +#endif + int blocks, inodes; + char buf[128]; + int newtimer = orig_timer; + time_t now; + static prior = -1; + struct tm *dt; + int apm, hour; + char *apmstr[] = {" A M ", " P M "}; + int fd; + struct utmp *utmp, uptime; + int users = 0; + int utcnt = 0; + +#ifdef __statfs__ + while(fs[i]) + { + if(!statfs(fs[i], &fnode)) + { + btotal += fnode.f_blocks; + bfree += fnode.f_bfree; + blocks = 100 - (int)(fnode.f_ffree / (fnode.f_files / 100l)); + inodes = 100 - (int)(fnode.f_bfree / (fnode.f_blocks / 100l)); + if((blocks < alert) && (inodes < alert)) + { + ++i; + continue; + } + } + else + { + inodes = 0; + blocks = 0; + failed = TRUE; + } + if(!fp) + { + fp = opentcp(host, port); + if(!fp) + { + newtimer = 300; + break; + } + gettcp(buf, 128, fp); + puttcp(alertmsg, fp); + } + + if(blocks > alert) + fprintf(fp, "File system %s is %d percent full.\r\n", fs[i], blocks); + + if(inodes > alert) + fprintf(fp, "File system %s i-node table is %d percent full.\r\n", fs[i], inodes); + + if(failed) + fprintf(fp, "File system %s is dismounted or failed\r\n", fs[i]); + + fflush(fp); + newtimer = 60; + ++i; + } +#endif + + if(fp) + closetcp(fp); + + time(&now); + if(prior == (now / freq)) + return newtimer; + + if(prior == -1) + prior = now / freq - 1; + else + prior = now / freq; + + dt = localtime(&now); + hour = dt->tm_hour % 12; + if(dt->tm_hour > mute[0] || dt->tm_hour < mute[1]) + return newtimer; + + if(!hour) + hour = 12; + + if(dt->tm_hour > 11) + apm = 1; + else + apm = 0; + + fp = opentcp(host, port); + if(!fp) + return newtimer; + + gettcp(buf, 128, fp); + fprintf(fp, "It is %d:%d %s \r\n", hour, dt->tm_min, apmstr[apm]); + fflush(fp); + + fd = open("/proc/uptime", O_RDONLY); + hour = -1; + if(fd > -1) + { + read(fd, buf, 128); + close(fd); + hour = atol(buf) / 3600; + } + +#if defined(BOOT_TIME) || defined(RUN_LVL) + if(hour == -1) + { + utmp = NULL; + memset(&uptime, 0, sizeof(uptime)); +#ifdef BOOT_TIME + setutent(); + uptime.ut_type = BOOT_TIME; + utmp = getutid(&uptime); +#endif +#ifdef RUN_LVL + if(!utmp) + { + setutent(); + uptime.ut_type = RUN_LVL; + utmp = getutid(&uptime); + } +#endif + if(utmp) + hour = (now - utmp->ut_time) / 3600l; + + endutent(); + } +#endif + + if(hour > -1) + { + if(hour == 1) + fprintf(fp, "The system has been up 1 hour\r\n"); + else if(hour < 48) + fprintf(fp, "The system has been up %d hours\r\n", hour); + else + fprintf(fp, "The system has been up %d days\r\n", hour / 24); + fflush(fp); + } + + setutent(); + while(NULL != (utmp = getutent())) + { + ++utcnt; + +#ifdef USER_PROCESS + if(utmp->ut_type != USER_PROCESS) + continue; +#endif + + utmp->ut_user[sizeof(utmp->ut_user)] = 0; + if(!strcmp(utmp->ut_user, "root")) + continue; + + if(!utmp->ut_user[0]) + continue; + + if(!utmp->ut_line[0]) + continue; + +#ifdef USER_PROCESS + if(kill(utmp->ut_pid, 0)) + continue; +#endif + + ++users; + } + endutent(); + + if(utcnt) + { + if(!users) + fprintf(fp, "There are no users online\r\n"); + else if(users == 1) + fprintf(fp, "There is 1 user online\r\n"); + else + fprintf(fp, "There are %d users online\r\n", users); + fflush(fp); + } + + if(btotal) + { + fprintf(fp, "The main system drives are at %d percent of capacity\r\n", + 100 - (int)(bfree / (btotal / 100))); + fflush(fp); + } + + closetcp(fp); + return newtimer; +} + +void main(int argc, char **argv) +{ + int port = getservice("speak"); + char *maildir = getenv("MAILDIR"); + MAILBOX *mbox = NULL, *newbox; + char *prog = basename(*argv); + CONFIG *cfg = sys_config("speak"); + time_t now; + char *p; + + if(argc < 2) + fatal(EX_USAGE, "use %s filesystems...\n", prog); + + if(!maildir) + maildir = "/var/spool/mail"; + + fs = ++argv; + + if(!port) + fatal(EX_UNAVAILABLE, "%s: speak: service unavailable\n", prog); + + if(!cfg) + fatal(EX_UNAVAILABLE, "%s: speak.conf: missing\n", prog); + + seek_config(cfg, "vmon"); + while(read_config(cfg)) + { + if(NULL != (p = get_config(cfg, "mailbox"))) + { + p = strtok(p, __SPACES); + while(p) + { + newbox = (MAILBOX *)malloc(sizeof(MAILBOX) + strlen(p) + 1); + newbox->next = mbox; + time(&newbox->update); + newbox->size = -1l; + strcpy(newbox->name, p); + mbox = newbox; + p = strtok(NULL, __SPACES); + } + continue; + } + + if(NULL != (p = get_config(cfg, "interval"))) + { + interval = atoi(p) * 60; + continue; + } + + if(NULL != (p = get_config(cfg, "frequency"))) + { + timer = 3600 / atoi(p); + continue; + } + + if(NULL != (p = get_config(cfg, "server"))) + { + strcpy(host, p); + continue; + } + + if(NULL != (p = get_config(cfg, "host"))) + { + strcpy(host, p); + continue; + } + + if(NULL != (p = get_config(cfg, "alert"))) + { + alert = atoi(p); + continue; + } + + if(NULL != (p = get_config(cfg, "timer"))) + { + timer = atoi(p) * 60; + continue; + } + + if(NULL != (p = get_config(cfg, "mute"))) + { + mute[0] = atoi(p); + p = strchr(p, '-'); + if(p) + mute[1] = atoi(strtrim(++p, __SPACES)); + continue; + } + + if(NULL != (p = get_config(cfg, "maildir"))) + { + maildir = strdup(p); + continue; + } + + } + close_config(cfg); + + if(stricmp(prog, "vmon")) + { + vstat(port); + exit(0); + } + + pdetach(D_KEEPNONE); + + chdir(maildir); + freq = timer; + orig_timer = timer; + time(&now); + for(;;) + { + timer = vstat(port); + iter = interval; + for(;;) + { + vmbox(mbox, port); + sleep(iter); + time(&now); + iter = timer - (now % timer) - 1; + + if(iter > interval) + iter = interval; + + if(iter < 2) + { + sleep(iter + 2); + break; + } + } + } +} + + -- cgit v1.2.3-54-g00ecf