0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037 #include <unistd.h>
0038 #include <stdio.h>
0039 #include <errno.h>
0040 #include <stdlib.h>
0041 #include <ndrx_config.h>
0042 #include <atmi.h>
0043 #include <atmi_int.h>
0044 #include <sys_unix.h>
0045 #include <ctype.h>
0046 #include <limits.h>
0047
0048 #include <ubf.h>
0049 #include <ferror.h>
0050 #include <fieldtable.h>
0051 #include <fdatatype.h>
0052
0053 #include <ndrstandard.h>
0054 #include <ndebug.h>
0055 #include "buildtools.h"
0056
0057
0058
0059
0060
0061
0062
0063 exprivate bs_svcnm_lst_t *M_bs_svcnm_lst = NULL;
0064 exprivate bs_svcnm_lst_t *M_bs_funcnm_lst = NULL;
0065
0066
0067
0068
0069
0070
0071 exprivate int chk_listed_svcnm(char *svcnm)
0072 {
0073 bs_svcnm_lst_t * ret = NULL;
0074
0075 EXHASH_FIND_STR( M_bs_svcnm_lst, svcnm, ret);
0076
0077 if (NULL==ret)
0078 {
0079 NDRX_LOG(log_debug, "Service name [%s] not in list", svcnm);
0080 goto out;
0081 }
0082
0083 out:
0084 if (NULL==ret)
0085 return EXFAIL;
0086 else
0087 return EXSUCCEED;
0088 }
0089
0090
0091
0092
0093
0094
0095
0096
0097 exprivate int chk_listed_funcnm(char *funcnm, int funcreg)
0098 {
0099 bs_svcnm_lst_t * ret = NULL;
0100
0101 EXHASH_FIND_STR( M_bs_funcnm_lst, funcnm, ret);
0102
0103 if (NULL==ret)
0104 {
0105 NDRX_LOG(log_debug, "Function name [%s] not in list", funcnm);
0106 goto out;
0107 }
0108
0109 if (funcreg && !ret->funcreg)
0110 {
0111 ret->funcreg = EXTRUE;
0112 }
0113
0114 out:
0115 if (NULL==ret)
0116 {
0117 return EXFAIL;
0118 }
0119 else
0120 {
0121 return EXSUCCEED;
0122 }
0123 }
0124
0125
0126
0127
0128
0129
0130
0131 exprivate int add_listed_svcnm(char *svcnm, char *funcnm)
0132 {
0133 bs_svcnm_lst_t * ret = NDRX_CALLOC(1, sizeof(bs_svcnm_lst_t));
0134
0135 if (NULL==ret)
0136 {
0137 int err = errno;
0138
0139 _Nset_error_fmt(NEMALLOC, "Failed to alloc: %s", strerror(err));
0140
0141 NDRX_LOG(log_error,
0142 "Failed to alloc bs_svcnm_lst_t: %s", strerror(errno));
0143 goto out;
0144 }
0145
0146 NDRX_STRCPY_SAFE(ret->svcnm, svcnm);
0147 NDRX_STRCPY_SAFE(ret->funcnm, funcnm);
0148
0149 EXHASH_ADD_STR( M_bs_svcnm_lst, svcnm, ret );
0150
0151 out:
0152 if (NULL==ret)
0153 {
0154 return EXFAIL;
0155 }
0156
0157 return EXSUCCEED;
0158 }
0159
0160
0161
0162
0163
0164
0165
0166
0167 exprivate int add_listed_funcnm(char *funcnm, int funcreg)
0168 {
0169 bs_svcnm_lst_t * ret = NDRX_CALLOC(1, sizeof(bs_svcnm_lst_t));
0170
0171 if (NULL==ret)
0172 {
0173 int err = errno;
0174 _Nset_error_fmt(NEMALLOC, "Failed to alloc: %s", strerror(err));
0175 NDRX_LOG(log_error,
0176 "Failed to alloc bs_svcnm_lst_t: %s", strerror(errno));
0177 goto out;
0178 }
0179
0180 NDRX_STRCPY_SAFE(ret->funcnm, funcnm);
0181 ret->funcreg = funcreg;
0182 EXHASH_ADD_STR( M_bs_funcnm_lst, funcnm, ret );
0183
0184 out:
0185 if (NULL==ret)
0186 {
0187 return EXFAIL;
0188 }
0189
0190 return EXSUCCEED;
0191 }
0192
0193
0194
0195
0196
0197
0198
0199
0200
0201
0202
0203
0204
0205
0206
0207
0208
0209 exprivate int parse_s_string(char *p_string)
0210 {
0211 int ret = EXSUCCEED;
0212 char svcnm[128+1]={EXEOS};
0213 char funcnm[MAXTIDENT+1]={EXEOS};
0214 char *f=NULL, *p=NULL, *str=NULL;
0215
0216 f=strchr(p_string, ':');
0217
0218 if (NULL != f)
0219 {
0220 NDRX_STRCPY_SAFE(funcnm, f+1);
0221 *f = EXEOS;
0222 }
0223
0224
0225
0226
0227 if (NULL != f && p_string==f)
0228 {
0229 NDRX_LOG(log_debug, "FUNCNM=[%s] Only", funcnm);
0230
0231 if (EXSUCCEED != chk_listed_funcnm(funcnm, EXTRUE) &&
0232 EXSUCCEED!=add_listed_funcnm(funcnm, EXTRUE))
0233 {
0234 EXFAIL_OUT(ret);
0235 }
0236
0237 return ret;
0238 }
0239
0240
0241 for (p = strtok_r(p_string, ",", &str);p != NULL; p = strtok_r(NULL, ",", &str))
0242 {
0243
0244 if (NULL != f)
0245 {
0246 NDRX_STRCPY_SAFE(funcnm, f+1);
0247 }
0248
0249 else
0250 {
0251 NDRX_STRCPY_SAFE(funcnm, p);
0252 }
0253
0254 NDRX_STRCPY_SAFE(svcnm, p);
0255
0256 NDRX_LOG(log_debug, "SVCNM=[%s] FUNCNM=[%s]\n", svcnm, funcnm);
0257
0258
0259 if (EXSUCCEED != chk_listed_funcnm(funcnm, EXFALSE) &&
0260 EXSUCCEED!=add_listed_funcnm(funcnm, EXFALSE))
0261 {
0262 NDRX_LOG(log_error, "Failed to list the function name");
0263 EXFAIL_OUT(ret);
0264 }
0265
0266 if (EXSUCCEED == chk_listed_svcnm(svcnm))
0267 {
0268 NDRX_LOG(log_debug,
0269 "Warning svcnm=[%s] already exist SKIP!!!", svcnm);
0270
0271 continue;
0272 }
0273
0274 if (EXSUCCEED!=add_listed_svcnm(svcnm, funcnm))
0275 {
0276 NDRX_LOG(log_error, "Failed to add service [%s]", svcnm);
0277 EXFAIL_OUT(ret);
0278 }
0279 }
0280
0281
0282 out:
0283 return ret;
0284 }
0285
0286
0287
0288
0289
0290 exprivate void print_help(char *name)
0291 {
0292 fprintf(stderr, "Usage: %s [options]\n", name);
0293 fprintf(stderr, "Options:\n");
0294 fprintf(stderr, " -n Do not generate main() entry\n");
0295 fprintf(stderr, " -C COBOL code (RFU)\n");
0296 fprintf(stderr, " -s {@filename|svc1,svc2,...:func|:func}\n");
0297 fprintf(stderr, " Services to be advertised. In case of @filename. \n");
0298 fprintf(stderr, " Each line in file shall contain the {svc1,svc2,...:func|:func} expression.\n");
0299 fprintf(stderr, " Lines starting with # are ignored\n");
0300 fprintf(stderr, " -o <filename> Output compiled file name, default is SERVER\n");
0301 fprintf(stderr, " -f <firstfiles> File names to be passed to compiler, on left side before Enduro/X libraries\n");
0302 fprintf(stderr, " -a <firstfiles> Alias of -f\n");
0303 fprintf(stderr, " -l <lastfiles> File names to be passed to compiler, on right side after Enduro/X libraries\n");
0304 fprintf(stderr, " -r <rm_name> Resource manager name to be searched in $NDRX_HOME/udataobj/RM.\n");
0305 fprintf(stderr, " If not set, null switch is used.\n");
0306 fprintf(stderr, " -g <rm_name> Same as -r\n");
0307 fprintf(stderr, " -k Keep generated source file\n");
0308 fprintf(stderr, " -t Program is built for threaded mode\n");
0309 fprintf(stderr, " -v Verbose mode (print build command)\n");
0310 fprintf(stderr, " -h Print this help\n");
0311 }
0312
0313
0314
0315
0316
0317
0318
0319 exprivate int parse_s_file(char *infile)
0320 {
0321 int ret = EXSUCCEED;
0322 FILE * fp;
0323 char buf[NDRX_BPATH_MAX+1];
0324
0325 if (NULL==(fp=NDRX_FOPEN(infile, "r")))
0326 {
0327 int err = errno;
0328
0329 _Nset_error_fmt(NENOENT, "Failed to open file [%s] for reading: %s",
0330 infile, strerror(err));
0331
0332 NDRX_LOG(log_error, "Failed to open file [%s] for reading: %s",
0333 infile, strerror(errno));
0334 EXFAIL_OUT(ret);
0335 }
0336
0337 while (NULL!=fgets(buf, sizeof(buf), fp))
0338 {
0339 char *stripped;
0340 ndrx_str_rstrip(buf," \t\n\r");
0341 stripped = ndrx_str_lstrip_ptr(buf," \t\n\r");
0342
0343 if (EXEOS==stripped[0] || '#'==stripped[0])
0344 {
0345 continue;
0346 }
0347
0348 if ( EXSUCCEED!= parse_s_string(stripped) )
0349 {
0350 EXFAIL_OUT(ret);
0351 }
0352 }
0353
0354 out:
0355
0356 if (NULL!=fp)
0357 {
0358 NDRX_FCLOSE(fp);
0359 fp = NULL;
0360 }
0361
0362 return ret;
0363 }
0364
0365
0366
0367
0368 int main(int argc, char **argv)
0369 {
0370 int ret = EXSUCCEED;
0371 int c;
0372 int lang_mode = HDR_C_LANG;
0373 char ofile[NDRX_BPATH_MAX+1]="SERVER";
0374 char cfile[NDRX_BPATH_MAX+1]="ndrx_bs_XXXXXX.c";
0375 char *s_value=NULL;
0376 int thread_option=EXFALSE;
0377 int keep_main=EXFALSE;
0378 char firstfiles[NDRX_BPATH_MAX+1] = {EXEOS};
0379 char lastfiles[NDRX_BPATH_MAX+1] = {EXEOS};
0380 int nomain = EXFALSE;
0381 int verbose = EXFALSE;
0382 FILE *out_fptr = NULL;
0383 ndrx_rm_def_t rmdef;
0384 bs_svcnm_lst_t *el, *elt;
0385
0386 NDRX_BANNER("BUILDSERVER Tool");
0387
0388
0389 _Nunset_error();
0390
0391 memset(&rmdef, 0, sizeof(rmdef));
0392
0393 while ((c = getopt (argc, argv, "Cktvr:g:s:o:f:l:nha:")) != -1)
0394 {
0395 switch (c)
0396 {
0397 case 'h':
0398 print_help(argv[0]);
0399 return 0;
0400 break;
0401 case 'n':
0402
0403 NDRX_LOG(log_debug, "Not generating main...");
0404 nomain=EXTRUE;
0405 break;
0406 case 'C':
0407 NDRX_LOG(log_warn, "COBOL mode not yet supported");
0408 _Nset_error_fmt(NESUPPORT, "COBOL mode not yet supported");
0409 EXFAIL_OUT(ret);
0410 break;
0411 case 's':
0412 s_value= optarg;
0413 NDRX_LOG(log_debug, "s_value: [%s]", s_value);
0414 if ( '@'==s_value[0] )
0415 {
0416 if (EXSUCCEED != parse_s_file(s_value+1) )
0417 {
0418 NDRX_LOG(log_warn,
0419 "Failed to read Service/Function from [%s]",
0420 s_value);
0421 EXFAIL_OUT(ret);
0422 }
0423 }
0424 else
0425 {
0426 if ( EXSUCCEED != parse_s_string(s_value) )
0427 {
0428 NDRX_LOG(log_error,
0429 "Failed to parse Service/Function from value [%s]",
0430 s_value);
0431 EXFAIL_OUT(ret);
0432 }
0433 }
0434 break;
0435 case 'o':
0436 NDRX_STRCPY_SAFE(ofile, optarg);
0437 NDRX_LOG(log_debug, "ofile: [%s]", ofile);
0438 break;
0439 case 'a':
0440 case 'f':
0441 if (EXEOS==firstfiles[0])
0442 {
0443 NDRX_STRCPY_SAFE(firstfiles, optarg);
0444 }
0445 else
0446 {
0447 NDRX_STRCAT_S(firstfiles, sizeof(firstfiles), " ");
0448 NDRX_STRCAT_S(firstfiles, sizeof(firstfiles), optarg);
0449 }
0450 break;
0451 case 'l':
0452 if (EXEOS==lastfiles[0])
0453 {
0454 NDRX_STRCPY_SAFE(lastfiles, optarg);
0455 }
0456 else
0457 {
0458 NDRX_STRCAT_S(lastfiles, sizeof(lastfiles), " ");
0459 NDRX_STRCAT_S(lastfiles, sizeof(lastfiles), optarg);
0460 }
0461 break;
0462 case 'r':
0463 case 'g':
0464
0465 if ( EXFAIL == (ret=ndrx_get_rm_name(optarg, &rmdef)))
0466 {
0467
0468 NDRX_LOG(log_error,
0469 "Failed to parse resource manager: [%s], check -r", optarg);
0470 EXFAIL_OUT(ret);
0471 }
0472 else if (EXTRUE!=ret)
0473 {
0474 NDRX_LOG(log_error,
0475 "Resource manager not defined: [%s], check -r", optarg);
0476
0477 _Nset_error_fmt(NEINVAL, "Resource manager [%s] not found "
0478 "in udataobj/RM files", optarg);
0479 EXFAIL_OUT(ret);
0480 }
0481
0482 ret = EXSUCCEED;
0483
0484 break;
0485 case 'k':
0486 keep_main=EXTRUE;
0487 break;
0488 case 't':
0489 thread_option = EXTRUE;
0490 break;
0491 case 'v':
0492 NDRX_LOG(log_debug, "running in verbose mode");
0493 verbose = EXTRUE;
0494 break;
0495
0496 case '?':
0497 default:
0498
0499 print_help(argv[0]);
0500 return EXFAIL;
0501 }
0502 }
0503
0504
0505 if (HDR_C_LANG==lang_mode)
0506 {
0507 if ( NULL==(out_fptr=ndrx_mkstemps(cfile,2, 0) ))
0508 {
0509 int err = errno;
0510 NDRX_LOG(log_error, "Failed with error %s", strerror(err));
0511 _Nset_error_fmt(NEUNIX, "Failed to create temporary file: %s",
0512 strerror(err));
0513 EXFAIL_OUT(ret);
0514 }
0515
0516 if (EXSUCCEED!=ndrx_buildsrv_generate_code(&out_fptr, cfile, thread_option,
0517 M_bs_svcnm_lst,
0518 M_bs_funcnm_lst,
0519 &rmdef, nomain))
0520 {
0521 NDRX_LOG(log_error, "Failed to generate code!");
0522 EXFAIL_OUT(ret);
0523 }
0524 }
0525
0526 if (HDR_C_LANG==lang_mode)
0527 {
0528 if (EXSUCCEED!=ndrx_compile_c(COMPILE_SRV, verbose, cfile, ofile,
0529 firstfiles, lastfiles, &rmdef))
0530 {
0531 NDRX_LOG(log_error, "Failed to build");
0532 EXFAIL_OUT(ret);
0533 }
0534 }
0535 else
0536 {
0537 NDRX_LOG(log_error, "Invalid language mode: %d", lang_mode);
0538 _Nset_error_fmt(NEINVAL, "Invalid language mode %d", lang_mode);
0539 EXFAIL_OUT(ret);
0540 }
0541
0542 out:
0543
0544
0545 if (EXSUCCEED!=ret)
0546 {
0547 if (!_Nis_error())
0548 {
0549 _Nset_error_fmt(NESYSTEM, "Generic error - see logs.");
0550 }
0551
0552
0553 fprintf(stderr, "%s: %s\n", argv[0], ndrx_Nstrerror2(Nerror));
0554 }
0555
0556 if (NULL!=out_fptr)
0557 {
0558 NDRX_FCLOSE(out_fptr);
0559 }
0560
0561 if (EXFALSE == keep_main)
0562 {
0563 unlink(cfile);
0564 }
0565
0566
0567 EXHASH_ITER(hh, M_bs_svcnm_lst, el, elt)
0568 {
0569 EXHASH_DEL(M_bs_svcnm_lst, el);
0570 NDRX_FREE(el);
0571 }
0572
0573 EXHASH_ITER(hh, M_bs_funcnm_lst, el, elt)
0574 {
0575 EXHASH_DEL(M_bs_funcnm_lst, el);
0576 NDRX_FREE(el);
0577 }
0578
0579 return ret;
0580 }
0581
0582