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