{
char *rv;
- if (con)
- {
- extern char version[];
+ if (con) {
rv = (char*)malloc(strlen(version)+2);
strcpy(rv+1, version);
rv[0] = 2;
static void do_die(char **args, char *host, void *con)
{
logmsg(LOG_WARNING, "Die request from %s", host);
- exit(1); /* FIXME */
+ exit(1);
}
static void do_disable(char **args, char *host, void *con)
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)
- {
+ if (sv->enabled) {
logmsg(LOG_INFO, "Disable request from %s for %s", host, sv->service);
(sv->class->disable_service)(sv);
sv->enabled = 0;
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)
- {
+ if (!sv->enabled) {
logmsg(LOG_INFO, "Enable request from %s for %s", host, sv->service);
(sv->class->register_service)(sv);
sv->enabled = 1;
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
- {
+ else {
char *env[3];
char *arg = gather_arg(args+2);
env[0] = strcat(strcpy((char*)malloc(20+strlen(host)), "METAD_REASON=run:"), host);
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)
- {
+ else if ((pid = atoi(args[2]))>0) {
proc_t *pp = skip_search(allprocs, &pid);
- if (pp)
- {
+ 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
+ } 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) {
+ for ( ; sv ; sv = find_service(NULL)) {
proc_t *pp;
for (pp = skip_first(sv->proc_list) ; pp ; pp = skip_next(pp))
- if ((*pp)->exit_time == 0 || (*pp)->it_forked)
- {
+ 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,
service_t sv, *svp;
init_return();
send_byte(3); /* listing */
- if (args[1] == NULL)
- {
+ 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)
- {
+ else if ((sv=find_service(args[1])) != NULL) {
for ( ; sv ; sv = find_service(NULL))
send_service(sv);
send_byte(0);
do_send(con);
- }
- else
+ } else
return_error(con, "Cannot find service %s to list", args[1]);
}
}
static struct commands cmds[] = {
- { "list", do_list },
- { "version",do_version },
- { "broad", do_broad },
- { "die", do_die },
- { "disable",do_disable},
- { "enable", do_enable},
+ { "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},
+ { "restart", do_restart},
{ NULL, NULL}
};
for (cmd = 0; cmds[cmd].name ; cmd++)
if (strcasecmp(cmds[cmd].name, args[0])==0)
break;
- if (cmds[cmd].name)
- {
+ if (cmds[cmd].name) {
(cmds[cmd].proc)(args, host, con);
return 1;
- }
- else
+ } else
return 0;
}
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 */
+ 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;
-
-
-
void return_error(struct tcpcon *con, char *fmt, char *a, char *b, char *c)
{
char buf[1024];
char *rv;
- extern char version[];
- if (con)
- {
+
+ if (con) {
sprintf(buf, fmt, a, b, c);
sprintf(buf+strlen(buf), " (metad version %s)", version);
rv = (char*)malloc(strlen(buf)+2);
if (ntohs(sa->sin_port) >= 1024 && geteuid() == 0)
return 0;
- if (sa->sin_addr.s_addr == htonl(0x7f000001))
- {
+ if (sa->sin_addr.s_addr == htonl(0x7f000001)) {
strcpy(host, "localhost");
return 1; /* localhost */
}
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 */
+ if (memcmp(&sa->sin_addr, he->h_addr_list[a], 4)==0) {
+ /* well, we have a believable name */
len = strlen(host);
if (len > strlen(tail) && strcasecmp(tail, host+len - strlen(tail))== 0)
char **words, **wp;
for (cp= buf; *cp ; cp++)
- {
- if (*cp == '\r' || *cp == '\n') *cp = 0;
- }
+ 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 control_init()
{
udp_sock = socket(AF_INET, SOCK_DGRAM, 0);
- if (udp_sock >= 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)
- {
+ if (bind(udp_sock, (struct sockaddr *)&sa, sizeof(sa)) != 0) {
error("cannot bind udp port");
return -1;
}
- }
- else
- {
+ } else {
error("cannot create udp socket");
return -1;
}
tcp_listen = socket(AF_INET, SOCK_STREAM, 0);
- if (tcp_listen >= 0)
- {
+ if (tcp_listen >= 0) {
struct sockaddr_in sa;
int i = 1;
nodelay(tcp_listen);
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)
- {
+ if (bind(tcp_listen, (struct sockaddr *)&sa, sizeof(sa)) != 0) {
error("cannot bind tcp port");
return -1;
}
listen(tcp_listen, 5);
- }
- else
- {
+ } else {
error("Cannot create tcp socket");
return -1;
}
void check_control(void)
{
/* first check udp */
- if (readyon(udp_sock))
- {
+ 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))
- {
+ if (n>0 && address_ok(&sa, host)) {
buf[n] = 0;
run_command(buf, host, NULL);
}
listenon(udp_sock);
/* then check tcpcon or tcp_listen */
- if (tcpcon.sock != -1)
- {
+ if (tcpcon.sock != -1) {
time_t now;
time(&now);
- if (tcpcon.connect_time + 120 < 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)
- {
+ } else if (tcpcon.outbuf) {
if (canwrite(tcpcon.sock) && tcpcon.outpos < tcpcon.outlen)
{
int l = tcpcon.outlen - tcpcon.outpos;
listenon(tcp_listen);
else
writeon(tcpcon.sock);
- }
- else /* we are still reading a command */
- {
- if (readyon(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)
- {
- close(tcpcon.sock); tcpcon.sock = -1;
- }
- else
- {
+ 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)
- {
+ 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 (tcpcon.outbuf == NULL) {
tcpcon.outbuf = malloc(1);
tcpcon.outbuf[0] = 0;
tcpcon.outlen = 1;
else
listenon(tcpcon.sock);
}
- }
- else
- {
- if (readyon(tcp_listen))
- {
+ } else {
+ if (readyon(tcp_listen)) {
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)
- {
+ if (tcpcon.sock >= 0) {
nodelay(tcpcon.sock);
- if (address_ok(&sa, tcpcon.host))
- {
+ if (address_ok(&sa, tcpcon.host)) {
time(&tcpcon.connect_time);
listenon(tcpcon.sock);
waituntil(tcpcon.connect_time+122);
- }
- else
- {
+ } else {
close(tcpcon.sock);
tcpcon.sock = -1;
}
if (tcpcon.sock < 0)
listenon(tcp_listen);
}
-
}
void set_reply(struct tcpcon *con, char *reply, int len)
{
- if (con)
- {
+ if (con) {
con->outbuf = reply;
con->outlen = len;
con->outpos = 0;
- }
- else free(reply);
+ } else
+ free(reply);
}
static int daemon_opt(service_t sv, char *opt)
{
/* understand min= period= */
- if (strncmp(opt, "min=", 4)==0)
- {
+ if (strncmp(opt, "min=", 4)==0) {
c(sv)->min = atoi(opt+4);
return 1;
}
- if (strncmp(opt, "period=", 7) == 0)
- {
+ if (strncmp(opt, "period=", 7) == 0) {
char *cp = opt+7;
int num = atoi(cp);
if (num==0) num=1;
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))
- {
+ 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 */
static void daemon_newchild(service_t sv)
{
-
}
static void daemon_send(service_t sv)
#endif
#include "skip.h"
-char *get_str();
-char *get_return();
void qfree(char *a)
{
if (a) free(a);
init_recv(buf);
if (get_byte() != 3) return; /* something VERY wrong */
b = get_byte();
- while(b==1 || b == 2) /* service */
- {
+ while ( b==1 || b == 2) { /* service */
+
char *sname;
int enabled;
int args;
service_t sv, *svp = NULL;
sname = get_str();
- if (sname)
- {
+ if (sname) {
svp = skip_search(services, sname);
free(sname);
}
qfree(get_str()); /* home */
qfree(get_str()); /* user */
qfree(get_str()); /* crash */
- if (b == 2)
- {
+ if (b == 2) {
get_int(); /* watch_output */
qfree(get_str()); /* pidfile */
}
while (args--)
qfree(get_str());
class = get_byte();
- switch(class)
- {
+ switch(class) {
case 1:
get_int();
get_int();
if (svp) sv= *svp ;else sv= NULL;
if (sv) sv->enabled = enabled;
b = get_byte();
- while (b == 3 || b == 4) /* process */
- {
+ while (b == 3 || b == 4) { /* process */
+
int pid, start, xit;
int forkedpid = 0, pipefd = -1;
pid = get_int();
- if (b == 4)
- {
+ if (b == 4) {
forkedpid = get_int();
pipefd = get_int();
}
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) )
- {
+ 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;
char *file = "/var/tmp/...metad-temp-file";
fd = open(file, O_RDWR|O_TRUNC|O_CREAT, 0600);
- if (fd < 0)
- {
+ 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))
- {
+ 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)
- {
+ if (fd > 0) {
close(0);
dup(fd);
close(fd);
*/
-fd_set wait_for, are_ready;
-fd_set write_on, can_write;
-time_t when_wake;
+static fd_set wait_for, are_ready;
+static fd_set write_on, can_write;
+static time_t when_wake;
void listenon(int socket)
{
#include "args.h"
#include "dlink.h"
-extern char version[];
char *progname;
void usage(char *fmt, char *arg)
, progname) ;
}
-int send_cmd(char *cmd, int udp, char *host, int verbose);
-
int main(int argc, char *argv[])
{
void *cmds = dl_head();
break;
}
- if (show_help)
- {
+ if (show_help) {
help();
exit(0);
}
- if (dl_next(hosts) == hosts && local_broad == 0)
- {
+ if (dl_next(hosts) == hosts && local_broad == 0) {
/* no where to send to... */
- if (dl_next(cmds) != cmds)
- {
+ if (dl_next(cmds) != cmds) {
fprintf(stderr,"%s: commands were specified with no where to send them!\n", progname);
exit(1);
}
usage("Nothing to do", NULL), exit(1);
exit(0);
}
- if (dl_next(hosts) != hosts && local_broad)
- {
+
+ 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)
- {
+ if (show_version) {
c = dl_strdup("version");
dl_insert(cmds, c);
}
- for (c= dl_next(cmds) ; c != cmds ; c = dl_next(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;
#ifdef SOLARIS
#include <sys/termios.h>
#endif
-char **gargv;
+
+char **gargv; /* used to pass args to 'restart' */
int main(int argc, char *argv[])
{
#include <syslog.h>
#include <ctype.h>
#include <signal.h>
+#include <time.h>
/* hold config file info */
int tcp_port(void);
void nodelay(int socket);
+int send_cmd(char *cmd, int udp, char *host, int verbose);
+
+char *get_str();
+char *get_return();
+
#ifndef IN_ERROR
void error(char *mesg,...);
void logmsg(int, char*, ...);
extern void *services;
extern void *allprocs;
-
-time_t time(time_t*);
-
extern int is_saved_pid(pid_t pid);
+extern char version[];
#define HOURS (MINUTES * 60L)
#define MINUTES 60L
-#ifndef HZ
-# define HZ 50
-#endif
-
/* static function declarations */
sprintf(tim,"%7ds", (int)time);
return tim;
}
-
-char *prticks(time_t ticks)
-{
- return prtime(ticks/HZ);
-}
(*serv)->pending = 1;
f = fopen(file, "r");
- if (f == NULL)
- {
+ if (f == NULL) {
error("cannot find config file %s", file);
return 1;
}
- while (fgets(linebuf, sizeof(linebuf), f)!= NULL)
- {
+ while (fgets(linebuf, sizeof(linebuf), f)!= NULL) {
int len = strlen(linebuf);
char **words;
int w;
- if (len > 1000 && linebuf[len-1] != '\n')
- {
+ if (len > 1000 && linebuf[len-1] != '\n') {
error("line too long in config file");
fclose(f);
return 1;
if (linebuf[len-1] == '\n') linebuf[--len] = 0;
words = strsplit(linebuf, " \t\n");
- if (words)
- {
- for (w=0 ;words[w] ; w++) if (words[w][0]=='#') words[w]=NULL;
- if (words[0] && words[1])
- {
+ if (words) {
+ 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 (svp != NULL &&
+ (*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)
- {
+ 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++)
- {
+ 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) {
if (ok == 0)
error("unknown option: %s", words[w]);
else
break;
}
}
- if (sv == NULL) continue;
+ if (sv == NULL)
+ continue;
if (words[w])
sv->program = strdup(words[w++]);
if (words[w])
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)
- {
+ else {
+ if (svp) {
proc_t *pp2;
service_t sv2 = *svp;
sv->enabled = sv2->enabled;
#include "metad.h"
char *get_str(void);
-#ifdef ULTRIX
-char *strdup(char*);
-#endif
/* cache addresses */
typedef struct acache
{
send_int(sv->start_cnt);
send_int(sv->enabled);
send_str(sv->program);
- for (i=0 ; sv->args[i] ; i++);
+ for (i=0 ; sv->args[i] ; i++)
+ ;
send_int(i);
for (i=0 ; sv->args[i] ; i++)
send_str(sv->args[i]);
s->sock = -1;
}
-
static void stream_check(service_t sv)
{
stream_t s = sv->classinfo;
{
int len = 0;
char **rv;
- while (l[len]) len++;
+ while (l[len])
+ len++;
rv = (char**)malloc((len+1)*sizeof(char *));
for (len=0 ; l[len]; len++)
char **
strsplit(char *s, char *fs)
{
- register char *sp, *sp2, *delim, **ssp, *ns;
- register unsigned i, num;
+ char *sp, *sp2, *delim, **ssp, *ns;
+ unsigned i, num;
static char quote[] = "'";
if((ns = malloc((unsigned) strlen(s) + 1)) == NULL)
char version[] = "2.17";
/*
- * 2.17 06aug2003 metad: check if pid has benee collected before assuming a failed kill means that it is lost.
+ * 2.17 06aug2003 metad: check if pid has been collected before assuming a failed kill means that it is lost.
* 2.16 18sep2002 metad: add "stream" service for tcp listening
* metac: understand listing of stream service
* 2.15 17aug2001 metad: fixed ordering in main_loop