~sysman-one/starlet/main

« back to all changes in this revision

Viewing changes to utility_routines.c

  • Committer: SysManOne
  • Date: 2021-02-27 15:51:54 UTC
  • Revision ID: git-v1:5b01b936f0df1cf02a7b704221ceb8b21f60f99a
Added files.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#define __MODULE__      "UTIL$"
 
2
#define __IDENT__       "V.01-00"
 
3
#define __REV__         "1.00.0"
 
4
 
 
5
 
 
6
/*
 
7
**  Abstract: General purpose and utility routines
 
8
**
 
9
**  Author: Ruslan R. Laishev
 
10
**
 
11
**  Creation date: 4-SEP-2017
 
12
**
 
13
**  Modification history:
 
14
**
 
15
**      25-SEP-2017     RRL     Added __util$log2buf(): format a message into the given buffer.
 
16
**
 
17
**       5-OCT-2017     RRL     Added __util$syslog() : format and send a message to SYSLOG server;
 
18
**                              recoding __util$setlogfile -> util$deflog() to accept a SYSLOG IP address
 
19
**                              as argument;
 
20
**
 
21
**       6-OCT-2017     RRL     Adopted __util$syslog() for M$ Windows.
 
22
**
 
23
**      12-OCT-2017     RRL     Added conditional blocks on the __SYSLOG__;
 
24
**                              other changes to improve stability of code;
 
25
**
 
26
**      27-APR-2018     RRL     Changed handling of the OPTS$K_INT to allow accept decimals and hexadecimals,
 
27
**                              replaced atoi() with strtoul().
 
28
**
 
29
**      28-MAY-2018     RRL     Correct text of message.
 
30
**
 
31
**       6-AUG-2018     SYS     Added a support for 64-bits long in the routines related option's processing.
 
32
**
 
33
**      10-NOV-2018     RRL     Recoded logging related routines to use 'fd' instead of FILE;
 
34
**
 
35
**      12-NOV-2018     RRL     Changed __util$rewindlog() to truncate file at begin after rewinding.
 
36
**
 
37
**      23-NOV-2018     RRL     Fixed lseek()->29 on STDOUT_FILENO in the __util$rewindlogfile();
 
38
**
 
39
**      23-APR-2019     RRL     Recoded __util$readconfig() to allow using similar keywords  like:
 
40
**                              /NSERVER
 
41
**                              /NSERVER6
 
42
**
 
43
**       4-JUN-2019     RRL     Improved output buffer security in the $trace(), $log(), $logd(), $log2buf() routines.
 
44
**
 
45
**      25-JUN-2019     ARL     Special changes for Adnroid;
 
46
**                      RRL     Small changes in the  __utility$trace();
 
47
**
 
48
**       8-JUL-2019     RRL     Improved code quality in the routines processing of configuration options.
 
49
**
 
50
**       5-OCT-2019     RRL     Adopted gettid() for APPLE/OSX
 
51
**
 
52
**      30-DEC-2019     RRL     Improved error handling during processing _CONF option.
 
53
**
 
54
**      19-MAR-2020     RRL     Addeв O_APPEND flag in call of open() in the __util$deflog().
 
55
**
 
56
**       7-MAY-2020     RRL     Fixed incorrect value of 'mode' argument of open() under Windows.
 
57
*/
 
58
 
 
59
 
 
60
#ifdef  _WIN32
 
61
#define _CRT_SECURE_NO_WARNINGS 1
 
62
#define WIN32_LEAN_AND_MEAN
 
63
 
 
64
#include        <winsock2.h>
 
65
#include        <windows.h>
 
66
#include        <ws2tcpip.h>
 
67
 
 
68
#include        <sys/timeb.h>
 
69
#include        <io.h>
 
70
#endif
 
71
 
 
72
#include        <stddef.h>
 
73
#include        <stdio.h>
 
74
#include        <stdarg.h>
 
75
#include        <time.h>
 
76
#include        <ctype.h>
 
77
#include        <string.h>
 
78
#include        <stdlib.h>
 
79
#include        <errno.h>
 
80
#include        <ctype.h>
 
81
#include        <sys/types.h>
 
82
#include        <sys/stat.h>
 
83
#include        <fcntl.h>
 
84
 
 
85
 
 
86
#ifdef  ANDROID
 
87
#include        <android/log.h>
 
88
#endif
 
89
 
 
90
#ifndef _WIN32
 
91
#include        <unistd.h>
 
92
//#include      <execinfo.h>
 
93
#include        <arpa/inet.h>
 
94
#include        <syslog.h>
 
95
 
 
96
#define PID_FMT "%6d"
 
97
 
 
98
 
 
99
        #define TIMSPECDEVIDER  1000000 /* Used to convert timespec's nanosec tro miliseconds */
 
100
#elif   _WIN32
 
101
        #define gettid()        GetCurrentThreadId()
 
102
        //#define       gettid()        GetCurrentProcessId()
 
103
        #define TIMSPECDEVIDER  1000    /* Used to convert timeval's microseconds to miliseconds */
 
104
        #define PID_FMT "%6d"
 
105
#else
 
106
        #define gettid()        (0xDEADBEEF)
 
107
#endif
 
108
 
 
109
#ifndef __TRACE__
 
110
#define         __TRACE__       /* Enable $TRACE facility macro                         */
 
111
#endif
 
112
 
 
113
#include        "utility_routines.h"
 
114
 
 
115
 
 
116
#ifndef WIN32
 
117
#pragma GCC diagnostic push
 
118
#pragma GCC diagnostic ignored  "-Wparentheses"
 
119
#endif
 
120
 
 
121
#ifdef _WIN32
 
122
 
 
123
#ifndef STDERR_FILENO
 
124
#define STDERR_FILENO   2
 
125
#endif
 
126
 
 
127
#ifndef STDIN_FILENO
 
128
#define STDIN_FILENO    0
 
129
#endif
 
130
 
 
131
#ifndef STDOUT_FILENO
 
132
#define STDOUT_FILENO   1
 
133
#endif
 
134
 
 
135
 
 
136
#endif // _WIN32
 
137
 
 
138
int     logoutput = STDOUT_FILENO;      /* Default descriptor for default output device         */
 
139
 
 
140
struct sockaddr_in slogsock;    /* SYSLOG Host socket                                   */
 
141
 
 
142
#ifndef WIN32
 
143
 
 
144
        #ifndef _GNU_SOURCE
 
145
                #define _GNU_SOURCE     1
 
146
        #endif
 
147
 
 
148
#include                <sys/syscall.h>
 
149
 
 
150
#ifndef ANDROID
 
151
 
 
152
static inline pid_t     gettid(void)
 
153
{
 
154
        return  syscall (
 
155
#if defined(__APPLE__) || defined(__OSX__)
 
156
        SYS_thread_selfid
 
157
#else
 
158
                SYS_gettid
 
159
#endif
 
160
        );
 
161
}
 
162
 
 
163
#endif  /* ANDROID */
 
164
#endif
 
165
 
 
166
/*
 
167
 *
 
168
 *  Description: a simplified analog of the C RTL syslog() routine is supposed to used to
 
169
 *      format and send a message directly to IP (has been defined by $deflog();
 
170
 *
 
171
 *  Usage:
 
172
 *      __util$deflog(NULL, "172.28.4.112");
 
173
 *      ...
 
174
 *      char msg [] = "GAMEOVER, all your base are belong to us";
 
175
 *      __util$syslog(LOG_KERN, LOG_DEBUG, "NOXBIT", msg, sizeof(msg));
 
176
 *
 
177
 *  Input:
 
178
 *      fac:    SYSLOG Facility code, see LOG_* constants
 
179
 *      pri:    SYSLOG Severity code, see LOG_* constants
 
180
 *      tag:    A tag string - a part of the MSG part :-)
 
181
 *      msg:    message buffer to be send
 
182
 *      msglen: message length
 
183
 *
 
184
 *
 
185
 *  Return:
 
186
 *      SS$_NORMAL
 
187
 *
 
188
 */
 
189
 
 
190
unsigned        __util$syslog
 
191
                (
 
192
                int             fac,
 
193
                int             sev,
 
194
                const char *    tag,
 
195
                const char *    msg,
 
196
                int             msglen
 
197
                )
 
198
{
 
199
static int      sd = -1;
 
200
char    buf[128];
 
201
 
 
202
#ifdef  _WIN32
 
203
 
 
204
WSAMSG msg_desc = { 0 };
 
205
WSABUF   bufv[] = {{buf, 0}, {msg, msglen}};
 
206
 
 
207
#else
 
208
struct  iovec bufv[] = {{buf, 0}, {msg, msglen}};
 
209
struct  msghdr  msg_desc = {0};
 
210
#endif
 
211
 
 
212
 
 
213
        if ( sd == -1 )
 
214
                {
 
215
                /*
 
216
                inet_aton("172.28.4.112", &slogsock.sin_addr);
 
217
                slogsock.sin_port = htons(514);
 
218
                slogsock.sin_family = AF_INET;
 
219
                */
 
220
#ifdef  _WIN32
 
221
                WSADATA wsa_data;
 
222
                int status;
 
223
 
 
224
                if ( status = WSAStartup(MAKEWORD(2,2), &wsa_data) )
 
225
                        {
 
226
                        perror("WSAstartup");
 
227
                        abort();
 
228
                        }
 
229
 
 
230
#endif
 
231
                if ( 0 > (sd = socket(AF_INET, SOCK_DGRAM, 0)) )
 
232
                        {
 
233
                        perror("socket");
 
234
                        return  STS$K_ERROR;
 
235
                        }
 
236
                }
 
237
 
 
238
        /* Prepare the msghdr structure */
 
239
#ifdef  _WIN32
 
240
        msg_desc.name = &slogsock;
 
241
        msg_desc.namelen = sizeof(slogsock);
 
242
 
 
243
        msg_desc.lpBuffers = (void *) &bufv;
 
244
        msg_desc.dwBufferCount = sizeof(bufv)/sizeof(bufv[0]);
 
245
 
 
246
        /* Form <priority + severity> part, add the tag field */
 
247
        bufv[0].len = sprintf(buf, "<%d> %s: ", fac  + sev, tag);
 
248
 
 
249
        if ( 0 >  WSASendMsg (sd, &msg_desc, 0, 0, 0, 0) )
 
250
                {
 
251
                perror("sendto");
 
252
                return  STS$K_ERROR;
 
253
                }
 
254
 
 
255
 
 
256
#else
 
257
        msg_desc.msg_name = &slogsock;
 
258
        msg_desc.msg_namelen = sizeof(slogsock);
 
259
 
 
260
        msg_desc.msg_iov = (void *) &bufv;
 
261
        msg_desc.msg_iovlen = sizeof(bufv)/sizeof(bufv[0]);
 
262
 
 
263
        /* Form <priority + severity> part, add the tag field */
 
264
        bufv[0].iov_len = sprintf(buf, "<%d> %16s: ", fac  + sev, tag);
 
265
        if ( 0 >  sendmsg (sd, &msg_desc, 0) )
 
266
                {
 
267
                perror("sendto");
 
268
                return  STS$K_ERROR;
 
269
                }
 
270
 
 
271
#endif
 
272
 
 
273
 
 
274
        return  STS$K_SUCCESS;
 
275
}
 
