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
|
struct Announce
|
||||||
{
|
{
|
||||||
Announce *next;
|
Announce *next;
|
||||||
char *a;
|
|
||||||
int announced;
|
int announced;
|
||||||
int whined;
|
char whined;
|
||||||
|
char mark;
|
||||||
|
char a[];
|
||||||
};
|
};
|
||||||
|
|
||||||
int readstr(char*, char*, char*, int);
|
int readstr(char*, char*, char*, int);
|
||||||
|
@ -292,66 +293,33 @@ addannounce(char *str)
|
||||||
/* look for duplicate */
|
/* look for duplicate */
|
||||||
l = &announcements;
|
l = &announcements;
|
||||||
for(a = announcements; a; a = a->next){
|
for(a = announcements; a; a = a->next){
|
||||||
if(strcmp(str, a->a) == 0)
|
if(strcmp(str, a->a) == 0){
|
||||||
|
a->mark = 0;
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
l = &a->next;
|
l = &a->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* accept it */
|
/* accept it */
|
||||||
a = mallocz(sizeof(*a) + strlen(str) + 1, 1);
|
a = mallocz(sizeof(*a) + strlen(str) + 1, 1);
|
||||||
if(a == 0)
|
if(a == nil)
|
||||||
return;
|
return;
|
||||||
a->a = ((char*)a)+sizeof(*a);
|
|
||||||
strcpy(a->a, str);
|
strcpy(a->a, str);
|
||||||
a->announced = 0;
|
|
||||||
*l = a;
|
*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
|
void
|
||||||
scandir(char *proto, char *protodir, char *dname)
|
scandir(char *proto, char *protodir, char *dname)
|
||||||
{
|
{
|
||||||
|
Announce *a, **l;
|
||||||
int fd, i, n, nlen;
|
int fd, i, n, nlen;
|
||||||
char *nm;
|
char *nm;
|
||||||
char ds[128];
|
char ds[128];
|
||||||
Dir *db;
|
Dir *db;
|
||||||
|
|
||||||
|
for(a = announcements; a != nil; a = a->next)
|
||||||
|
a->mark = 1;
|
||||||
|
|
||||||
fd = open(dname, OREAD);
|
fd = open(dname, OREAD);
|
||||||
if(fd < 0)
|
if(fd < 0)
|
||||||
return;
|
return;
|
||||||
|
@ -360,20 +328,31 @@ scandir(char *proto, char *protodir, char *dname)
|
||||||
while((n=dirread(fd, &db)) > 0){
|
while((n=dirread(fd, &db)) > 0){
|
||||||
for(i=0; i<n; i++){
|
for(i=0; i<n; i++){
|
||||||
nm = db[i].name;
|
nm = db[i].name;
|
||||||
if(!(db[i].qid.type&QTDIR) &&
|
if(db[i].qid.type&QTDIR)
|
||||||
strncmp(nm, proto, nlen) == 0) {
|
continue;
|
||||||
snprint(ds, sizeof ds, "%s!*!%s", protodir,
|
if(db[i].length <= 0)
|
||||||
nm + nlen);
|
continue;
|
||||||
if (ignore(dname, nm))
|
if(strncmp(nm, proto, nlen) != 0)
|
||||||
delannounce(ds);
|
continue;
|
||||||
else
|
snprint(ds, sizeof ds, "%s!*!%s", protodir, nm + nlen);
|
||||||
addannounce(ds);
|
addannounce(ds);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
free(db);
|
free(db);
|
||||||
}
|
}
|
||||||
|
|
||||||
close(fd);
|
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
|
void
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue