home *** CD-ROM | disk | FTP | other *** search
- /* Copyright 1990 The President and Fellows of Harvard University
-
- Permission to use, copy, modify, and distribute this program for any
- purpose and without fee is hereby granted, provided that this
- copyright and permission notice appear on all copies and supporting
- documentation, the name of Harvard University not be used in advertising
- or publicity pertaining to distribution of the program, or to results
- derived from its use, without specific prior written permission, and notice
- be given in supporting documentation that copying and distribution is by
- permission of Harvard University. Harvard University makes no
- representations about the suitability of this software for any purpose.
- It is provided "as is" without express or implied warranty. */
-
-
- /* qmaster.c - Dan Lanciani '89 */
-
- /*
- refresh hosts less
- pick up strays
- */
-
- #include <stdio.h>
- #include <sys/types.h>
- #include <sys/socket.h>
- #include <sys/wait.h>
- #include <sys/time.h>
- #include <netinet/in.h>
- #include <netdb.h>
- #include <errno.h>
- #include <signal.h>
- #include <sgtty.h>
- #include <setjmp.h>
-
- #include "queue.h"
-
- #define GARBAGE (1*60)
- #define HOLDDOWN (2*60)
- #define HOSTPOLLTIME (5*60)
- #define DEADMAN (1*60)
-
- struct hostinfo {
- struct hostinfo *hi_next;
- char *hi_name;
- struct sockaddr_in hi_addr;
- int hi_equiv;
- int hi_load;
- time_t hi_timestamp;
- int hi_dead;
- int hi_queued;
- } *hostinfo;
-
- struct userinfo {
- struct userinfo *ui_next;
- long ui_unid;
- struct sockaddr_in ui_addr;
- char *ui_name;
- struct proginfo *ui_prog;
- time_t ui_timestamp;
- int ui_mark;
- };
-
- struct queueinfo {
- struct queueinfo *qi_next;
- char *qi_name;
- int qi_maxrun;
- int qi_minload;
- int qi_maxperu;
- int qi_hcnt;
- struct hostinfo *qi_hosts[MAXHCNT];
- struct userinfo *qi_heads[MAXHCNT];
- struct userinfo *qi_head;
- } *queueinfo;
-
- struct proginfo {
- struct proginfo *pi_next;
- char *pi_name;
- struct queueinfo *pi_queue;
- } *proginfo;
-
- struct sockaddr_in sin = { AF_INET };
- time_t time();
- extern int errno;
- int reapchild();
- long atol();
-
- long
- newunid()
- {
- static int fd = -1;
- long unid;
- char buf[100];
-
- if(fd < 0) {
- if((fd = open(UNID, 2)) < 0) {
- if((fd = creat(UNID, 0644)) < 0) {
- perror("creat");
- exit(1);
- }
- sprintf(buf, "%ld", FIRSTUNID);
- write(fd, buf, strlen(buf) + 1);
- close(fd);
- if((fd = open(UNID, 2)) < 0) {
- perror("open");
- exit(1);
- }
- }
- }
- lseek(fd, 0L, 0);
- read(fd, buf, sizeof(buf));
- unid = atol(buf) + 1;
- if(!isunid(unid))
- unid = FIRSTUNID;
- sprintf(buf, "%ld", unid);
- lseek(fd, 0L, 0);
- write(fd, buf, strlen(buf) + 1);
- return(unid);
- }
-
- #define refresh(hi) \
- if(time((time_t)0) - (hi)->hi_timestamp > HOSTPOLLTIME) { \
- (hi)->hi_load = getrload((hi)->hi_name); \
- (hi)->hi_timestamp = time((time_t)0); \
- } \
- else
-
- struct hostinfo *
- hibyname(name)
- register char *name;
- {
- register struct hostinfo *hi;
- register struct hostent *hp;
-
- for(hi = hostinfo; hi; hi = hi->hi_next)
- if(!strcmp(hi->hi_name, name)) {
- refresh(hi);
- return(hi);
- }
- if(!(hp = gethostbyname(name)))
- return(0);
- hi = (struct hostinfo *)malloc(sizeof(struct hostinfo));
- hi->hi_name = newstring(name);
- if(infile(EQUIVFILE, hi->hi_name))
- hi->hi_equiv = 1;
- else
- hi->hi_equiv = 0;
- hi->hi_addr.sin_family = hp->h_addrtype;
- bcopy(hp->h_addr, &hi->hi_addr.sin_addr, hp->h_length);
- hi->hi_load = getrload(name);
- hi->hi_timestamp = time((time_t)0);
- hi->hi_dead = 0;
- hi->hi_queued = 0;
- hi->hi_next = hostinfo;
- hostinfo = hi;
- return(hi);
- }
-
- struct hostinfo *
- hibyaddr(addr)
- register struct sockaddr_in *addr;
- {
- register struct hostinfo *hi;
- register struct hostent *hp;
-
- for(hi = hostinfo; hi; hi = hi->hi_next)
- if(addr->sin_addr.s_addr == hi->hi_addr.sin_addr.s_addr) {
- refresh(hi);
- return(hi);
- }
- if(!(hp=gethostbyaddr(&addr->sin_addr, sizeof(struct in_addr),AF_INET)))
- return(0);
- hi = (struct hostinfo *)malloc(sizeof(struct hostinfo));
- hi->hi_name = newstring(hp->h_name);
- if(index(hi->hi_name, '.'))
- *index(hi->hi_name, '.') = '\0';
- if(infile(EQUIVFILE, hi->hi_name))
- hi->hi_equiv = 1;
- else
- hi->hi_equiv = 0;
- hi->hi_addr.sin_family = hp->h_addrtype;
- bcopy(hp->h_addr, &hi->hi_addr.sin_addr, hp->h_length);
- hi->hi_load = getrload(hi->hi_name);
- hi->hi_timestamp = time((time_t)0);
- hi->hi_dead = 0;
- hi->hi_queued = 0;
- hi->hi_next = hostinfo;
- hostinfo = hi;
- return(hi);
- }
-
- struct userinfo *
- uibyunid(unid, unlnk)
- register long unid;
- {
- register struct queueinfo *qi;
- register struct userinfo *ui, *pu;
- register int i;
-
- for(qi = queueinfo; qi; qi = qi->qi_next) {
- for(i = 0; i < qi->qi_hcnt; i++)
- for(pu = 0, ui =qi->qi_heads[i];ui;pu=ui,ui=ui->ui_next)
- if(unid == ui->ui_unid) {
- if(unlnk)
- if(pu)
- pu->ui_next = ui->ui_next;
- else
- qi->qi_heads[i] = ui->ui_next;
- return(ui);
- }
- for(pu = 0, ui = qi->qi_head; ui; pu = ui, ui = ui->ui_next)
- if(unid == ui->ui_unid) {
- if(unlnk)
- if(pu)
- pu->ui_next = ui->ui_next;
- else
- qi->qi_head = ui->ui_next;
- return(ui);
- }
- }
- return(0);
- }
-
- struct queueinfo *
- qibyname(name)
- register char *name;
- {
- register struct queueinfo *qi;
-
- for(qi = queueinfo; qi; qi = qi->qi_next)
- if(!strcmp(qi->qi_name, name))
- return(qi);
- return(0);
- }
-
- struct proginfo *
- pibyname(name)
- register char *name;
- {
- register struct proginfo *pi;
- register struct queueinfo *qi;
- register int i;
-
- for(pi = proginfo; pi; pi = pi->pi_next)
- if(!strcmp(pi->pi_name, name))
- return(pi);
- if(readconf(name))
- return(0);
- if(!(qi = qibyname(queue))) {
- qi = (struct queueinfo *)malloc(sizeof(struct queueinfo));
- qi->qi_name = newstring(queue);
- qi->qi_maxrun = maxrun;
- qi->qi_minload = minload;
- qi->qi_maxperu = maxperu;
- for(i = 0; i < hcnt; i++) {
- if(!(qi->qi_hosts[i] = hibyname(hosts[i]))) {
- i--;
- hcnt--;
- continue;
- }
- qi->qi_hosts[i]->hi_queued = 1;
- qi->qi_heads[i] = 0;
- }
- if(hcnt <= 0) {
- free(qi);
- return(0);
- }
- qi->qi_hcnt = hcnt;
- qi->qi_head = 0;
- qi->qi_next = queueinfo;
- queueinfo = qi;
- }
- pi = (struct proginfo *)malloc(sizeof(struct proginfo));
- pi->pi_name = newstring(name);
- pi->pi_queue = qi;
- pi->pi_next = proginfo;
- proginfo = pi;
- return(pi);
- }
-
- char *
- getln(n, buf)
- char *buf;
- {
- register char *p = buf;
-
- do
- if(read(n, p, 1) != 1)
- return(0);
- while(*p++ != '\n');
- p[-1] = 0;
- return(buf);
- }
-
- char *
- getstr(n, buf)
- char *buf;
- {
- register char *p = buf;
-
- do
- if(read(n, p, 1) != 1)
- return(0);
- while(*p++);
- return(buf);
- }
-
- struct timeval timeout = { 60, 0 };
- char myname[100];
- int s, u, on = 1;
- int strays, dropouts, upstarts;
- int deadmans, enqueues, dequeues, showqueues;
- jmp_buf jb;
-
- catch()
- {
- deadmans++;
- longjmp(jb, 1);
- }
-
- main(argc, argv, envp)
- char **argv, **envp;
- {
- register struct servent *sp;
- register struct queueinfo *qi;
- register struct userinfo *ui, *pu;
- register struct hostinfo *hi, *garbagehi = 0;
- register int i, j, qport;
- long probe, mask, unid;
- char buf[BUFSIZ];
- time_t garbage = 0;
-
- gethostname(myname, sizeof(myname));
- if(argc > 1) {
- for(i = 1; i < argc; i++)
- if(!strcmp(argv[i], myname))
- goto iammaster;
- fprintf(stderr, "I am not master %s\n", myname);
- exit(0);
- }
- iammaster:
- #ifndef DEBUG
- for(s = 0; s < 30; s++)
- close(s);
- if((s = open("/dev/tty", 2)) >= 0) {
- ioctl(s, TIOCNOTTY, 0);
- close(s);
- }
- s = open("/", 0);
- dup(s);
- dup(s);
- signal(SIGALRM, SIG_IGN);
- signal(SIGPIPE, SIG_IGN);
- if(fork())
- exit(0);
- #endif
-
- while(fork()) {
- wait((int *)0);
- sleep(15);
- }
- if(!(sp = getservbyname("queue", "tcp"))) {
- fprintf(stderr, "queue/tcp: Bad service?!?\n");
- exit(1);
- }
- qport = sp->s_port;
- if(!(sp = getservbyname("qmaster", "tcp"))) {
- fprintf(stderr, "qmaster/tcp: Bad service?!?\n");
- exit(1);
- }
- if((s = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
- perror("socket");
- exit(1);
- }
- setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
- setsockopt(s, SOL_SOCKET, SO_KEEPALIVE, &on, sizeof(on));
- sin.sin_port = sp->s_port;
- if(bind(s, &sin, sizeof(sin))) {
- perror("bind");
- exit(1);
- }
- listen(s, 10);
- mask = (1L << s);
- if(!(sp = getservbyname("qmaster", "udp"))) {
- fprintf(stderr, "qmaster/udp: Bad service?!?\n");
- exit(1);
- }
- if((u = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
- perror("socket");
- exit(1);
- }
- setsockopt(u, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
- sin.sin_port = sp->s_port;
- if(bind(u, &sin, sizeof(sin))) {
- perror("bind");
- exit(1);
- }
- mask |= (1L << u);
- while(1) {
- struct sockaddr_in from;
- int s0, fromlen;
- signal(SIGCHLD, reapchild);
- probe = mask;
- if(select(32, &probe, 0, 0, &timeout) < 0) {
- sleep(1);
- continue;
- }
- if(probe & (1L << s)) {
- fromlen = sizeof(from);
- if((s0 = accept(s, &from, &fromlen)) < 0) {
- if(errno = EINTR)
- continue;
- perror("accept");
- sleep(1);
- continue;
- }
- if(from.sin_family != AF_INET ||
- htons((u_short)from.sin_port) >= IPPORT_RESERVED
- || htons((u_short)from.sin_port)
- < IPPORT_RESERVED / 2) {
- close(s0);
- continue;
- }
- dostream(s0, &from);
- }
- if(probe & (1L << u))
- dodgram(u);
- for(hi = hostinfo; hi; hi = hi->hi_next)
- if(hi->hi_queued)
- refresh(hi);
- for(qi = queueinfo; qi; qi = qi->qi_next) {
- if(!qi->qi_head)
- continue;
- for(i = 0; i < qi->qi_hcnt; i++)
- for(j = i + 1; j < qi->qi_hcnt; j++)
- if(qi->qi_hosts[j]->hi_load <
- qi->qi_hosts[i]->hi_load) {
- ui = qi->qi_heads[i];
- hi = qi->qi_hosts[i];
- qi->qi_heads[i]=qi->qi_heads[j];
- qi->qi_hosts[i]=qi->qi_hosts[j];
- qi->qi_heads[j] = ui;
- qi->qi_hosts[j] = hi;
- }
- for(i = 0; i < qi->qi_hcnt && qi->qi_head; i++) {
- if(qi->qi_hosts[i]->hi_dead)
- continue;
- if(qi->qi_minload &&
- qi->qi_hosts[i]->hi_load>qi->qi_minload)
- continue;
- j = 0;
- for(ui = qi->qi_heads[i]; ui; ui = ui->ui_next)
- j++;
- while(j < qi->qi_maxrun && (ui = qi->qi_head)) {
- qi->qi_head = ui->ui_next;
- ui->ui_next = qi->qi_heads[i];
- qi->qi_heads[i] = ui;
- sprintf(buf, "\1%s",
- qi->qi_hosts[i]->hi_name);
- sendto(u, buf, strlen(buf) + 1, 0,
- &ui->ui_addr,
- sizeof(ui->ui_addr));
- ui->ui_timestamp = time((time_t)0);
- j++;
- }
- }
- *buf = 0;
- for(ui = qi->qi_head; ui; ui = ui->ui_next)
- sendto(u, buf, 1, 0, &ui->ui_addr,
- sizeof(ui->ui_addr));
- }
- if(time((time_t)0) - garbage > GARBAGE) {
- int rp = IPPORT_RESERVED - 1;
- register char *p;
- if(!garbagehi)
- garbagehi = hostinfo;
- if(!(hi = garbagehi) || !hi->hi_queued)
- goto out;
- hi->hi_addr.sin_port = qport;
- if((i = rresvport(&rp)) < 0)
- goto out;
- if(setjmp(jb))
- goto out2;
- #ifdef DEBUG
- fprintf(stderr, "gc host %s\n", hi->hi_name);
- #endif
- signal(SIGALRM, catch);
- alarm(DEADMAN);
- if(connect(i, &hi->hi_addr, sizeof(hi->hi_addr))) {
- hi->hi_dead = 1;
- goto out2;
- }
- hi->hi_dead = 0;
- alarm(DEADMAN);
- write(i, "\1", 2);
- alarm(DEADMAN);
- while(getln(i, buf)) {
- alarm(0);
- if(strncmp(buf, "Queue: ", 7))
- goto out2;
- if(!(p = index(buf + 7, ',')))
- goto out2;
- *p = 0;
- #ifdef DEBUG
- fprintf(stderr, "queue = %s\n", buf);
- #endif
- if(!(qi = qibyname(buf + 7))) {
- skip:
- alarm(DEADMAN);
- while(getln(i, buf) && *buf)
- alarm(DEADMAN);
- continue;
- }
- for(j = 0; j < qi->qi_hcnt; j++)
- if(hi == qi->qi_hosts[j])
- break;
- if(j >= qi->qi_hcnt)
- goto skip;
- for(ui = qi->qi_heads[j]; ui; ui = ui->ui_next)
- ui->ui_mark = 0;
- alarm(DEADMAN);
- if(!getln(i, buf) || strncmp(buf, "Pid", 3))
- goto out2;
- #ifdef DEBUG
- fprintf(stderr, "header = %s\n", buf);
- #endif
- while(getln(i, buf) && *buf) {
- alarm(0);
- #ifdef DEBUG
- fprintf(stderr, "entry = %s\n", buf);
- #endif
- unid = atol(buf);
- for(ui = qi->qi_heads[j]; ui;
- ui = ui->ui_next)
- if(ui->ui_unid == unid) {
- /* XXX check mark */
- ui->ui_mark = 1;
- break;
- }
- if(ui) {
- alarm(DEADMAN);
- continue;
- }
- if(ui = uibyunid(unid, 1)) {
- ui->ui_mark = 1;
- ui->ui_next = qi->qi_heads[j];
- qi->qi_heads[j] = ui;
- upstarts++;
- alarm(DEADMAN);
- continue;
- }
- /* XXX add it */
- strays++;
- alarm(DEADMAN);
- }
- alarm(0);
- again:
- for(pu = 0, ui = qi->qi_heads[j]; ui;
- pu = ui, ui = ui->ui_next)
- if(!ui->ui_mark && time((time_t)0) -
- ui->ui_timestamp > HOLDDOWN) {
- if(pu)
- pu->ui_next = ui->ui_next;
- else
- qi->qi_heads[j] = ui->ui_next;
- free(ui->ui_name);
- free(ui);
- dropouts++;
- goto again;
- }
- alarm(DEADMAN);
- }
- out2:
- close(i);
- out:
- alarm(0);
- signal(SIGALRM, SIG_DFL);
- garbagehi = hi->hi_next;
- garbage = time((time_t)0);
- }
- }
- }
-
- reapchild()
- {
- union wait status;
-
- while(wait3(&status, WNOHANG, 0) > 0);
- }
-
- dostream(s, sin)
- register int s;
- struct sockaddr_in *sin;
- {
- register struct hostinfo *hi;
-
- if(!(hi = hibyaddr(sin)))
- goto bad;
- if(setjmp(jb))
- goto bad;
- signal(SIGALRM, catch);
- alarm(DEADMAN);
- if(!strcmp(hi->hi_name, "localhost") || !strcmp(hi->hi_name, myname))
- qservice(s, myname, sin, 1);
- else if(hi->hi_equiv)
- qservice(s, hi->hi_name, sin, 0);
- bad:
- alarm(0);
- signal(SIGALRM, SIG_IGN);
- close(s);
- }
-
- dodgram(s)
- register int s;
- {
- char buf[BUFSIZ];
- struct sockaddr_in sin;
- int len, fromlen = sizeof(sin);
- register struct userinfo *ui;
-
- if(setjmp(jb))
- goto bad;
- signal(SIGALRM, catch);
- alarm(10);
- if((len = recvfrom(s, buf, sizeof(buf), 0, &sin, sizeof(sin))) <= 0)
- goto bad;
- alarm(0);
- switch(*buf&0377) {
-
- case 0:
- if(ui = uibyunid(atol(buf + 1), 1)) {
- free(ui->ui_name);
- free(ui);
- }
- break;
- }
- bad:
- alarm(0);
- signal(SIGALRM, SIG_IGN);
- }
-
- qservice(s, host, sin, local)
- register int s;
- register char *host;
- register struct sockaddr_in *sin;
- register int local;
- {
- char request;
-
- if(read(s, &request, 1) != 1)
- return;
- switch(request&0377) {
-
- case 0:
- menqueue(s, host, sin, local);
- enqueues++;
- break;
-
- case 1:
- mshowqueue(s, host, sin, local);
- showqueues++;
- break;
-
- case 2:
- mdequeue(s, host, sin, local);
- dequeues++;
- break;
- }
- }
-
- menqueue(s, host, sin, local)
- register int s;
- register char *host;
- register struct sockaddr_in *sin;
- register int local;
- {
- char what[BUFSIZ], prog[BUFSIZ], user[BUFSIZ], buf[BUFSIZ];
- register struct proginfo *pi;
- register struct queueinfo *qi;
- register struct userinfo *ui, *u2;
- register int i, j;
-
- if(!getstr(s, what) || !getstr(s, prog) || !getstr(s, user))
- return;
- alarm(0);
- if(!(pi = pibyname(prog)))
- return;
- qi = pi->pi_queue;
- if(qi->qi_maxperu) {
- for(i = j = 0; i < qi->qi_hcnt; i++)
- for(ui = qi->qi_heads[i]; ui; ui = ui->ui_next)
- if(!strcmp(user, ui->ui_name))
- j++;
- for(ui = qi->qi_head; ui; ui = ui->ui_next)
- if(!strcmp(user, ui->ui_name))
- j++;
- if(j >= qi->qi_maxperu) {
- *buf = 1;
- sprintf(buf + 1, "You already have %d jobs queued", j);
- alarm(DEADMAN);
- write(s, buf, strlen(buf + 1) + 2);
- return;
- }
- }
- ui = (struct userinfo *)malloc(sizeof(struct userinfo));
- *buf = 0;
- sprintf(buf + 1, "%ld", ui->ui_unid = newunid());
- alarm(DEADMAN);
- write(s, buf, strlen(buf + 1) + 2);
- alarm(0);
- ui->ui_addr = *sin;
- ui->ui_addr.sin_port = atoi(what);
- ui->ui_name = newstring(user);
- ui->ui_prog = pi;
- ui->ui_next = 0;
- if(u2 = qi->qi_head) {
- while(u2->ui_next)
- u2 = u2->ui_next;
- u2->ui_next = ui;
- }
- else
- qi->qi_head = ui;
- }
-
- mshowqueue(s, host, sin, local)
- register int s;
- register char *host;
- register struct sockaddr_in *sin;
- register int local;
- {
- register int i;
- register struct queueinfo *qi;
- register struct userinfo *ui;
- register struct hostinfo *hi;
- char buf[BUFSIZ];
-
- alarm(0);
- if(fork())
- return;
- for(i = 0; i < 3; i++)
- dup2(s, i);
- if(!getstr(s, buf))
- exit(1);
- if(s > 2)
- close(s);
- if(!strcmp(buf, "test")) {
- printf("Debugging information:\n");
- printf("Strays: %d, Dropouts: %d, Upstarts: %d\n",
- strays, dropouts, upstarts);
- printf("Deadmans: %d\n", deadmans);
- printf("Enqueues: %d, Dequeues: %d, Showqueues: %d\n",
- enqueues, dequeues, showqueues);
- printf("Host\t\tAddr\t\tEquiv\tLoad\tDead\tQueued\n");
- for(hi = hostinfo; hi; hi = hi->hi_next)
- printf("%-16s%s\t%d\t%d\t%d\t%d\n",
- hi->hi_name, inet_ntoa(hi->hi_addr.sin_addr),
- hi->hi_equiv, hi->hi_load,
- hi->hi_dead, hi->hi_queued);
- printf("\n");
- }
- printf("Queue: %s\n", buf);
- printf("Pid\t\tState\tUser\tHost\tCommand\n");
- fflush(stdout);
- if(!(qi = qibyname(buf)))
- exit(1);
- for(i = 0; i < qi->qi_hcnt; i++)
- for(ui = qi->qi_heads[i]; ui; ui = ui->ui_next) {
- printf("%-16ld", ui->ui_unid);
- printf("RUN\t");
- printf("%s\t", ui->ui_name);
- if(hi = hibyaddr(&ui->ui_addr))
- printf("%s\t", hi->hi_name);
- else
- printf("%s\t", inet_ntoa(ui->ui_addr.sin_addr.s_addr));
- printf("%s\n", ui->ui_prog->pi_name);
- }
- for(ui = qi->qi_head; ui; ui = ui->ui_next) {
- printf("%-16ld", ui->ui_unid);
- printf("WAIT\t");
- printf("%s\t", ui->ui_name);
- if(hi = hibyaddr(&ui->ui_addr))
- printf("%s\t", hi->hi_name);
- else
- printf("%s\t", inet_ntoa(ui->ui_addr.sin_addr.s_addr));
- printf("%s\n", ui->ui_prog->pi_name);
- }
- fflush(stdout);
- exit(0);
- }
-
- mdequeue(s, host, sin, local)
- register int s;
- register char *host;
- register struct sockaddr_in *sin;
- register int local;
- {
- char what[BUFSIZ], prog[BUFSIZ], user[BUFSIZ], buf[BUFSIZ];
- long unid;
- register struct proginfo *pi;
- register struct queueinfo *qi;
- register struct userinfo *ui, *pu;
- register int i;
-
- if(!getstr(s, user) || !getstr(s, prog) || !getstr(s, what))
- return;
- if(!(pi = pibyname(prog)))
- return;
- qi = pi->pi_queue;
- if(strcmp(what, "all"))
- unid = atol(what);
- else
- unid = -1;
- alarm(DEADMAN);
- for(i = 0; i < qi->qi_hcnt; i++)
- top: for(pu = 0, ui = qi->qi_heads[i]; ui; pu = ui, ui = ui->ui_next)
- if(ui->ui_unid == unid ||
- (!unid && !strcmp(ui->ui_name, what)) ||
- unid == -1) {
- if(strcmp(ui->ui_name, user) &&
- strcmp(user, "root")) {
- /*sprintf(buf, "Not owner (%s, %d)\n",
- ui->ui_name, ui->ui_unid);
- write(s, buf, strlen(buf));*/
- continue;
- }
- alarm(0);
- if(pu)
- pu->ui_next = ui->ui_next;
- else
- qi->qi_heads[i] = ui->ui_next;
- free(ui->ui_name);
- free(ui);
- alarm(DEADMAN);
- /*sprintf(buf, "Killed %d of %s for %s\n",
- ui->ui_unid, ui->ui_name, user);
- write(s, buf, strlen(buf));*/
- goto top;
- }
- alarm(DEADMAN);
- top2: for(pu = 0, ui = qi->qi_head; ui; pu = ui, ui = ui->ui_next)
- if(ui->ui_unid == unid ||
- (!unid && !strcmp(ui->ui_name, what)) || unid == -1) {
- if(strcmp(ui->ui_name, user) &&
- strcmp(user, "root")) {
- sprintf(buf, "Not owner (%s, %d)\n",
- ui->ui_name, ui->ui_unid);
- write(s, buf, strlen(buf));
- continue;
- }
- alarm(0);
- if(pu)
- pu->ui_next = ui->ui_next;
- else
- qi->qi_head = ui->ui_next;
- *buf = 2;
- sendto(u, buf, 1, 0, &ui->ui_addr, sizeof(ui->ui_addr));
- free(ui->ui_name);
- free(ui);
- alarm(DEADMAN);
- sprintf(buf, "Killed %d of %s for %s\n",
- ui->ui_unid, ui->ui_name, user);
- write(s, buf, strlen(buf));
- goto top2;
- }
- }
-