276
 
 
277
/*
 
278
 *
 
279
 *  Description: out to the current SYS$OUTPUT option's name  and values.
 
280
 *
 
281
 *  Input:
 
282
 *
 
283
 *      opts:   options' table, address of array terminated by 'NUL' entry
 
284
 *
 
285
 *
 
286
 *  Return:
 
287
 *      SS$_NORMAL
 
288
 *
 
289
 */
 
290
int     __util$showparams       (
 
291
                        OPTS *  opts
 
292
                        )
 
293
{
 
294
OPTS    *optp;
 
295
 
 
296
        for (optp = opts; $ASCLEN(&optp->name); optp++)
 
297
                {
 
298
                switch ( optp->type )
 
299
                        {
 
300
                        case    OPTS$K_PORT:
 
301
                                $LOG(STS$K_INFO, "%.*s = %d (0x%04.4x)", $ASC(&optp->name),
 
302
                                         *((unsigned short *) optp->ptr), *((unsigned short *) optp->ptr));
 
303
                                break;
 
304
 
 
305
                        case    OPTS$K_IP4:
 
306
                                $LOG(STS$K_INFO, "%.*s = %s", $ASC(&optp->name), inet_ntoa( *((struct in_addr *) optp->ptr)) );
 
307
                                break;
 
308
 
 
309
                        case    OPTS$K_OPT:
 
310
                                $LOG(STS$K_INFO, "%.*s = %s", $ASC(&optp->name), * ((int *)optp->ptr) ? "ON" : "OFF");
 
311
                                break;
 
312
 
 
313
                         case   OPTS$K_INT:
 
314
                                switch ( optp->sz )
 
315
                                        {
 
316
                                        case (sizeof (unsigned long long)):
 
317
                                                $LOG(STS$K_INFO, "%.*s = %llu (%#llx)", $ASC(&optp->name), *((unsigned long long *) optp->ptr),
 
318
                                                        *((unsigned long long *) optp->ptr));
 
319
                                                break;
 
320
 
 
321
                                        case (sizeof (unsigned short)):
 
322
                                                $LOG(STS$K_INFO, "%.*s = %d (%#x)", $ASC(&optp->name), *((unsigned short *) optp->ptr),
 
323
                                                        *((unsigned short *) optp->ptr));
 
324
                                                break;
 
325
 
 
326
                                        default:
 
327
                                                $LOG(STS$K_INFO, "%.*s = %d (%#x)", $ASC(&optp->name), *((int *) optp->ptr), *((int *) optp->ptr));
 
328
                                                break;
 
329
                                        }
 
330
                                break;
 
331
 
 
332
                        case    OPTS$K_STR:
 
333
                                $LOG(STS$K_INFO, "%.*s[0:%u] ='%.*s'", $ASC(&optp->name), ((ASC *)optp->ptr)->len, $ASC(optp->ptr));
 
334
                                break;
 
335
 
 
336
                        case    OPTS$K_PWD:
 
337
                                $LOG(STS$K_INFO, "%.*s[0:%u] ='<password>'", $ASC(&optp->name), ((ASC *)optp->ptr)->len, $ASC(optp->ptr));
 
338
                                break;
 
339
 
 
340
                        }
 
341
                }
 
342
 
 
343
        return  STS$K_SUCCESS;
 
344
}
 
345
 
 
346
 
 
347
/*
 
348
 *
 
349
 *  Description: processing command line arguments to extract parameters according of options table;
 
350
 *              performs basic syntax checking, copy options values to local storage for using at run-time.
 
351
 *  Input:
 
352
 *      fconf:  A configuration file to be processed
 
353
 *      opts:   options' table, address of array terminated by 'NUL' entry
 
354
 *
 
355
 *  Output:
 
356
 *      fills the 'runparams' vector by option
 
357
 *
 
358
 *  Return:
 
359
 *      SS$_NORMAL
 
360
 *
 
361
 */
 
362
int     __util$readconfig       (
 
363
                        char *  fconf,
 
364
                        OPTS *  opts
 
365
                        )
 
366
{
 
367
int     i, argslen;
 
368
FILE    *finp = stdin;
 
369
const char novalp [ 32 ] = {0};
 
370
char    *argp, *valp = novalp, buf[256];
 
371
OPTS    *optp, *optp2;
 
372
 
 
373
        /*
 
374
         * Is the configuration file has been specified ?
 
375
         */
 
376
        if ( fconf && (*fconf) )
 
377
                {
 
378
                if ( !(finp = fopen(fconf, "r")) )
 
379
                        return  $LOG(STS$K_ERROR, "Error open file '%s', errno = %d", fconf, errno);
 
380
                }
 
381
 
 
382
        /*
 
383
        * We expect to see opts in form: -<options_name>=<options_value>
 
384
        */
 
385
        for ( i = 1; fgets(buf, sizeof(buf), finp); i++ )
 
386
                {
 
387
                if ( !__util$uncomment(buf, (int) strlen(buf), '!') )
 
388
                        continue;
 
389
 
 
390
                if ( !__util$trim(buf, (int) strlen(buf)) )
 
391
                        continue;
 
392
 
 
393
                if ( (*(argp = buf) != '-') && (*(argp = buf) != '/') )
 
394
                        {
 
395
                        $LOG(STS$K_ERROR, "%s : %d : Option must be started with a '-' or '/', skip : '%s'", fconf, i, buf);
 
396
                        continue;
 
397
                        }
 
398
 
 
399
                if ( valp = strchr(++argp, '=') )
 
400
                        {
 
401
                        argslen = (int) (valp - argp);
 
402
                        valp++;
 
403
                        }
 
404
                else    {
 
405
                        argslen = (int) strlen(argp);
 
406
                        valp = novalp;
 
407
                        }
 
408
 
 
409
 
 
410
                /*
 
411
                * Compare a given from command line option name against options list,
 
412
                * we expect that options list is terminated by zero-length entry.
 
413
                *
 
414
                * We allow an shortened keywords but it can be a reason of conflicts.
 
415
                */
 
416
                for (optp2 = NULL, optp = opts; $ASCLEN(&optp->name); optp++)
 
417
                        {
 
418
#if _WIN32
 
419
                        if ( !(_strnicmp (argp, $ASCPTR(&optp->name), $MIN(argslen, $ASCLEN(&optp->name)))) )
 
420
#else
 
421
                        if ( !(strncasecmp (argp, $ASCPTR(&optp->name), $MIN(argslen, $ASCLEN(&optp->name)))) )
 
422
#endif
 
423
                                {
 
424
                                if ( argslen == $ASCLEN(&optp->name) )  /* Full matching */
 
425
                                        {
 
426
                                        optp2 = optp;
 
427
                                        break;
 
428
                                        }
 
429
 
 
430
                                if ( !optp2 )   /* If it's first hit - save option */
 
431
                                        {
 
432
                                        optp2 = optp;
 
433
                                        continue;
 
434
                                        }
 
435
 
 
436
 
 
437
                                /*
 
438
                                 * Is the new hit is longest than old ?
 
439
                                */
 
440
                                if ( $ASCLEN(&optp2->name) < $ASCLEN(&optp->name) )
 
441
                                        optp2 = optp;
 
442
                                }
 
443
                        }
 
444
 
 
445
                if ( !optp2 || !$ASCLEN(&optp2->name) )
 
446
                        {
 
447
                        $LOG(STS$K_WARN, "%s : %d : Skip unrecognized or unused option", fconf, i);
 
448
                        continue;
 
449
                        }
 
450
 
 
451
 
 
452
                optp = optp2 ? optp2 : optp;
 
453
 
 
454
                if ( valp && *valp)
 
455
                        __util$trim (valp, (int) strlen(valp));
 
456
 
 
457
                switch ( optp->type )
 
458
                        {
 
459
                        case    OPTS$K_PORT:
 
460
                                * ((unsigned short  *) optp->ptr) = (unsigned short) atoi(valp);
 
461
                                break;
 
462
 
 
463
                        case    OPTS$K_IP4:
 
464
#ifdef WIN32
 
465
                                if ( ! ((*(long *) optp->ptr) =  inet_addr (valp)) )
 
466
#else
 
467
                                if ( !inet_aton(valp, (struct in_addr *) optp->ptr) )
 
468
#endif
 
469
                                        $LOG(STS$K_ERROR, "%s : %d : Error conversion '%s' to IP4 address", fconf, i, valp);
 
470
                                break;
 
471
 
 
472
                        case    OPTS$K_OPT:
 
473
                                * ((int *)optp->ptr) = 1;
 
474
                                break;
 
475
 
 
476
                        case    OPTS$K_INT:
 
477
                                switch ( optp->sz )
 
478
                                        {
 
479
                                        char *endptr = NULL;
 
480
 
 
481
                                        case (sizeof (unsigned long long)):
 
482
                                                * ((unsigned long long *) optp->ptr) =  strtoull(valp, &endptr, 0);
 
483
                                                break;
 
484
 
 
485
                                        default:
 
486
                                                * ((int *) optp->ptr) =  strtoul(valp, &endptr, 0);
 
487
                                                break;
 
488
 
 
489
                                        }
 
490
                                break;
 
491
 
 
492
                        case    OPTS$K_PWD:
 
493
                        case    OPTS$K_STR:
 
494
                                ((ASC *)optp->ptr)->len  = (unsigned char) $MIN(strnlen(valp, optp->sz), ASC$K_SZ);
 
495
                                memcpy( ((ASC *)optp->ptr)->sts, valp, ((ASC *)optp->ptr)->len);
 
496
                                ((ASC *)optp->ptr)->sts[((ASC *)optp->ptr)->len] = '\0';
 
497
                                break;
 
498
 
 
499
                        default:
 
500
                                $LOG(STS$K_ERROR, "%s : %d : Unrecognized option's '%.*s' internal type : 0x%X", fconf, i, $ASC(&optp->name), optp->type);
 
501
                        }
 
502
                }
 
503
 
 
504
        if ( finp && (finp != stdin) )
 
505
                fclose(finp);
 
506
 
 
507
 
 
508
        return  STS$K_SUCCESS;
 
509
}
 
510
 
 
511
 
 
512
/*
 
513
 *
 
514
 *  Description: processing command line arguments to extract parameters according of options table;
 
515
 *              performs basic syntax checking, copy options values to local storage for using at run-time.
 
516
 *  Input:
 
517
 *      argc:   an argument count
 
518
 *      argv:   an array of command line options
 
519
 *      opts:   options' table, address of array terminated by 'NUL' entry
 
520
 *
 
521
 *  Output:
 
522
 *      fills the 'runparams' vector by option
 
523
 *
 
524
 *  Return:
 
525
 *      SS$_NORMAL
 
526
 *
 
527
 */
 
528
int     __util$getparams        (
 
529
                        int     argc,
 
530
                        char *  argv[],
 
531
                        OPTS *  opts
 
532
                        )
 
533
{
 
534
int     i;
 
535
size_t  argslen;
 
536
const char novalp [ 32 ] = {0};
 
537
char    *argp, *valp = novalp;
 
538
OPTS    *optp;
 
539
 
 
540
 
 
541
        /*
 
542
        * We expect to see opts in form:
 
543
        *       -<options_name>=<options_value>
 
544
        *  or
 
545
        *       /<options_name>=<options_value>
 
546
        */
 
547
        for ( i = 1; i < argc; i++ )
 
548
                {
 
549
                /* Skip zero length strings     */
 
550
                if ( !strlen (argv[i]) )
 
551
                        continue;
 
552
 
 
553
                /* Check option designator      */
 
554
                if ( (*(argp = argv[i]) != '-') && (*(argp = argv[i]) != '/') )
 
555
                        {
 
556
                        $LOG(STS$K_ERROR, "%d: Option must be started with '-' or '/', skip : '%s'", i, argv[i]);
 
557
                        continue;
 
558
                        }
 
559
 
 
560
                if ( valp = strchr(++argp, '=') )
 
561
                        {
 
562
                        argslen = valp - argp;
 
563
                        valp++;
 
564
                        }
 
565
                else    {
 
566
                        argslen = strlen(argp);
 
567
                        valp = novalp;
 
568
                        }
 
569
 
 
570
                /*
 
571
                * Compare a given from command line option name against options list,
 
572
                * we expect that options list is terminated by zero-length entry.
 
573
                *
 
574
                * We allow an shortened keywords but it can be a reao of conflicts.
 
575
                */
 
576
                for (optp = opts; $ASCLEN(&optp->name); optp++)
 
577
                        {
 
578
                        if ( argslen != $ASCLEN(&optp->name) )
 
579
                                continue;
 
580
 
 
581
#if _WIN32
 
582
                        if ( !(_strnicmp (argp, $ASCPTR(&optp->name), $MIN(argslen, $ASCLEN(&optp->name)))) )
 
583
#else
 
584
                        if ( !(strncasecmp (argp, $ASCPTR(&optp->name), $MIN(argslen, $ASCLEN(&optp->name)))) )
 
585
#endif
 
586
                                break;
 
587
                        }
 
588
 
 
589
                if ( !optp || !$ASCLEN(&optp->name) )
 
590
                        {
 
591
                        $LOG(STS$K_ERROR, "%d : Skip unrecognized option: '%s'", i, argp);
 
592
                        continue;
 
593
                        }
 
594
 
 
595
                if ( valp && *valp)
 
596
                        __util$trim (valp, (int) strlen(valp));
 
597
 
 
598
                switch ( optp->type )
 
599
                        {
 
600
                        case    OPTS$K_CONF:
 
601
                                if ( optp->ptr )
 
602
                                        {
 
603
                                        /* Store name of configuration file     */
 
604
                                        ((ASC *)optp->ptr)->len  = (unsigned char) strnlen(valp, sizeof(((ASC *)optp->ptr)->sts));
 
605
                                        memcpy( ((ASC *)optp->ptr)->sts, valp, ((ASC *)optp->ptr)->len);
 
606
                                        ((ASC *)optp->ptr)->sts[((ASC *)optp->ptr)->len] = '\0';
 
607
                                        }
 
608
 
 
609
                                if ( !(1 & __util$readconfig (valp, opts)) )
 
610
                                        return  STS$K_ERROR;
 
611
 
 
612
                                break;
 
613
 
 
614
                        case    OPTS$K_PORT:
 
615
                                * ((unsigned short  *) optp->ptr) = (unsigned short) atoi(valp);
 
616
                                break;
 
617
 
 
618
                        case    OPTS$K_IP4:
 
619
#ifdef WIN32
 
620
                                if ( ! ((*(long *) optp->ptr) =  inet_addr (valp)) )
 
621
#else
 
622
                                if ( !inet_aton(valp, (struct in_addr *) optp->ptr) )
 
623
#endif
 
624
                                        $LOG(STS$K_ERROR, "%d : Error conversion '%s' to IP4 address", i, valp);
 
625
                                break;
 
626
 
 
627
                        case    OPTS$K_OPT:
 
628
                                * ((int *)optp->ptr) = 1;
 
629
                                break;
 
630
 
 
631
                        case    OPTS$K_INT:
 
632
                                switch ( optp->sz )
 
633
                                        {
 
634
                                        char *endptr = NULL;
 
635
 
 
636
                                        case (sizeof (unsigned long long)):
 
637
                                                * ((unsigned long long *) optp->ptr) =  strtoull(valp, &endptr, 0);
 
638
                                                break;
 
639
 
 
640
                                        default:
 
641
                                                * ((int *) optp->ptr) =  strtoul(valp, &endptr, 0);
 
642
                                                break;
 
643
 
 
644
                                        }
 
645
                                break;
 
646
 
 
647
                        case    OPTS$K_PWD:
 
648
                        case    OPTS$K_STR:
 
649
                                ((ASC *)optp->ptr)->len  = (unsigned char) $MIN(strnlen(valp, optp->sz), ASC$K_SZ);
 
650
                                memcpy( ((ASC *)optp->ptr)->sts, valp, ((ASC *)optp->ptr)->len);
 
651
                                ((ASC *)optp->ptr)->sts[((ASC *)optp->ptr)->len] = '\0';
 
652
                                break;
 
653
 
 
654
                        default:
 
655
                                $LOG(STS$K_ERROR, "%d : Unrecognized option's '%.*s' internal type : 0x%X", i, $ASC(&optp->name), optp->type);
 
656
                        }
 
657
                }
 
658
 
 
659
        return  STS$K_SUCCESS;
 
660
}
 
661
 
 
662
 
 
663
/*
 
664
 *++
 
665
 *  Description: dump byte array to sys$output in hex, is supposed to be called indirectly by $DUMPHEX macro.
 
666
 *
 
667
 * Input:
 
668
 *      __fi:   A file name or module name string
 
669
 *      __li:   Line number in the sourve file
 
670
 *      src:    A pointer to source buffer  do be dumped
 
671
 *      srclen: A Length of the source buffer
 
672
 *
 
673
 * Output:
 
674
 *      NONE
 
675
 * Return:
 
676
 *      NONE
 
677
 *
 
678
 *--
 
679
 */
 
680
 
 
681
void    __util$dumphex  (
 
682
                char *  __fi,
 
683
                unsigned        __li,
 
684
                void *  src,
 
685
                unsigned short  srclen
 
686
                        )
 
