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>
27 struct sockaddr_in addr;
30 extern char *progname;
32 static int acmp(acache a, acache b, char *host)
35 return strcmp(a->host, host);
37 static void afree(acache a)
44 static void *addr_cache = NULL;
46 static void list_service(char *, int);
48 int send_cmd(char *cmd, int udp, char *host, int verbose)
52 if (addr_cache == NULL)
53 addr_cache = skip_new(acmp, afree, NULL);
55 cp = skip_search(addr_cache, host);
60 c = (acache)malloc(sizeof(struct acache));
61 c->host = strdup(host);
62 c->addr.sin_port = udp ? udp_port() : tcp_port();
63 c->addr.sin_addr.s_addr = inet_addr(host);
64 if (c->addr.sin_addr.s_addr > 0 && c->addr.sin_addr.s_addr < 0xffffffff)
66 c->addr.sin_family = AF_INET;
71 he = gethostbyname(host);
74 c->addr.sin_family = -1;
75 fprintf(stderr, "%s: unknown host %s\n", progname, host);
79 memcpy(&c->addr.sin_addr, he->h_addr_list[0], 4);
80 c->addr.sin_family = AF_INET;
83 skip_insert(addr_cache, c);
85 if (c->addr.sin_family != AF_INET)
93 sock = socket(AF_INET, SOCK_DGRAM, 0);
97 struct sockaddr_in myaddr;
98 port = 600 + time(0)%400;
100 memset(&myaddr, 0, sizeof(myaddr));
101 myaddr.sin_family = AF_INET;
104 myaddr.sin_port = htons(port);
105 if (bind(sock, (struct sockaddr *)&myaddr, sizeof(myaddr))== 0)
111 fprintf(stderr, "%s: cannot bind priv udp port...\n", progname);
115 sendto(sock, cmd, strlen(cmd)+1, 0, (struct sockaddr *)&c->addr, sizeof(c->addr));
119 /* tcp - have to make a new connection each time */
122 char buf[8192]; /* FIXME autosize */
127 port = 600 + time(0)%400;
130 sock = rresvport(&port);
132 sock = socket(AF_INET, SOCK_STREAM, 0);
135 fprintf(stderr, "%s: cannot bind socket!!\n", progname);
138 #ifdef TCP_CONN_ABORT_THRESHOLD
142 setsockopt(sock, IPPROTO_TCP, TCP_CONN_ABORT_THRESHOLD, (char*)&thresh, 4);
146 if (connect(sock, (struct sockaddr *)&c->addr, sizeof(c->addr))!= 0)
148 fprintf(stderr, "%s: cannot connect to %s\n", progname, c->host);
150 c->addr.sin_family = -1;
153 write(sock, cmd, strlen(cmd)+1);
154 shutdown(sock, 1); /* don't want to write no more */
157 n = read(sock, buf+have, sizeof(buf)-1 - have);
159 } while (n>0 && have < sizeof(buf)-1);
162 return 0; /* probably OK, FIXME */
166 case 0: return 0; /* definately ok */
167 case 1: /* error message */
168 fprintf(stderr, "%s: %s: %s\n", progname, c->host, buf+1);
170 case 2: /* version number */
171 fprintf(stdout, "%s: %s\n", c->host, buf+1);
173 case 3: /* listing */
175 list_service(c->host, verbose);
179 case 'm': /* old version number */
180 fprintf(stdout, "%s\n", buf);
182 default: /* old metad */
191 static void list_service(char *host, int verbose)
195 while (b == 1 || b == 2) /* a service */
197 char *sname, *home, *user, *crash, *prog;
200 int max, cnt, enabled;
203 char *classname=NULL;
204 char *pidfile = NULL;
205 int watch_output = 0;
206 int min=0, period=0, last;
207 int proto, port=0, active=0, backlog=0;
216 watch_output = get_int();
223 args = (char**)malloc((argc+1)*sizeof(char*));
224 for (i=0 ; i<argc ; i++)
231 classname = "daemon";
237 classname = "stream";
244 /* printf("Host: %s\n", host); */
245 if (sname == NULL) sname = "*unknown*";
246 printf("%s:%s%*.0s %s %s (x%d)", host, sname, 18-(int)strlen(host) - (int)strlen(sname), "",
247 classname, enabled?"enabled":"DISABLED", cnt);
251 printf(" Prog: %s\n", prog);
253 for (i=0; i<argc ; i++)
254 printf(" %s", args[i]);
257 if (max) printf(" max=%d", max);
258 if (home) printf(" dir=%s", home);
259 if (user) printf(" user=%s", user);
260 if (crash) printf(" crash=%s", crash);
261 if (pidfile) printf(" pidfile=%s", pidfile);
262 if (watch_output) printf(" watch_output");
266 if (min) printf(" min=%d", min);
267 if (period) printf(" period=%d", period);
270 printf(" port=%d", port);
271 printf(" backlog=%d", backlog);
272 if (!active) printf(" INACTIVE");
279 while (b == 3 || b == 4) /* process */
281 int pid, hold, status;
287 forkedpid = get_int();
288 get_int(); /* pipefd */
297 printf(" Proc: pid=%5d%s %s", (xit && forkedpid) ? forkedpid : pid,
298 (xit&&forkedpid)?"f":"", ctime(&start));
299 if (xit && forkedpid==0)
303 holdt = hold - time(0);
305 while(*t == ' ') t++;
307 printf(" Exited %1.12s holding for %s\n", t2, t);
313 time_t age = time(0) - start;
314 t = (char*)prtime(age);
315 while(*t == ' ') t++;
316 printf(" %d%s(%s%s)", (xit && forkedpid) ? forkedpid : pid,
317 (xit&&forkedpid)?"f":"",
318 (xit && forkedpid==0)?"exited:":"", t);
322 if (!verbose) printf("\n");