From 43faadaa24e8c19724a776cf1332d20fa55303c8 Mon Sep 17 00:00:00 2001 From: Neil Brown Date: Tue, 6 Jun 2006 21:21:07 +1000 Subject: [PATCH] Lots of reformatting --- args.c | 162 ++++++------ broadcast.c | 50 ++-- classes.c | 16 +- commands.c | 368 +++++++++++++------------- control.c | 437 ++++++++++++++++--------------- daemon.c | 170 ++++++------ dlink.c | 62 +++-- error.c | 136 +++++----- loadstate.c | 238 ++++++++--------- mainloop.c | 168 ++++++------ meta.c | 374 +++++++++++++-------------- metad.c | 36 +-- metad.h | 100 ++++---- nargs.c | 162 ++++++------ ports.c | 32 +-- prtime.c | 4 +- read_config.c | 228 ++++++++-------- recvlist.c | 36 +-- sendcmd.c | 506 ++++++++++++++++++------------------ sendlist.c | 146 +++++------ service.c | 700 +++++++++++++++++++++++--------------------------- skip.c | 351 ++++++++++++------------- strccmp.c | 30 +-- strdup.c | 20 +- stream.c | 22 +- strlistdup.c | 26 +- strsplit.c | 5 +- version.c | 2 +- 28 files changed, 2262 insertions(+), 2325 deletions(-) diff --git a/args.c b/args.c index 26bded0..fa1061b 100644 --- a/args.c +++ b/args.c @@ -20,100 +20,100 @@ void *malloc(int); struct handle { - int argc; - char **argv; - char *ctl; - int nextarg, nextchar; + int argc; + char **argv; + char *ctl; + int nextarg, nextchar; }; #define NULLH ((struct handle *)0) struct handle *args_init(int argc, char **argv, char *ctl) { - /* if ctl is bad, return NULL, else a handle */ - int i; - struct handle *h; - for (i=0 ; ctl[i]; i+= 2) - if (ctl[i+1] != '?' && ctl[i+1] != '-' && ctl[i+1] != '+' && ctl[i+1] != ':') - break; - if (ctl[i]) - return NULLH; + /* if ctl is bad, return NULL, else a handle */ + int i; + struct handle *h; + for (i=0 ; ctl[i]; i+= 2) + if (ctl[i+1] != '?' && ctl[i+1] != '-' && ctl[i+1] != '+' && ctl[i+1] != ':') + break; + if (ctl[i]) + return NULLH; - h = (struct handle*)malloc(sizeof(struct handle)); - if (h == NULLH) + h = (struct handle*)malloc(sizeof(struct handle)); + if (h == NULLH) + return h; + h->argc = argc; + h->argv = argv; + h->ctl = ctl; + h->nextarg = 1; + h->nextchar = 0; return h; - h->argc = argc; - h->argv = argv; - h->ctl = ctl; - h->nextarg = 1; - h->nextchar = 0; - return h; } int args_next(struct handle *h, int *pos, int *inv, char **opt) { - int invc = 0; - int invfound = 0; - int i; - char *a; - if (h->nextarg >= h->argc) - return END_ARGS; - if (h->nextchar == 0) - { - if (h->argv[h->nextarg][0] != '-') + int invc = 0; + int invfound = 0; + int i; + char *a; + if (h->nextarg >= h->argc) + return END_ARGS; + if (h->nextchar == 0) { - if (pos) *pos = h->nextarg; - if (inv) *inv = 0; - if (opt) *opt = h->argv[h->nextarg]; - h->nextarg++; - return NO_FLAG; + if (h->argv[h->nextarg][0] != '-') + { + if (pos) *pos = h->nextarg; + if (inv) *inv = 0; + if (opt) *opt = h->argv[h->nextarg]; + h->nextarg++; + return NO_FLAG; + } + h->nextchar++; + } + a = h->argv[h->nextarg]; + while (a[h->nextchar] == '~') + { + invc = !invc; + invfound = 1; + h->nextchar++; + } + for (i=0 ; h->ctl[i] ; i+=2) + if (h->ctl[i] == a[h->nextchar]) + break; + if (h->ctl[i] == 0) + { + h->nextchar = 0; + h->nextarg ++; + return BAD_FLAG; } h->nextchar++; - } - a = h->argv[h->nextarg]; - while (a[h->nextchar] == '~') - { - invc = !invc; - invfound = 1; - h->nextchar++; - } - for (i=0 ; h->ctl[i] ; i+=2) - if (h->ctl[i] == a[h->nextchar]) - break; - if (h->ctl[i] == 0) - { - h->nextchar = 0; - h->nextarg ++; - return BAD_FLAG; - } - h->nextchar++; - if (pos) *pos = h->nextarg; - if (inv) *inv = invc; - if (a[h->nextchar] == 0) - { - h->nextchar = 0; - h->nextarg ++; - } - switch(h->ctl[i+1]) - { - case '?': + if (pos) *pos = h->nextarg; + if (inv) *inv = invc; + if (a[h->nextchar] == 0) + { + h->nextchar = 0; + h->nextarg ++; + } + switch(h->ctl[i+1]) + { + case '?': + return h->ctl[i]; + case '+': + if (inv) + return h->ctl[i]; + break; + case '-': + if (!inv) + return h->ctl[i]; + break; + case ':': + break; + } + /* need optarg */ + if (h->nextarg >= h->argc) + return BAD_FLAG; + if (opt) + *opt = h->argv[h->nextarg] + h->nextchar; + h->nextarg++; + h->nextchar=0; return h->ctl[i]; - case '+': - if (inv) - return h->ctl[i]; - break; - case '-': - if (!inv) - return h->ctl[i]; - break; - case ':': - break; - } - /* need optarg */ - if (h->nextarg >= h->argc) - return BAD_FLAG; - if (opt) - *opt = h->argv[h->nextarg] + h->nextchar; - h->nextarg++; - h->nextchar=0; - return h->ctl[i]; } diff --git a/broadcast.c b/broadcast.c index 8baf55c..4af003c 100644 --- a/broadcast.c +++ b/broadcast.c @@ -1,6 +1,6 @@ /* broadcast a string on all interfaces, to udp_port(); */ - + #include #include #include @@ -43,42 +43,42 @@ static int ifconfinit() static void sendaddr(struct sockaddr_in addr, char *packet) { - addr.sin_port = udp_port(); - addr.sin_family = AF_INET; + addr.sin_port = udp_port(); + addr.sin_family = AF_INET; - sendto(sock, packet, strlen(packet), 0, (struct sockaddr *)&addr, sizeof(addr)); + sendto(sock, packet, strlen(packet), 0, (struct sockaddr *)&addr, sizeof(addr)); } static void sendinter(int n, char *packet) { - struct ifreq ifr; + struct ifreq ifr; - ifr = iflist.ifc_req[n]; + ifr = iflist.ifc_req[n]; /* printf("interface = %s\n", ifr.ifr_name); */ - ioctl(sock, SIOCGIFBRDADDR, &ifr); - sendaddr(*(struct sockaddr_in*)&ifr.ifr_broadaddr, packet); + ioctl(sock, SIOCGIFBRDADDR, &ifr); + sendaddr(*(struct sockaddr_in*)&ifr.ifr_broadaddr, packet); } void broadcast(char *packet) { - int n; - int port; - struct sockaddr_in myaddr; - int a = -1; + int n; + int port; + struct sockaddr_in myaddr; + int a = -1; - sock = socket(AF_INET, SOCK_DGRAM, 0); - setsockopt(sock, SOL_SOCKET, SO_BROADCAST, (char*)&a, 4); - memset(&myaddr, 0, sizeof(myaddr)); - myaddr.sin_family = AF_INET; - if (geteuid()==0) - port = 1023; - else - port = 10230; - myaddr.sin_port = htons(port); - while (bind(sock, (struct sockaddr *)&myaddr, sizeof(myaddr))== -1) myaddr.sin_port = htons(--port); - if (ifconfinit()!= -1) /* gets list of interfaces */ - for (n = 0 ; n < interfaces ; n++) - sendinter(n, packet); + sock = socket(AF_INET, SOCK_DGRAM, 0); + setsockopt(sock, SOL_SOCKET, SO_BROADCAST, (char*)&a, 4); + memset(&myaddr, 0, sizeof(myaddr)); + myaddr.sin_family = AF_INET; + if (geteuid()==0) + port = 1023; + else + port = 10230; + myaddr.sin_port = htons(port); + while (bind(sock, (struct sockaddr *)&myaddr, sizeof(myaddr))== -1) myaddr.sin_port = htons(--port); + if (ifconfinit()!= -1) /* gets list of interfaces */ + for (n = 0 ; n < interfaces ; n++) + sendinter(n, packet); } diff --git a/classes.c b/classes.c index 088fc42..f3243ae 100644 --- a/classes.c +++ b/classes.c @@ -4,14 +4,16 @@ extern struct class daemon_class; extern struct class stream_class; static struct class *classes[] = { - &daemon_class, &stream_class, NULL - }; + &daemon_class, + &stream_class, + NULL +}; class_t find_class(char *name) { - int c; - for (c=0 ; classes[c] ; c++) - if (strccmp(name, classes[c]->class)==0) - return classes[c]; - return NULL; + int c; + for (c=0 ; classes[c] ; c++) + if (strcasecmp(name, classes[c]->class)==0) + return classes[c]; + return NULL; } diff --git a/commands.c b/commands.c index be79f75..cdd4106 100644 --- a/commands.c +++ b/commands.c @@ -6,248 +6,246 @@ static char *gather_arg(char **args) { - char *line; - int len = 0; - int a; - for (a=0 ; args[a] ; a++) len += strlen(args[a])+1; - line = (char*)malloc(len+1); - len = 0; - for (a=0 ; args[a] ; a++) - { - strcpy(line+len, args[a]); - len += strlen(args[a]); - line[len++] = ' '; - } - if (len>0) - line[len-1] = '\0'; - else - line[len] = 0; - return line; + char *line; + int len = 0; + int a; + for (a=0 ; args[a] ; a++) len += strlen(args[a])+1; + line = (char*)malloc(len+1); + len = 0; + for (a=0 ; args[a] ; a++) + { + strcpy(line+len, args[a]); + len += strlen(args[a]); + line[len++] = ' '; + } + if (len>0) + line[len-1] = '\0'; + else + line[len] = 0; + return line; } static void do_version(char **args, char *host, void *con) { - char *rv; - - if (con) - { - extern char version[]; - rv = (char*)malloc(strlen(version)+2); - strcpy(rv+1, version); - rv[0] = 2; - set_reply(con, rv, strlen(version)+2); - } - + char *rv; + + if (con) + { + extern char version[]; + rv = (char*)malloc(strlen(version)+2); + strcpy(rv+1, version); + rv[0] = 2; + set_reply(con, rv, strlen(version)+2); + } } static void do_broad(char **args, char *host, void *con) { - /* remaining args are packaged up and broadcast on all interfaces */ - char *line; - line = gather_arg(args+1); - logmsg(LOG_INFO, "Broadcast request from %s for %s", host, line); - broadcast(line); - free(line); + /* remaining args are packaged up and broadcast on all interfaces */ + char *line; + line = gather_arg(args+1); + logmsg(LOG_INFO, "Broadcast request from %s for %s", host, line); + broadcast(line); + free(line); } static void do_die(char **args, char *host, void *con) { - logmsg(LOG_WARNING, "Die request from %s", host); - exit(1); /* FIXME */ + logmsg(LOG_WARNING, "Die request from %s", host); + exit(1); /* FIXME */ } static void do_disable(char **args, char *host, void *con) { - service_t sv; - if (args[1] == NULL) - return_error(con, "No service given for disabling"); - else if ((sv=find_service(args[1]))==NULL) - return_error(con, "Cannot find service %s to disable it", args[1]); - else for ( ; sv ; sv=find_service(NULL)) - if (sv->enabled) - { - logmsg(LOG_INFO, "Disable request from %s for %s", host, sv->service); - (sv->class->disable_service)(sv); - sv->enabled = 0; - } + service_t sv; + if (args[1] == NULL) + return_error(con, "No service given for disabling"); + else if ((sv=find_service(args[1]))==NULL) + return_error(con, "Cannot find service %s to disable it", args[1]); + else for ( ; sv ; sv=find_service(NULL)) + if (sv->enabled) + { + logmsg(LOG_INFO, "Disable request from %s for %s", host, sv->service); + (sv->class->disable_service)(sv); + sv->enabled = 0; + } } static void do_enable(char **args, char *host, void *con) { - service_t sv; - if (args[1] == NULL) - return_error(con, "No service given for enabling"); - else if ((sv=find_service(args[1]))==NULL) - return_error(con, "Cannot find service %s to enable it", args[1]); - else for ( ; sv ; sv=find_service(NULL)) - if (!sv->enabled) - { - logmsg(LOG_INFO, "Enable request from %s for %s", host, sv->service); - (sv->class->register_service)(sv); - sv->enabled = 1; - } + service_t sv; + if (args[1] == NULL) + return_error(con, "No service given for enabling"); + else if ((sv=find_service(args[1]))==NULL) + return_error(con, "Cannot find service %s to enable it", args[1]); + else for ( ; sv ; sv=find_service(NULL)) + if (!sv->enabled) + { + logmsg(LOG_INFO, "Enable request from %s for %s", host, sv->service); + (sv->class->register_service)(sv); + sv->enabled = 1; + } } static void do_run(char **args, char *host, void *con) { - /* attempt to run service called args[1] with METAD_ARG set to remaining args and METAD_HOST set to host - */ - service_t sv; - if (args[1] == NULL) - return_error(con, "No service given to run"); - else if ((sv=find_service(args[1]))==NULL) - return_error(con, "Cannot find service %s to run", args[1]); - else - { - char *env[3]; - char *arg = gather_arg(args+2); - env[0] = strcat(strcpy((char*)malloc(20+strlen(host)), "METAD_REASON=run:"), host); - env[1] = strcat(strcpy((char*)malloc(11+strlen(arg)), "METAD_ARG="), arg); - env[2] = NULL; - for ( ; sv ; sv = find_service(NULL)) + /* attempt to run service called args[1] with METAD_ARG set to remaining args and METAD_HOST set to host + */ + service_t sv; + if (args[1] == NULL) + return_error(con, "No service given to run"); + else if ((sv=find_service(args[1]))==NULL) + return_error(con, "Cannot find service %s to run", args[1]); + else { - /* first clear all hold-times */ - proc_t *pp; - for (pp=skip_first(sv->proc_list) ; pp ; pp=skip_next(pp)) - if ((*pp)->hold_time != 0) - (*pp)->hold_time = 1; - sv->next_hold = 2; - logmsg(LOG_INFO,"starting %s for %s : arg = %s", sv->service, host, arg); - new_proc(sv, env); + char *env[3]; + char *arg = gather_arg(args+2); + env[0] = strcat(strcpy((char*)malloc(20+strlen(host)), "METAD_REASON=run:"), host); + env[1] = strcat(strcpy((char*)malloc(11+strlen(arg)), "METAD_ARG="), arg); + env[2] = NULL; + for ( ; sv ; sv = find_service(NULL)) + { + /* first clear all hold-times */ + proc_t *pp; + for (pp=skip_first(sv->proc_list) ; pp ; pp=skip_next(pp)) + if ((*pp)->hold_time != 0) + (*pp)->hold_time = 1; + sv->next_hold = 2; + logmsg(LOG_INFO,"starting %s for %s : arg = %s", sv->service, host, arg); + new_proc(sv, env); + } + free(arg); + free(env[1]); + free(env[0]); } - free(arg); - free(env[1]); - free(env[0]); - } } static void do_kill(char **args, char *host, void *con) { - /* args[1] = signal - * args[2] = pid or service name - */ - int sig; - pid_t pid; - service_t sv; - if (args[1] == NULL) - return_error(con, "No signal number given for kill"); - else if ((sig=atoi(args[1]))<= 0) - return_error(con, "Bad signal number given for kill: %s", args[1]); - else if (args[2] == NULL) - return_error(con, "No process id or service name given for kill"); - else if ((pid = atoi(args[2]))>0) - { - proc_t *pp = skip_search(allprocs, &pid); - if (pp) + /* args[1] = signal + * args[2] = pid or service name + */ + int sig; + pid_t pid; + service_t sv; + if (args[1] == NULL) + return_error(con, "No signal number given for kill"); + else if ((sig=atoi(args[1]))<= 0) + return_error(con, "Bad signal number given for kill: %s", args[1]); + else if (args[2] == NULL) + return_error(con, "No process id or service name given for kill"); + else if ((pid = atoi(args[2]))>0) { - logmsg(LOG_INFO, "killing %s for %s", args[2], host); - if ((*pp)->exit_time == 0) - kill((*pp)->pid, sig); - else if ((*pp)->it_forked > 1) - kill((*pp)->it_forked, sig); + proc_t *pp = skip_search(allprocs, &pid); + if (pp) + { + logmsg(LOG_INFO, "killing %s for %s", args[2], host); + if ((*pp)->exit_time == 0) + kill((*pp)->pid, sig); + else if ((*pp)->it_forked > 1) + kill((*pp)->it_forked, sig); + } + else + return_error(con, "Cannot find process %s to kill", args[2]); } - else - return_error(con, "Cannot find process %s to kill", args[2]); - } - else if ((sv = find_service(args[2]))!= NULL) - { - for ( ; sv ; sv = find_service(NULL)) + else if ((sv = find_service(args[2]))!= NULL) { - proc_t *pp; - for (pp = skip_first(sv->proc_list) ; pp ; pp = skip_next(pp)) - if ((*pp)->exit_time == 0 || (*pp)->it_forked) + for ( ; sv ; sv = find_service(NULL)) { - logmsg(LOG_INFO, - "signalling %s:%d with %d for %s", sv->service, - (*pp)->exit_time?(*pp)->it_forked:(*pp)->pid, - sig, host); - if ((*pp)->exit_time == 0) - kill((*pp)->pid, sig); - else if ((*pp)->it_forked > 1) - kill((*pp)->it_forked, sig); + proc_t *pp; + for (pp = skip_first(sv->proc_list) ; pp ; pp = skip_next(pp)) + if ((*pp)->exit_time == 0 || (*pp)->it_forked) + { + logmsg(LOG_INFO, + "signalling %s:%d with %d for %s", sv->service, + (*pp)->exit_time?(*pp)->it_forked:(*pp)->pid, + sig, host); + if ((*pp)->exit_time == 0) + kill((*pp)->pid, sig); + else if ((*pp)->it_forked > 1) + kill((*pp)->it_forked, sig); + } } } - } - else - return_error(con, "Cannot find service %s to kill", args[2]); + else + return_error(con, "Cannot find service %s to kill", args[2]); } static void do_reread(char **args, char *host, void *con) { - char *errs = NULL; - int old; - logmsg(LOG_INFO, "Rereading config file for %s", host); - old= errors_to(ERROR_STRING, &errs); - if (read_config(services, NULL) != 0) - return_error(con, "%s", errs); - errors_to(old, NULL); - if (errs) free(errs); + char *errs = NULL; + int old; + logmsg(LOG_INFO, "Rereading config file for %s", host); + old= errors_to(ERROR_STRING, &errs); + if (read_config(services, NULL) != 0) + return_error(con, "%s", errs); + errors_to(old, NULL); + if (errs) free(errs); } static void do_list(char **args, char *host, void *con) { - service_t sv, *svp; - init_return(); - send_byte(3); /* listing */ - if (args[1] == NULL) - { - for (svp = skip_first(services) ; svp ; svp = skip_next(svp)) + service_t sv, *svp; + init_return(); + send_byte(3); /* listing */ + if (args[1] == NULL) + { + for (svp = skip_first(services) ; svp ; svp = skip_next(svp)) + { + send_service(*svp); + } + send_byte(0); /* finished */ + do_send(con); + } + else if ((sv=find_service(args[1])) != NULL) { - send_service(*svp); + for ( ; sv ; sv = find_service(NULL)) + send_service(sv); + send_byte(0); + do_send(con); } - send_byte(0); /* finished */ - do_send(con); - } - else if ((sv=find_service(args[1])) != NULL) - { - for ( ; sv ; sv = find_service(NULL)) - send_service(sv); - send_byte(0); - do_send(con); - } - else - return_error(con, "Cannot find service %s to list", args[1]); + else + return_error(con, "Cannot find service %s to list", args[1]); } void do_restart(char **args, char *host, void *con) { - logmsg(LOG_INFO, "About to restart for %s", host); - control_close(); - prepare_restart(); - restart(); - exit(0); + logmsg(LOG_INFO, "About to restart for %s", host); + control_close(); + prepare_restart(); + restart(); + exit(0); } - static struct commands cmds[] = { - { "list", do_list }, - { "version",do_version }, - { "broad", do_broad }, - { "die", do_die }, - { "disable",do_disable}, - { "enable", do_enable}, - { "kick", do_run}, - { "run", do_run}, - { "kill", do_kill}, - { "reread", do_reread}, - { "restart", do_restart}, - { NULL, NULL} - }; + { "list", do_list }, + { "version",do_version }, + { "broad", do_broad }, + { "die", do_die }, + { "disable",do_disable}, + { "enable", do_enable}, + { "kick", do_run}, + { "run", do_run}, + { "kill", do_kill}, + { "reread", do_reread}, + { "restart", do_restart}, + { NULL, NULL} +}; int do_command(char **args, char *host, void *con) { - int cmd = 0; - for (cmd = 0; cmds[cmd].name ; cmd++) - if (strccmp(cmds[cmd].name, args[0])==0) - break; - if (cmds[cmd].name) - { - (cmds[cmd].proc)(args, host, con); - return 1; - } - else - return 0; + int cmd = 0; + for (cmd = 0; cmds[cmd].name ; cmd++) + if (strcasecmp(cmds[cmd].name, args[0])==0) + break; + if (cmds[cmd].name) + { + (cmds[cmd].proc)(args, host, con); + return 1; + } + else + return 0; } diff --git a/control.c b/control.c index a5e6d55..dbf114f 100644 --- a/control.c +++ b/control.c @@ -29,14 +29,14 @@ static int udp_sock; static int tcp_listen; static struct tcpcon { - int sock; - char buf[1024]; /*for incoming command */ - char host[1024]; /* host connection is from */ - int buflen; /* how much has been read */ - char *outbuf; /* outgoing data */ - int outlen; /* size of outgoing data */ - int outpos; /* how much sent so far */ - time_t connect_time;/* when the connection was established */ + int sock; + char buf[1024]; /*for incoming command */ + char host[1024]; /* host connection is from */ + int buflen; /* how much has been read */ + char *outbuf; /* outgoing data */ + int outlen; /* size of outgoing data */ + int outpos; /* how much sent so far */ + time_t connect_time;/* when the connection was established */ } tcpcon; @@ -44,269 +44,268 @@ static struct tcpcon { void return_error(struct tcpcon *con, char *fmt, char *a, char *b, char *c) { - char buf[1024]; - char *rv; - extern char version[]; - if (con) - { - sprintf(buf, fmt, a, b, c); - sprintf(buf+strlen(buf), " (metad version %s)", version); - rv = (char*)malloc(strlen(buf)+2); - strcpy(rv+1, buf); - rv[0]= 1; - con->outbuf = rv; - con->outlen = strlen(buf)+2; - con->outpos = 0; - } + char buf[1024]; + char *rv; + extern char version[]; + if (con) + { + sprintf(buf, fmt, a, b, c); + sprintf(buf+strlen(buf), " (metad version %s)", version); + rv = (char*)malloc(strlen(buf)+2); + strcpy(rv+1, buf); + rv[0]= 1; + con->outbuf = rv; + con->outlen = strlen(buf)+2; + con->outpos = 0; + } } static int address_ok(struct sockaddr_in *sa, char *host) { - struct hostent *he; - int len; - int a; - static char *tail = ".cse.unsw.edu.au"; + struct hostent *he; + int len; + int a; + static char *tail = ".cse.unsw.edu.au"; - if (ntohs(sa->sin_port) >= 1024 && geteuid() == 0) - return 0; - if (sa->sin_addr.s_addr == htonl(0x7f000001)) - { - strcpy(host, "localhost"); - return 1; /* localhost */ - } - he = gethostbyaddr((char*)&sa->sin_addr, 4, AF_INET); - if (he == NULL) - return 0; - strcpy(host, he->h_name); - he = gethostbyname(host); - if (he == NULL) - return 0; - for (a=0; he->h_addr_list[a] ; a++) - if (memcmp(&sa->sin_addr, he->h_addr_list[a], 4)==0) + if (ntohs(sa->sin_port) >= 1024 && geteuid() == 0) + return 0; + if (sa->sin_addr.s_addr == htonl(0x7f000001)) { - /* well, we have a believeable name */ - - len = strlen(host); - if (len > strlen(tail) && strccmp(tail, host+len - strlen(tail))== 0) - return 1; - return 0; + strcpy(host, "localhost"); + return 1; /* localhost */ } - return 0; + he = gethostbyaddr((char*)&sa->sin_addr, 4, AF_INET); + if (he == NULL) + return 0; + strcpy(host, he->h_name); + he = gethostbyname(host); + if (he == NULL) + return 0; + for (a=0; he->h_addr_list[a] ; a++) + if (memcmp(&sa->sin_addr, he->h_addr_list[a], 4)==0) + { + /* well, we have a believeable name */ + + len = strlen(host); + if (len > strlen(tail) && strcasecmp(tail, host+len - strlen(tail))== 0) + return 1; + return 0; + } + return 0; } static void run_command(char *buf, char *host, struct tcpcon *con) { - char *cp; - char **words, **wp; + char *cp; + char **words, **wp; - for (cp= buf; *cp ; cp++) - { - if (*cp == '\r' || *cp == '\n') *cp = 0; - } - wp = words = strsplit(buf, " "); - if (isdigit(wp[0][0])) - wp++; /* old gossip put a port number at the start for return info */ - if (!do_command(wp, host, con)) - { - /* possibly return error */ - if (con) - return_error(con, "unknown command %s", wp[0], NULL, NULL); - } + for (cp= buf; *cp ; cp++) + { + if (*cp == '\r' || *cp == '\n') *cp = 0; + } + wp = words = strsplit(buf, " "); + if (isdigit(wp[0][0])) + wp++; /* old gossip put a port number at the start for return info */ + if (!do_command(wp, host, con)) + { + /* possibly return error */ + if (con) + return_error(con, "unknown command %s", wp[0], NULL, NULL); + } } void nodelay(int socket) { - int f; - f = fcntl(socket, F_GETFL, 0); - fcntl(socket, F_SETFL, f|O_NDELAY); - fcntl(socket, F_SETFD, 1); /* set close-on-exec */ + int f; + f = fcntl(socket, F_GETFL, 0); + fcntl(socket, F_SETFL, f|O_NDELAY); + fcntl(socket, F_SETFD, 1); /* set close-on-exec */ } int control_init() { - udp_sock = socket(AF_INET, SOCK_DGRAM, 0); - if (udp_sock >= 0) - { - struct sockaddr_in sa; - memset(&sa, 0, sizeof(sa)); - sa.sin_family = AF_INET; - sa.sin_port = udp_port(); - nodelay(udp_sock); - if (bind(udp_sock, (struct sockaddr *)&sa, sizeof(sa)) != 0) + udp_sock = socket(AF_INET, SOCK_DGRAM, 0); + if (udp_sock >= 0) + { + struct sockaddr_in sa; + memset(&sa, 0, sizeof(sa)); + sa.sin_family = AF_INET; + sa.sin_port = udp_port(); + nodelay(udp_sock); + if (bind(udp_sock, (struct sockaddr *)&sa, sizeof(sa)) != 0) + { + error("cannot bind udp port"); + return -1; + } + } + else + { + error("cannot create udp socket"); + return -1; + } + tcp_listen = socket(AF_INET, SOCK_STREAM, 0); + if (tcp_listen >= 0) { - error("cannot bind udp port"); - return -1; + struct sockaddr_in sa; + int i = 1; + nodelay(tcp_listen); + memset(&sa, 0, sizeof(sa)); + sa.sin_family = AF_INET; + sa.sin_port = tcp_port(); + setsockopt(tcp_listen, SOL_SOCKET, SO_REUSEADDR, (char*)&i, 4); + if (bind(tcp_listen, (struct sockaddr *)&sa, sizeof(sa)) != 0) + { + error("cannot bind tcp port"); + return -1; + } + listen(tcp_listen, 5); } - } - else - { - error("cannot create udp socket"); - return -1; - } - tcp_listen = socket(AF_INET, SOCK_STREAM, 0); - if (tcp_listen >= 0) - { - struct sockaddr_in sa; - int i = 1; - nodelay(tcp_listen); - memset(&sa, 0, sizeof(sa)); - sa.sin_family = AF_INET; - sa.sin_port = tcp_port(); - setsockopt(tcp_listen, SOL_SOCKET, SO_REUSEADDR, (char*)&i, 4); - if (bind(tcp_listen, (struct sockaddr *)&sa, sizeof(sa)) != 0) + else { - error("cannot bind tcp port"); - return -1; + error("Cannot create tcp socket"); + return -1; } - listen(tcp_listen, 5); - } - else - { - error("Cannot create tcp socket"); - return -1; - } - tcpcon.sock = -1; - return 0; + tcpcon.sock = -1; + return 0; } void control_close(void) { - close(tcp_listen); - close(udp_sock); - close(tcpcon.sock); + close(tcp_listen); + close(udp_sock); + close(tcpcon.sock); } void check_control(void) { - /* first check udp */ - if (readyon(udp_sock)) - { - char buf[1024]; - char host[1024]; - int n; - struct sockaddr_in sa; - unsigned int salen = sizeof(sa); - n = recvfrom(udp_sock, buf, sizeof(buf)-1, 0, (struct sockaddr *)&sa, &salen ); - if (n>0 && address_ok(&sa, host)) + /* first check udp */ + if (readyon(udp_sock)) { - buf[n] = 0; - run_command(buf, host, NULL); + char buf[1024]; + char host[1024]; + int n; + struct sockaddr_in sa; + unsigned int salen = sizeof(sa); + n = recvfrom(udp_sock, buf, sizeof(buf)-1, 0, (struct sockaddr *)&sa, &salen ); + if (n>0 && address_ok(&sa, host)) + { + buf[n] = 0; + run_command(buf, host, NULL); + } } - } - listenon(udp_sock); + listenon(udp_sock); - /* then check tcpcon or tcp_listen */ - if (tcpcon.sock != -1) - { - time_t now; - time(&now); - if (tcpcon.connect_time + 120 < now) - { - /* just give up */ - close(tcpcon.sock); - tcpcon.sock = -1; - if (tcpcon.outbuf) free(tcpcon.outbuf); - tcpcon.outbuf = NULL; - listenon(tcp_listen); - } - else if (tcpcon.outbuf) + /* then check tcpcon or tcp_listen */ + if (tcpcon.sock != -1) { - if (canwrite(tcpcon.sock) && tcpcon.outpos < tcpcon.outlen) - { - int l = tcpcon.outlen - tcpcon.outpos; - if (l>1024) l = 1024; - l = write(tcpcon.sock, tcpcon.outbuf+tcpcon.outpos, l); - if (l< 0) - { - close(tcpcon.sock); tcpcon.sock = -1; free(tcpcon.outbuf); - tcpcon.outbuf = NULL; - } - else - tcpcon.outpos += l; - if (tcpcon.outpos >= tcpcon.outlen) + time_t now; + time(&now); + if (tcpcon.connect_time + 120 < now) { - close(tcpcon.sock); tcpcon.sock = -1; free(tcpcon.outbuf); - tcpcon.outbuf = NULL; + /* just give up */ + close(tcpcon.sock); + tcpcon.sock = -1; + if (tcpcon.outbuf) free(tcpcon.outbuf); + tcpcon.outbuf = NULL; + listenon(tcp_listen); } - } - if (tcpcon.sock == -1) - listenon(tcp_listen); - else - writeon(tcpcon.sock); - } - else /* we are still reading a command */ - { - if (readyon(tcpcon.sock)) - { - int l = sizeof(tcpcon.buf) - tcpcon.buflen; - l = read(tcpcon.sock, tcpcon.buf+tcpcon.buflen, l-1); - if (l<0) + else if (tcpcon.outbuf) { - close(tcpcon.sock); tcpcon.sock = -1; + if (canwrite(tcpcon.sock) && tcpcon.outpos < tcpcon.outlen) + { + int l = tcpcon.outlen - tcpcon.outpos; + if (l>1024) l = 1024; + l = write(tcpcon.sock, tcpcon.outbuf+tcpcon.outpos, l); + if (l< 0) + { + close(tcpcon.sock); tcpcon.sock = -1; free(tcpcon.outbuf); + tcpcon.outbuf = NULL; + } + else + tcpcon.outpos += l; + if (tcpcon.outpos >= tcpcon.outlen) + { + close(tcpcon.sock); tcpcon.sock = -1; free(tcpcon.outbuf); + tcpcon.outbuf = NULL; + } + } + if (tcpcon.sock == -1) + listenon(tcp_listen); + else + writeon(tcpcon.sock); } - else + else /* we are still reading a command */ { - tcpcon.buf[l] = 0; - if (l == 0 || strchr(tcpcon.buf, '\n') || strchr(tcpcon.buf, '\r') || strlen(tcpcon.buf) < l) - { - run_command(tcpcon.buf, tcpcon.host, &tcpcon); - if (tcpcon.outbuf == NULL) + if (readyon(tcpcon.sock)) { - tcpcon.outbuf = malloc(1); - tcpcon.outbuf[0] = 0; - tcpcon.outlen = 1; - tcpcon.outpos = 0; + int l = sizeof(tcpcon.buf) - tcpcon.buflen; + l = read(tcpcon.sock, tcpcon.buf+tcpcon.buflen, l-1); + if (l<0) + { + close(tcpcon.sock); tcpcon.sock = -1; + } + else + { + tcpcon.buf[l] = 0; + if (l == 0 || strchr(tcpcon.buf, '\n') || strchr(tcpcon.buf, '\r') || strlen(tcpcon.buf) < l) + { + run_command(tcpcon.buf, tcpcon.host, &tcpcon); + if (tcpcon.outbuf == NULL) + { + tcpcon.outbuf = malloc(1); + tcpcon.outbuf[0] = 0; + tcpcon.outlen = 1; + tcpcon.outpos = 0; + } + } + } } - } + if (tcpcon.sock == -1) + listenon(tcp_listen); + else if (tcpcon.outbuf) + writeon(tcpcon.sock); + else + listenon(tcpcon.sock); } - } - if (tcpcon.sock == -1) - listenon(tcp_listen); - else if (tcpcon.outbuf) - writeon(tcpcon.sock); - else - listenon(tcpcon.sock); - } - } - else - { - if (readyon(tcp_listen)) + else { - struct sockaddr_in sa; - unsigned int salen = sizeof(sa); - tcpcon.buflen = 0; - tcpcon.outbuf = NULL; - tcpcon.sock = accept(tcp_listen, (struct sockaddr *)&sa, &salen); - if (tcpcon.sock >= 0) - { - nodelay(tcpcon.sock); - if (address_ok(&sa, tcpcon.host)) - { - time(&tcpcon.connect_time); - listenon(tcpcon.sock); - waituntil(tcpcon.connect_time+122); - } - else + if (readyon(tcp_listen)) { - close(tcpcon.sock); - tcpcon.sock = -1; + struct sockaddr_in sa; + unsigned int salen = sizeof(sa); + tcpcon.buflen = 0; + tcpcon.outbuf = NULL; + tcpcon.sock = accept(tcp_listen, (struct sockaddr *)&sa, &salen); + if (tcpcon.sock >= 0) + { + nodelay(tcpcon.sock); + if (address_ok(&sa, tcpcon.host)) + { + time(&tcpcon.connect_time); + listenon(tcpcon.sock); + waituntil(tcpcon.connect_time+122); + } + else + { + close(tcpcon.sock); + tcpcon.sock = -1; + } + } } - } + if (tcpcon.sock < 0) + listenon(tcp_listen); } - if (tcpcon.sock < 0) - listenon(tcp_listen); - } } void set_reply(struct tcpcon *con, char *reply, int len) { - if (con) - { - con->outbuf = reply; - con->outlen = len; - con->outpos = 0; - } - else free(reply); + if (con) + { + con->outbuf = reply; + con->outlen = len; + con->outpos = 0; + } + else free(reply); } diff --git a/daemon.c b/daemon.c index c7c016a..02c7c98 100644 --- a/daemon.c +++ b/daemon.c @@ -3,52 +3,51 @@ typedef struct daemon_opts { - int min; - int period; - time_t last_start; + int min; + int period; + time_t last_start; } *daemon_t; #define c(sv) ((daemon_t)((sv)->classinfo)) static int daemon_opt(service_t sv, char *opt) { - /* understand min= period= */ - if (strncmp(opt, "min=", 4)==0) - { - c(sv)->min = atoi(opt+4); - return 1; - } - if (strncmp(opt, "period=", 7) == 0) - { - char *cp = opt+7; - int num = atoi(cp); - if (num==0) num=1; - while (isdigit(*cp)) cp++; - switch(*cp) { - case 0: break; - case 's': break; - case 'm': num *= 60; break; - case 'h': num *= 3600 ; break; - case 'd': num *= 24*3600 ; break; - default: error("bad period specifier, %s", opt); break; + /* understand min= period= */ + if (strncmp(opt, "min=", 4)==0) + { + c(sv)->min = atoi(opt+4); + return 1; } - c(sv)->period = num; - return 1; - } - return 0; + if (strncmp(opt, "period=", 7) == 0) + { + char *cp = opt+7; + int num = atoi(cp); + if (num==0) num=1; + while (isdigit(*cp)) cp++; + switch(*cp) { + case 0: break; + case 's': break; + case 'm': num *= 60; break; + case 'h': num *= 3600 ; break; + case 'd': num *= 24*3600 ; break; + default: error("bad period specifier, %s", opt); break; + } + c(sv)->period = num; + return 1; + } + return 0; } static void daemon_register(service_t sv) { - /* nothing to do.. */ - c(sv)->last_start = 0; + /* nothing to do.. */ + c(sv)->last_start = 0; } static void daemon_unregister(service_t sv) { - /* nothing to do... */ - + /* nothing to do... */ } static int daemon_prefork(service_t sv) @@ -58,55 +57,55 @@ static int daemon_prefork(service_t sv) static void daemon_check(service_t sv) { - /* make sure min are running, and watch for next period */ - char *env[3]; - env[0] = "METAD_REASON=min"; - env[1] = "METAD_ARG="; - env[2] = NULL; - while (c(sv)->min > 0 && count_procs(sv) < c(sv)->min) - { - if (new_proc(sv, env)<=0) - break; - } - if (c(sv)->period > 0 && - c(sv)->last_start + c(sv)->period <= time(0)) - { - env[0] = "METAD_REASON=period"; - new_proc(sv, env); - c(sv)->last_start = time(0); /* even if it didn't start, we tried */ - } - if (c(sv)->period > 0) - waituntil(c(sv)->last_start + c(sv)->period); + /* make sure min are running, and watch for next period */ + char *env[3]; + env[0] = "METAD_REASON=min"; + env[1] = "METAD_ARG="; + env[2] = NULL; + while (c(sv)->min > 0 && count_procs(sv) < c(sv)->min) + { + if (new_proc(sv, env)<=0) + break; + } + if (c(sv)->period > 0 && + c(sv)->last_start + c(sv)->period <= time(0)) + { + env[0] = "METAD_REASON=period"; + new_proc(sv, env); + c(sv)->last_start = time(0); /* even if it didn't start, we tried */ + } + if (c(sv)->period > 0) + waituntil(c(sv)->last_start + c(sv)->period); } static void daemon_copy(service_t from, service_t to) { - /* copy the classinfo - min and period */ - daemon_t n; // o; - if (from) - { - /* no special state to copy - * the new service should have parsed its own args - * - simonb 11nov2003 - */ - //o = from->classinfo; - //n->min = o->min; - //n->period = o->period; - //n->last_start = o->last_start; - } - else - { - n = (daemon_t)malloc(sizeof(struct daemon_opts)); - n->min = 0; - n->period = 0; - n->last_start = 0; - to->classinfo = n; - } + /* copy the classinfo - min and period */ + daemon_t n; // o; + if (from) + { + /* no special state to copy + * the new service should have parsed its own args + * - simonb 11nov2003 + */ + //o = from->classinfo; + //n->min = o->min; + //n->period = o->period; + //n->last_start = o->last_start; + } + else + { + n = (daemon_t)malloc(sizeof(struct daemon_opts)); + n->min = 0; + n->period = 0; + n->last_start = 0; + to->classinfo = n; + } } static void daemon_freestate(service_t sv) { - free(sv->classinfo); + free(sv->classinfo); } @@ -122,16 +121,23 @@ static void daemon_newchild(service_t sv) static void daemon_send(service_t sv) { - /* send min, period, last_start */ - send_byte(1); /* daemon */ - send_int(c(sv)->min); - send_int(c(sv)->period); - send_int(c(sv)->last_start); + /* send min, period, last_start */ + send_byte(1); /* daemon */ + send_int(c(sv)->min); + send_int(c(sv)->period); + send_int(c(sv)->last_start); } -struct class daemon_class = - { "daemon", daemon_opt, daemon_register, daemon_check, - daemon_copy, daemon_freestate, daemon_send, - daemon_unregister, daemon_newparent, daemon_newchild, - daemon_prefork - }; +struct class daemon_class = { + .class = "daemon", + .c_process_opt = daemon_opt, + .register_service = daemon_register, + .c_check_service= daemon_check, + .copy_state = daemon_copy, + .free_state = daemon_freestate, + .send_class = daemon_send, + .disable_service= daemon_unregister, + .new_parent = daemon_newparent, + .new_child = daemon_newchild, + .prefork = daemon_prefork, +}; diff --git a/dlink.c b/dlink.c index 77c7b5e..e5722e0 100644 --- a/dlink.c +++ b/dlink.c @@ -9,23 +9,21 @@ void *dl_head() { - void *h; - h = dl_alloc(0); - dl_next(h) = h; - dl_prev(h) = h; - return h; + void *h; + h = dl_alloc(0); + dl_next(h) = h; + dl_prev(h) = h; + return h; } -void dl_free(v) -void *v; +void dl_free(void *v) { - struct __dl_head *vv = v; - free(vv-1); + struct __dl_head *vv = v; + free(vv-1); } -void dl_insert(head, val) -void *head, *val; +void dl_insert(void *head, void *val) { dl_next(val) = dl_next(head); dl_prev(val) = head; @@ -33,8 +31,7 @@ void *head, *val; dl_prev(dl_next(val)) = val; } -void dl_add(head, val) -void *head, *val; +void dl_add(void *head, void *val) { dl_prev(val) = dl_prev(head); dl_next(val) = head; @@ -42,33 +39,32 @@ void *head, *val; dl_prev(dl_next(val)) = val; } -void dl_del(val) -void *val; +void dl_del(void *val) { - if (dl_prev(val) == 0 || dl_next(val) == 0) - return; - dl_prev(dl_next(val)) = dl_prev(val); - dl_next(dl_prev(val)) = dl_next(val); - dl_prev(val) = dl_next(val) = 0; + if (dl_prev(val) == 0 || dl_next(val) == 0) + return; + dl_prev(dl_next(val)) = dl_prev(val); + dl_next(dl_prev(val)) = dl_next(val); + dl_prev(val) = dl_next(val) = 0; } char *dl_strndup(char *s, int l) { - char *n; - if (s == NULL) - return NULL; - n = dl_newv(char, l+1); - if (n == NULL) - return NULL; - else - { - strncpy(n, s, l); - n[l] = 0; - return n; - } + char *n; + if (s == NULL) + return NULL; + n = dl_newv(char, l+1); + if (n == NULL) + return NULL; + else + { + strncpy(n, s, l); + n[l] = 0; + return n; + } } char *dl_strdup(char *s) { - return dl_strndup(s, (int)strlen(s)); + return dl_strndup(s, (int)strlen(s)); } diff --git a/error.c b/error.c index db8cf0c..f5f199e 100644 --- a/error.c +++ b/error.c @@ -12,52 +12,52 @@ int err_str_len; int errors_to(int where, char **place) { - int rv = error_dest; - error_dest = where; - if (where == ERROR_STRING) - error_str = place; - if (rv == ERROR_SYSLOG && where != ERROR_SYSLOG) - closelog(); - if (where == ERROR_SYSLOG && rv != ERROR_SYSLOG) - { + int rv = error_dest; + error_dest = where; + if (where == ERROR_STRING) + error_str = place; + if (rv == ERROR_SYSLOG && where != ERROR_SYSLOG) + closelog(); + if (where == ERROR_SYSLOG && rv != ERROR_SYSLOG) + { #ifdef LOG_DAEMON - openlog("metad", LOG_PID, LOG_DAEMON); + openlog("metad", LOG_PID, LOG_DAEMON); #else - openlog("metad", 0); + openlog("metad", 0); #endif - } - return rv; + } + return rv; } void error(char *mesg, char *a, char *b, char *c) { - char buf[1024]; - - sprintf(buf, mesg, a, b, c); + char buf[1024]; - switch(error_dest) - { - case ERROR_STDERR: - fprintf(stderr, "metad: %s\n", buf); - break; - case ERROR_STRING: - if (*error_str == NULL) - { - *error_str = (char*)malloc(err_str_len=(strlen(buf)+100)); - strcpy(*error_str, buf); - } - else if (strlen(*error_str)+strlen(buf)+1 > err_str_len) + sprintf(buf, mesg, a, b, c); + + switch(error_dest) { - *error_str = (char*)realloc(*error_str, err_str_len += strlen(buf)+100); - strcat(*error_str, buf); + case ERROR_STDERR: + fprintf(stderr, "metad: %s\n", buf); + break; + case ERROR_STRING: + if (*error_str == NULL) + { + *error_str = (char*)malloc(err_str_len=(strlen(buf)+100)); + strcpy(*error_str, buf); + } + else if (strlen(*error_str)+strlen(buf)+1 > err_str_len) + { + *error_str = (char*)realloc(*error_str, err_str_len += strlen(buf)+100); + strcat(*error_str, buf); + } + else + strcat(*error_str, buf); + break; + case ERROR_SYSLOG: + syslog(LOG_ERR, "%s", buf); + break; } - else - strcat(*error_str, buf); - break; - case ERROR_SYSLOG: - syslog(LOG_ERR, "%s", buf); - break; - } } #ifdef STDARGS @@ -67,46 +67,46 @@ void logmsg(va_alist) va_dcl #endif { - va_list pvar; - char buf[1024]; - char *format; + va_list pvar; + char buf[1024]; + char *format; #ifdef STDARGS - va_start(pvar, level); + va_start(pvar, level); #else - int level; - va_start(pvar); - level = va_arg(pvar, int); + int level; + va_start(pvar); + level = va_arg(pvar, int); #endif - format = va_arg(pvar, char *); - vsprintf(buf, format, pvar); - switch(error_dest) - { - case ERROR_STDERR: - fprintf(stderr, "metad: %s\n", buf); - break; - case ERROR_STRING: - if (*error_str == NULL) - { - *error_str = (char*)malloc(err_str_len=(strlen(buf)+100)); - strcpy(*error_str, buf); - } - else if (strlen(*error_str)+strlen(buf)+1 > err_str_len) + format = va_arg(pvar, char *); + vsprintf(buf, format, pvar); + switch(error_dest) { - *error_str = (char*)realloc(*error_str, err_str_len += strlen(buf)+100); - strcat(*error_str, buf); + case ERROR_STDERR: + fprintf(stderr, "metad: %s\n", buf); + break; + case ERROR_STRING: + if (*error_str == NULL) + { + *error_str = (char*)malloc(err_str_len=(strlen(buf)+100)); + strcpy(*error_str, buf); + } + else if (strlen(*error_str)+strlen(buf)+1 > err_str_len) + { + *error_str = (char*)realloc(*error_str, err_str_len += strlen(buf)+100); + strcat(*error_str, buf); + } + else + strcat(*error_str, buf); + break; + case ERROR_SYSLOG: + syslog(level, "%s", buf); + break; } - else - strcat(*error_str, buf); - break; - case ERROR_SYSLOG: - syslog(level, "%s", buf); - break; - } -} +} void dolog(service_t sv, proc_t p, char *buf) { - logmsg(LOG_INFO, "%s: %d: %s\n", sv->service, p->pid, buf); + logmsg(LOG_INFO, "%s: %d: %s\n", sv->service, p->pid, buf); } diff --git a/loadstate.c b/loadstate.c index 620b508..e9f810b 100644 --- a/loadstate.c +++ b/loadstate.c @@ -19,140 +19,140 @@ char *get_str(); char *get_return(); void qfree(char *a) { - if (a) free(a); + if (a) free(a); } void loadstate(int fd) { - int len = lseek(fd, 0, 2); - int b; - char *buf; - lseek(fd, 0, 0); - - buf = (char*)malloc(len); - read(fd, buf, len); - close(fd); + int len = lseek(fd, 0, 2); + int b; + char *buf; + lseek(fd, 0, 0); - init_recv(buf); - if (get_byte() != 3) return; /* something VERY wrong */ - b = get_byte(); - while(b==1 || b == 2) /* service */ - { - char *sname; - int enabled; - int args; - int class; - service_t sv, *svp = NULL; + buf = (char*)malloc(len); + read(fd, buf, len); + close(fd); - sname = get_str(); - if (sname) - { - svp = skip_search(services, sname); - free(sname); - } - get_int(); /* max */ - qfree(get_str()); /* home */ - qfree(get_str()); /* user */ - qfree(get_str()); /* crash */ - if (b == 2) - { - get_int(); /* watch_output */ - qfree(get_str()); /* pidfile */ - } - get_int(); /* cnt */ - enabled = get_int(); - qfree(get_str()); /* prog */ - args = get_int(); - while (args--) - qfree(get_str()); - class = get_byte(); - switch(class) - { - case 1: - get_int(); - get_int(); - get_int(); - break; - case 2: - get_int(); - get_int(); - get_int(); - get_int(); - break; - } - if (svp) sv= *svp ;else sv= NULL; - if (sv) sv->enabled = enabled; + init_recv(buf); + if (get_byte() != 3) return; /* something VERY wrong */ b = get_byte(); - while (b == 3 || b == 4) /* process */ + while(b==1 || b == 2) /* service */ { - int pid, start, xit; - int forkedpid = 0, pipefd = -1; - pid = get_int(); - if (b == 4) - { - forkedpid = get_int(); - pipefd = get_int(); - } - - start = get_int(); /* start */ - get_int(); /* hold */ - xit = get_int(); - get_int(); /* status */ - if ((sv && (xit == 0 && kill(pid, 0)==0)) || (xit>0 && forkedpid>0 && kill(forkedpid,0)==0) ) - { - proc_t p = (proc_t)malloc(sizeof(struct proc)); - p->pid = pid; - p->service = sv; - p->pipefd = pipefd; - p->bufptr = 0; - p->it_forked = forkedpid; - p->is_crash = 0; - p->start_time = start; - p->hold_time = xit?1:0; - p->exit_time = xit; - skip_insert(sv->proc_list, p); - skip_insert(allprocs, p); - } - b = get_byte(); + char *sname; + int enabled; + int args; + int class; + service_t sv, *svp = NULL; + + sname = get_str(); + if (sname) + { + svp = skip_search(services, sname); + free(sname); + } + get_int(); /* max */ + qfree(get_str()); /* home */ + qfree(get_str()); /* user */ + qfree(get_str()); /* crash */ + if (b == 2) + { + get_int(); /* watch_output */ + qfree(get_str()); /* pidfile */ + } + get_int(); /* cnt */ + enabled = get_int(); + qfree(get_str()); /* prog */ + args = get_int(); + while (args--) + qfree(get_str()); + class = get_byte(); + switch(class) + { + case 1: + get_int(); + get_int(); + get_int(); + break; + case 2: + get_int(); + get_int(); + get_int(); + get_int(); + break; + } + if (svp) sv= *svp ;else sv= NULL; + if (sv) sv->enabled = enabled; + b = get_byte(); + while (b == 3 || b == 4) /* process */ + { + int pid, start, xit; + int forkedpid = 0, pipefd = -1; + pid = get_int(); + if (b == 4) + { + forkedpid = get_int(); + pipefd = get_int(); + } + + start = get_int(); /* start */ + get_int(); /* hold */ + xit = get_int(); + get_int(); /* status */ + if ((sv && (xit == 0 && kill(pid, 0)==0)) || (xit>0 && forkedpid>0 && kill(forkedpid,0)==0) ) + { + proc_t p = (proc_t)malloc(sizeof(struct proc)); + p->pid = pid; + p->service = sv; + p->pipefd = pipefd; + p->bufptr = 0; + p->it_forked = forkedpid; + p->is_crash = 0; + p->start_time = start; + p->hold_time = xit?1:0; + p->exit_time = xit; + skip_insert(sv->proc_list, p); + skip_insert(allprocs, p); + } + b = get_byte(); + } } - } - free(buf); + free(buf); } extern char **gargv; void restart(void) { - int fd; - int len; - char *buf; - service_t *svp; - char *file = "/var/tmp/...metad-temp-file"; + int fd; + int len; + char *buf; + service_t *svp; + char *file = "/var/tmp/...metad-temp-file"; - fd = open(file, O_RDWR|O_TRUNC|O_CREAT, 0600); - if (fd < 0) - { - close(0); + fd = open(file, O_RDWR|O_TRUNC|O_CREAT, 0600); + if (fd < 0) + { + close(0); + execv(gargv[2], gargv); + exit(1); + } + unlink(file); + init_return(); + send_byte(3); /* listing */ + for (svp = skip_first(services) ; svp ; svp = skip_next(svp)) + { + send_service(*svp); + } + send_byte(0); /* finished */ + + buf = get_return(&len); + write(fd, buf, len); + if (fd > 0) + { + close(0); + dup(fd); + close(fd); + } + gargv[0] = "metad-restart"; execv(gargv[2], gargv); exit(1); - } - unlink(file); - init_return(); - send_byte(3); /* listing */ - for (svp = skip_first(services) ; svp ; svp = skip_next(svp)) - { - send_service(*svp); - } - send_byte(0); /* finished */ - - buf = get_return(&len); - write(fd, buf, len); - if (fd > 0) - { - close(0); - dup(fd); - close(fd); - } - gargv[0] = "metad-restart"; - execv(gargv[2], gargv); - exit(1); } diff --git a/mainloop.c b/mainloop.c index 21da64d..f38d740 100644 --- a/mainloop.c +++ b/mainloop.c @@ -27,58 +27,58 @@ time_t when_wake; void listenon(int socket) { - FD_SET(socket, &wait_for); + FD_SET(socket, &wait_for); } int readyon(int socket) { - return FD_ISSET(socket, &are_ready); + return FD_ISSET(socket, &are_ready); } void writeon(int socket) { - FD_SET(socket, &write_on); + FD_SET(socket, &write_on); } int canwrite(int socket) { - return FD_ISSET(socket, &can_write); + return FD_ISSET(socket, &can_write); } void waituntil(time_t when) { - if (when_wake == 0 || when_wake > when) when_wake = when; + if (when_wake == 0 || when_wake > when) when_wake = when; } static struct { - pid_t pid; - int status; - time_t time; + pid_t pid; + int status; + time_t time; } saved_pids[20] = { { 0 } }; static struct timeval select_tv; static void collectchild() { - pid_t pid; - int status; + pid_t pid; + int status; - if ((pid = waitpid(-1, &status, WNOHANG)) > 0) - { - int i; - for (i=0; i<20 ; i++) - if (saved_pids[i].pid == 0) - { - saved_pids[i].pid = pid; - saved_pids[i].status = status; - time(&saved_pids[i].time); - break; - } - } - select_tv.tv_usec = 0; - select_tv.tv_sec = 0; + if ((pid = waitpid(-1, &status, WNOHANG)) > 0) + { + int i; + for (i=0; i<20 ; i++) + if (saved_pids[i].pid == 0) + { + saved_pids[i].pid = pid; + saved_pids[i].status = status; + time(&saved_pids[i].time); + break; + } + } + select_tv.tv_usec = 0; + select_tv.tv_sec = 0; } int is_saved_pid(pid_t pid) @@ -92,67 +92,67 @@ int is_saved_pid(pid_t pid) void main_loop() { - struct sigaction sa; - sigset_t ss; - sa.sa_handler = collectchild; - sa.sa_flags = 0; - sigemptyset(&ss); - sigaddset(&ss, SIGCLD); - sa.sa_mask = ss; - sigaction(SIGCLD, &sa, NULL); - - FD_ZERO(&are_ready); - FD_ZERO(&can_write); - while (1) - { - service_t *svp; - int i; - FD_ZERO(&wait_for); - FD_ZERO(&write_on); - when_wake = time(0)+5*60; /* always wakeup every 5minutes to look around... */ - collectchild(); /* incase signal was missed */ - - for (i=0 ; i<20 ; i++) - if (saved_pids[i].pid) - { - proc_t *pp; - pp = skip_search(allprocs, &saved_pids[i].pid); - if (pp) - { - (*pp)->status = saved_pids[i].status; - (*pp)->exit_time = saved_pids[i].time;; - select_tv.tv_sec = 0; - logmsg(LOG_INFO, "process %d (%s) exited - status 0x%04x", saved_pids[i].pid, (*pp)->service->service, (*pp)->status); - } else - logmsg(LOG_INFO, "process %d exited - status 0x%04x", saved_pids[i].pid, saved_pids[i].status); - saved_pids[i].pid = 0; - - } - - for (svp = skip_first(services) ; svp ; svp = skip_next(svp)) - check_service(*svp); - check_control(); - are_ready = wait_for; - can_write = write_on; - - if (when_wake) - { - time_t now; - time(&now); - select_tv.tv_sec = when_wake - now; - select_tv.tv_usec = 0; - if (when_wake < now) select_tv.tv_sec = 0; - } - else - { - select_tv.tv_sec = 100000; - select_tv.tv_usec = 0; - } - if (select(FD_SETSIZE, &are_ready, &can_write, NULL, &select_tv) <= 0) + struct sigaction sa; + sigset_t ss; + sa.sa_handler = collectchild; + sa.sa_flags = 0; + sigemptyset(&ss); + sigaddset(&ss, SIGCLD); + sa.sa_mask = ss; + sigaction(SIGCLD, &sa, NULL); + + FD_ZERO(&are_ready); + FD_ZERO(&can_write); + while (1) { - FD_ZERO(&are_ready); - FD_ZERO(&can_write); + service_t *svp; + int i; + FD_ZERO(&wait_for); + FD_ZERO(&write_on); + when_wake = time(0)+5*60; /* always wakeup every 5minutes to look around... */ + collectchild(); /* incase signal was missed */ + + for (i=0 ; i<20 ; i++) + if (saved_pids[i].pid) + { + proc_t *pp; + pp = skip_search(allprocs, &saved_pids[i].pid); + if (pp) + { + (*pp)->status = saved_pids[i].status; + (*pp)->exit_time = saved_pids[i].time;; + select_tv.tv_sec = 0; + logmsg(LOG_INFO, "process %d (%s) exited - status 0x%04x", saved_pids[i].pid, (*pp)->service->service, (*pp)->status); + } else + logmsg(LOG_INFO, "process %d exited - status 0x%04x", saved_pids[i].pid, saved_pids[i].status); + saved_pids[i].pid = 0; + + } + + for (svp = skip_first(services) ; svp ; svp = skip_next(svp)) + check_service(*svp); + check_control(); + are_ready = wait_for; + can_write = write_on; + + if (when_wake) + { + time_t now; + time(&now); + select_tv.tv_sec = when_wake - now; + select_tv.tv_usec = 0; + if (when_wake < now) select_tv.tv_sec = 0; + } + else + { + select_tv.tv_sec = 100000; + select_tv.tv_usec = 0; + } + if (select(FD_SETSIZE, &are_ready, &can_write, NULL, &select_tv) <= 0) + { + FD_ZERO(&are_ready); + FD_ZERO(&can_write); + } } - } } diff --git a/meta.c b/meta.c index 49a4e4e..f6cc8a0 100644 --- a/meta.c +++ b/meta.c @@ -35,210 +35,210 @@ char *progname; void usage(char *fmt, char *arg) { - char buf[1024]; - sprintf(buf, fmt, arg); - fprintf(stderr,"%s: %s\n", progname, buf); - fprintf(stderr,"Usage: %s -[h?Vubv] -[LRXB] {-[rklDEK] service} [-C command] hostlist ...\n", progname); + char buf[1024]; + sprintf(buf, fmt, arg); + fprintf(stderr,"%s: %s\n", progname, buf); + fprintf(stderr,"Usage: %s -[h?Vubv] -[LRXB] {-[rklDEK] service} [-C command] hostlist ...\n", progname); } void help() { - printf( - "Usage: %s -[h?Vubv] -[LRXB] {-[rklDEK] service} [-C command] hostlist ...\n" - " -h This help message\n" - " -? As above\n" - " -V Print version number of metac and the metad running on any\n" - " host listed\n" - " -u Send commands in udp datagrams. This is faster than the\n" - " normal tcp, but\n" - " avoids delays on dead machines.\n" - " -b Send each request as a broadcast on any available network\n" - " interfaces.\n" - " -v Be verbose when listing services.\n" - " -L List all services supported by the metad on the remote host.\n" - " -R Tell metad to reread it's configuration file.\n" - " -X Tell metad to eXit.\n" - " -B Tell the metad to rebroadcast the request on it's\n" - " interfaces.\n" - " -r service Try to start a process running for the service.\n" - " -k service Kick a service into action, same as above.\n" - " -l service List details of the named service.\n" - " -D service Disable a service. No more processes will be started for\n" - " that service.\n" - " -E service Enable a service. Metad will start processes as\n" - " appropriate.\n" - " -K pid Of metad is managing a process with number pid, then it\n" - " is sent a SIGTERM.\n" - " -K service Every process running for the given service is sent a\n" - " SIGTERM.\n" - " -C command Send the given command (which will usually be quoted).\n" - " Commands are:\n" - " run service args like -r, but allows args to be passed to\n" - " the process.\n" - " kill signum pid-or-service like -K, but allows a signal number\n" - " to be given.\n" - " restart tell metad to re-exec itself, for use when a\n" - " new version is installed\n" - " (plus others that duplicate the above flags)\n" - , progname) ; + printf( + "Usage: %s -[h?Vubv] -[LRXB] {-[rklDEK] service} [-C command] hostlist ...\n" + " -h This help message\n" + " -? As above\n" + " -V Print version number of metac and the metad running on any\n" + " host listed\n" + " -u Send commands in udp datagrams. This is faster than the\n" + " normal tcp, but\n" + " avoids delays on dead machines.\n" + " -b Send each request as a broadcast on any available network\n" + " interfaces.\n" + " -v Be verbose when listing services.\n" + " -L List all services supported by the metad on the remote host.\n" + " -R Tell metad to reread it's configuration file.\n" + " -X Tell metad to eXit.\n" + " -B Tell the metad to rebroadcast the request on it's\n" + " interfaces.\n" + " -r service Try to start a process running for the service.\n" + " -k service Kick a service into action, same as above.\n" + " -l service List details of the named service.\n" + " -D service Disable a service. No more processes will be started for\n" + " that service.\n" + " -E service Enable a service. Metad will start processes as\n" + " appropriate.\n" + " -K pid Of metad is managing a process with number pid, then it\n" + " is sent a SIGTERM.\n" + " -K service Every process running for the given service is sent a\n" + " SIGTERM.\n" + " -C command Send the given command (which will usually be quoted).\n" + " Commands are:\n" + " run service args like -r, but allows args to be passed to\n" + " the process.\n" + " kill signum pid-or-service like -K, but allows a signal number\n" + " to be given.\n" + " restart tell metad to re-exec itself, for use when a\n" + " new version is installed\n" + " (plus others that duplicate the above flags)\n" + , progname) ; } int send_cmd(char *cmd, int udp, char *host, int verbose); int main(int argc, char *argv[]) { - void *cmds = dl_head(); - void *hosts = dl_head(); - int local_broad = 0; - int remote_broad = 0; - int use_dgram = 0; - int show_version = 0; - int show_help = 0; - int verbose = 0; - char *c, *c2; - void *opts = args_init(argc, argv, "??h?V?u?b?r:a:k:l:L?D:E:K:R?X?v?C:B?"); - int opt; - char *arg; - int pos, inv; - progname = strrchr(argv[0], '/'); - if (progname) progname++; else progname = argv[0]; + void *cmds = dl_head(); + void *hosts = dl_head(); + int local_broad = 0; + int remote_broad = 0; + int use_dgram = 0; + int show_version = 0; + int show_help = 0; + int verbose = 0; + char *c, *c2; + void *opts = args_init(argc, argv, "??h?V?u?b?r:a:k:l:L?D:E:K:R?X?v?C:B?"); + int opt; + char *arg; + int pos, inv; + progname = strrchr(argv[0], '/'); + if (progname) progname++; else progname = argv[0]; - while ((opt = args_next(opts, &pos, &inv, &arg))!= END_ARGS) - switch(opt) + while ((opt = args_next(opts, &pos, &inv, &arg))!= END_ARGS) + switch(opt) + { + case BAD_FLAG: + usage("Bad option: %s", argv[pos]); + exit(1); + case NO_FLAG: + c = dl_strdup(arg); + dl_add(hosts, c); + break; + case 'h': + case '?': + show_help = 1; + break; + case 'V': /* my version number */ + printf("%s: version %s\n", progname, version); + show_version =1; + break; + case 'u': + use_dgram = 1; + break; + case 'b': + local_broad = 1; + break; + case 'r': + case 'k': + c = dl_strndup("kick ", 5+strlen(arg)+1); + strcat(c, arg); + dl_add(cmds, c); + break; + case 'a': + c = dl_prev(cmds); + if (c == cmds || (strncmp(c, "kick ", 5)!= 0 && strncmp(c, "run ", 4)!= 0)) + { + usage("%s: -a only valid after -r or -k", NULL); + exit(1); + } + c2 = dl_strndup(c, strlen(c)+1+strlen(arg)+1); + strcat(c2, " "); + strcat(c2, arg); + dl_del(c); dl_free(c); + dl_add(cmds, c2); + break; + case 'l': + c = dl_strndup("list ", 5+strlen(arg)+1); + strcat(c, arg); + dl_add(cmds, c); + break; + case 'L': + c = dl_strdup("list"); + dl_add(cmds, c); + break; + case 'D': + c = dl_strndup("disable ", 8+strlen(arg)+1); + strcat(c, arg); + dl_add(cmds, c); + break; + case 'E': + c = dl_strndup("enable ", 7+strlen(arg)+1); + strcat(c, arg); + dl_add(cmds, c); + break; + case 'K': + c = dl_strndup("kill 15 ", 8+strlen(arg)+1); + strcat(c, arg); + dl_add(cmds, c); + break; + case 'R': + c = dl_strdup("reread"); + dl_add(cmds, c); + break; + case 'X': + c = dl_strdup("die"); + dl_add(cmds, c); + break; + case 'v': + verbose = 1; + break; + case 'C': + c = dl_strdup(arg); + dl_add(cmds, c); + break; + case 'B': + remote_broad = 1; + break; + } + + if (show_help) + { + help(); + exit(0); + } + if (dl_next(hosts) == hosts && local_broad == 0) + { + /* no where to send to... */ + if (dl_next(cmds) != cmds) + { + fprintf(stderr,"%s: commands were specified with no where to send them!\n", progname); + exit(1); + } + /* nothing to do, though might has displayed version. + * Should probably give usage... + */ + if (show_version == 0) + usage("Nothing to do", NULL), exit(1); + exit(0); + } + if (dl_next(hosts) != hosts && local_broad) { - case BAD_FLAG: - usage("Bad option: %s", argv[pos]); - exit(1); - case NO_FLAG: - c = dl_strdup(arg); - dl_add(hosts, c); - break; - case 'h': - case '?': - show_help = 1; - break; - case 'V': /* my version number */ - printf("%s: version %s\n", progname, version); - show_version =1; - break; - case 'u': - use_dgram = 1; - break; - case 'b': - local_broad = 1; - break; - case 'r': - case 'k': - c = dl_strndup("kick ", 5+strlen(arg)+1); - strcat(c, arg); - dl_add(cmds, c); - break; - case 'a': - c = dl_prev(cmds); - if (c == cmds || (strncmp(c, "kick ", 5)!= 0 && strncmp(c, "run ", 4)!= 0)) - { - usage("%s: -a only valid after -r or -k", NULL); + fprintf(stderr, "%s: you probably don't want to broadcast AND list hosts...\n", progname); exit(1); - } - c2 = dl_strndup(c, strlen(c)+1+strlen(arg)+1); - strcat(c2, " "); - strcat(c2, arg); - dl_del(c); dl_free(c); - dl_add(cmds, c2); - break; - case 'l': - c = dl_strndup("list ", 5+strlen(arg)+1); - strcat(c, arg); - dl_add(cmds, c); - break; - case 'L': - c = dl_strdup("list"); - dl_add(cmds, c); - break; - case 'D': - c = dl_strndup("disable ", 8+strlen(arg)+1); - strcat(c, arg); - dl_add(cmds, c); - break; - case 'E': - c = dl_strndup("enable ", 7+strlen(arg)+1); - strcat(c, arg); - dl_add(cmds, c); - break; - case 'K': - c = dl_strndup("kill 15 ", 8+strlen(arg)+1); - strcat(c, arg); - dl_add(cmds, c); - break; - case 'R': - c = dl_strdup("reread"); - dl_add(cmds, c); - break; - case 'X': - c = dl_strdup("die"); - dl_add(cmds, c); - break; - case 'v': - verbose = 1; - break; - case 'C': - c = dl_strdup(arg); - dl_add(cmds, c); - break; - case 'B': - remote_broad = 1; - break; } - if (show_help) - { - help(); - exit(0); - } - if (dl_next(hosts) == hosts && local_broad == 0) - { - /* no where to send to... */ - if (dl_next(cmds) != cmds) + if (show_version) { - fprintf(stderr,"%s: commands were specified with no where to send them!\n", progname); - exit(1); + c = dl_strdup("version"); + dl_insert(cmds, c); } - /* nothing to do, though might has displayed version. - * Should probably give usage... - */ - if (show_version == 0) - usage("Nothing to do", NULL), exit(1); - exit(0); - } - if (dl_next(hosts) != hosts && local_broad) - { - fprintf(stderr, "%s: you probably don't want to broadcast AND list hosts...\n", progname); - exit(1); - } - - if (show_version) - { - c = dl_strdup("version"); - dl_insert(cmds, c); - } - for (c= dl_next(cmds) ; c != cmds ; c = dl_next(c)) - { - char *cmd = (char*)malloc(10 + strlen(c)); /* make sure there is room for port and broad */ - char *h; - - strcpy(cmd, "1 "); - if (remote_broad) - strcat(cmd, "BROAD "); - strcat(cmd, c); - if (local_broad) - broadcast(cmd); - else for (h=dl_next(hosts) ; h != hosts ; h = dl_next(h)) + for (c= dl_next(cmds) ; c != cmds ; c = dl_next(c)) { - if (strcmp(h, ".")== 0) - send_cmd(cmd, use_dgram, "localhost", verbose); - else - send_cmd(cmd, use_dgram, h, verbose); + char *cmd = (char*)malloc(10 + strlen(c)); /* make sure there is room for port and broad */ + char *h; + + strcpy(cmd, "1 "); + if (remote_broad) + strcat(cmd, "BROAD "); + strcat(cmd, c); + if (local_broad) + broadcast(cmd); + else for (h=dl_next(hosts) ; h != hosts ; h = dl_next(h)) + { + if (strcmp(h, ".")== 0) + send_cmd(cmd, use_dgram, "localhost", verbose); + else + send_cmd(cmd, use_dgram, h, verbose); + } } - } - exit(0); /* FIXME what exit status */ + exit(0); /* FIXME what exit status */ } diff --git a/metad.c b/metad.c index 9586578..c75e51b 100644 --- a/metad.c +++ b/metad.c @@ -9,25 +9,25 @@ char **gargv; int main(int argc, char *argv[]) { - gargv = argv; + gargv = argv; - { - int ttyfd = open("/dev/tty", 2, 0); - if (ttyfd >= 0) { - ioctl(ttyfd, TIOCNOTTY, NULL); - close(ttyfd); + { + int ttyfd = open("/dev/tty", 2, 0); + if (ttyfd >= 0) { + ioctl(ttyfd, TIOCNOTTY, NULL); + close(ttyfd); + } } - } - /* FIXME should make sure stdin/stdout/stderr are open to something */ - service_init(); - control_init(); - errors_to(ERROR_SYSLOG, NULL); - read_config(services, argv[1]); - if (strcmp(argv[0], "metad-restart")==0) { - loadstate(0); - open("/dev/null", O_RDONLY); - } - main_loop(); - exit(0); + /* FIXME should make sure stdin/stdout/stderr are open to something */ + service_init(); + control_init(); + errors_to(ERROR_SYSLOG, NULL); + read_config(services, argv[1]); + if (strcmp(argv[0], "metad-restart")==0) { + loadstate(0); + open("/dev/null", O_RDONLY); + } + main_loop(); + exit(0); } diff --git a/metad.h b/metad.h index 2728ad8..033d4b2 100644 --- a/metad.h +++ b/metad.h @@ -8,73 +8,71 @@ #include #include /* hold config file info */ -#ifdef ULTRIX -char *strdup(char*); -#endif + typedef struct service { - char *service; /* name of service */ - struct class *class; /* pointer to class*/ - void *classinfo; /* class specific options */ - /* class independant options */ - - int max_proc; /* max number of processes */ - char *crash_prog; /* prog to call when process crashes */ - char *home_dir; /* directory to run process in */ - char *username; /* who to run process as */ - char *pidfile; /* file to read process id from after child exits */ - int watch_output; /* if true, attatch a pipe to std{out,err} and what it */ - int enabled; /* whether to start enabled */ - int start_cnt; - char *program; /* program to run */ - char **args; /* arguments */ - - int pending; /* set before reprocessing config file, cleared when found in file */ - - void *proc_list; /* skiplist of currently active processes */ - time_t next_hold; /* hold time for next crashing processes */ + char *service; /* name of service */ + struct class *class; /* pointer to class*/ + void *classinfo; /* class specific options */ + /* class independant options */ + + int max_proc; /* max number of processes */ + char *crash_prog; /* prog to call when process crashes */ + char *home_dir; /* directory to run process in */ + char *username; /* who to run process as */ + char *pidfile; /* file to read process id from after child exits */ + int watch_output; /* if true, attatch a pipe to std{out,err} and what it */ + int enabled; /* whether to start enabled */ + int start_cnt; + char *program; /* program to run */ + char **args; /* arguments */ + + int pending; /* set before reprocessing config file, cleared when found in file */ + + void *proc_list; /* skiplist of currently active processes */ + time_t next_hold; /* hold time for next crashing processes */ } *service_t; typedef struct class { - char *class; /* name of class */ - int (*c_process_opt)(); /* function to processes options */ - void (*register_service)(); /* register the service if necessary */ - void (*c_check_service)(); /* check if anything needs to be done for a service */ - void (*copy_state)(); /* copy state from old service struct to new */ - void (*free_state)(); /* free class dependant state */ - void (*send_class)(); /* send class info */ - void (*disable_service)(); /* unregister service */ - void (*new_parent)(); /* in parent of new child */ - void (*new_child)(); /* in a new child */ - int (*prefork)(); /* just before fork */ + char *class; /* name of class */ + int (*c_process_opt)(); /* function to processes options */ + void (*register_service)(); /* register the service if necessary */ + void (*c_check_service)(); /* check if anything needs to be done for a service */ + void (*copy_state)(); /* copy state from old service struct to new */ + void (*free_state)(); /* free class dependant state */ + void (*send_class)(); /* send class info */ + void (*disable_service)(); /* unregister service */ + void (*new_parent)(); /* in parent of new child */ + void (*new_child)(); /* in a new child */ + int (*prefork)(); /* just before fork */ } *class_t; typedef struct proc { - pid_t pid; /* pid of process */ - service_t service; - int pipefd; /* if a pipe was conencted to stdout/stderr */ - char pipebuf[300]; /* buffer lines of data from pipefd before syslogging */ - int bufptr; /* how full buf is */ - int it_forked; /* true if process fork/exited, and we have pid from pidfile */ - int is_crash; /* if cleaning up after core dump */ - time_t start_time; /* when processes started */ - time_t hold_time; /* time to let go of processes slot - set if process crashes early */ - time_t exit_time; /* the time that it exited */ - int status; /* wait status if exit_time > 0 */ + pid_t pid; /* pid of process */ + service_t service; + int pipefd; /* if a pipe was conencted to stdout/stderr */ + char pipebuf[300]; /* buffer lines of data from pipefd before syslogging */ + int bufptr; /* how full buf is */ + int it_forked; /* true if process fork/exited, and we have pid from pidfile */ + int is_crash; /* if cleaning up after core dump */ + time_t start_time; /* when processes started */ + time_t hold_time; /* time to let go of processes slot - set if process crashes early */ + time_t exit_time; /* the time that it exited */ + int status; /* wait status if exit_time > 0 */ } *proc_t; typedef struct daemon_info { /* class specific info for class "daemon" */ - int min_proc; /* minimum number of processes to have running */ - int period; /* period in seconds for restarts */ + int min_proc; /* minimum number of processes to have running */ + int period; /* period in seconds for restarts */ - time_t last_restart; /* last time a periodic restart was attempted */ + time_t last_restart; /* last time a periodic restart was attempted */ } *daemon_info_t; typedef struct commands { - char * name; - void (*proc)(); + char * name; + void (*proc)(); } *commands_t; class_t find_class(char *name); @@ -121,7 +119,6 @@ int udp_port(void); int tcp_port(void); void nodelay(int socket); -int strccmp(char*, char*); #ifndef IN_ERROR void error(char *mesg,...); void logmsg(int, char*, ...); @@ -134,7 +131,6 @@ int errors_to(int where, char **place); char **strlistdup(char **l); void strlistfree(char **l); char **strsplit(char *line, char *sep); -/*char *strdup(char*);*/ void dolog(service_t, proc_t, char *); diff --git a/nargs.c b/nargs.c index f831299..cd6b819 100644 --- a/nargs.c +++ b/nargs.c @@ -19,99 +19,99 @@ #include "args.h" struct handle { - int argc; - char **argv; - char *ctl; - int nextarg, nextchar; + int argc; + char **argv; + char *ctl; + int nextarg, nextchar; }; struct handle *args_init(int argc, char **argv, char *ctl) { - /* if ctl is bad, return NULL, else a handle */ - int i; - handle *h; - for (i=0 ; ctl[i]; i+= 2) - if (ctl[i+1] != '?' && ctl[i+1] != '-' && ctl[i+1] != '+' && ctl[i+1] != ':') - break; - if (ctl[i]) - return NULL; + /* if ctl is bad, return NULL, else a handle */ + int i; + handle *h; + for (i=0 ; ctl[i]; i+= 2) + if (ctl[i+1] != '?' && ctl[i+1] != '-' && ctl[i+1] != '+' && ctl[i+1] != ':') + break; + if (ctl[i]) + return NULL; - h = (struct handle*)malloc(sizeof(struct handle)); - if (h == NULL) + h = (struct handle*)malloc(sizeof(struct handle)); + if (h == NULL) + return h; + h->argc = argc; + h->argv = argv; + h->ctl = ctl; + h->nextarg = 1; + h->nextchar = 0; return h; - h->argc = argc; - h->argv = argv; - h->ctl = ctl; - h->nextarg = 1; - h->nextchar = 0; - return h; } int args_next(struct handle *h, int *pos, int *inv, char **opt) { - int invc = 0; - int invfound = 0; - int i; - char *a; - if (h->nextarg >= h->argc) - return END_ARGS; - if (h->nextchar == 0) - { - if (h->argv[h->nextarg][0] != '-') + int invc = 0; + int invfound = 0; + int i; + char *a; + if (h->nextarg >= h->argc) + return END_ARGS; + if (h->nextchar == 0) { - if (pos) *pos = h->nextarg; - if (inv) *inv = 0; - if (opt) *opt = h->argv[h->nextarg]; - h->nextarg++; - return NO_FLAG; + if (h->argv[h->nextarg][0] != '-') + { + if (pos) *pos = h->nextarg; + if (inv) *inv = 0; + if (opt) *opt = h->argv[h->nextarg]; + h->nextarg++; + return NO_FLAG; + } + h->nextchar++; + } + a = h->argv[h->nextarg]; + while (a[h->nextchar] == '~') + { + invc = !invc; + invfound = 1; + h->nextchar++; + } + for (i=0 ; h->ctl[i] ; i+=2) + if (h->ctl[i] == a[h->nextchar]) + break; + if (h->ctl[i] == 0) + { + h->nextchar = 0; + h->nextarg ++; + return BAD_FLAG; } h->nextchar++; - } - a = h->argv[h->nextarg]; - while (a[h->nextchar] == '~') - { - invc = !invc; - invfound = 1; - h->nextchar++; - } - for (i=0 ; h->ctl[i] ; i+=2) - if (h->ctl[i] == a[h->nextchar]) - break; - if (h->ctl[i] == 0) - { - h->nextchar = 0; - h->nextarg ++; - return BAD_FLAG; - } - h->nextchar++; - if (pos) *pos = h->nextarg; - if (inv) *inv = invc; - if (a[h->nextchar] == 0) - { - h->nextchar = 0; - h->nextarg ++; - } - switch(h->ctl[i+1]) - { - case '?': + if (pos) *pos = h->nextarg; + if (inv) *inv = invc; + if (a[h->nextchar] == 0) + { + h->nextchar = 0; + h->nextarg ++; + } + switch(h->ctl[i+1]) + { + case '?': + return h->ctl[i]; + case '+': + if (inv) + return h->ctl[i]; + break; + case '-': + if (!inv) + return h->ctl[i]; + break; + case ':': + break; + } + /* need optarg */ + if (h->nextarg >= h->argc) + return BAD_FLAG; + if (opt) + *opt = h->argv[h->nextarg] + h->nextchar; + h->nextarg++; + h->nextchar=0; return h->ctl[i]; - case '+': - if (inv) - return h->ctl[i]; - break; - case '-': - if (!inv) - return h->ctl[i]; - break; - case ':': - break; - } - /* need optarg */ - if (h->nextarg >= h->argc) - return BAD_FLAG; - if (opt) - *opt = h->argv[h->nextarg] + h->nextchar; - h->nextarg++; - h->nextchar=0; - return h->ctl[i]; } diff --git a/ports.c b/ports.c index 34ba265..20f05ac 100644 --- a/ports.c +++ b/ports.c @@ -6,24 +6,24 @@ int tcp_port() { - struct servent *sv; - if (geteuid() > 0) - return htons(6110); - sv = getservbyname("metad","tcp"); - if (sv) - return sv->s_port; - else - return htons(611); + struct servent *sv; + if (geteuid() > 0) + return htons(6110); + sv = getservbyname("metad","tcp"); + if (sv) + return sv->s_port; + else + return htons(611); } int udp_port() { - struct servent *sv; - if (geteuid() > 0) - return htons(6110); - sv = getservbyname("metad","udp"); - if (sv) - return sv->s_port; - else - return htons(611); + struct servent *sv; + if (geteuid() > 0) + return htons(6110); + sv = getservbyname("metad","udp"); + if (sv) + return sv->s_port; + else + return htons(611); } diff --git a/prtime.c b/prtime.c index bca343c..3346753 100644 --- a/prtime.c +++ b/prtime.c @@ -18,7 +18,7 @@ char *prtime(time_t time) { -static char tim[9]; + static char tim[9]; if (time >= WEEKS) { sprintf(tim,"%4ldw%02ldd", time / WEEKS, (time % WEEKS) / DAYS); } else if (time >= DAYS) { @@ -34,5 +34,5 @@ static char tim[9]; char *prticks(time_t ticks) { - return prtime(ticks/HZ); + return prtime(ticks/HZ); } diff --git a/read_config.c b/read_config.c index feab240..6d81f2a 100644 --- a/read_config.c +++ b/read_config.c @@ -22,127 +22,127 @@ int read_config(void *services, char *file) { - service_t *serv; - char linebuf[1024]; - FILE *f; - int err = 0; - static char *lastfile = NULL; - if (file) lastfile = file; - else file = lastfile; - - for (serv = skip_first(services) ; serv ; serv = skip_next(serv)) - (*serv)->pending = 1; + service_t *serv; + char linebuf[1024]; + FILE *f; + int err = 0; + static char *lastfile = NULL; + if (file) lastfile = file; + else file = lastfile; - f = fopen(file, "r"); - if (f == NULL) - { - error("cannot find config file %s", file); - return 1; - } - while (fgets(linebuf, sizeof(linebuf), f)!= NULL) - { - int len = strlen(linebuf); - char **words; - int w; - - if (len > 1000 && linebuf[len-1] != '\n') + for (serv = skip_first(services) ; serv ; serv = skip_next(serv)) + (*serv)->pending = 1; + + f = fopen(file, "r"); + if (f == NULL) { - error("line too long in config file"); - fclose(f); - return 1; + error("cannot find config file %s", file); + return 1; } - if (linebuf[len-1] == '\n') linebuf[--len] = 0; - - words = strsplit(linebuf, " \t\n"); - if (words) + while (fgets(linebuf, sizeof(linebuf), f)!= NULL) { - for (w=0 ;words[w] ; w++) if (words[w][0]=='#') words[w]=NULL; - if (words[0] && words[1]) - { - /* not a comment */ - service_t *svp = skip_search(services, words[0]); - service_t sv; - class_t cl = find_class(words[1]); - if (svp != NULL) - { - if ((*svp)->class != cl) - { - /* different classes - rename old services */ - skip_delete(services, words[0]); - strcpy(linebuf, words[0]); - do { strcat(linebuf, ".old"); } while (skip_search(services, linebuf)!= NULL); - free((*svp)->service); - (*svp)->service = strdup(linebuf); - skip_insert(services, *svp); - svp = NULL; - } - } - if (cl == NULL) - { - error("unknown class %s", words[1]); - err ++; - continue; - } - sv = new_service(words[0], cl); - /* now process options */ - for (w=2 ; words[w] && words[w][0] != '/' ; w++) + int len = strlen(linebuf); + char **words; + int w; + + if (len > 1000 && linebuf[len-1] != '\n') { - int ok = process_opt(sv, words[w]); - if (ok == 0) - ok = sv->class->c_process_opt(sv, words[w]); - if (ok <= 0) - { - if (ok == 0) - error("unknown option: %s", words[w]); - else - error("error in option: %s", words[w]); - free_service(sv); - sv = NULL; - err++; - break; - } + error("line too long in config file"); + fclose(f); + return 1; } - if (sv == NULL) continue; - if (words[w]) - sv->program = strdup(words[w++]); - if (words[w]) - sv->args = strlistdup(words+w); - if (sv->program == NULL) - error("missing program name for service %s", words[0]), err++; - else if (sv->args == NULL) - error("missing program arguments for service %s", words[0]), err++; - else + if (linebuf[len-1] == '\n') linebuf[--len] = 0; + + words = strsplit(linebuf, " \t\n"); + if (words) { - if (svp) - { - proc_t *pp2; - service_t sv2 = *svp; - sv->enabled = sv2->enabled; - sv->proc_list = sv2->proc_list; - - /* change service pointer to the new structure (for aidan) */ - if (sv->proc_list) - for (pp2 = skip_first(sv->proc_list) ; pp2 ; pp2=skip_next(pp2)) - (*pp2)->service = sv; - - sv2->proc_list = NULL; - sv->class->copy_state(sv2, sv); - skip_delete(services, sv2->service); - free_service(sv2); - } - skip_insert(services, sv); - sv->class->register_service(sv); - sv = NULL; + for (w=0 ;words[w] ; w++) if (words[w][0]=='#') words[w]=NULL; + if (words[0] && words[1]) + { + /* not a comment */ + service_t *svp = skip_search(services, words[0]); + service_t sv; + class_t cl = find_class(words[1]); + if (svp != NULL) + { + if ((*svp)->class != cl) + { + /* different classes - rename old services */ + skip_delete(services, words[0]); + strcpy(linebuf, words[0]); + do { strcat(linebuf, ".old"); } while (skip_search(services, linebuf)!= NULL); + free((*svp)->service); + (*svp)->service = strdup(linebuf); + skip_insert(services, *svp); + svp = NULL; + } + } + if (cl == NULL) + { + error("unknown class %s", words[1]); + err ++; + continue; + } + sv = new_service(words[0], cl); + /* now process options */ + for (w=2 ; words[w] && words[w][0] != '/' ; w++) + { + int ok = process_opt(sv, words[w]); + if (ok == 0) + ok = sv->class->c_process_opt(sv, words[w]); + if (ok <= 0) + { + if (ok == 0) + error("unknown option: %s", words[w]); + else + error("error in option: %s", words[w]); + free_service(sv); + sv = NULL; + err++; + break; + } + } + if (sv == NULL) continue; + if (words[w]) + sv->program = strdup(words[w++]); + if (words[w]) + sv->args = strlistdup(words+w); + if (sv->program == NULL) + error("missing program name for service %s", words[0]), err++; + else if (sv->args == NULL) + error("missing program arguments for service %s", words[0]), err++; + else + { + if (svp) + { + proc_t *pp2; + service_t sv2 = *svp; + sv->enabled = sv2->enabled; + sv->proc_list = sv2->proc_list; + + /* change service pointer to the new structure (for aidan) */ + if (sv->proc_list) + for (pp2 = skip_first(sv->proc_list) ; pp2 ; pp2=skip_next(pp2)) + (*pp2)->service = sv; + + sv2->proc_list = NULL; + sv->class->copy_state(sv2, sv); + skip_delete(services, sv2->service); + free_service(sv2); + } + skip_insert(services, sv); + sv->class->register_service(sv); + sv = NULL; + } + if (sv) free_service(sv); + } + free(words[-1]); + free(words-1); } - if (sv) free_service(sv); - } - free(words[-1]); - free(words-1); } - } - fclose(f); - for (serv = skip_first(services) ; serv ; serv = skip_next(serv)) - if ((*serv)->pending) - (*serv)->enabled = 0; - return err; + fclose(f); + for (serv = skip_first(services) ; serv ; serv = skip_next(serv)) + if ((*serv)->pending) + (*serv)->enabled = 0; + return err; } diff --git a/recvlist.c b/recvlist.c index a13b426..d112591 100644 --- a/recvlist.c +++ b/recvlist.c @@ -1,37 +1,37 @@ +#include -void *malloc(int); char *recvbuf; int recvptr; void init_recv(char *buf) { - recvbuf = buf; - recvptr = 0; + recvbuf = buf; + recvptr = 0; } int get_byte() { - return 0xff & recvbuf[recvptr++]; + return 0xff & recvbuf[recvptr++]; } int get_int() { - int i = 0; - i = get_byte(); - i = (i<<8) | get_byte(); - i = (i<<8) | get_byte(); - i = (i<<8) | get_byte(); - return i; + int i = 0; + i = get_byte(); + i = (i<<8) | get_byte(); + i = (i<<8) | get_byte(); + i = (i<<8) | get_byte(); + return i; } char *get_str() { - int l = get_int(); - char *s,*p; - if (l == 0) - return (char*)0; - p = s = (char*)malloc(l); - while (l--) - *p++ = get_byte(); - return s; + int l = get_int(); + char *s,*p; + if (l == 0) + return (char*)0; + p = s = (char*)malloc(l); + while (l--) + *p++ = get_byte(); + return s; } diff --git a/sendcmd.c b/sendcmd.c index 61094c8..68d3061 100644 --- a/sendcmd.c +++ b/sendcmd.c @@ -23,21 +23,21 @@ char *strdup(char*); /* cache addresses */ typedef struct acache { - char *host; - struct sockaddr_in addr; + char *host; + struct sockaddr_in addr; } *acache; extern char *progname; static int acmp(acache a, acache b, char *host) { - if (b) host=b->host; - return strcmp(a->host, host); + if (b) host=b->host; + return strcmp(a->host, host); } static void afree(acache a) { - free(a->host); - free(a); + free(a->host); + free(a); } @@ -48,277 +48,277 @@ static void list_service(char *, int); int send_cmd(char *cmd, int udp, char *host, int verbose) { - acache *cp, c; - if (addr_cache == NULL) - addr_cache = skip_new(acmp, afree, NULL); + acache *cp, c; + if (addr_cache == NULL) + addr_cache = skip_new(acmp, afree, NULL); - cp = skip_search(addr_cache, host); - if (cp != NULL) - c = *cp; - else - { - c = (acache)malloc(sizeof(struct acache)); - c->host = strdup(host); - c->addr.sin_port = udp ? udp_port() : tcp_port(); - c->addr.sin_addr.s_addr = inet_addr(host); - if (c->addr.sin_addr.s_addr > 0 && c->addr.sin_addr.s_addr < 0xffffffff) - { - c->addr.sin_family = AF_INET; - } + cp = skip_search(addr_cache, host); + if (cp != NULL) + c = *cp; else { - struct hostent *he; - he = gethostbyname(host); - if (he == NULL) - { - c->addr.sin_family = -1; - fprintf(stderr, "%s: unknown host %s\n", progname, host); - } - else - { - memcpy(&c->addr.sin_addr, he->h_addr_list[0], 4); - c->addr.sin_family = AF_INET; - } - } - skip_insert(addr_cache, c); - } - if (c->addr.sin_family != AF_INET) - return -1; - if (udp) - { - static int sock = -1; - - if (sock == -1) - { - sock = socket(AF_INET, SOCK_DGRAM, 0); - if (geteuid() == 0) - { - int port; - struct sockaddr_in myaddr; - port = 600 + time(0)%400; - - memset(&myaddr, 0, sizeof(myaddr)); - myaddr.sin_family = AF_INET; - while (port > 500) + c = (acache)malloc(sizeof(struct acache)); + c->host = strdup(host); + c->addr.sin_port = udp ? udp_port() : tcp_port(); + c->addr.sin_addr.s_addr = inet_addr(host); + if (c->addr.sin_addr.s_addr > 0 && c->addr.sin_addr.s_addr < 0xffffffff) { - myaddr.sin_port = htons(port); - if (bind(sock, (struct sockaddr *)&myaddr, sizeof(myaddr))== 0) - break; - port --; + c->addr.sin_family = AF_INET; } - if (port == 500) + else { - fprintf(stderr, "%s: cannot bind priv udp port...\n", progname); + struct hostent *he; + he = gethostbyname(host); + if (he == NULL) + { + c->addr.sin_family = -1; + fprintf(stderr, "%s: unknown host %s\n", progname, host); + } + else + { + memcpy(&c->addr.sin_addr, he->h_addr_list[0], 4); + c->addr.sin_family = AF_INET; + } } - } + skip_insert(addr_cache, c); } - sendto(sock, cmd, strlen(cmd)+1, 0, (struct sockaddr *)&c->addr, sizeof(c->addr)); - } - else - { - /* tcp - have to make a new connection each time */ - int sock; - static int port = 0; - char buf[8192]; /* FIXME autosize */ - int n; - int have = 0; + if (c->addr.sin_family != AF_INET) + return -1; + if (udp) + { + static int sock = -1; - if (port == 0) - port = 600 + time(0)%400; + if (sock == -1) + { + sock = socket(AF_INET, SOCK_DGRAM, 0); + if (geteuid() == 0) + { + int port; + struct sockaddr_in myaddr; + port = 600 + time(0)%400; - if (geteuid() == 0) - sock = rresvport(&port); + memset(&myaddr, 0, sizeof(myaddr)); + myaddr.sin_family = AF_INET; + while (port > 500) + { + myaddr.sin_port = htons(port); + if (bind(sock, (struct sockaddr *)&myaddr, sizeof(myaddr))== 0) + break; + port --; + } + if (port == 500) + { + fprintf(stderr, "%s: cannot bind priv udp port...\n", progname); + } + } + } + sendto(sock, cmd, strlen(cmd)+1, 0, (struct sockaddr *)&c->addr, sizeof(c->addr)); + } else - sock = socket(AF_INET, SOCK_STREAM, 0); - if (sock == -1) { - fprintf(stderr, "%s: cannot bind socket!!\n", progname); - return -1; - } + /* tcp - have to make a new connection each time */ + int sock; + static int port = 0; + char buf[8192]; /* FIXME autosize */ + int n; + int have = 0; + + if (port == 0) + port = 600 + time(0)%400; + + if (geteuid() == 0) + sock = rresvport(&port); + else + sock = socket(AF_INET, SOCK_STREAM, 0); + if (sock == -1) + { + fprintf(stderr, "%s: cannot bind socket!!\n", progname); + return -1; + } #ifdef TCP_CONN_ABORT_THRESHOLD - { - int thresh; - thresh = 10*1000; - setsockopt(sock, IPPROTO_TCP, TCP_CONN_ABORT_THRESHOLD, (char*)&thresh, 4); - } + { + int thresh; + thresh = 10*1000; + setsockopt(sock, IPPROTO_TCP, TCP_CONN_ABORT_THRESHOLD, (char*)&thresh, 4); + } #endif -/* */ - if (connect(sock, (struct sockaddr *)&c->addr, sizeof(c->addr))!= 0) - { - fprintf(stderr, "%s: cannot connect to %s\n", progname, c->host); - close(sock); - c->addr.sin_family = -1; - return -1; - } - write(sock, cmd, strlen(cmd)+1); - shutdown(sock, 1); /* don't want to write no more */ - do - { - n = read(sock, buf+have, sizeof(buf)-1 - have); - if (n>0) have += n; - } while (n>0 && have < sizeof(buf)-1); - close(sock); - if (have <= 0) - return 0; /* probably OK, FIXME */ - buf[have] = 0; - switch(buf[0]) - { - case 0: return 0; /* definately ok */ - case 1: /* error message */ - fprintf(stderr, "%s: %s: %s\n", progname, c->host, buf+1); - return 1; - case 2: /* version number */ - fprintf(stdout, "%s: %s\n", c->host, buf+1); - return 0; - case 3: /* listing */ - init_recv(buf+1); - list_service(c->host, verbose); - /* FIXME */ - return 0; +/* */ + if (connect(sock, (struct sockaddr *)&c->addr, sizeof(c->addr))!= 0) + { + fprintf(stderr, "%s: cannot connect to %s\n", progname, c->host); + close(sock); + c->addr.sin_family = -1; + return -1; + } + write(sock, cmd, strlen(cmd)+1); + shutdown(sock, 1); /* don't want to write no more */ + do + { + n = read(sock, buf+have, sizeof(buf)-1 - have); + if (n>0) have += n; + } while (n>0 && have < sizeof(buf)-1); + close(sock); + if (have <= 0) + return 0; /* probably OK, FIXME */ + buf[have] = 0; + switch(buf[0]) + { + case 0: return 0; /* definately ok */ + case 1: /* error message */ + fprintf(stderr, "%s: %s: %s\n", progname, c->host, buf+1); + return 1; + case 2: /* version number */ + fprintf(stdout, "%s: %s\n", c->host, buf+1); + return 0; + case 3: /* listing */ + init_recv(buf+1); + list_service(c->host, verbose); + /* FIXME */ + return 0; - case 'm': /* old version number */ - fprintf(stdout, "%s\n", buf); - return 0; - default: /* old metad */ - /* FIXME */ - return 0; + case 'm': /* old version number */ + fprintf(stdout, "%s\n", buf); + return 0; + default: /* old metad */ + /* FIXME */ + return 0; + } } - } - return 0; + return 0; } - + static void list_service(char *host, int verbose) { - int b; - b = get_byte(); - while (b == 1 || b == 2) /* a service */ - { - char *sname, *home, *user, *crash, *prog; - char **args; - int argc; - int max, cnt, enabled; - int i; - int class; - char *classname=NULL; - char *pidfile = NULL; - int watch_output = 0; - int min=0, period=0, last; - int proto, port=0, active=0, backlog=0; - - sname = get_str(); - max = get_int(); - home = get_str(); - user = get_str(); - crash = get_str(); - if (b == 2) - { - watch_output = get_int(); - pidfile = get_str(); - } - cnt = get_int(); - enabled = get_int(); - prog = get_str(); - argc = get_int(); - args = (char**)malloc((argc+1)*sizeof(char*)); - for (i=0 ; iit_forked > 0 || p->pipefd >= 0) - { - send_byte(4); - send_int(p->pid); - send_int(p->it_forked); - send_int(p->pipefd); - } - else - { - send_byte(3); /* process */ - send_int(p->pid); - } - send_int(p->start_time); - send_int(p->hold_time); - send_int(p->exit_time); - send_int(p->status); + if (p->it_forked > 0 || p->pipefd >= 0) { + send_byte(4); + send_int(p->pid); + send_int(p->it_forked); + send_int(p->pipefd); + } else { + send_byte(3); /* process */ + send_int(p->pid); + } + send_int(p->start_time); + send_int(p->hold_time); + send_int(p->exit_time); + send_int(p->status); } void send_service(service_t sv) { - int i; - proc_t *pp; - if (sv->watch_output || sv->pidfile) - send_byte(2); - else - send_byte(1); /* service */ - send_str(sv->service); - send_int(sv->max_proc); - send_str(sv->home_dir); - send_str(sv->username); - send_str(sv->crash_prog); - if (sv->watch_output || sv->pidfile) - { - send_int(sv->watch_output); - send_str(sv->pidfile); - } - send_int(sv->start_cnt); - send_int(sv->enabled); - send_str(sv->program); - for (i=0 ; sv->args[i] ; i++); - send_int(i); - for (i=0 ; sv->args[i] ; i++) - send_str(sv->args[i]); - (sv->class->send_class)(sv); - for (pp = skip_first(sv->proc_list) ; pp ; pp = skip_next(pp)) - send_proc(*pp); + int i; + proc_t *pp; + if (sv->watch_output || sv->pidfile) + send_byte(2); + else + send_byte(1); /* service */ + send_str(sv->service); + send_int(sv->max_proc); + send_str(sv->home_dir); + send_str(sv->username); + send_str(sv->crash_prog); + if (sv->watch_output || sv->pidfile) { + send_int(sv->watch_output); + send_str(sv->pidfile); + } + send_int(sv->start_cnt); + send_int(sv->enabled); + send_str(sv->program); + for (i=0 ; sv->args[i] ; i++); + send_int(i); + for (i=0 ; sv->args[i] ; i++) + send_str(sv->args[i]); + (sv->class->send_class)(sv); + for (pp = skip_first(sv->proc_list) ; pp ; pp = skip_next(pp)) + send_proc(*pp); } void send_int(int i) { - send_byte((i>>24)& 0xff); - send_byte((i>>16)& 0xff); - send_byte((i>> 8)& 0xff); - send_byte((i>> 0)& 0xff); -} + send_byte((i>>24)& 0xff); + send_byte((i>>16)& 0xff); + send_byte((i>> 8)& 0xff); + send_byte((i>> 0)& 0xff); +} + void send_str(char *s) { - if (s == NULL) - send_int(0); - else - { - send_int(strlen(s)+1); - while (*s) - send_byte(*s++); - send_byte(0); - } + if (s == NULL) + send_int(0); + else { + send_int(strlen(s)+1); + while (*s) + send_byte(*s++); + send_byte(0); + } } static char *sendbuf = NULL; @@ -86,36 +82,34 @@ static int sendptr; void send_byte(int b) { - if (sendptr >= sendsize) - { - sendsize += 100; - sendbuf = (char*)realloc(sendbuf, sendsize); - } - sendbuf[sendptr++] = b; + if (sendptr >= sendsize) { + sendsize += 100; + sendbuf = (char*)realloc(sendbuf, sendsize); + } + sendbuf[sendptr++] = b; } void init_return() { - sendptr = 0; - if (sendbuf == NULL) - { - sendsize = 200; - sendbuf = malloc(sendsize); - } + sendptr = 0; + if (sendbuf == NULL) { + sendsize = 200; + sendbuf = malloc(sendsize); + } } void do_send(void *con) { - set_reply(con, sendbuf, sendptr); - sendbuf = NULL; - sendptr = 0; + set_reply(con, sendbuf, sendptr); + sendbuf = NULL; + sendptr = 0; } char *get_return(int *i) { - char *c = sendbuf; - *i = sendptr; - sendbuf = NULL; - sendptr = 0; - return c; + char *c = sendbuf; + *i = sendptr; + sendbuf = NULL; + sendptr = 0; + return c; } diff --git a/service.c b/service.c index 4d3a09f..3ce6828 100644 --- a/service.c +++ b/service.c @@ -6,444 +6,396 @@ #include #include #include -#include +#include void *services; void *allprocs; int count_procs(service_t sv) { - proc_t *pp, p; - int cnt; - time_t now = time(0); - for (cnt=0, pp=skip_first(sv->proc_list) ; pp ; pp=skip_next(pp)) - { - p = *pp; - if (p->exit_time == 0 || p->hold_time > now || p->pipefd >=0 || p->it_forked) - cnt++; - } - return cnt; + proc_t *pp, p; + int cnt; + time_t now = time(0); + for (cnt=0, pp=skip_first(sv->proc_list) ; pp ; pp=skip_next(pp)) + { + p = *pp; + if (p->exit_time == 0 || p->hold_time > now || p->pipefd >=0 || p->it_forked) + cnt++; + } + return cnt; } void check_service(service_t sv) { - /* check for exited processes and possibly run crash */ - proc_t *pp; - time_t now = time(0); + /* check for exited processes and possibly run crash */ + proc_t *pp; + time_t now = time(0); - for (pp=skip_first(sv->proc_list) ; pp ; ) - { - proc_t p; - p = *pp; - pp = skip_next(pp); - if (p->exit_time == 0) { - /* monitoring a normal child - * we should have been alerted if the child exitted, - * but just-in-case... try sig0 - */ - if (kill(p->pid, 0) == -1 && errno == ESRCH && !is_saved_pid(p->pid)) { - p->status = 0; /* who knows. */ - p->exit_time = now; - } - } - if (p->exit_time > 0 && p->hold_time == 0) - { - /* a newly exited process */ - if (p->is_crash) - { - /* this is a crash recover prog exitting. just set the hold time */ - p->hold_time = p->exit_time + sv->next_hold; - } - else if (WIFSIGNALED(p->status) || (WIFEXITED(p->status) && WEXITSTATUS(p->status) != 0)) - { - /* exited badly */ - if (p->exit_time - p->start_time < 30) { - if (sv->next_hold < MAXINT/2) - sv->next_hold *= 2; - } else - sv->next_hold = 2; - if (0 && sv->crash_prog) - { - /* FIXME */ - } - else p->hold_time = p->exit_time + sv->next_hold; - } - else - { - if (sv->pidfile) - { - /* if this file is newer than start_time and contains a pid, - * record that pid as this pid and shedule regular checks - */ - int fd = open(sv->pidfile, 0); - struct stat stb; - char pidline[100]; - int n; - int pid; - if (fd >= 0 - && fstat(fd, &stb) != -1 - && stb.st_mtime >= p->start_time - && (n=read(fd, pidline, sizeof(pidline)-1))> 0 - && (pidline[n]=0 , pid=atoi(pidline)) > 1 - && kill(pid, 0) != -1 - ) - { - /* looks good ! */ - p->it_forked = pid; - p->hold_time = 1; - waituntil(now+5); /* check it in 5 seconds and periodically */ - } - else - { - /* give the program a few seconds to write to the file - * e.g. xdm forks, then creates the pid file + for (pp=skip_first(sv->proc_list) ; pp ; ) { + proc_t p; + p = *pp; + pp = skip_next(pp); + if (p->exit_time == 0) { + /* monitoring a normal child + * we should have been alerted if the child exitted, + * but just-in-case... try sig0 */ - if (p->exit_time + 10 > now) - { - p->it_forked = -1; - waituntil(p->exit_time + 11); + if (kill(p->pid, 0) == -1 && errno == ESRCH && !is_saved_pid(p->pid)) { + p->status = 0; /* who knows. */ + p->exit_time = now; } - else - { - // give up waiting - p->it_forked = 0; + } + if (p->exit_time > 0 && p->hold_time == 0) { + /* a newly exited process */ + if (p->is_crash) { + /* this is a crash recover prog exitting. just set the hold time */ + p->hold_time = p->exit_time + sv->next_hold; + } + else if (WIFSIGNALED(p->status) || + (WIFEXITED(p->status) && + WEXITSTATUS(p->status) != 0)) { + /* exited badly */ + if (p->exit_time - p->start_time < 30) { + if (sv->next_hold < MAXINT/2) + sv->next_hold *= 2; + } else + sv->next_hold = 2; + if (0 && sv->crash_prog) { + /* FIXME */ + } + else p->hold_time = p->exit_time + sv->next_hold; + } + else + { + if (sv->pidfile) { + /* if this file is newer than start_time and contains a pid, + * record that pid as this pid and shedule regular checks + */ + int fd = open(sv->pidfile, 0); + struct stat stb; + char pidline[100]; + int n; + int pid; + if (fd >= 0 + && fstat(fd, &stb) != -1 + && stb.st_mtime >= p->start_time + && (n=read(fd, pidline, sizeof(pidline)-1))> 0 + && (pidline[n]=0 , pid=atoi(pidline)) > 1 + && kill(pid, 0) != -1 + ) { + /* looks good ! */ + p->it_forked = pid; + p->hold_time = 1; + waituntil(now+5); /* check it in 5 seconds and periodically */ + } else { + /* give the program a few seconds to write to the file + * e.g. xdm forks, then creates the pid file + */ + if (p->exit_time + 10 > now) { + p->it_forked = -1; + waituntil(p->exit_time + 11); + } else { + // give up waiting + p->it_forked = 0; - /* probably exited badly if it didn't run for long - (keep in mind that the pidfile wasn't updated) */ - if (p->exit_time - p->start_time < 30) { - if (sv->next_hold < MAXINT/2) - sv->next_hold *= 2; - } else - sv->next_hold = 2; + /* probably exited badly if it didn't run for long + (keep in mind that the pidfile wasn't updated) */ + if (p->exit_time - p->start_time < 30) { + if (sv->next_hold < MAXINT/2) + sv->next_hold *= 2; + } else + sv->next_hold = 2; - p->hold_time = p->exit_time + sv->next_hold; - } - } - if (fd >= 0) close(fd); - } else - sv->next_hold = 2; + p->hold_time = p->exit_time + sv->next_hold; + } + } + if (fd >= 0) close(fd); + } else + sv->next_hold = 2; - } - } - else if (p->exit_time > 0 && p->it_forked > 0) - { - /* monitoring forked child - * try sending sig0 to see if process still exists - */ - if (kill(p->it_forked, 0)== -1 && errno == ESRCH) - { - p->it_forked = 0; - p->exit_time = now; - } - else - waituntil(now+30); /* wait 30 seconds and check again */ - } - if (p->pipefd >= 0) - { - if (readyon(p->pipefd)) - { - int n = read(p->pipefd, p->pipebuf+p->bufptr, sizeof(p->pipebuf)-p->bufptr-1); - if (n<= 0) - { - close(p->pipefd); - p->pipefd = -1; + } } - else - { - int i = 0; - p->bufptr += n; - while (i < p->bufptr) - { - while (i < p->bufptr && p->pipebuf[i] != '\n') - i++; - if (p->pipebuf[i] == '\n' || i > sizeof(p->pipebuf)-2) - { - /* ship out this much */ - int j; - p->pipebuf[i] = '\0'; - dolog(sv, p, p->pipebuf); - for (j=i+1 ; jbufptr ; j++) - p->pipebuf[j-i-1] = p->pipebuf[j]; - p-> bufptr -= i+1; - i = 0; + else if (p->exit_time > 0 && p->it_forked > 0) { + /* monitoring forked child + * try sending sig0 to see if process still exists + */ + if (kill(p->it_forked, 0)== -1 && errno == ESRCH) { + p->it_forked = 0; + p->exit_time = now; + } else + waituntil(now+30); /* wait 30 seconds and check again */ + } + if (p->pipefd >= 0) { + if (readyon(p->pipefd)) { + int n = read(p->pipefd, p->pipebuf+p->bufptr, sizeof(p->pipebuf)-p->bufptr-1); + if (n<= 0) { + close(p->pipefd); + p->pipefd = -1; + } else { + int i = 0; + p->bufptr += n; + while (i < p->bufptr) { + while (i < p->bufptr && p->pipebuf[i] != '\n') + i++; + if (p->pipebuf[i] == '\n' || + i > sizeof(p->pipebuf)-2) { + /* ship out this much */ + int j; + p->pipebuf[i] = '\0'; + dolog(sv, p, p->pipebuf); + for (j=i+1 ; jbufptr ; j++) + p->pipebuf[j-i-1] = p->pipebuf[j]; + p-> bufptr -= i+1; + i = 0; + } else + i++; + } + } } - else - i++; - } + if (p->pipefd >= 0) + listenon(p->pipefd); } - } - if (p->pipefd >= 0) - listenon(p->pipefd); - } - if (p->exit_time > 0 && p->hold_time < now && p->it_forked == 0 - && (p->pipefd == -1 || p->exit_time +30 pipefd>=0) - { - /* it has been 30 seconds since the parent exitted, time to - * discard the pipe... - */ - close(p->pipefd); - p->pipefd = -1; - } - skip_delete(sv->proc_list, &p->pid); - skip_delete(allprocs, &p->pid); - free(p); + if (p->exit_time > 0 && p->hold_time < now && p->it_forked == 0 + && (p->pipefd == -1 || p->exit_time +30 pipefd>=0) { + /* it has been 30 seconds since the parent exitted, time to + * discard the pipe... + */ + close(p->pipefd); + p->pipefd = -1; + } + skip_delete(sv->proc_list, &p->pid); + skip_delete(allprocs, &p->pid); + free(p); + } + else if (p->exit_time > 0 && p->hold_time > 2) + waituntil(p->hold_time+1); } - else if (p->exit_time > 0 && p->hold_time > 2) - waituntil(p->hold_time+1); - } - (sv->class->c_check_service)(sv); + (sv->class->c_check_service)(sv); } int new_proc(service_t sv, char **env) { - /* fork, register new child - * in child, call sv->class->new_child for final setup before exec - */ - int pid; - proc_t p; - char **envp; - extern char **environ; - time_t now; - int pipefd[2]; + /* fork, register new child + * in child, call sv->class->new_child for final setup before exec + */ + int pid; + proc_t p; + char **envp; + extern char **environ; + time_t now; + int pipefd[2]; - if (sv->enabled == 0) - return -2; - if (sv->max_proc > 0 && count_procs(sv) >= sv->max_proc) - return -2; /* too many already */ + if (sv->enabled == 0) + return -2; + if (sv->max_proc > 0 && count_procs(sv) >= sv->max_proc) + return -2; /* too many already */ - if (sv->class->prefork(sv)) - return -2; + if (sv->class->prefork(sv)) + return -2; - now = time(0); - if (sv->watch_output) - { - if (pipe(pipefd)== -1) - pipefd[0] = pipefd[1] = -1; - } - switch (pid = fork()) - { - case -1: - if (sv->watch_output) - { - close(pipefd[0]); close(pipefd[1]); - } - return -1; /* cannot fork */ - case 0: /* child */ - errors_to(ERROR_SYSLOG, NULL); - if (sv->home_dir) - { - if (chdir(sv->home_dir)!=0) - { - error("Couldn't chdir to %s", sv->home_dir); - exit(10); - } - } - if (sv->username) - { - struct passwd *pw = getpwnam(sv->username); - if (pw) { - initgroups(sv->username, pw->pw_gid); - setgid(pw->pw_gid); - setuid(pw->pw_uid); - } else { - error("unknown user %s", sv->username); - exit(10); - } - } - (sv->class->new_child)(sv); - if (!env) - envp = environ; - else - { - int cnt, i; - cnt = 0; - for (i=0 ; env[i] ; i++) cnt++; - for (i=0 ; environ[i] ; i++) cnt++; - envp = (char**)malloc((cnt+1) * sizeof(char*)); - cnt = 0; - for (i=0 ; env[i] ; i++) - envp[cnt++] = env[i]; - for (i=0 ; environ[i] ; i++) - envp[cnt++] = environ[i]; - envp[cnt] = NULL; - } - if (sv->watch_output && pipefd[0] >= 0) - { - close(pipefd[0]); - if (pipefd[1] != 1) close(1); - if (pipefd[1] != 2) close(2); - if (pipefd[1] == 0) - { - pipefd[1] = dup(pipefd[1]); - close(0); - } - open("/dev/null", 0); - dup(pipefd[1]); - if (pipefd[1] > 2) - { - dup(pipefd[1]); - close(pipefd[1]); - } + now = time(0); + if (sv->watch_output) { + if (pipe(pipefd)== -1) + pipefd[0] = pipefd[1] = -1; } - execve(sv->program, sv->args, envp); - exit(11); - default: /* parent */ - p = (proc_t)malloc(sizeof(struct proc)); - if (sv->watch_output) - { - close(pipefd[1]); - p->pipefd = pipefd[0]; - p->bufptr = 0; - if (p->pipefd >= 0) listenon(p->pipefd); - fcntl(p->pipefd, F_SETFD, 1); + switch (pid = fork()) { + case -1: + if (sv->watch_output) { + close(pipefd[0]); close(pipefd[1]); + } + return -1; /* cannot fork */ + case 0: /* child */ + errors_to(ERROR_SYSLOG, NULL); + if (sv->home_dir) { + if (chdir(sv->home_dir)!=0) { + error("Couldn't chdir to %s", sv->home_dir); + exit(10); + } + } + if (sv->username) { + struct passwd *pw = getpwnam(sv->username); + if (pw) { + initgroups(sv->username, pw->pw_gid); + setgid(pw->pw_gid); + setuid(pw->pw_uid); + } else { + error("unknown user %s", sv->username); + exit(10); + } + } + (sv->class->new_child)(sv); + if (!env) + envp = environ; + else { + int cnt, i; + cnt = 0; + for (i=0 ; env[i] ; i++) cnt++; + for (i=0 ; environ[i] ; i++) cnt++; + envp = (char**)malloc((cnt+1) * sizeof(char*)); + cnt = 0; + for (i=0 ; env[i] ; i++) + envp[cnt++] = env[i]; + for (i=0 ; environ[i] ; i++) + envp[cnt++] = environ[i]; + envp[cnt] = NULL; + } + if (sv->watch_output && pipefd[0] >= 0) { + close(pipefd[0]); + if (pipefd[1] != 1) close(1); + if (pipefd[1] != 2) close(2); + if (pipefd[1] == 0) { + pipefd[1] = dup(pipefd[1]); + close(0); + } + open("/dev/null", 0); + dup(pipefd[1]); + if (pipefd[1] > 2) { + dup(pipefd[1]); + close(pipefd[1]); + } + } + execve(sv->program, sv->args, envp); + exit(11); + default: /* parent */ + p = (proc_t)malloc(sizeof(struct proc)); + if (sv->watch_output) { + close(pipefd[1]); + p->pipefd = pipefd[0]; + p->bufptr = 0; + if (p->pipefd >= 0) listenon(p->pipefd); + fcntl(p->pipefd, F_SETFD, 1); + } + else + p->pipefd = -1; + p->pid = pid; + p->service = sv; + p->it_forked = 0; + p->is_crash = 0; + p->start_time = now; + p->hold_time = 0; + p->exit_time = 0; + skip_insert(sv->proc_list, p); + sv->start_cnt ++; + skip_insert(allprocs, p); + sv->class->new_parent(sv,p); } - else - p->pipefd = -1; - p->pid = pid; - p->service = sv; - p->it_forked = 0; - p->is_crash = 0; - p->start_time = now; - p->hold_time = 0; - p->exit_time = 0; - skip_insert(sv->proc_list, p); - sv->start_cnt ++; - skip_insert(allprocs, p); - sv->class->new_parent(sv,p); - } - return pid; + return pid; } void prepare_restart(void) { - service_t *sp; - for (sp = skip_first(services) ; sp ; sp=skip_next(sp)) - { - service_t sv = *sp; - proc_t *pp; - for (pp=skip_first(sv->proc_list) ; pp ; pp=skip_next(pp)) - { - proc_t p = *pp; - if (p->pipefd >= 0) - fcntl(p->pipefd, F_SETFD, 0); + service_t *sp; + for (sp = skip_first(services) ; sp ; sp=skip_next(sp)) { + service_t sv = *sp; + proc_t *pp; + for (pp=skip_first(sv->proc_list) ; pp ; pp=skip_next(pp)) { + proc_t p = *pp; + if (p->pipefd >= 0) + fcntl(p->pipefd, F_SETFD, 0); + } } - } } static int proc_cmp(proc_t a, proc_t b, int *kp) { - int k; - if (b) k=b->pid; else k = *kp; - return k - a->pid; + int k; + if (b) k=b->pid; else k = *kp; + return k - a->pid; } service_t new_service(char *name, class_t class) { - service_t sv = (service_t)malloc(sizeof(struct service)); + service_t sv = (service_t)malloc(sizeof(struct service)); - sv->service = strdup(name); - sv->class = class; - sv->max_proc = 1; - sv->crash_prog = NULL; - sv->home_dir = NULL; - sv->username = NULL; - sv->pidfile = NULL; - sv->watch_output = 0; - sv->enabled = 1; - sv->start_cnt = 0; - sv->program = NULL; - sv->args = 0; - sv->pending = 0; - sv->proc_list = skip_new(proc_cmp, NULL, NULL); - sv->next_hold = 2; - (*class->copy_state)(NULL, sv); - return sv; + sv->service = strdup(name); + sv->class = class; + sv->max_proc = 1; + sv->crash_prog = NULL; + sv->home_dir = NULL; + sv->username = NULL; + sv->pidfile = NULL; + sv->watch_output = 0; + sv->enabled = 1; + sv->start_cnt = 0; + sv->program = NULL; + sv->args = 0; + sv->pending = 0; + sv->proc_list = skip_new(proc_cmp, NULL, NULL); + sv->next_hold = 2; + (*class->copy_state)(NULL, sv); + return sv; } int process_opt(service_t sv, char *opt) { - /* max= crash= dir= user= enabled= */ + /* max= crash= dir= user= enabled= */ - if (strncmp(opt, "max=", 4)==0) - { - sv->max_proc = atoi(opt+4); - return 1; - } - else if (strncmp(opt, "crash=", 6)==0) - { - sv->crash_prog = strdup(opt+6); - return 1; - } - else if (strncmp(opt, "dir=", 4)==0) - { - sv->home_dir = strdup(opt+4); - return 1; - } - else if (strncmp(opt, "user=", 5)==0) - { - sv->username = strdup(opt+5); - return 1; - } - else if (strncmp(opt, "enabled=", 8)==0) - { - if (strcmp(opt+8, "no")==0) - sv->enabled = 0; - else if (strcmp(opt+8, "yes")==0) - sv->enabled = 1; - else return -1; - return 1; - } - else if (strncmp(opt, "pidfile=", 8)==0) - { - sv->pidfile = strdup(opt+8); - return 1; - } - else if (strcmp(opt, "watch_output")==0) - { - sv->watch_output = 1; - return 1; - } - else return 0; + if (strncmp(opt, "max=", 4)==0) { + sv->max_proc = atoi(opt+4); + return 1; + } else if (strncmp(opt, "crash=", 6)==0) { + sv->crash_prog = strdup(opt+6); + return 1; + } else if (strncmp(opt, "dir=", 4)==0) { + sv->home_dir = strdup(opt+4); + return 1; + } else if (strncmp(opt, "user=", 5)==0) { + sv->username = strdup(opt+5); + return 1; + } else if (strncmp(opt, "enabled=", 8)==0) { + if (strcmp(opt+8, "no")==0) + sv->enabled = 0; + else if (strcmp(opt+8, "yes")==0) + sv->enabled = 1; + else return -1; + return 1; + } else if (strncmp(opt, "pidfile=", 8)==0) { + sv->pidfile = strdup(opt+8); + return 1; + } else if (strcmp(opt, "watch_output")==0) { + sv->watch_output = 1; + return 1; + } else + return 0; } static int service_cmp(service_t a, service_t b, char *k) { - if (b) k = b->service; - return strcmp(a->service, k); + if (b) k = b->service; + return strcmp(a->service, k); } void service_init(void) { - services = skip_new(service_cmp, NULL, NULL); - allprocs = skip_new(proc_cmp, NULL, NULL); + services = skip_new(service_cmp, NULL, NULL); + allprocs = skip_new(proc_cmp, NULL, NULL); } void free_service(service_t sv) { - if (sv->service) free(sv->service); - if (sv->crash_prog) free(sv->crash_prog); - if (sv->classinfo) (sv->class->free_state)(sv); - if (sv->home_dir) free(sv->home_dir); - if (sv->username) free(sv->username); - if (sv->program) free(sv->program); - if (sv->pidfile) free(sv->pidfile); - if (sv->args) strlistfree(sv->args); - if (sv->proc_list) skip_free(sv->proc_list); + if (sv->service) free(sv->service); + if (sv->crash_prog) free(sv->crash_prog); + if (sv->classinfo) (sv->class->free_state)(sv); + if (sv->home_dir) free(sv->home_dir); + if (sv->username) free(sv->username); + if (sv->program) free(sv->program); + if (sv->pidfile) free(sv->pidfile); + if (sv->args) strlistfree(sv->args); + if (sv->proc_list) skip_free(sv->proc_list); - free(sv); + free(sv); } service_t find_service(char *name) { - service_t *sp; - if (name == NULL) return NULL; - sp = skip_search(services, name); - if (sp) - return *sp; - else - return NULL; + service_t *sp; + if (name == NULL) return NULL; + sp = skip_search(services, name); + if (sp) + return *sp; + else + return NULL; } diff --git a/skip.c b/skip.c index 06bba30..b61c51c 100644 --- a/skip.c +++ b/skip.c @@ -5,7 +5,7 @@ This should compare e1 with e2 or (if null) k (a key) free should free an entry errfn should do something with an error message - + skip_new(cmp,free,errfn) -> list skip_insert(list,entry) -> bool skip_delete(list,key) -> bool @@ -33,223 +33,214 @@ typedef void *valueType; typedef struct node { - valueType value; /* must be first for skip_next to work */ - struct node *forward[1]; /* variable sized array of forward pointers */ + valueType value; /* must be first for skip_next to work */ + struct node *forward[1]; /* variable sized array of forward pointers */ } *node; typedef struct list { - int level; /* Maximum level of the list - (1 more than the number of levels in the list) */ - node header; /* pointer to head of list */ - int (*cmpfn)(); /* compares two values or a key an a value */ - void (*freefn)(); /* free a value */ - void (*errfn)(); /* when malloc error occurs */ + int level; /* Maximum level of the list + (1 more than the number of levels in the list) */ + node header; /* pointer to head of list */ + int (*cmpfn)(); /* compares two values or a key an a value */ + void (*freefn)(); /* free a value */ + void (*errfn)(); /* when malloc error occurs */ } *list; static void default_errfn(char *msg) { - write(2, msg, (int)strlen(msg)); - write(2, "\n", 2); - abort(); + write(2, msg, (int)strlen(msg)); + write(2, "\n", 2); + abort(); } static int randomsLeft = 0; static int randomBits; -list skip_new(cmpfn, freefn, errfn) -int (*cmpfn)(); -void (*freefn)(); -void (*errfn)(); +list skip_new( + int (*cmpfn)(), + void (*freefn)(), + void (*errfn)()) { - list l; - int i; - - if (errfn == NULL) - errfn = default_errfn; - l = (list)malloc(sizeof(struct list)); - if (l == NULL) - { - (*errfn)("Malloc failed in skip_new"); - return NULL; - } - l->level = 0; - l->header = newNodeOfLevel(MaxNumberOfLevels); - if (l->header == NULL) - { - (*errfn)("Malloc failed in skip_new"); - return NULL; - } - for (i=0; iheader->forward[i] = NULL; - l->header->value = NULL; - l->cmpfn = cmpfn; - l->freefn = freefn; - if (errfn) - l->errfn = errfn; - else - l->errfn = default_errfn; - return l; + list l; + int i; + + if (errfn == NULL) + errfn = default_errfn; + l = (list)malloc(sizeof(struct list)); + if (l == NULL) + { + (*errfn)("Malloc failed in skip_new"); + return NULL; + } + l->level = 0; + l->header = newNodeOfLevel(MaxNumberOfLevels); + if (l->header == NULL) + { + (*errfn)("Malloc failed in skip_new"); + return NULL; + } + for (i=0; iheader->forward[i] = NULL; + l->header->value = NULL; + l->cmpfn = cmpfn; + l->freefn = freefn; + if (errfn) + l->errfn = errfn; + else + l->errfn = default_errfn; + return l; } -void skip_free(l) -list l; +void skip_free(list l) { - register node p; - p = l->header; - while (p != NULL) - { - register node q; - q = p->forward[0]; - if (p != l->header) /* header has no meaningful value */ - (*l->freefn)(p->value); - free(p); - p = q; - } - free(l); + register node p; + p = l->header; + while (p != NULL) + { + register node q; + q = p->forward[0]; + if (p != l->header) /* header has no meaningful value */ + (*l->freefn)(p->value); + free(p); + p = q; + } + free(l); } static int randomLevel() { - register int level = 0; - register int b; - do { - if (randomsLeft == 0) { + register int level = 0; + register int b; + do { + if (randomsLeft == 0) { #ifdef POSIX - randomBits = lrand48(); + randomBits = lrand48(); #else - randomBits = random(); + randomBits = random(); #endif - randomsLeft = BitsInRandom/2; - } - b = randomBits&3; - randomBits>>=2; - randomsLeft--; - if (!b) level++; - } while (!b); - return(level>MaxLevel ? MaxLevel : level); + randomsLeft = BitsInRandom/2; + } + b = randomBits&3; + randomBits>>=2; + randomsLeft--; + if (!b) level++; + } while (!b); + return(level>MaxLevel ? MaxLevel : level); } -boolean skip_insert(l, value) -list l; -valueType value; +boolean skip_insert(list l, valueType value) { - int k; - node update[MaxNumberOfLevels]; - node p,q; - int cm=0; - - p = l->header; - for (k=l->level ; k>=0 ; k--) - { - cm = 1; - while ( p->forward[k] != NULL - && (cm=(*l->cmpfn)(p->forward[k]->value, value, 0))<0) - p = p->forward[k]; - update[k] = p; - } - - if (cm == 0) - return false; - - k = randomLevel(); - if (k> l->level) - { - k = ++l->level; - update[k] = l->header; - } - q = newNodeOfLevel(k); - if (q == NULL) - { - (*l->errfn)("Malloc failed in skip_insert"); - return false; - } - q->value = value; - for ( ; k>=0 ; k--) - { - p = update[k]; - q->forward[k] = p->forward[k]; - p->forward[k] = q; - } - return true; + int k; + node update[MaxNumberOfLevels]; + node p,q; + int cm=0; + + p = l->header; + for (k=l->level ; k>=0 ; k--) + { + cm = 1; + while ( p->forward[k] != NULL + && (cm=(*l->cmpfn)(p->forward[k]->value, value, 0))<0) + p = p->forward[k]; + update[k] = p; + } + + if (cm == 0) + return false; + + k = randomLevel(); + if (k> l->level) + { + k = ++l->level; + update[k] = l->header; + } + q = newNodeOfLevel(k); + if (q == NULL) + { + (*l->errfn)("Malloc failed in skip_insert"); + return false; + } + q->value = value; + for ( ; k>=0 ; k--) + { + p = update[k]; + q->forward[k] = p->forward[k]; + p->forward[k] = q; + } + return true; } -boolean skip_delete(l, key) -list l; -keyType key; +boolean skip_delete(list l, keyType key) { - int k, m; - node update[MaxNumberOfLevels]; - node p,q; - int cm = 0; - - p = l->header; - - for (k=l->level ; k>=0 ; k--) - { - cm = 1; - while ( p->forward[k] != NULL - && (cm=(*l->cmpfn)(p->forward[k]->value, NULL, key))<0) - p = p->forward[k]; - update[k] = p; - } - - if (cm == 0) - { - q = update[0]->forward[0]; - m=l->level; - for (k=0; k<=m && (p=update[k])->forward[k] == q ; k++) - p->forward[k] = q->forward[k]; - if (l->freefn) - (*l->freefn)(q->value); - free(q); - while (l->header->forward[m] == NULL && m > 0) - m--; - l->level = m; - return true; - } - else - return false; + int k, m; + node update[MaxNumberOfLevels]; + node p,q; + int cm = 0; + + p = l->header; + + for (k=l->level ; k>=0 ; k--) + { + cm = 1; + while ( p->forward[k] != NULL + && (cm=(*l->cmpfn)(p->forward[k]->value, NULL, key))<0) + p = p->forward[k]; + update[k] = p; + } + + if (cm == 0) + { + q = update[0]->forward[0]; + m=l->level; + for (k=0; k<=m && (p=update[k])->forward[k] == q ; k++) + p->forward[k] = q->forward[k]; + if (l->freefn) + (*l->freefn)(q->value); + free(q); + while (l->header->forward[m] == NULL && m > 0) + m--; + l->level = m; + return true; + } + else + return false; } -valueType *skip_search(l, key) -list l; -keyType key; +valueType *skip_search(list l, keyType key) { - int k; - node p; - int cm = 0; - - p = l->header; - for (k=l->level ; k>=0 ; k--) - { - cm = 1; - while ( p->forward[k] != NULL - && (cm=(*l->cmpfn)(p->forward[k]->value, NULL, key))<0) - p = p->forward[k]; - } - if (cm != 0) - return NULL; - return &p->forward[0]->value; + int k; + node p; + int cm = 0; + + p = l->header; + for (k=l->level ; k>=0 ; k--) + { + cm = 1; + while ( p->forward[k] != NULL + && (cm=(*l->cmpfn)(p->forward[k]->value, NULL, key))<0) + p = p->forward[k]; + } + if (cm != 0) + return NULL; + return &p->forward[0]->value; } -valueType *skip_first(l) -list l; +valueType *skip_first(list l) { - node p; + node p; - p = l->header; - if (p->forward[0] == NULL) - return NULL; - return & p->forward[0]->value; + p = l->header; + if (p->forward[0] == NULL) + return NULL; + return & p->forward[0]->value; } -valueType *skip_next(c) -valueType *c; +valueType *skip_next(valueType *c) { - node p; - p = (node)c; - if (p->forward[0] == NULL) - return NULL; - return & p->forward[0]->value; + node p; + p = (node)c; + if (p->forward[0] == NULL) + return NULL; + return & p->forward[0]->value; } diff --git a/strccmp.c b/strccmp.c index a4de904..fcabe52 100644 --- a/strccmp.c +++ b/strccmp.c @@ -1,26 +1,26 @@ #include -int strnccmp(a,b, n) +int strncasecmp(a,b, n) char *a, *b; int n; { - char ac=0, bc=0; + char ac=0, bc=0; - while(n--) - { - ac = *a++; - if (ac>='a' && ac <= 'z') ac -= 'a'-'A'; - bc = *b++; - if (bc>='a' && bc <= 'z') bc -= 'a'-'A'; - if (ac == 0 || ac != bc) break; - } - if (ac bc) return 1; - return 0; + while(n--) + { + ac = *a++; + if (ac>='a' && ac <= 'z') ac -= 'a'-'A'; + bc = *b++; + if (bc>='a' && bc <= 'z') bc -= 'a'-'A'; + if (ac == 0 || ac != bc) break; + } + if (ac bc) return 1; + return 0; } -int strccmp(a,b) +int strcasecmp(a,b) char *a, *b; { - return strnccmp(a,b,(int)strlen(a)+1); + return strncasecmp(a,b,(int)strlen(a)+1); } diff --git a/strdup.c b/strdup.c index 35bbb06..36b9015 100644 --- a/strdup.c +++ b/strdup.c @@ -4,19 +4,19 @@ char *malloc(); char *strdup(char *s) { - if (s==NULL) - return s; - return (char *)strcpy(malloc(strlen(s)+1), s); + if (s==NULL) + return s; + return (char *)strcpy(malloc(strlen(s)+1), s); } char *strndup(char *s, int a) { - char *r; - if (s == NULL) - return s; + char *r; + if (s == NULL) + return s; - r = (char*)malloc(a+1); - strncpy(r, s, a); - r[a] = 0; - return r; + r = (char*)malloc(a+1); + strncpy(r, s, a); + r[a] = 0; + return r; } diff --git a/stream.c b/stream.c index ae6b818..d350499 100644 --- a/stream.c +++ b/stream.c @@ -110,15 +110,13 @@ static void stream_check(service_t sv) } } - - static int stream_prefork(service_t sv) { int f; stream_t s = sv->classinfo; if (s->sock < 0) return -2; - + s->newsock = accept(s->sock, NULL, 0); if (s->newsock < 0) return -2; @@ -188,11 +186,17 @@ static void stream_send(service_t sv) send_int(c(sv)->sock>=0); } -struct class stream_class = -{ "stream", stream_opt, stream_register, stream_check, - stream_copy, stream_freestate, stream_send, - stream_unregister, stream_newparent, stream_newchild, - stream_prefork +struct class stream_class = { + .class = "stream", + .c_process_opt = stream_opt, + .register_service= stream_register, + .c_check_service= stream_check, + .copy_state = stream_copy, + .free_state = stream_freestate, + .send_class = stream_send, + .disable_service= stream_unregister, + .new_parent = stream_newparent, + .new_child = stream_newchild, + .prefork = stream_prefork, }; - diff --git a/strlistdup.c b/strlistdup.c index a3f78c3..fd18df5 100644 --- a/strlistdup.c +++ b/strlistdup.c @@ -6,22 +6,22 @@ char **strlistdup(char **l) { - int len = 0; - char **rv; - while (l[len]) len++; - - rv = (char**)malloc((len+1)*sizeof(char *)); - for (len=0 ; l[len]; len++) - rv[len] = strdup(l[len]); - rv[len] = NULL; - return rv; + int len = 0; + char **rv; + while (l[len]) len++; + + rv = (char**)malloc((len+1)*sizeof(char *)); + for (len=0 ; l[len]; len++) + rv[len] = strdup(l[len]); + rv[len] = NULL; + return rv; } void strlistfree(char **l) { - int i; - for (i=0 ; l[i] ; i++) - free(l[i]); - free(l); + int i; + for (i=0 ; l[i] ; i++) + free(l[i]); + free(l); } diff --git a/strsplit.c b/strsplit.c index 45396d1..afbb2bb 100644 --- a/strsplit.c +++ b/strsplit.c @@ -3,7 +3,7 @@ #include /* - * split a string into an array of strings, + * split a string into an array of strings, * separated by any chars in the fs string * strings may contain chars from fs if quoted * quotes may be escaped or quoted @@ -12,8 +12,7 @@ */ char ** -strsplit(s, fs) -char *s, *fs; +strsplit(char *s, char *fs) { register char *sp, *sp2, *delim, **ssp, *ns; register unsigned i, num; diff --git a/version.c b/version.c index c84afa1..cb5cb8d 100644 --- a/version.c +++ b/version.c @@ -26,6 +26,6 @@ char version[] = "2.17"; * 2.02 31oct95 metad: pidfile and watch_output options, minor improvements to logging * metac: understand new protocol phrases for pidfile and watch_output * 2.01 25oct95 metad: zero holdtimes when run command received - * metac: improve listings: brief and long, hostname included + * metac: improve listings: brief and long, hostname included * */ -- 2.39.5