687
{
 
688
const char      lfmt [] = {"%02u-%02u-%04u %02u:%02u:%02u.%03u [%s\\%u] Dump of %u octets follows:"};
 
689
char    out[80];
 
690
unsigned char *srcp = (unsigned char *) src, low, high;
 
691
unsigned olen = 0, i, j;
 
692
struct tm _tm;
 
693
struct timespec now;
 
694
 
 
695
        /*
 
696
        ** Out to buffer "DD-MM-YYYY HH:MM:SS.msec [<function>\<line>]" prefix
 
697
        */
 
698
        ____time(&now);
 
699
 
 
700
#ifdef  WIN32
 
701
        localtime_s(&_tm, (time_t *)&now);
 
702
#else
 
703
        localtime_r((time_t *)&now, &_tm);
 
704
#endif
 
705
 
 
706
        olen = snprintf (out, sizeof(out) - 1, lfmt,
 
707
                _tm.tm_mday, _tm.tm_mon + 1, 1900 + _tm.tm_year,
 
708
                _tm.tm_hour, _tm.tm_min, _tm.tm_sec, (unsigned) now.tv_nsec/TIMSPECDEVIDER,
 
709
                __fi, __li, srclen);
 
710
 
 
711
        /* Add <LF> at end of record*/
 
712
        out[$MIN(olen++, sizeof(out))] = '\n';
 
713
        write (logoutput, out, olen );
 
714
 
 
715
        memset(out, ' ', sizeof(out));
 
716
 
 
717
        /*
 
718
        ** Format variable part of string line
 
719
        */
 
720
        for (i = 0; i < ((srclen / 16));  i++)
 
721
                {
 
722
                olen = sprintf(out, "\t+%04x:  ", i * 16);
 
723
                memset(out + olen, ' ', sizeof(out) - olen);
 
724
 
 
725
                for (j = 0; j < 16; j++, srcp++)
 
726
                        {
 
727
                        high = (*srcp) >> 4;
 
728
                        low = (*srcp) & 0x0f;
 
729
 
 
730
                        out[olen + j * 3] = high + ((high < 10) ? '0' : 'a' - 10);
 
731
                        out[olen + j * 3 + 1] = low + ((low < 10) ? '0' : 'a' - 10);
 
732
 
 
733
                        out[olen + 16*3 + 2 + j] = isprint(*srcp) ? *srcp : '.';
 
734
                        }
 
735
 
 
736
                /* Add <LF> at end of record*/
 
737
                out[sizeof(out) - 1] = '\n';
 
738
 
 
739
                /* Write to file and flush buffer depending on severity level */
 
740
                write (logoutput, out, sizeof(out) );
 
741
                }
 
742
 
 
743
        if ( srclen % 16 )
 
744
                {
 
745
                olen = sprintf(out, "\t+%04x:  ", i * 16);
 
746
                memset(out + olen, ' ', sizeof(out) - olen);
 
747
 
 
748
                for (j = 0; j < srclen % 16; j++, srcp++)
 
749
                        {
 
750
                        high = (*srcp) >> 4;
 
751
                        low = (*srcp) & 0x0f;
 
752
 
 
753
                        out[olen + j * 3] = high + ((high < 10) ? '0' : 'a' - 10);
 
754
                        out[olen + j * 3 + 1] = low + ((low < 10) ? '0' : 'a' - 10);
 
755
 
 
756
                        out[olen + 16*3 + 2 + j] = isprint(*srcp) ? *srcp : '.';
 
757
                        }
 
758
 
 
759
                /* Add <LF> at end of record*/
 
760
                out[sizeof(out) - 1] = '\n';
 
761
 
 
762
                /* Write to file and flush buffer depending on severity level */
 
763
                write (logoutput, out, sizeof(out) );
 
764
                }
 
765
}
 
766
 
 
767
 
 
768
/*
 
769
 *++
 
770
 *  Description: dump byte array to sys$output in hex, is supposed to be called indirectly by $DUMPHEX macro.
 
771
 *
 
772
 * Input:
 
773
 *      src:    A pointer to source buffer  do be dumped
 
774
 *      srclen: A Length of the source buffer
 
775
 *      dst:
 
776
 *      dstsz:
 
777
 *      dstlen:
 
778
 *
 
779
 * Return:
 
780
 *      NONE
 
781
 *
 
782
 *--
 
783
 */
 
784
int     __util$faohex   (
 
785
                void *  src,
 
786
                unsigned short  srclen,
 
787
                char *  out,
 
788
                unsigned short  outsz
 
789
                        )
 
790
{
 
791
unsigned char *srcp = (unsigned char *) src, low, high;
 
792
unsigned j;
 
793
 
 
794
        memset(out, ' ', outsz);
 
795
 
 
796
        for (j = 0; j < 16; j++, srcp++)
 
797
                {
 
798
                high = (*srcp) >> 4;
 
799
                low = (*srcp) & 0x0f;
 
800
 
 
801
                out[j * 3] = high + ((high < 10) ? '0' : 'a' - 10);
 
802
                out[j * 3 + 1] = low + ((low < 10) ? '0' : 'a' - 10);
 
803
 
 
804
                out[16*3 + 2 + j] = isprint(*srcp) ? *srcp : '.';
 
805
                }
 
806
 
 
807
        out[16*3 + 2 + j] = '\0';
 
808
 
 
809
        return  16*3 + 2 + j;
 
810
}
 
811
 
 
812
 
 
813
 
 
814
 
 
815
 
 
816
 
 
817
 
 
818
 
 
819
/*
 
820
 *++
 
821
 *  Description: print to sys$output a programm trace information, supposed to be called from
 
822
 *              $TRACE  macro.
 
823
 *
 
824
 * Input:
 
825
 *      fmt:    A format string
 
826
 *      __fi:   A file name or module name string
 
827
 *      __li:   Line number in the source file
 
828
 *      ...     Format string arguments
 
829
 * Output:
 
830
 *      NONE
 
831
 * Return:
 
832
 *      NONE
 
833
 *
 
834
 *--
 
835
 */
 
836
 
 
837
void    __util$trace    (
 
838
                        int     cond,
 
839
                const char *    fmt,
 
840
                const char *    __mod,
 
841
                const char *    __fi,
 
842
                unsigned        __li,
 
843
                        ...
 
844
                        )
 
845
{
 
846
va_list arglist;
 
847
 
 
848
const char      lfmt [] = {"%02u-%02u-%04u %02u:%02u:%02u.%03u " PID_FMT " [%s\\%u] "},
 
849
        mfmt [] = {"%02u-%02u-%04u %02u:%02u:%02u.%03u " PID_FMT " [%s\\%s\\%u] "};
 
850
char    out[1024];
 
851
 
 
852
unsigned olen, len;
 
853
struct tm _tm;
 
854
struct timespec now;
 
855
 
 
856
        if ( !cond )
 
857
                return;
 
858
 
 
859
 
 
860
        /*
 
861
        ** Out to buffer "DD-MM-YYYY HH:MM:SS.msec [<function>\<line>]" prefix
 
862
        */
 
863
        ____time(&now);
 
864
 
 
865
#ifdef  WIN32
 
866
        localtime_s(&_tm, (time_t *)&now);
 
867
#else
 
868
        localtime_r((time_t *)&now, &_tm);
 
869
#endif
 
870
 
 
871
        olen = __mod
 
872
                ? sprintf (out, mfmt, _tm.tm_mday, _tm.tm_mon + 1, 1900 + _tm.tm_year,
 
873
                _tm.tm_hour, _tm.tm_min, _tm.tm_sec, (unsigned) now.tv_nsec/TIMSPECDEVIDER,
 
874
                (unsigned) gettid(), __mod, __fi, __li)
 
875
                : sprintf (out, lfmt, _tm.tm_mday, _tm.tm_mon + 1, 1900 + _tm.tm_year,
 
876
                        _tm.tm_hour, _tm.tm_min, _tm.tm_sec, (unsigned) now.tv_nsec/TIMSPECDEVIDER,
 
877
                (unsigned) gettid(), __fi, __li);
 
878
 
 
879
        /*
 
880
        ** Format variable part of string line
 
881
        */
 
882
        va_start (arglist, __li);
 
883
        olen += vsnprintf(out + olen, sizeof(out), fmt, arglist);
 
884
        va_end (arglist);
 
885
 
 
886
        olen = $MIN(olen, sizeof(out) - 1);
 
887
 
 
888
        /* Add <LF> at end of record*/
 
889
        out[olen++] = '\n';
 
890
 
 
891
        /* Write to file and flush buffer */
 
892
        write (logoutput, out, olen );
 
893
 
 
894
 
 
895
 
 
896
        /* ARL - for android logcat */
 
897
        #ifdef ANDROID
 
898
                __android_log_print(ANDROID_LOG_VERBOSE, __mod, "%.*s", olen, out);
 
899
        #endif
 
900
 
 
901
#ifdef  __SYSLOG__
 
902
#ifndef WIN32
 
903
        va_start (arglist, __li);
 
904
        olen = vsnprintf(out, sizeof(out), fmt, arglist);
 
905
        va_end (arglist);
 
906
 
 
907
        __util$syslog (LOG_USER, LOG_DEBUG, __mod, out, olen);
 
908
 
 
909
//      syslog( LOG_PID | ((sev & 1) ? LOG_INFO : LOG_ERR), "%.*s", olen, out);
 
910
#endif
 
911
#endif  /* __SYSLOG__ */
 
912
 
 
913
}
 
914
 
 
915
/*
 
916
 *
 
917
 */
 
918
const char severity[STS$K_UNDEF + 1][16] = { "-W: ", "-S: ", "-E: ", "-I: ", "-F: ", "-?: "};
 
919
 
 
920
unsigned        __util$log
 
921
                        (
 
922
                const char *    fac,
 
923
                unsigned        sev,
 
924
                const char *    fmt,
 
925
                        ...
 
926
                        )
 
