1 /*****************************************************************************/
2 /*                                                                           */
3 /*                 (C) Copyright 1995-1996  Alberto Pasquale                 */
4 /*                 Portions (C) Copyright 1999 Per Lundberg                  */
5 /*                                                                           */
6 /*                   A L L   R I G H T S   R E S E R V E D                   */
7 /*                                                                           */
8 /*****************************************************************************/
9 /*                                                                           */
10 /*   How to contact the author:  Alberto Pasquale of 2:332/504@fidonet       */
11 /*                               Viale Verdi 106                             */
12 /*                               41100 Modena                                */
13 /*                               Italy                                       */
14 /*                                                                           */
15 /*****************************************************************************/
16 
17 #include "bbsgenlb.hpp"
18 #include "apgenlib.hpp"
19 #include <string.h>
20 
21 #define TAGSIZE     256
22 #define SQLNSIZE    1024
23 
24 // returns 0 on "EchoArea or NetArea"
25 // returns -1 on Address not found before "Echo/NetArea"
26 // returns 1 on "not Echo/NetArea"
27 // returns 2 on Include: path contains the include filename.
28 
29 
parsesq(char * linebuf,char * echotag,char * path,word * type,ADR * adr)30 int SqTag2Path::parsesq (char *linebuf, char *echotag, char *path, word *type,
31                          ADR *adr)
32 {
33     const char *c;
34     uint toklen;
35 
36     c = linebuf;
37     c += strspn (c, " \t");     /* skip blank */
38     toklen = strcspn (c, " \t"); /* token length */
39 
40     *type = 0;
41 
42     switch (toklen) {
43         case 8:
44             if (strncasecmp (c, "EchoArea", toklen) == 0) {   /* is echo */
45                 *type |= MSGTYPE_ECHO;
46                 break;
47             }
48             return 1;
49         case 7:
50             if (strncasecmp (c, "NetArea", toklen) == 0) {  /* is netmail */
51                 break;
52             }
53             if (strncasecmp (c, "Include", toklen) == 0) { // Include
54                 c += toklen;
55                 GetName (c, path, PATH_MAX);
56                 return 2;
57             }
58             if (!primary && (strncasecmp (c, "Address", toklen) == 0)) {
59                 c += toklen;
60                 primary = new ADR;
61                 strto4Dadr (c, primary);
62             }
63             return 1;
64         default:
65             return 1;
66     }
67 
68     if (!primary)       // Address must have already been found
69         return -1;
70 
71     c += toklen;    /* skip token */
72 
73     c += strspn (c, " \t"); /* skip blank */
74     toklen = strcspn (c, " \t"); /* Tag length */
75     if (toklen >= TAGSIZE)
76         return 1;       // Tag too long
77     strncpy (echotag, c, toklen);
78     echotag[toklen] = '\0';    /* echotag copied */
79     c += toklen;         /* skip echotag */
80 
81 
82     c += strspn (c, " \t"); /* skip blank */
83     toklen = strcspn (c, " \t"); /* path length */
84     if (toklen >= PATH_MAX)    // Path too long
85         return 1;
86     strncpy (path, c, toklen);
87     path[toklen] = '\0';    /* path copied */
88     c += toklen;         /* skip path */
89 
90     *adr  = *primary;
91 
92     c += strspn (c, " \t"); /* skip blank */
93     while (*c == '-') {
94         c++;
95         switch (*c) {
96             case '$': // Squish Format
97                 *type |= MSGTYPE_SQUISH;
98                 break;
99             case 'p':
100             case 'P':
101                 c ++;
102                 strto4Dadr (c, adr);
103                 break;
104         }
105         c += strcspn (c, " \t"); /* skip flag */
106         c += strspn (c, " \t");  /* skip blank */
107     }
108 
109     if (!(*type & MSGTYPE_SQUISH))
110         *type |= MSGTYPE_SDM;
111 
112     return 0;
113 }
114 
115 
SqTag2Path()116 SqTag2Path::SqTag2Path ()
117 {
118     sqhead = NULL;
119     sqtail = &sqhead;
120     primary = NULL;
121 }
122 
123 
~SqTag2Path()124 SqTag2Path::~SqTag2Path ()
125 {
126     if (primary)
127         delete primary;
128 
129     _SqTagSearch *sq = sqhead,
130                  *next;
131     while (sq) {
132         next = sq->next;
133         delete sq;
134         sq = next;
135     }
136 }
137 
138 
AddTag(const char * Tag,char ** Path,word * Type,ADR * adr,char ** origin,dword * attr)139 void SqTag2Path::AddTag (const char *Tag, char **Path, word *Type, ADR *adr,
140                          char **origin, dword *attr)
141 {
142     _SqTagSearch *sqt = *sqtail = new _SqTagSearch;
143     sqt->Tag    = Tag;
144     sqt->Path   = Path;
145     sqt->Type   = Type;
146     sqt->adr    = adr;
147     sqt->origin = origin;
148     sqt->attr   = attr;
149     sqt->next   = NULL;
150     sqtail = &sqt->next;
151 }
152 
153 
ParseSquishCfg(char * SquishCfg,CharPVoid sqtnf)154 int SqTag2Path::ParseSquishCfg (char *SquishCfg, CharPVoid sqtnf)
155 {
156     FILE *sqf = fopen (SquishCfg, "rt");
157     if (!sqf)
158         return -1;
159     setvbuf (sqf, NULL, _IOFBF, 8192);
160     char *linebuf = new char[SQLNSIZE],
161          *echotag = new char[TAGSIZE],
162          *path    = new char[PATH_MAX];
163     word type;
164     ADR  adr;
165     BOOL Done = FALSE;
166     int error = 0;
167     while (_fgets (linebuf, SQLNSIZE, sqf)) {
168         int pret = parsesq (linebuf, echotag, path, &type, &adr);
169         if (pret < 0) {
170             error = -2;
171             break;
172         }
173 
174         if (pret == 2) {     // Include
175             error = ParseSquishCfg (path);
176             if (error)
177                 break;
178             continue;
179         }
180 
181         if (pret == 0) {
182             _SqTagSearch *sq = sqhead;
183             Done = TRUE;
184             while (sq) {
185                 if (*sq->Path == NULL) {
186                     if (stricmp (sq->Tag, echotag) == 0) {
187                         *sq->Path = newcpy (path);
188                         *sq->Type = type;
189                         if (sq->adr)
190                             *sq->adr = adr;
191                         if (!(type & MSGTYPE_ECHO)) {
192                             if (sq->origin)
193                                 *sq->origin = NULL;
194                             if (sq->attr)
195                                 *sq->attr = MSGPRIVATE;
196                         }
197                     } else
198                         Done = FALSE;
199                 }
200                 sq = sq->next;
201             }
202             if (Done)
203                 break;
204         }
205     }
206     delete[] path;
207     delete[] echotag;
208     delete[] linebuf;
209     fclose (sqf);
210 
211     if (error)
212         return error;
213 
214     if (sqtnf)
215     if (!Done) {        // report tags not found
216         _SqTagSearch *sq = sqhead;
217         while (sq) {
218             if (*sq->Path == NULL)
219                 sqtnf (sq->Tag);
220             sq = sq->next;
221         }
222     }
223 
224     return 0;
225 }
226 
227 
228 
229 
230 
231