2 /* send a command to a metad somewhere
3 * if we use tcp, wait for reply and interpret it
7 #include <sys/socket.h>
8 #include <netinet/in.h>
9 #include <netinet/tcp.h>
10 #include <arpa/inet.h>
24 struct sockaddr_in addr;
27 extern char *progname;
29 static int acmp(acache a, acache b, char *host)
32 return strcmp(a->host, host);
34 static void afree(acache a)
41 static void *addr_cache = NULL;
43 static void list_service(char *, int);
45 int send_cmd(char *cmd, int udp, char *host, int verbose)
49 if (addr_cache == NULL)
50 addr_cache = skip_new(acmp, afree, NULL);
52 cp = skip_search(addr_cache, host);
57 c = (acache)malloc(sizeof(struct acache));
58 c->host = strdup(host);
59 c->addr.sin_port = udp ? udp_port() : tcp_port();
60 c->addr.sin_addr.s_addr = inet_addr(host);
61 if (c->addr.sin_addr.s_addr > 0 && c->addr.sin_addr.s_addr < 0xffffffff)
63 c->addr.sin_family = AF_INET;
68 he = gethostbyname(host);
71 c->addr.sin_family = -1;
72 fprintf(stderr, "%s: unknown host %s\n", progname, host);
76 memcpy(&c->addr.sin_addr, he->h_addr_list[0], 4);
77 c->addr.sin_family = AF_INET;
80 skip_insert(addr_cache, c);
82 if (c->addr.sin_family != AF_INET)
90 sock = socket(AF_INET, SOCK_DGRAM, 0);
94 struct sockaddr_in myaddr;
95 port = 600 + time(0)%400;
97 memset(&myaddr, 0, sizeof(myaddr));
98 myaddr.sin_family = AF_INET;
101 myaddr.sin_port = htons(port);
102 if (bind(sock, (struct sockaddr *)&myaddr, sizeof(myaddr))== 0)
108 fprintf(stderr, "%s: cannot bind priv udp port...\n", progname);
112 sendto(sock, cmd, strlen(cmd)+1, 0, (struct sockaddr *)&c->addr, sizeof(c->addr));
116 /* tcp - have to make a new connection each time */
119 char buf[8192]; /* FIXME autosize */
124 port = 600 + time(0)%400;
127 sock = rresvport(&port);
129 sock = socket(AF_INET, SOCK_STREAM, 0);
132 fprintf(stderr, "%s: cannot bind socket!!\n", progname);
135 #ifdef TCP_CONN_ABORT_THRESHOLD
139 setsockopt(sock, IPPROTO_TCP, TCP_CONN_ABORT_THRESHOLD, (char*)&thresh, 4);
143 if (connect(sock, (struct sockaddr *)&c->addr, sizeof(c->addr))!= 0)
145 fprintf(stderr, "%s: cannot connect to %s\n", progname, c->host);
147 c->addr.sin_family = -1;
150 write(sock, cmd, strlen(cmd)+1);
151 shutdown(sock, 1); /* don't want to write no more */
154 n = read(sock, buf+have, sizeof(buf)-1 - have);
156 } while (n>0 && have < sizeof(buf)-1);
159 return 0; /* probably OK, FIXME */
163 case 0: return 0; /* definately ok */
164 case 1: /* error message */
165 fprintf(stderr, "%s: %s: %s\n", progname, c->host, buf+1);
167 case 2: /* version number */
168 fprintf(stdout, "%s: %s\n", c->host, buf+1);
170 case 3: /* listing */
172 list_service(c->host, verbose);
176 case 'm': /* old version number */
177 fprintf(stdout, "%s\n", buf);
179 default: /* old metad */
188 static void list_service(char *host, int verbose)
192 while (b == 1 || b == 2) /* a service */
194 char *sname, *home, *user, *crash, *prog;
197 int max, cnt, enabled;
200 char *classname=NULL;
201 char *pidfile = NULL;
202 int watch_output = 0;
203 int min=0, period=0, last;
204 int proto, port=0, active=0, backlog=0;
213 watch_output = get_int();
220 args = (char**)malloc((argc+1)*sizeof(char*));
221 for (i=0 ; i<argc ; i++)
228 classname = "daemon";
234 classname = "stream";
241 /* printf("Host: %s\n", host); */
242 if (sname == NULL) sname = "*unknown*";
243 printf("%s:%s%*.0s %s %s (x%d)", host, sname, 18-(int)strlen(host) - (int)strlen(sname), "",
244 classname, enabled?"enabled":"DISABLED", cnt);
248 printf(" Prog: %s\n", prog);
250 for (i=0; i<argc ; i++)
251 printf(" %s", args[i]);
254 if (max) printf(" max=%d", max);
255 if (home) printf(" dir=%s", home);
256 if (user) printf(" user=%s", user);
257 if (crash) printf(" crash=%s", crash);
258 if (pidfile) printf(" pidfile=%s", pidfile);
259 if (watch_output) printf(" watch_output");
263 if (min) printf(" min=%d", min);
264 if (period) printf(" period=%d", period);
267 printf(" port=%d", port);
268 printf(" backlog=%d", backlog);
269 if (!active) printf(" INACTIVE");
276 while (b == 3 || b == 4) /* process */
278 int pid, hold, status;
284 forkedpid = get_int();
285 get_int(); /* pipefd */
294 printf(" Proc: pid=%5d%s %s", (xit && forkedpid) ? forkedpid : pid,
295 (xit&&forkedpid)?"f":"", ctime(&start));
296 if (xit && forkedpid==0)
300 holdt = hold - time(0);
302 while(*t == ' ') t++;
304 printf(" Exited %1.12s holding for %s\n", t2, t);
310 time_t age = time(0) - start;
311 t = (char*)prtime(age);
312 while(*t == ' ') t++;
313 printf(" %d%s(%s%s)", (xit && forkedpid) ? forkedpid : pid,
314 (xit&&forkedpid)?"f":"",
315 (xit && forkedpid==0)?"exited:":"", t);
319 if (!verbose) printf("\n");