927
 
 
928
{
 
929
va_list arglist;
 
930
const char lfmt [] = "%02u-%02u-%04u %02u:%02u:%02u.%03u " PID_FMT " %%%s%3s";
 
931
char    out[1024];
 
932
unsigned olen, _sev = sev, opcom = sev & STS$K_SYSLOG;
 
933
struct tm _tm;
 
934
struct timespec now;
 
935
 
 
936
        /*
 
937
        ** Some sanity check
 
938
        */
 
939
        if ( !($ISINRANGE(sev, STS$K_WARN, STS$K_ERROR)) )
 
940
                sev = STS$K_UNDEF;
 
941
 
 
942
        /*
 
943
        ** Out to buffer "DD-MM-YYYY HH:MM:SS.msec [<function>\<line>]<FAC>-E:" prefix
 
944
        */
 
945
        ____time(&now);
 
946
 
 
947
#ifdef  WIN32
 
948
        localtime_s(&_tm, (time_t *)&now);
 
949
#else
 
950
        localtime_r((time_t *)&now, &_tm);
 
951
#endif
 
952
 
 
953
        olen = sprintf (out, lfmt,
 
954
                _tm.tm_mday, _tm.tm_mon + 1, 1900 + _tm.tm_year,
 
955
                _tm.tm_hour, _tm.tm_min, _tm.tm_sec, (unsigned) now.tv_nsec/TIMSPECDEVIDER,
 
956
                (unsigned) gettid(), fac, severity[sev]);
 
957
 
 
958
        va_start (arglist, fmt);
 
959
        olen += vsnprintf(out + olen, sizeof(out) - olen, fmt, arglist);
 
960
        va_end (arglist);
 
961
 
 
962
        olen = $MIN(olen, sizeof(out) - 1);
 
963
 
 
964
        /* Add <LF> at end of record*/
 
965
        out[olen++] = '\n';
 
966
 
 
967
        /* Write to file and flush buffer depending on severity level */
 
968
        write (logoutput, out, olen );
 
969
 
 
970
        /* ARL - for android logcat */
 
971
        #ifdef ANDROID
 
972
                __android_log_print(ANDROID_LOG_VERBOSE, fac, "%.*s", olen, out);
 
973
        #endif
 
974
 
 
975
 
 
976
#ifndef WIN32
 
977
        if ( opcom )
 
978
                {
 
979
                va_start (arglist, fmt);
 
980
                olen = vsnprintf(out, sizeof(out), fmt, arglist);
 
981
                va_end (arglist);
 
982
 
 
983
                syslog( LOG_PID | ((sev & 1) ? LOG_INFO : LOG_ERR), "%.*s", olen, out);
 
984
                }
 
985
#endif
 
986
 
 
987
        return  _sev;
 
988
}
 
989
 
 
990
/**
 
991
 * @brief __util$log2buf - format a message into the given output buffer
 
992
 * @param out
 
993
 * @param outsz
 
994
 * @param outlen
 
995
 * @param fac
 
996
 * @param sev
 
997
 * @param fmt
 
998
 */
 
999
unsigned        __util$log2buf
 
1000
                        (
 
1001
                void    *       out,
 
1002
                int             outsz,
 
1003
                int     *       outlen,
 
1004
                const char *    fac,
 
1005
                unsigned        sev,
 
1006
                const char *    fmt,
 
1007
                        ...
 
1008
                        )
 
1009
 
 
1010
{
 
1011
va_list arglist;
 
1012
const char lfmt [] = "%02u-%02u-%04u %02u:%02u:%02u.%03u " PID_FMT " %%%s%3s";
 
1013
char    *__outbuf = (char *) out;
 
1014
unsigned        _sev = sev;
 
1015
struct tm _tm;
 
1016
struct timespec now;
 
1017
 
 
1018
        /*
 
1019
        ** Some sanity check
 
1020
        */
 
1021
        if ( !($ISINRANGE(sev, STS$K_WARN, STS$K_ERROR)) )
 
1022
                sev = STS$K_UNDEF;
 
1023
 
 
1024
        /*
 
1025
        ** Out to buffer "DD-MM-YYYY HH:MM:SS.msec [<function>\<line>]<FAC>-E:" prefix
 
1026
        */
 
1027
        ____time(&now);
 
1028
 
 
1029
#ifdef  WIN32
 
1030
        localtime_s(&_tm, (time_t *)&now);
 
1031
#else
 
1032
        localtime_r((time_t *)&now, &_tm);
 
1033
#endif
 
1034
 
 
1035
        *outlen = sprintf (__outbuf, lfmt,
 
1036
                _tm.tm_mday, _tm.tm_mon + 1, 1900+_tm.tm_year,
 
1037
                _tm.tm_hour, _tm.tm_min, _tm.tm_sec, (unsigned) now.tv_nsec/TIMSPECDEVIDER,
 
1038
                (unsigned) gettid(), fac, severity[sev]);
 
1039
 
 
1040
        va_start (arglist, fmt);
 
1041
        *outlen += vsnprintf(__outbuf + *outlen, outsz - *outlen, fmt, arglist);
 
1042
        va_end (arglist);
 
1043
 
 
1044
        *outlen = $MIN(*outlen, outsz);
 
1045
 
 
1046
        /* Add NIL at end of record*/
 
1047
        __outbuf[*outlen] = '\0';
 
1048
 
 
1049
        return  _sev;
 
1050
}
 
1051
 
 
1052
 
 
1053
 
 
1054
unsigned        __util$logd
 
1055
                        (
 
1056
                const char *    fac,
 
1057
                unsigned        sev,
 
1058
                const char *    fmt,
 
1059
                const char *    __mod,
 
1060
                const char *    __fi,
 
1061
                unsigned        __li,
 
1062
                        ...
 
1063
                        )
 
1064
 
 
1065
{
 
1066
va_list arglist;
 
1067
const char      lfmt [] = {"%02u-%02u-%04u %02u:%02u:%02u.%03u " PID_FMT " [%s\\%u] %%%s%3s"},
 
1068
        mfmt [] = {"%02u-%02u-%04u %02u:%02u:%02u.%03u " PID_FMT " [%s\\%s\\%u] %%%s%3s"};
 
1069
char    out[1024];
 
1070
unsigned olen, _sev = sev, opcom = sev & STS$K_SYSLOG;
 
1071
struct tm _tm = {0};
 
1072
struct timespec now = {0};
 
1073
 
 
1074
        sev &= ~STS$K_SYSLOG;
 
1075
 
 
1076
        /*
 
1077
        ** Some sanity check
 
1078
        */
 
1079
        if ( !($ISINRANGE(sev, STS$K_WARN, STS$K_ERROR)) )
 
1080
                sev = STS$K_UNDEF;
 
1081
 
 
1082
        /*
 
1083
        ** Out to buffer "DD-MM-YYYY HH:MM:SS.msec [<function>\<line>]-E-:" prefix
 
1084
        */
 
1085
        ____time(&now);
 
1086
 
 
1087
#ifdef  WIN32
 
1088
        localtime_s(&_tm, (time_t *)&now);
 
1089
#else
 
1090
        localtime_r((time_t *)&now, &_tm);
 
1091
#endif
 
1092
 
 
1093
        olen = __mod
 
1094
                ? sprintf (out, mfmt, _tm.tm_mday, _tm.tm_mon + 1, 1900 + _tm.tm_year,
 
1095
                        _tm.tm_hour, _tm.tm_min, _tm.tm_sec, (unsigned) now.tv_nsec/TIMSPECDEVIDER,
 
1096
                        (unsigned) gettid(), __mod, __fi, __li, fac, severity[sev])
 
1097
                : sprintf (out, lfmt, _tm.tm_mday, _tm.tm_mon + 1, 1900 + _tm.tm_year,
 
1098
                        _tm.tm_hour, _tm.tm_min, _tm.tm_sec, (unsigned) now.tv_nsec/TIMSPECDEVIDER,
 
1099
                        (unsigned) gettid(), __fi, __li, fac, severity[sev]);
 
1100
 
 
1101
        va_start (arglist, __li);
 
1102
        olen += vsnprintf(out + olen, sizeof(out) - olen, fmt, arglist);
 
1103
        va_end (arglist);
 
1104
 
 
1105
        olen = $MIN(olen, sizeof(out) - 1);
 
1106
 
 
1107
        /* Add <LF> at end of record*/
 
1108
        out[olen++] = '\n';
 
1109
 
 
1110
        /* Write to file and flush buffer depending on severity level */
 
1111
        write (logoutput, out, olen );
 
1112
 
 
1113
                /* ARL - for android logcat */
 
1114
        #ifdef ANDROID
 
1115
                __android_log_print(ANDROID_LOG_VERBOSE, fac, "%.*s", olen, out);
 
1116
        #endif
 
1117
 
 
1118
 
 
1119
#ifdef  __SYSLOG__
 
1120
#ifndef WIN32
 
1121
        va_start (arglist, __li);
 
1122
        olen = vsnprintf(out, sizeof(out), fmt, arglist);
 
1123
        va_end (arglist);
 
1124
 
 
1125
        __util$syslog (LOG_USER, LOG_DEBUG, fac, out, olen);
 
1126
 
 
1127
//      syslog( LOG_PID | ((sev & 1) ? LOG_INFO : LOG_ERR), "%.*s", olen, out);
 
1128
#endif
 
1129
#endif  /* __SYSLOG__ */
 
1130
 
 
1131
        return  _sev;
 
1132
}
 
1133
 
 
1134
/*
 
1135
 * Description: Open a file to be used as default output file for $TRACE/$LOG/$DUMPHEX routines.
 
1136
 *              File will be open in shared for read and append mode!
 
1137
 *
 
1138
 *  Input:
 
1139
 *      logfile:        a log file name string, ASCIZ
 
1140
 *      sloghost:       a SYSLOG Host IP address, ASCIZ
 
1141
 *
 
1142
 *  Implicit output:    global logoutput variable
 
1143
 *
 
1144
 *  Return:
 
1145
 *      condition status, see STS$ constants
 
1146
 */
 
1147
int     __util$deflog   (
 
1148
                const char *    logfile,
 
1149
                const char *    sloghost
 
1150
                                )
 
1151
{
 
1152
#ifdef  _WIN32
 
1153
int     mode = _S_IREAD | _S_IWRITE;
 
1154
#else
 
1155
const mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
 
1156
#endif
 
1157
 
 
1158
int     fd = -1;
 
1159
 
 
1160
        /* Is there SYSLOG Host IP ? */
 
1161
        if ( sloghost )
 
1162
                {
 
1163
                inet_pton(AF_INET, sloghost, &slogsock.sin_addr);
 
1164
                slogsock.sin_port = htons(514);
 
1165
                slogsock.sin_family = AF_INET;
 
1166
                }
 
1167
 
 
1168
        if ( !logfile )
 
1169
                return  STS$K_SUCCESS;
 
1170
 
 
1171
        if ( !*logfile)
 
1172
                return  STS$K_SUCCESS;
 
1173
 
 
1174
        if ( 0 > (fd = open(logfile, O_RDWR | O_CREAT | O_APPEND, mode)) )
 
1175
                return  $LOG(STS$K_ERROR, "Error opening log file '%s', errno = %d.", logfile, errno);
 
1176
 
 
1177
        lseek(fd, 0L, SEEK_END);
 
1178
 
 
1179
        logoutput = fd;
 
1180
 
 
1181
        return $LOG(STS$K_SUCCESS, "Log file '%s' has been opened.", logfile);
 
1182
 
 
1183
}
 
