1 /*:ts=8*/
2 /*****************************************************************************
3 * FIDOGATE --- Gateway UNIX Mail/News <-> FIDO NetMail/EchoMail
4 *
5 *
6 * Read area uplinks list from file. The format is as follows:
7 * ROBOT_TYPE AREAS Z:N/F.P ROBOT_NAME PASSWORD
8 *
9 *****************************************************************************
10 * Copyright (C) 2000
11 *
12 * Oleg Derevenetz FIDO: 2:5025/3.4
13 *
14 * This file is part of FIDOGATE.
15 *
16 * FIDOGATE is free software; you can redistribute it and/or modify it
17 * under the terms of the GNU General Public License as published by the
18 * Free Software Foundation; either version 2, or (at your option) any
19 * later version.
20 *
21 * FIDOGATE is distributed in the hope that it will be useful, but
22 * WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
24 * General Public License for more details.
25 *
26 * You should have received a copy of the GNU General Public License
27 * along with FIDOGATE; see the file COPYING. If not, write to the Free
28 * Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
29 *****************************************************************************/
30
31 #include "fidogate.h"
32
33 /*
34 * Local prototypes
35 */
36 static AreaUplink *uplinks_parse_line(char *);
37 static int uplinks_do_file(char *);
38 void uplinks_lookup_save(int, char *, const AreaUplink *);
39 int is_wildcard(char *);
40 #ifdef DEBUG
41 static int anodeeq(Node *, Node *);
42 static int uplinks_check_dups(int, Node *);
43 #endif /* DEBUG */
44
45 /*
46 * Uplinks list
47 */
48 static AreaUplink *uplinks_list = NULL;
49 static AreaUplink *uplinks_last = NULL;
50 static AreaUplink *upll_ap = NULL;
51 static AreaUplink *upll_ap_last = NULL;
52
53 /*
54 * Read list of uplinks from CONFIGDIR/UPLINKS file.
55 *
56 * Format:
57 * ROBOT_TYPE AREAS NODE ROBOT_NAME
58 */
uplinks_parse_line(char * buf)59 static AreaUplink *uplinks_parse_line(char *buf)
60 {
61 AreaUplink *p;
62 char *t, *a, *n, *f, *w;
63 Node uplink;
64 char *opt;
65
66 t = xstrtok(buf, " \t"); /* Robot type (af-AreaFix, ff-FileFix) */
67 a = xstrtok(NULL, " \t"); /* Areas */
68 n = xstrtok(NULL, " \t"); /* Uplink */
69 f = xstrtok(NULL, " \t"); /* Robot name */
70 w = xstrtok(NULL, " \t"); /* Password */
71 opt = xstrtok(NULL, ""); /* Options */
72 if (t == NULL || a == NULL)
73 return NULL;
74 if (strieq(t, "include")) {
75 uplinks_do_file(a);
76 return NULL;
77 }
78 if (n == NULL || f == NULL || w == NULL)
79 return NULL;
80
81 if (asc_to_node(n, &uplink, FALSE) == ERROR) {
82 fglog("uplinks: illegal FTN address %s", n);
83 return NULL;
84 }
85
86 #ifdef DEBUG
87 if (uplinks_check_dups((!strcmp(t, "af")) ? TRUE : FALSE, &uplink)) {
88 fglog("uplinks: duplicate uplink entry %s", n);
89 return NULL;
90 }
91 #endif /* DEBUG */
92 p = (AreaUplink *) xmalloc(sizeof(AreaUplink));
93 p->next = NULL;
94 p->areafix = (!strcmp(t, "af")) ? TRUE : FALSE;
95 p->areas = strsave(a);
96 p->uplink = uplink;
97 p->robotname = strsave(f);
98 p->password = strsave(w);
99 p->options = strsave(opt);
100
101 debug(15, "uplinks: %s %s %s %s %s %s", p->areafix ? "af" : "ff",
102 p->areas, znfp1(&p->uplink), p->robotname, p->password, p->options);
103
104 return p;
105 }
106
uplinks_do_file(char * name)107 static int uplinks_do_file(char *name)
108 {
109 FILE *fp;
110 AreaUplink *p;
111
112 debug(14, "Reading uplinks file %s", name);
113
114 fp = fopen_expand_name(name, R_MODE_T, FALSE);
115 if (fp == NULL)
116 return ERROR;
117
118 while (cf_getline(buffer, BUFFERSIZE, fp)) {
119 p = uplinks_parse_line(buffer);
120 if (p == NULL)
121 continue;
122
123 /*
124 * Put into linked list
125 */
126 if (uplinks_list)
127 uplinks_last->next = p;
128 else
129 uplinks_list = p;
130 uplinks_last = p;
131 }
132
133 fclose(fp);
134
135 return OK;
136 }
137
138 #ifdef DEBUG
uplinks_check_dups(int areafix,Node * uplink)139 static int uplinks_check_dups(int areafix, Node * uplink)
140 {
141 AreaUplink *a;
142
143 for (a = uplinks_list; a; a = a->next) {
144 if ((a->areafix == areafix) && anodeeq(uplink, &a->uplink))
145 return TRUE;
146 }
147
148 return FALSE;
149 }
150 #endif /* DEBUG */
151
uplinks_init(void)152 void uplinks_init(void)
153 {
154 uplinks_do_file(cf_p_uplinks());
155 }
156
uplinks_lookup_save(int afix,char * area,const AreaUplink * a)157 void uplinks_lookup_save(int afix, char *area, const AreaUplink * a)
158 {
159 AreaUplink *list;
160
161 list = (AreaUplink *) xmalloc(sizeof(AreaUplink));
162 list->next = NULL;
163 list->areafix = afix;
164 list->areas = strsave(area);
165 list->uplink = a->uplink;
166 list->robotname = a->robotname;
167 list->password = a->password;
168 list->options = a->options;
169
170 if (!upll_ap)
171 upll_ap = list;
172 else
173 upll_ap_last->next = list;
174 upll_ap_last = list;
175 }
176
uplinks_lookup_free(void)177 void uplinks_lookup_free(void)
178 {
179 AreaUplink *p, *s;
180
181 for (p = upll_ap; p; p = s) {
182 s = p->next;
183 xfree(p->areas);
184 p->next = NULL;
185 xfree(p);
186 }
187 upll_ap = NULL;
188 }
189
190 /*
191 * Lookup uplink for area
192 *
193 * Parameters:
194 * areafix --- robot type (areafix or filefix)
195 * area --- lookup by area name
196 *
197 */
uplinks_lookup(int areafix,char * area)198 AreaUplink *uplinks_lookup(int areafix, char *area)
199 {
200 const AreaUplink *a;
201 char *t, *n, *f;
202 int iswc;
203 FILE *fp1;
204
205 iswc = is_wildcard(area);
206
207 for (a = uplinks_list; a; a = a->next) {
208 if (a->areafix != areafix)
209 continue;
210 t = strsave(a->areas);
211 for (n = strtok(t, ","); n; n = strtok(NULL, ",")) {
212 if (*n == '/' || *n == '%' || *n == '.') {
213 if ((fp1 = fopen_expand_name(n, R_MODE_T, FALSE))) {
214 while (cf_getline(buffer, BUFFERSIZE, fp1)) {
215 if (!(f = xstrtok(buffer, " \t")))
216 continue;
217
218 if (*f == '!') {
219 if (wildmatch(area, (char *)(&f[1]), TRUE + iswc)
220 && !iswc)
221 break;
222 } else {
223 if (wildmatch(area, f, TRUE + iswc)) {
224 uplinks_lookup_save(areafix, f, a);
225 if (!iswc) {
226 fclose(fp1);
227 return upll_ap;
228 }
229 }
230 }
231 }
232 fclose(fp1);
233 }
234 } else {
235 if (*n == '!') {
236 if (wildmatch(area, (char *)(&n[1]), TRUE + iswc) && !iswc)
237 break;
238 } else {
239 if (wildmatch(area, n, TRUE + iswc)) {
240 uplinks_lookup_save(areafix, n, a);
241 if (!iswc)
242 return upll_ap;
243 }
244 }
245 }
246 }
247 xfree(t);
248 }
249
250 return upll_ap;
251 }
252
uplinks_line_get(int areafix,Node * uplink)253 AreaUplink *uplinks_line_get(int areafix, Node * uplink)
254 {
255 AreaUplink *p1;
256
257 for (p1 = uplinks_list; p1; p1 = p1->next) {
258 if (p1->areafix != areafix)
259 continue;
260 if (node_eq(&p1->uplink, uplink))
261 return p1;
262 }
263 return NULL;
264 }
265
uplinks_first(void)266 AreaUplink *uplinks_first(void)
267 {
268 return uplinks_list;
269 }
270
271 /*
272 * anodeeq() --- compare node adresses
273 *
274 * Compare node FTN addresses.
275 *
276 */
277 #ifdef DEBUG
anodeeq(Node * a,Node * b)278 static int anodeeq(Node * a, Node * b)
279 {
280 return a->zone == b->zone && a->net == b->net && a->node == b->node;
281 }
282 #endif
283
uplinks_free(void)284 void uplinks_free(void)
285 {
286 AreaUplink *p, *s;
287
288 for (p = uplinks_list; p; p = s) {
289 s = p->next;
290 xfree(p->areas);
291 xfree(p->robotname);
292 xfree(p->password);
293 xfree(p->options);
294 p->next = NULL;
295 xfree(p);
296 }
297 }
298