/* external function definitions */ void lstnfree(struct lstn * p) { if (p != (struct lstn *) (0)) { p->retry = LSTN_RETRY_NO; lstnclose(p); exbofree(p->retry_time); bfree(p->name); bfree((char *) p); } return; }
/* internal function definitions */ static void acpt(struct lstn * p) { static char fnc[] = "acpt"; int r_namelen = p->r_namelen; struct sockaddr *r_name; int fd; int l_namelen = p->l_namelen; struct sockaddr *l_name; r_name = (struct sockaddr *) balloc(r_namelen); if ((fd = accept(p->fd, r_name, &r_namelen)) < 0) { if ((errno == EWOULDBLOCK) || (errno == EINTR)) { /* nothing to report */ } else if ((errno == EMFILE) || (errno == ENFILE) || (errno == ENXIO) || (errno == EIO)) { Warn("%t %s(%s): warn: accept(%d): %m\n", fnc, p->name, p->fd); } else { Warn("%t %s(%s): error: accept(%d): %m\n", fnc, p->name, p->fd); lstnclose(p); } bfree((char *) r_name); return; } l_name = (struct sockaddr *) balloc(l_namelen); if (getsockname(fd, l_name, &l_namelen) < 0) { Warn("%t %s(%s): error: getsockname(%d): %m\n", fnc, p->name, fd); doclose(fd); bfree((char *) l_name); bfree((char *) r_name); return; } p->acpttod = todsec(); (p->acptcount)++; r_name = (struct sockaddr *) brealloc((char *) r_name, r_namelen); l_name = (struct sockaddr *) brealloc((char *) l_name, l_namelen); (*(p->acptfunc)) (p, fd, r_name, r_namelen, l_name, l_namelen); return; }
/* external function definitions */ void lstnopen(struct lstn * p) { static char fnc[] = "lstnopen"; if ((p != (struct lstn *) (0)) || (p->fd >= 0)) { int fd; int toggle; p->retry_tp = (struct timer *) (0); if ((fd = socket(p->domain, p->type, p->protocol)) < 0) { Warn("%t %s(%s): error: socket(): %m\n", fnc, p->name); lstnclose(p); return; } p->opentod = todsec(); (p->opencount)++; fdsfresh(fd); p->fd = fd; toggle = 1; if (ioctl(fd, FIONBIO, &toggle) < 0) { Warn("%t %s(%s): warning: ioctl(%d, FIONBIO): %m\n", fnc, p->name, fd); } toggle = 1; if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *) (&toggle), sizeof(toggle)) < 0) { Warn("%t %s(%s): warning: setsockopt(%d, REUSEADDR): %m\n", fnc, p->name, fd); } if ((*(p->l_namefunc)) (p) != 0) { lstnclose(p); return; } if (p->l_name == (struct sockaddr *) (0)) { p->l_name = (struct sockaddr *) balloc(p->l_namelen); bzero((char *) (p->l_name), p->l_namelen); } else { if (bind(fd, p->l_name, p->l_namelen) < 0) { Warn("%t %s(%s): error: bind(%d): %m\n", fnc, p->name, fd); lstnclose(p); return; } } if (listen(fd, 5) < 0) { Warn("%t %s(%s): error: listen(%d): %m\n", fnc, p->name, fd); lstnclose(p); return; } if (getsockname(fd, p->l_name, &(p->l_namelen)) < 0) { Warn("%t %s(%s): error: getsockname(%d): %m\n", fnc, p->name, fd); lstnclose(p); return; } if ((*(p->l_regfunc)) (p) != 0) { lstnclose(p); return; } p->lstntod = todsec(); (p->lstncount)++; p->acptchan = chanopen(p->name, fd, p->pri, CHAN_R, (void (*)(void *))acpt, (void *) p); chanenbl(p->acptchan); exboreset(p->retry_time); } return; }