1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119
|
/* $Id: lc.c 6155 2003-01-19 19:58:25Z rra $
**
** Routines for the local connect channel. Create a Unix-domain stream
** socket that processes on the local server connect to. Once the
** connection is set up, we speak NNTP. The connect channel is used only
** by rnews to feed in articles from the UUCP sites.
*/
#include "config.h"
#include "clibrary.h"
#include "inn/innconf.h"
#include "innd.h"
#if HAVE_UNIX_DOMAIN_SOCKETS
# include <sys/un.h>
static char *LCpath = NULL;
static CHANNEL *LCchan;
/*
** Read function. Accept the connection and create an NNTP channel.
*/
static void
LCreader(CHANNEL *cp)
{
int fd;
CHANNEL *new;
if (cp != LCchan) {
syslog(L_ERROR, "%s internal LCreader wrong channel 0x%p not 0x%p",
LogName, (void *)cp, (void *)LCchan);
return;
}
if ((fd = accept(cp->fd, NULL, NULL)) < 0) {
syslog(L_ERROR, "%s cant accept CCreader %m", LogName);
return;
}
if ((new = NCcreate(fd, false, true)) != NULL) {
memset( &new->Address, 0, sizeof( new->Address ) );
syslog(L_NOTICE, "%s connected %d", "localhost", new->fd);
NCwritereply(new, (char *)NCgreeting);
}
}
/*
** Write-done function. Shouldn't happen.
*/
static void
LCwritedone(CHANNEL *unused)
{
unused = unused; /* ARGSUSED */
syslog(L_ERROR, "%s internal LCwritedone", LogName);
}
#endif /* HAVE_UNIX_DOMAIN_SOCKETS */
/*
** Create the channel.
*/
void
LCsetup(void)
{
#if defined(HAVE_UNIX_DOMAIN_SOCKETS)
int i;
struct sockaddr_un server;
if (LCpath == NULL)
LCpath = concatpath(innconf->pathrun, _PATH_NNTPCONNECT);
/* Remove old detritus. */
if (unlink(LCpath) < 0 && errno != ENOENT) {
syslog(L_FATAL, "%s cant unlink %s %m", LogName, LCpath);
exit(1);
}
/* Create a socket and name it. */
if ((i = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
syslog(L_FATAL, "%s cant socket %s %m", LogName, LCpath);
exit(1);
}
memset(&server, 0, sizeof server);
server.sun_family = AF_UNIX;
strlcpy(server.sun_path, LCpath, sizeof(server.sun_path));
if (bind(i, (struct sockaddr *) &server, SUN_LEN(&server)) < 0) {
syslog(L_FATAL, "%s cant bind %s %m", LogName, LCpath);
exit(1);
}
/* Set it up to wait for connections. */
if (listen(i, MAXLISTEN) < 0) {
syslog(L_FATAL, "%s cant listen %s %m", LogName, LCpath);
exit(1);
}
LCchan = CHANcreate(i, CTlocalconn, CSwaiting, LCreader, LCwritedone);
syslog(L_NOTICE, "%s lcsetup %s", LogName, CHANname(LCchan));
RCHANadd(LCchan);
#endif /* defined(HAVE_UNIX_DOMAIN_SOCKETS) */
}
/*
** Cleanly shut down the channel.
*/
void
LCclose(void)
{
#if defined(HAVE_UNIX_DOMAIN_SOCKETS)
CHANclose(LCchan, CHANname(LCchan));
LCchan = NULL;
if (unlink(LCpath) < 0)
syslog(L_ERROR, "%s cant unlink %s %m", LogName, LCpath);
free(LCpath);
#endif /* defined(HAVE_UNIX_DOMAIN_SOCKETS) */
}
|