1184
 
 
1185
 
 
1186
/*
 
1187
 * Description: compare a current file size with the 'limit' and rewind a current file pointer at begining of file.
 
1188
 *
 
1189
 *  Return:
 
1190
 *      condition status, see STS$ constants
 
1191
 */
 
1192
int     __util$rewindlogfile    (
 
1193
                        int     limit
 
1194
                                )
 
1195
{
 
1196
int     status;
 
1197
 
 
1198
        if ( (logoutput == STDOUT_FILENO) || !limit )
 
1199
                return  STS$K_SUCCESS;
 
1200
 
 
1201
        if ( 0 > (status = lseek (logoutput, 0, SEEK_CUR)) )
 
1202
                return  $LOG(STS$K_ERROR, "lseek() -> %d", errno);
 
1203
 
 
1204
        if ( status < limit )
 
1205
                return  STS$K_SUCCESS;
 
1206
 
 
1207
        if ( 0 > (status = lseek(logoutput, 0L, SEEK_SET)) )
 
1208
                $LOG(STS$K_ERROR, "fseek() -> %d", errno);
 
1209
 
 
1210
#ifndef WIN32
 
1211
        if ( 0  > (ftruncate(logoutput, status )) )
 
1212
                $LOG(STS$K_ERROR, "ftruncate(%d, %d) -> %d", logoutput, status, errno);
 
1213
#endif
 
1214
 
 
1215
 
 
1216
        return  STS$K_SUCCESS;
 
1217
}
 
1218
 
 
1219
 
 
1220
 
 
1221
/*
 
1222
        http://util.deltatelecom.ru/ovms82src/debug/lis/strings.lis
 
1223
 
 
1224
                                Source Listing                  19-NOV-2004 08:39:18  Compaq C V6.5-001-48BCD           Page 42
 
1225
                                                                 4-MAR-2003 15:31:10  $1$DGA1016:[DEBUG_2.SRC]STRINGS.C;1
 
1226
*/
 
1227
 
 
1228
/*++***********************************************************************/
 
1229
/*
 
1230
 * FUNCTION : C_STR$pattern_match
 
1231
 *
 
1232
 * FUNCTIONALITY :
 
1233
 *  This function is passed a pattern and a string to match against the
 
1234
 *  pattern.  The pattern may contain wildcards (*,%), where '*' matches
 
1235
 *  0 or more occurrences of anything, and '%' matches any one character.
 
1236
 *  In addition, a '\' in the pattern string will translate the next
 
1237
 *  character as literal.  This is a recursive routine.
 
1238
 *
 
1239
 * COMMUNICATION :
 
1240
 *
 
1241
 *  PROTOTYPE/PARAMETERS :
 
1242
 *      (see below)
 
1243
 *
 
1244
 *  RETURN VALUE :
 
1245
 *      int : success or failure
 
1246
 *
 
1247
 *  ERROR HANDLING :
 
1248
 *
 
1249
 * ALGORITHM :
 
1250
 *  establish a pointer to the first character in the magic string
 
1251
 *  and a pointer to the first character in the text string.
 
1252
 *
 
1253
 *   while there are still characters:
 
1254
 *    If the current character in the magic string is not a wild card
 
1255
 *    and they are different, then declare it a mismatch.  If they
 
1256
 *    point to identical characters, then advance each pointer by one
 
1257
 *    and go aroung the loop again.
 
1258
 *
 
1259
 *    If the magic string pointer points at a WILD_PERCENT, then advance
 
1260
 *    both pointers, regardless of what's in the test string.
 
1261
 *
 
1262
 *    If the magic pointer points to WILD_STAR, then try matching the
 
1263
 *    rest of the magic string at each character position in the text
 
1264
 *    string by calling C_STR$pattern_match (i.e. this function)
 
1265
 *    recursively.  If any of those succeed then declare this one a success.
 
1266
 *
 
1267
 * CAVEATS :
 
1268
 *  (1) pattern$ is assumed to be preprocessed, i.e, * replaced by WILD_STAR,
 
1269
 *     '%' replaced by WILD_PERCENT, '\<character>' by '<character>', etc.
 
1270
 *
 
1271
 *  (2) str$, however, is LITERAL, ie, it does not have wildcards or
 
1272
 *      '\<character>', etc.  *, %, and \ are given no special treatment.
 
1273
 *
 
1274
 * HISTORY :
 
1275
 *
 
1276
 *  V0 - V7
 
1277
 *
 
1278
 *  12-JUL-89   A. Seigel
 
1279
 *      (1) Created this function.
 
1280
 *
 
1281
 *  11-SEP-89   A. Seigel
 
1282
 *      (1) Fixed bug with literals (\) in pattern$.
 
1283
 *
 
1284
 
 
1285
                       Source Listing                  19-NOV-2004 08:39:18  Compaq C V6.5-001-48BCD           Page 43
 
1286
                                                        4-MAR-2003 15:31:10  $1$DGA1016:[DEBUG_2.SRC]STRINGS.C;1
 
1287
 
 
1288
 *  V8
 
1289
 *
 
1290
 *  24-MAY-1990        J. Bell
 
1291
 *      (1) ANSI-ized declaration.
 
1292
 *
 
1293
 *
 
1294
 *      27-NOV-2015     RRL     Some reformating.
 
1295
 */
 
1296
/*--***********************************************************************/
 
1297
 
 
1298
#define WILD_PERCENT    '%'
 
1299
#define WILD_STAR       '*'
 
1300
 
 
1301
#ifndef FALSE
 
1302
#define FALSE   0
 
1303
#endif
 
1304
 
 
1305
#ifndef TRUE
 
1306
#define TRUE    1
 
1307
#endif
 
1308
 
 
1309
 
 
1310
int     __util$pattern_match    (
 
1311
                char    *       str$,        /* A LITERAL string to match */
 
1312
                char    *       pattern$     /* Pattern, with potential wildcards (*,%) to * match the string.*/
 
1313
                                )
 
1314
{
 
1315
int done = FALSE, matched_to_eos = FALSE;
 
1316
 
 
1317
        while( (*pattern$ != '\0') && (!done) && ( ((*str$=='\0') && ( (*pattern$==WILD_STAR)) ) || (*str$!='\0')) )
 
1318
                {
 
1319
                switch (*pattern$)
 
1320
                        {
 
1321
                        case WILD_STAR:
 
1322
                                pattern$++;
 
1323
                                matched_to_eos = FALSE;
 
1324
                                while ( (*str$ != '\0') && (! ( matched_to_eos = __util$pattern_match( str$++, pattern$))));
 
1325
 
 
1326
                                if ( matched_to_eos )
 
1327
                                        {
 
1328
                                        while (*str$ != '\0') str$++;
 
1329
                                        while (*pattern$ != '\0') pattern$++;
 
1330
                                        }
 
1331
                                break;
 
1332
 
 
1333
                        case WILD_PERCENT:
 
1334
                                pattern$++;
 
1335
                                str$++;
 
1336
                                break;
 
1337
 
 
1338
                        /* case '\\':*/
 
1339
                        /* pattern$++;*/
 
1340
 
 
1341
                        default:
 
1342
                                if (*str$ == *pattern$)
 
1343
                                        {
 
1344
                                        str$++;
 
1345
                                        pattern$++;
 
1346
                                        }
 
1347
                                else done = TRUE;
 
1348
                        }
 
1349
                }
 
1350
 
 
1351
        while (*pattern$ == WILD_STAR) pattern$++;
 
1352
 
 
1353
        return ( (*str$ == '\0') && (*pattern$ == '\0') );
 
1354
 
 
1355
 
 
1356
}
 
1357
/******************* end of C_STR$pattern_match *******************/
 
1358
 
 
1359
#if     0
 
1360
#ifndef WIN32
 
1361
void    __util$traceback        (void)
 
1362
{
 
1363
int     i, nptrs;
 
1364
void *  buffer[128];
 
1365
char ** strings;
 
1366
 
 
1367
        nptrs = backtrace(buffer, sizeof(buffer));
 
1368
 
 
1369
        $LOG(STS$K_INFO, " --------------------- TRACEBACK BEGIN (%d) ------", nptrs);
 
1370
 
 
1371
        if ( !(strings = backtrace_symbols(buffer, nptrs)) )
 
1372
                {
 
1373
                perror("backtrace_symbols");
 
1374
 
 
1375
                exit(EXIT_FAILURE);
 
1376
                }
 
1377
 
 
1378
        for (i = 0; i < nptrs; i++)
 
1379
                $LOG(STS$K_INFO, "%d\t%s", i, strings[i]);
 
1380
 
 
1381
        $LOG(STS$K_INFO, " --------------------- TRACEBACK END ------");
 
1382
 
 
1383
}
 
1384
 
 
1385
#endif
 
1386
#endif
 
1387
 
 
1388
 
 
1389
#ifndef WIN32
 
1390
#pragma GCC diagnostic pop
 
1391
#endif
 
1392
 
 
1393
 
 
1394
 
 
1395
 
 
1396
 
 
1397
#ifdef  __CRC32_TAB__
 
1398
 
 
1399
extern unsigned int crc32c_tab[];
 
1400
 
 
1401
 
 
1402
#else
 
1403
#define __CRC32_TAB__   1
 
1404
 
 
1405
/*      CRC32-C */
 
