chiark / gitweb /
use libinn logging where applicable
[inn-innduct.git] / lib / getmodaddr.c
1 /*  $Id: getmodaddr.c 6155 2003-01-19 19:58:25Z rra $
2 **
3 */
4
5 #include "config.h"
6 #include "clibrary.h"
7 #include <errno.h>
8
9 #include "inn/innconf.h"
10 #include "libinn.h"
11 #include "nntp.h"
12 #include "paths.h"
13
14
15 static char     *GMApathname = NULL;
16 static FILE     *GMAfp = NULL;
17
18
19 /*
20 **  Close the file opened by GMAlistopen.
21 */
22 static void
23 GMAclose(void)
24 {
25     if (GMAfp) {
26         fclose(GMAfp);
27         GMAfp = NULL;
28     }
29     if (GMApathname != NULL) {
30         unlink(GMApathname);
31         free(GMApathname);
32         GMApathname = NULL;
33     }
34 }
35
36 /*
37 **  Internal library routine.
38 */
39 static FILE *
40 GMA_listopen(int fd, FILE *FromServer, FILE *ToServer, const char *request)
41 {
42     char        buff[BUFSIZ];
43     char        *p;
44     int         oerrno;
45     FILE        *F;
46
47     F = fdopen(fd, "r+");
48     if (F == NULL)
49         return NULL;
50
51     /* Send a LIST command to and capture the output. */
52     if (request == NULL)
53         fprintf(ToServer, "list moderators\r\n");
54     else
55         fprintf(ToServer, "list %s\r\n", request);
56     fflush(ToServer);
57
58     /* Get the server's reply to our command. */
59     if (fgets(buff, sizeof buff, FromServer) == NULL
60      || strncmp(buff, NNTP_LIST_FOLLOWS, strlen(NNTP_LIST_FOLLOWS)) != 0) {
61         oerrno = errno;
62         fclose(F);
63         GMAclose();
64         errno = oerrno;
65         return NULL;
66     }
67
68     /* Slurp up the rest of the response. */
69     while (fgets(buff, sizeof buff, FromServer) != NULL) {
70         if ((p = strchr(buff, '\r')) != NULL)
71             *p = '\0';
72         if ((p = strchr(buff, '\n')) != NULL)
73             *p = '\0';
74         if (buff[0] == '.' && buff[1] == '\0') {
75             if (ferror(F) || fflush(F) == EOF || fseeko(F, 0, SEEK_SET) != 0)
76                 break;
77             return F;
78         }
79         fprintf(F, "%s\n", buff);
80     }
81
82     /* Ran out of input before finding the terminator; quit. */
83     oerrno = errno;
84     fclose(F);
85     GMAclose();
86     errno = oerrno;
87     return NULL;
88 }
89
90 /*
91 **  Read the moderators file, looking for a moderator.
92 */
93 char *
94 GetModeratorAddress(FILE *FromServer, FILE *ToServer, char *group,
95                     char *moderatormailer)
96 {
97     static char         address[SMBUF];
98     char                *p;
99     char                *save;
100     char                *path;
101     char                buff[BUFSIZ];
102     char                name[SMBUF];
103     int                 fd;
104
105     strlcpy(name, group, sizeof(name));
106     address[0] = '\0';
107
108     if (FromServer==NULL || ToServer==NULL){
109
110         /*
111          *  This should be part of nnrpd or the like running on the server.
112          *  Open the server copy of the moderators file.
113          */
114         path = concatpath(innconf->pathetc, _PATH_MODERATORS);
115         GMAfp = fopen(path, "r");
116         free(path);
117     }else{
118         /*
119          *  Get a local copy of the moderators file from the server.
120          */
121         GMApathname = concatpath(innconf->pathtmp, _PATH_TEMPMODERATORS);
122         fd = mkstemp(GMApathname);
123         if (fd >= 0)
124             GMAfp = GMA_listopen(fd, FromServer, ToServer, "moderators");
125         else
126             GMAfp = NULL;
127
128         /* Fallback to the local copy if the server doesn't have it */
129         if (GMAfp == NULL) {
130             path = concatpath(innconf->pathetc, _PATH_MODERATORS);
131             GMAfp = fopen(path, "r");
132             free(path);
133         }
134     }
135
136     if (GMAfp != NULL) {
137         while (fgets(buff, sizeof buff, GMAfp) != NULL) {
138             /* Skip blank and comment lines. */
139             if ((p = strchr(buff, '\n')) != NULL)
140                 *p = '\0';
141             if (buff[0] == '\0' || buff[0] == '#')
142                 continue;
143
144             /* Snip off the first word. */
145             if ((p = strchr(buff, ':')) == NULL)
146                 /* Malformed line... */
147                 continue;
148             *p++ = '\0';
149
150             /* If it pattern-matches the newsgroup, the second field is a
151              * format for mailing, with periods changed to dashes. */
152             if (uwildmat(name, buff)) {
153                 for (save = p; ISWHITE(*save); save++)
154                     continue;
155                 for (p = name; *p; p++)
156                     if (*p == '.')
157                         *p = '-';
158                 snprintf(address, sizeof(address), save, name);
159                 break;
160             }
161         }
162
163          GMAclose();
164         if (address[0])
165             return address;
166     }
167
168     /* If we don't have an address, see if the config file has a default. */
169     if ((save = moderatormailer) == NULL)
170         return NULL;
171
172     for (p = name; *p; p++)
173         if (*p == '.')
174             *p = '-';
175     snprintf(address, sizeof(address), save, name);
176     return address;
177 }