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