1406
static const  unsigned int __crc32c_tab__[] = {
 
1407
        0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f,
 
1408
        0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
 
1409
        0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2,
 
1410
        0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
 
1411
        0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
 
1412
        0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
 
1413
        0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c,
 
1414
        0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
 
1415
        0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423,
 
1416
        0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
 
1417
        0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106,
 
1418
        0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
 
1419
        0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d,
 
1420
        0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
 
1421
        0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
 
1422
        0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
 
1423
        0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7,
 
1424
        0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
 
1425
        0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa,
 
1426
        0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
 
1427
        0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81,
 
1428
        0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
 
1429
        0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84,
 
1430
        0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
 
1431
        0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
 
1432
        0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
 
1433
        0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e,
 
1434
        0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
 
1435
        0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55,
 
1436
        0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
 
1437
        0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28,
 
1438
        0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
 
1439
        0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f,
 
1440
        0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
 
1441
        0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
 
1442
        0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
 
1443
        0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69,
 
1444
        0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
 
1445
        0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc,
 
1446
        0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
 
1447
        0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693,
 
1448
        0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
 
1449
        0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
 
1450
};
 
1451
#endif  /* __CRC32_TAB__ */
 
1452
 
 
1453
unsigned int    __util$crc32c (unsigned int crc, const void *buf, size_t buflen)
 
1454
{
 
1455
const unsigned char  *p = (unsigned char *) buf;
 
1456
 
 
1457
        crc = crc ^ ~0U;
 
1458
 
 
1459
        while (buflen--)
 
1460
                crc = __crc32c_tab__[(crc ^ *p++) & 0xFF] ^ (crc >> 8);
 
1461
 
 
1462
        return crc ^ ~0U;
 
1463
}
 
1464
 
 
1465
 
 
1466
 
 
1467
 
 
1468
 
 
1469
 
 
1470
/*
 
1471
**  STRSTR/_STRSTR64
 
1472
**
 
1473
**  The 'strstr' function locates the first occurrence in the string pointed
 
1474
**  to by 's1' of the sequence of characters in the string pointed to by 's2'.
 
1475
**
 
1476
**  Return values:
 
1477
**
 
1478
**      non-NULL    the address of the located string
 
1479
**      NULL        indicates that the string was not found
 
1480
*/
 
1481
char *  __util$strstr
 
1482
                        (
 
1483
                char    * s1,
 
1484
                size_t  s1len,
 
1485
                char    * s2,
 
1486
                size_t  s2len
 
1487
                        )
 
1488
{
 
1489
char    *p1 = s1, *p2 = s2 + 1;
 
1490
size_t  p1len = s1len, cmplen = s2len - 1;
 
1491
 
 
1492
        /*
 
1493
         * Sanity check ...
 
1494
         */
 
1495
        if ( !s1 || !s2 || !s1len || !s2len )
 
1496
                return  NULL;
 
1497
 
 
1498
        if ( s1len < s2len )
 
1499
                return  NULL;
 
1500
 
 
1501
        /*
 
1502
         * Special check for single-byte substring
 
1503
         */
 
1504
        if ( !cmplen )
 
1505
                return  memchr(s1, *s2, s1len);
 
1506
 
 
1507
        /*
 
1508
        **  Find the first character of s2 in the remaining string.  If it is
 
1509
        **  found, compare the rest of s2.
 
1510
        */
 
1511
        while ( p1len && (p1 = memchr(p1, *s2, p1len)) )
 
1512
                {
 
1513
                /*
 
1514
                 * Is the rest of the p1 is more then length of the s2 ?
 
1515
                 * No ?! Stop comparing ,  return the NULL pointer.
 
1516
                 */
 
1517
                if ( (s1len - (p1 - s1)) < cmplen )
 
1518
                        return  (NULL);
 
1519
 
 
1520
                if ( !memcmp(p1 + 1,  p2, cmplen) )
 
1521
                        return  (p1);
 
1522
 
 
1523
                p1++;
 
1524
                p1len = s1len - (p1 - s1);
 
1525
                };
 
1526
 
 
1527
 
 
1528
        /*
 
1529
        **  No match.  Return the NULL pointer.
 
1530
        */
 
1531
        return((char *) NULL);
 
1532
}
 
1533
 
 
1534
 
 
1535
 
 
1536
 
 
1537
 
 
1538
 
 
1539
 
 
1540
 
 
1541
 
 
1542
 
 
1543
#if __util_DEBUG__
 
1544
 
 
1545
 
 
1546
/*
 
1547
 * stc_msg_vformat
 
1548
 *
 
1549
 * The core formatting routine.
 
1550
 * Do NOT use sprintf-style formatting codes in
 
1551
 * message strings! Use the formatting directives
 
1552
 * below:
 
1553
 * !AD
 
1554
 * !AZ
 
1555
 * !AC
 
1556
 * !U{L, W, B} = unsigned int, short, byte
 
1557
 * !S{L, W, B} = signed int, short, byte
 
1558
 * !X{L, W, B} = hexadecimal int, short, byte
 
1559
 * !P = pointer
 
1560
 * !! = exclamation point
 
1561
 */
 
1562
#ifdef  WIN32
 
1563
#define snprintf(buf, len, format,...)  _snprintf_s(buf, len, len, format, __VA_ARGS__)
 
1564
#endif
 
1565
 
 
1566
static int      __util$vfao (char *fmt, char *buf, size_t bufsz, va_list ap)
 
1567
{
 
1568
int     len;
 
1569
char    tmpbuf[32], *outp = buf;
 
1570
 
 
1571
        for ( ;bufsz && *fmt; )
 
1572
                {
 
1573
                if (*fmt != '!')
 
1574
                        {
 
1575
                        *outp++ = *fmt++;
 
1576
                        bufsz--;
 
1577
 
 
1578
                        continue;
 
1579
                        }
 
1580
 
 
1581
                if ( !(*(++fmt)) )
 
1582
                        break;
 
1583
 
 
1584
                /* !!
 
1585
                */
 
1586
                if (*fmt == '!')
 
1587
                        {
 
1588
                        *outp++ = *fmt++;
 
1589
                        bufsz--;
 
1590
 
 
1591
                        continue;
 
1592
                        }
 
1593
 
 
1594
                /* !X{L, W, B}, U{L, W, B}, S{L, W, B}
 
1595
                */
 
1596
                if (*fmt == 'U' || *fmt == 'X' || *fmt == 'S' )
 
1597
                        {
 
1598
                        unsigned long val = 0;
 
1599
 
 
1600
                        if (*(fmt+1) == 'B')
 
1601
                                {
 
1602
                                val = va_arg(ap, unsigned char);
 
1603
                                len = snprintf(tmpbuf, sizeof(tmpbuf),  ((*fmt == 'X') ?  "0x%02X" : (*fmt == 'U') ? "%3u" : "%3d"),
 
1604
                                        (unsigned char) val);
 
1605
                                }
 
1606
                        else if (*(fmt + 1) == 'W')
 
1607
                                {
 
1608
                                val = va_arg(ap, unsigned short);
 
1609
                                len = snprintf(tmpbuf, sizeof(tmpbuf),  ((*fmt == 'X') ?  "0x%04X" : ( *fmt == 'U') ? "%5u" : "%6d"),
 
1610
                                        (unsigned short) val);
 
1611
                                }
 
1612
                        else if (*(fmt + 1) == 'L')
 
1613
                                {
 
1614
                                val = va_arg(ap, unsigned long);
 
1615
                                len = snprintf(tmpbuf, sizeof(tmpbuf),  ((*fmt == 'X') ?  "0x%08X": ( *fmt == 'U') ? "%11u" : "%11d"),
 
1616
                                        (unsigned long) val);
 
1617
 
 
1618
                                }
 
1619
                        else    continue;
 
1620
 
 
1621
                        if ( len < 0 )
 
1622
                                break;
 
1623
 
 
1624
                        if (len >= bufsz)
 
1625
                                len = bufsz - 1;
 
1626
 
 
1627
                        memcpy(outp, tmpbuf, len);
 
1628
 
 
1629
                        outp    += len;
 
1630
                        bufsz   -= len;
 
1631
                        fmt     += 2;
 
1632
 
 
1633
                        continue;
 
1634
                        }
 
1635
 
 
1636
 
 
1637
 
 
1638
 
 
1639
                /* !P
 
1640
                */
 
1641
                if (*fmt == 'P')
 
1642
                        {
 
1643
                        if ( 0 > (len = snprintf(tmpbuf, sizeof(tmpbuf), "@%p", va_arg(ap, void *))) )
 
1644
                                break;
 
1645
 
 
1646
                        if (len >= bufsz)
 
1647
                                len = bufsz - 1;
 
1648
 
 
1649
                        memcpy(outp, tmpbuf, len);
 
1650
 
 
1651
                        outp    += len;
 
1652
                        bufsz   -= len;
 
1653
                        fmt     += 1;
 
1654
 
 
1655
                        continue;
 
1656
                        }
 
1657
 
 
1658
                /* !AD, !AC, !AZ ...    */
 
1659
                if (*fmt == 'A')
 
1660
                        {
 
1661
                        unsigned int slen = 0;
 
1662
                        char *ptr;
 
1663
 
 
1664
                        if (*(fmt+1) == 'D')
 
1665
                                {
 
1666
                                slen    = va_arg(ap, unsigned int);
 
1667
                                ptr     = va_arg(ap, char *);
 
1668
 
 
1669
                                }
 
1670
                        else if (*(fmt+1) == 'Z')
 
1671
                                {
 
1672
                                ptr     = va_arg(ap, char *);
 
1673
                                slen    = (unsigned int) strnlen(ptr, bufsz);
 
1674
                                }
 
1675
                        else if (*(fmt+1) == 'C')
 
1676
                                {
 
1677
                                ptr     = va_arg(ap, char *);
 
1678
                                slen    = *(ptr++);
 
1679
                                }
 
1680
                        else    continue;
 
1681
 
 
1682
                        if (slen >= (unsigned int) bufsz)
 
1683
                                slen = (unsigned int)bufsz - 1;
 
1684
 
 
1685
                        memcpy(outp, ptr, slen);
 
1686
 
 
1687
                        outp    += slen;
 
1688
                        bufsz   -= slen;
 
1689
                        fmt     += 2;
 
1690
 
 
1691
                        continue;
 
1692
                }
 
1693
 
 
1694
        // Unrecognized directive here, just loop back up to the top
 
1695
        } /* while bufsz > 0 && *fmt != null char */
 
1696
 
 
1697
        *outp = '\0';
 
1698
        return (outp - buf);
 
1699
}
 
