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.
This commit is contained in:
parent
8cb7211a42
commit
7f0728b7f4
1 changed files with 31 additions and 52 deletions
|
@ -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
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue