diff options
author | cinap_lenrek <cinap_lenrek@felloff.net> | 2015-04-23 03:17:25 +0200 |
---|---|---|
committer | cinap_lenrek <cinap_lenrek@felloff.net> | 2015-04-23 03:17:25 +0200 |
commit | 7f0728b7f446a77b8606ed3dffd48deb48697384 (patch) | |
tree | eb251760b538b06017669e625b81347befa6eae6 /sys/src/cmd/aux | |
parent | 8cb7211a42d8811302968dd75cd14e1fc47a289c (diff) |
aux/listen: removing service script sholud kill listener (thanks mischief)
mischief spotted that the only way for listeners to go away was
truncating (but not removing) a service script. this is wrong and
not as described in the manpage.
this change makes removing (or truncating) a listen script stop
the listener.
scandir() first marks all current announces, then reads the service
directory adding announces which will clear the marks for the ones
already there or add a new unmarked one. finally, we shoot down and
remove all still marked announces.
Diffstat (limited to 'sys/src/cmd/aux')
-rw-r--r-- | sys/src/cmd/aux/listen.c | 83 |
1 files changed, 31 insertions, 52 deletions
diff --git a/sys/src/cmd/aux/listen.c b/sys/src/cmd/aux/listen.c index 82580d9f5..5c5b51fcd 100644 --- a/sys/src/cmd/aux/listen.c +++ b/sys/src/cmd/aux/listen.c @@ -16,9 +16,10 @@ typedef struct Announce Announce; struct Announce { Announce *next; - char *a; int announced; - int whined; + char whined; + char mark; + char a[]; }; int readstr(char*, char*, char*, int); @@ -292,66 +293,33 @@ addannounce(char *str) /* look for duplicate */ l = &announcements; for(a = announcements; a; a = a->next){ - if(strcmp(str, a->a) == 0) + if(strcmp(str, a->a) == 0){ + a->mark = 0; return; + } l = &a->next; } /* accept it */ a = mallocz(sizeof(*a) + strlen(str) + 1, 1); - if(a == 0) + if(a == nil) return; - a->a = ((char*)a)+sizeof(*a); strcpy(a->a, str); - a->announced = 0; *l = a; } -/* - * delete a service for announcement list - */ -void -delannounce(char *str) -{ - Announce *a, **l; - - /* look for service */ - l = &announcements; - for(a = announcements; a; a = a->next){ - if(strcmp(str, a->a) == 0) - break; - l = &a->next; - } - if (a == nil) - return; - *l = a->next; /* drop from the list */ - if (a->announced > 0) - postnote(PNPROC, a->announced, "die"); - a->announced = 0; - free(a); -} - -static int -ignore(char *srvdir, char *name) -{ - int rv; - char *file = smprint("%s/%s", srvdir, name); - Dir *d = dirstat(file); - - rv = !d || d->length <= 0; /* ignore unless it's non-empty */ - free(d); - free(file); - return rv; -} - void scandir(char *proto, char *protodir, char *dname) { + Announce *a, **l; int fd, i, n, nlen; char *nm; char ds[128]; Dir *db; + for(a = announcements; a != nil; a = a->next) + a->mark = 1; + fd = open(dname, OREAD); if(fd < 0) return; @@ -360,20 +328,31 @@ scandir(char *proto, char *protodir, char *dname) while((n=dirread(fd, &db)) > 0){ for(i=0; i<n; i++){ nm = db[i].name; - if(!(db[i].qid.type&QTDIR) && - strncmp(nm, proto, nlen) == 0) { - snprint(ds, sizeof ds, "%s!*!%s", protodir, - nm + nlen); - if (ignore(dname, nm)) - delannounce(ds); - else - addannounce(ds); - } + if(db[i].qid.type&QTDIR) + continue; + if(db[i].length <= 0) + continue; + if(strncmp(nm, proto, nlen) != 0) + continue; + snprint(ds, sizeof ds, "%s!*!%s", protodir, nm + nlen); + addannounce(ds); } free(db); } close(fd); + + l = &announcements; + while((a = *l) != nil){ + if(a->mark){ + *l = a->next; + if (a->announced > 0) + postnote(PNPROC, a->announced, "die"); + free(a); + continue; + } + l = &a->next; + } } void |