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