1 /*****************************************************************************/
2 /* */
3 /* (C) Copyright 1994-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 "apgenlib.hpp"
18 #include <string.h>
19 #include <fcntl.h>
20 #include <sys/stat.h>
21 #include <errno.h>
22 #include <unistd.h>
23 #include <ctype.h>
24
newcpy(pcsz text)25 char *newcpy (pcsz text)
26 {
27 char *tmp = new char[strlen (text) + 1];
28 strcpy (tmp, text);
29 return tmp;
30 }
31
32
newncpy(pcsz text,size_t len)33 char *newncpy (pcsz text, size_t len)
34 {
35 char *tmp = new char[len + 1];
36 strncpy (tmp, text, len);
37 tmp[len] = '\0';
38 return tmp;
39 }
40
41
strzcpy(char * dest,const char * src,size_t maxlen)42 char *strzcpy (char *dest, const char *src, size_t maxlen)
43 {
44 *dest = '\0';
45 return strncat (dest, src, maxlen-1);
46 }
47
48
fl_stpcpy(char * dest,const char * src)49 char *fl_stpcpy (char *dest, const char *src)
50 {
51 while (*src)
52 *(dest++) = *(src++);
53 *dest = '\0'; // set terminating null
54 return dest;
55 }
56
stpzcpy(char * dest,const char * src,size_t maxlen)57 char *stpzcpy (char *dest, const char *src, size_t maxlen)
58 {
59 size_t count = 0;
60 maxlen --;
61
62 while (*src && (count < maxlen)) {
63 *(dest++) = *(src++);
64 count ++;
65 }
66 *dest = '\0'; // set terminating null
67 return dest;
68 }
69
70 #if !defined(__FreeBSD__) && !defined(__CYGWIN__)
71
strlcat(char * dest,const char * src,size_t totsize)72 char *strlcat (char *dest, const char *src, size_t totsize)
73 {
74 size_t curlen = strlen (dest);
75 size_t srclen = strlen (src);
76 if ((curlen + srclen) >= totsize)
77 return NULL;
78 strcpy (dest+curlen, src);
79 return dest;
80 }
81
82 #endif
83
stristr(const char * str,const char * substr)84 char *stristr (const char *str, const char *substr)
85 {
86 int slen = strlen (substr);
87 if (slen == 0)
88 return NULL;
89
90 const char *d = str;
91 while (*d) { // look for 1st char of substr
92 if (strncasecmp (d, substr, slen) == 0)
93 return (char *)d;
94 d ++;
95 }
96
97 return NULL;
98 }
99
100
StrChg(char * src,char from,char to)101 char *StrChg (char *src, char from, char to)
102 {
103 char *p = src;
104 while (*p) {
105 if (*p == from)
106 *p = to;
107 p ++;
108 }
109
110 return src;
111 }
112
113
_fgets(char * buf,size_t n,FILE * fp,int * buflen)114 char *_fgets (char *buf, size_t n, FILE *fp, int *buflen)
115 {
116 char *ret = fgets (buf, n, fp);
117
118 if (!ret)
119 return NULL;
120
121 int blen = strlen (buf);
122 if (blen > 0) {
123 if (buf[blen-1] == '\n') { // remove trailing lf
124 buf[blen-1] = '\0';
125 blen --;
126 } else { // skip to EOL
127 int c;
128 do
129 c = fgetc (fp);
130 while ((c != EOF) && (c != '\n'));
131 }
132 }
133
134 if (buflen)
135 *buflen = blen;
136
137 return ret;
138 }
139
140
_fputs(const char * buf,FILE * fp)141 int _fputs (const char *buf, FILE *fp)
142 {
143 int ret = fputs (buf, fp);
144 if (fputc ('\n', fp) == EOF)
145 return EOF;
146 return ret;
147 }
148
waitopen(const char * bsyname,int timeout)149 static int waitopen (const char *bsyname, int timeout) // -1 on timeout
150 {
151 int ret = -1;
152 int i = 0;
153
154 do {
155 if (i > 0)
156 sleep (1);
157 if (access (bsyname, F_OK)) { // file not existent
158 int handle = open (bsyname, O_WRONLY | O_CREAT | O_TRUNC, 0644);
159 if (handle != -1)
160 close (handle);
161 }
162 ret = open (bsyname, O_RDONLY);
163 i ++;
164 } while ((ret == -1) && (i < timeout) && (errno == ENOENT));
165
166 return ret;
167 }
168
fl_strupr(char * string)169 void fl_strupr (char *string)
170 {
171 while (*string !=0) {
172 *string = (char)toupper (*string);
173 string++;
174 }
175 }
176
177 // strto4Dadr: convert string to binary FNT address.
178 // adrs is a pointer to a 4D address string that must not necessarily
179 // be terminated just after the address specification;
180 // spaces and tabs are allowed before the address; space, tab, newline,
181 // @ are allowed after the address.
182 // adr is a pointer to a 4D address.
183 // Returns 0 on success address parsing
184 // Returns not zero on illegal or not full address (*adr unchanged, adrs not moved).
strto4Dadr(const char * & adrs,ADR * adr)185 int strto4Dadr (const char *&adrs, ADR *adr)
186 {
187 int ret = 0;
188 register unsigned zone, net, node, point=0;
189
190 if(!adrs || !adr) return -1;
191
192 if(strchr(adrs, '.'))
193 ret = (4 != sscanf (adrs, "%u:%u/%u.%u", &zone, &net, &node, &point));
194 else
195 ret = (3 != sscanf (adrs, "%u:%u/%u", &zone, &net, &node));
196 adr->zone = zone;
197 adr->net = net;
198 adr->node = node;
199 adr->point = point;
200 return(ret);
201 }
202
203
Busy(pcsz refname)204 Busy::Busy (pcsz refname)
205 {
206 bsyname = new char[PATH_MAX];
207 strcpy (bsyname, refname);
208 setext (bsyname, ".bsy");
209 bsyh = -1;
210 }
211
212
Wait(int timeout,byte shflg)213 int Busy::Wait (int timeout, byte shflg)
214 {
215 if (shflg == BSY_EXCL)
216 bsyh = open (bsyname, O_WRONLY | O_CREAT | O_TRUNC, 0644);
217 else // BSY_SHARE
218 bsyh = waitopen (bsyname, timeout);
219
220 if (bsyh == -1)
221 return -1;
222 return 0;
223 }
224
filelength(int fd)225 int filelength (int fd)
226 {
227 lseek (fd, 0, SEEK_END);
228 return tell (fd);
229 }
230
~Busy()231 Busy::~Busy ()
232 {
233 if (bsyh != -1) {
234 close (bsyh);
235 unlink (bsyname);
236 }
237 delete[] bsyname;
238 }
239
240
241
TagMatch(const char * Tag,const char * WildTag)242 BOOL TagMatch (const char *Tag, const char *WildTag)
243 {
244 if (Tag[0] == '<') // exclude special tags
245 return (stricmp (Tag, WildTag) == 0);
246
247 return (fnamecmp (Tag, WildTag) == 0);
248 }
249
250
251 // gets keys from src, stores in *keys, advances src
252 // returns length, -1 on error
253
getkeys(const char * & src,dword * keys)254 static int getkeys (const char *&src, dword *keys)
255 {
256 *keys = 0;
257
258 const char *p = src;
259 while (*p) {
260 if ((*p == ' ') || (*p == '\t'))
261 break;
262
263 int u = toupper (*p);
264 int nbit;
265 if ((u >= '1') && (u <= '8'))
266 nbit = u - '1';
267 else if ((u >= 'A') && (u <= 'X'))
268 nbit = u - 'A' + 8;
269 else
270 return -1;
271
272 *keys |= (1L << nbit);
273 p ++;
274 }
275
276 int slen = int (p - src);
277
278 src += slen;
279
280 return slen;
281 }
282
283
GetLevKey(const char * & src,word * level,dword * keys,byte flags)284 int GetLevKey (const char *&src, word *level, dword *keys, byte flags)
285 {
286 const char *p = src;
287
288 p += strspn (p, " \t"); // skip leading blanks
289
290 if (!isdigit (*p)) { // decimal level ?
291 if ((flags & MSC_Allow_NoLevel) && (*p == '/'))
292 *level = USHRT_MAX;
293 else
294 return -1;
295 } else
296 *level = (word) strtoul (p, (char **)&p, 10); // convert to ulong
297
298
299 if (keys)
300 *keys = 0;
301
302 if (*p == '/') { // keys present
303 if (!keys)
304 return -1;
305 p ++;
306 if (getkeys (p, keys) == -1)
307 return -1;
308 }
309
310 switch (*p) {
311 case '\0':
312 break;
313 case ' ': // skip trailing blanks
314 case '\t':
315 p += strspn (p, " \t");
316 break;
317 default: // illegal chars
318 return -1;
319 }
320
321 int slen = int (p - src);
322
323 if (flags & MSC_SrcMov)
324 src += slen;
325
326 return slen;
327 }
328
329
Ibm2Ascii(char c)330 char Ibm2Ascii (char c)
331 {
332 if ((unsigned char)c <= 127) // 0->127, return unchanged
333 return c;
334
335 static char cvt[129] = "CueaaaaceeeiiiAAEaAooouuyOUcLYPfaiounNao?++24!<>XXX|++++++|+++++++++-++++++++-+++++++++++++XXXXXabgpEouTOOOqooeU=+><()%=o../n2X";
336
337 return cvt[c-128];
338 }
339
340
341 static char keych[33] = "12345678abcdefghijklmnopqrstuvwx";
342
343
PrintLevKey(char * buffer,word level,dword keys)344 void PrintLevKey (char *buffer, word level, dword keys)
345 {
346 #ifdef UNIX
347 sprintf(buffer,"%u",level);
348 #else
349 utoa (level, buffer, 10); // write the level
350 #endif
351 char *p = strchr (buffer, '\0'); // points after level
352 if (keys == 0UL)
353 return;
354
355 *(p++) = '/';
356
357 dword ibit = 0x00000001;
358 for (int i = 0; i < 32; i ++) {
359 if (ibit & keys)
360 *(p++) = keych[i];
361 ibit <<= 1;
362 }
363
364 *p = '\0';
365 }
366
367
eq4Dadr(const ADR * adr1,const ADR * adr2)368 bool eq4Dadr (const ADR *adr1, const ADR *adr2)
369 {
370 if (adr1->zone != adr2->zone) return false;
371 if (adr1->net != adr2->net) return false;
372 if (adr1->node != adr2->node) return false;
373 if (adr1->point != adr2->point) return false;
374 return true;
375 }
376
377