1700
 
 
1701
 
 
1702
 
 
1703
int     __util$fao (void *fmt, void *buf, size_t bufsz, ...)
 
1704
{
 
1705
va_list ap;
 
1706
int result;
 
1707
 
 
1708
        va_start(ap, bufsz);
 
1709
        result = __util$vfao((char *) fmt, (char*) buf, bufsz, ap);
 
1710
        va_end(ap);
 
1711
 
 
1712
        return result;
 
1713
}
 
1714
 
 
1715
 
 
1716
 
 
1717
struct _stm_buf                         /* One item of Stream buffer                    */
 
1718
{
 
1719
        ENTRY   links;                  /* Left, right links, used by queue macros      */
 
1720
        int     len;                    /* Actual length of data in the buffer          */
 
1721
        int     ref;                    /* Count of reference                           */
 
1722
        char buf[32];           /* Buffer itself                                */
 
1723
} _stm_buf_area[32];            /* We declare a static buffers area             */
 
1724
 
 
1725
QUEUE   free_bufs = QUEUE_INITIALIZER,
 
1726
        busy_bufs = QUEUE_INITIALIZER;
 
1727
 
 
1728
 
 
1729
int     main (int argc, char *argv[])
 
1730
{
 
1731
int count, bcnt;
 
1732
char    buf[1024];
 
1733
 
 
1734
 
 
1735
        bcnt  = __util$fao("!UL, !UW, !UB", buf, sizeof(buf), 1, 2, 3);
 
1736
 
 
1737
        for (bcnt = 0; bcnt < 32; bcnt++)
 
1738
                $INSQTAIL(&free_bufs, &_stm_buf_area[bcnt], &count);
 
1739
 
 
1740
        return  1;
 
1741
}
 
1742
 
 
1743
 
 
1744
 
 
1745
 
 
1746
#if     0
 
1747
// Factory macros
 
1748
#undef  $DEFMSG
 
1749
 
 
1750
#define $DEFMSGLIST \
 
1751
        $DEFMSG(util,  0, S, NORMAL,            "normal successful completion") \
 
1752
        $DEFMSG(util,  1, W, WARNING,   "unknown warning") \
 
1753
        $DEFMSG(util,  2, E, ERROR,             "unknown error") \
 
1754
        $DEFMSG(util,  3, F, FATALERR,  "unknown fatal error") \
 
1755
        $DEFMSG(util, 13, E, NUMCNVERR, "numeric conversion error: !SL") \
 
1756
        #DEFMSG(util,122, E, LIBRDERR,  "error reading library file !SZ")
 
1757
 
 
1758
#define $DEFMSG(fac, num, sev, nam, txt) #nam,
 
1759
static const char *__$msgmnemonics[] = {
 
1760
        $DEFMSGLIST
 
1761
};
 
1762
#undef  $DEFMSG
 
1763
 
 
1764
#define $DEFMSG(fac, num, sev,nam, txt) txt,
 
1765
static const char *__$msgtexts[] = {
 
1766
        $DEFMSGLIST
 
1767
};
 
1768
#undef  $DEFMSG
 
1769
 
 
1770
#define $DEFMSG(fac, num, sev, nam, txt) #define fac##txt num
 
1771
static const char *__$msgtexts[] = {
 
1772
        $DEFMSGLIST
 
1773
};
 
1774
 
 
1775
#define $DEFMSG(fac, num, sev, nam, txt) fac##__##nam =  STC_CODE_##typ(msg),
 
1776
typedef enum {
 
1777
STATCODES
 
1778
} statcode_t;
 
1779
#undef STATCODE
 
1780
 
 
1781
 
 
1782
 
 
1783
//#define       $MSGCOUNT (sizeof(__$##fac##msgmnemonics)/sizeof(__$##fac##msgmnemonics))
 
1784
 
 
1785
#endif
 
1786
 
 
1787
 
 
1788
 
 
1789
#if     0
 
1790
OPTS    opts [] = {
 
1791
                OPTS_NULL
 
1792
};
 
1793
 
 
1794
 
 
1795
#define IOBUFSZ         4096            /* A size of single buffer                      */
 
1796
#define IOBUFCNT        4096            /* A total number of buffers                    */
 
1797
 
 
1798
struct _stm_buf                         /* One item of Stream buffer                    */
 
1799
{
 
1800
        ENTRY   links;                  /* Left, right links, used by queue macros      */
 
1801
        int     len;                    /* Actual length of data in the buffer          */
 
1802
        int     ref;                    /* Count of reference                           */
 
1803
        char buf[IOBUFSZ];              /* Buffer itself                                */
 
1804
} _stm_buf_area[IOBUFCNT];              /* We declare a static buffers area             */
 
1805
 
 
1806
QUEUE   free_bufs = QUEUE_INITIALIZER,
 
1807
        busy_bufs = QUEUE_INITIALIZER;
 
1808
 
 
1809
 
 
1810
DWORD WINAPI worker_f2b (void *arg)
 
1811
{
 
1812
int     status, count, i;
 
1813
struct _stm_buf * sbuf;
 
1814
 
 
1815
        $LOG(STS$K_INFO, "tid : %d running ...", GetCurrentThreadId());
 
1816
 
 
1817
        for (i = 0; i < 10000 * 500; i++)
 
1818
                {
 
1819
                if ( !(i %  10000) )
 
1820
                        $LOG(STS$K_INFO, "tid:%d, iteration %d", GetCurrentThreadId(), i);
 
1821
 
 
1822
                if ( !(1 & (status = $REMQHEAD(&free_bufs, &sbuf, &count))) )
 
1823
                        {
 
1824
                        $LOG(STS$K_ERROR, "$REMQHEAD() ->  %d, count = %d", status, count);
 
1825
                        continue;
 
1826
                        }
 
1827
 
 
1828
                if ( !sbuf )
 
1829
                        $LOG(STS$K_ERROR, "sbuf == NULL");
 
1830
 
 
1831
 
 
1832
                if ( !(1 & (status = status = $INSQTAIL(&busy_bufs, sbuf, &count))) )
 
1833
                        $LOG(STS$K_ERROR, "$INSQTAIL() ->  %d", status);
 
1834
                }
 
1835
 
 
1836
        return  status;
 
1837
}
 
1838
 
 
1839
DWORD WINAPI worker_b2f (void *arg)
 
1840
{
 
1841
        int     status, count, i;
 
1842
        struct _stm_buf * sbuf;
 
1843
 
 
1844
        $LOG(STS$K_INFO, "tid : %d running ...", GetCurrentThreadId());
 
1845
 
 
1846
        for (i = 0; i < 10000 * 500; i++)
 
1847
                {
 
1848
                if ( !(i %  10000) )
 
1849
                        $LOG(STS$K_INFO, "tid:%d, iteration %d", GetCurrentThreadId(), i);
 
1850
 
 
1851
                if ( !(1 & (status = $REMQHEAD(&busy_bufs, &sbuf, &count))) )
 
1852
                        {
 
1853
                        $LOG(STS$K_ERROR, "$REMQHEAD() ->  %d, count = %d", status, count);
 
1854
                        continue;
 
1855
                        }
 
1856
 
 
1857
 
 
1858
                if ( !sbuf )
 
1859
                        $LOG(STS$K_ERROR, "sbuf == NULL");
 
1860
 
 
1861
 
 
1862
                if ( !(1 & (status = status = $INSQTAIL(&free_bufs, sbuf, &count))) )
 
1863
                        $LOG(STS$K_ERROR, "$INSQTAIL() ->  %d", status);
 
1864
                }
 
1865
 
 
1866
        return  status;
 
1867
}
 
1868
 
 
1869
 
 
1870
 
 
1871
int     main (int argc, char *argv[])
 
1872
{
 
1873
int count, i;
 
1874
HANDLE scan_tid;
 
1875
char    buf[1024];
 
1876
 
 
1877
 
 
1878
        i = __util$fao("!UL, !UW, !UB", buf, sizeof(buf), 1, 2, 3);
 
1879
 
 
1880
 
 
1881
        /*
 
1882
        **
 
1883
        */
 
1884
        i = __util$pattern_match("ch33---0010904935.torrent", "*.torrent");
 
1885
 
 
1886
        i = __util$pattern_match("Hello World!!!", "*llo*");
 
1887
 
 
1888
 
 
1889
 
 
1890
 
 
1891
        __util$getparams(argc, argv, opts);
 
1892
//      __util$setlogfile("logfile2.log");
 
1893
 
 
1894
 
 
1895
        //InitializeSRWLock(&free_bufs.lock);
 
1896
 
 
1897
 
 
1898
        for (i = 0; i < IOBUFCNT; i++)
 
1899
                $INSQTAIL(&free_bufs, &_stm_buf_area[i], &count);
 
1900
 
 
1901
 
 
1902
 
 
1903
        for (i = 0; i <  32; i++)
 
1904
                {
 
1905
                if ( (scan_tid = CreateThread(NULL, 0, worker_f2b, NULL, 0, NULL)) == NULL )
 
1906
                        return $LOG(STS$K_ERROR, "Creation streaming thread was failed : %d", GetLastError());
 
1907
                }
 
1908
 
 
1909
 
 
1910
        for (i = 0; i <  32; i++)
 
1911
                {
 
1912
                if ( (scan_tid = CreateThread(NULL, 0, worker_b2f, NULL, 0, NULL)) == NULL )
 
1913
                        return $LOG(STS$K_ERROR, "Creation streaming thread was failed : %d", GetLastError());
 
1914
                }
 
1915
 
 
1916
        WaitForSingleObject(scan_tid, INFINITE);
 
1917
 
 
1918
        return STS$K_SUCCESS;
 
1919
}
 
1920
#endif
 
1921
#endif