/* Note: Need condition handler to clean-up allocated structures and close intput file in the event of an error */ struct extcall_package_list *exttab_parse(mval *package) { int parameter_alloc_values[MAX_ACTUALS], parameter_count, ret_pre_alloc_val, i, fclose_res; int len, keywordlen; boolean_t is_input[MAX_ACTUALS], is_output[MAX_ACTUALS], got_status; mstr callnam, rtnnam, clnuprtn; mstr val, trans; void_ptr_t pakhandle; enum gtm_types ret_tok, parameter_types[MAX_ACTUALS], pr; char str_buffer[MAX_TABLINE_LEN], *tbp, *end; char str_temp_buffer[MAX_TABLINE_LEN]; FILE *ext_table_file_handle; struct extcall_package_list *pak; struct extcall_entry_list *entry_ptr; /* First, construct package name environment variable */ memcpy(str_buffer, PACKAGE_ENV_PREFIX, SIZEOF(PACKAGE_ENV_PREFIX)); tbp = &str_buffer[SIZEOF(PACKAGE_ENV_PREFIX) - 1]; if (package->str.len) { /* guaranteed by compiler */ assert(package->str.len < MAX_NAME_LENGTH - SIZEOF(PACKAGE_ENV_PREFIX) - 1); *tbp++ = '_'; memcpy(tbp, package->str.addr, package->str.len); tbp += package->str.len; } *tbp = 0; /* Now we have the environment name, lookup file name */ ext_table_file_name = GETENV(str_buffer); if (NULL == ext_table_file_name) { /* Environment variable for the package not found */ rts_error_csa(CSA_ARG(NULL) VARLSTCNT(4) ERR_ZCCTENV, 2, LEN_AND_STR(str_buffer)); } ext_table_file_handle = Fopen(ext_table_file_name, "r"); if (NULL == ext_table_file_handle) { /* Package's external call table could not be found */ rts_error_csa(CSA_ARG(NULL) VARLSTCNT(4) ERR_ZCCTOPN, 2, LEN_AND_STR(ext_table_file_name)); } ext_source_line_num = 0; /* Pick-up name of shareable library */ tbp = read_table(LIT_AND_LEN(str_buffer), ext_table_file_handle); if (NULL == tbp) { /* External call table is a null file */ rts_error_csa(CSA_ARG(NULL) VARLSTCNT(4) ERR_ZCCTNULLF, 2, package->str.len, package->str.addr); } STRNCPY_STR(str_temp_buffer, str_buffer, MAX_TABLINE_LEN); val.addr = str_temp_buffer; val.len = STRLEN(str_temp_buffer); /* Need to copy the str_buffer into another temp variable since * TRANS_LOG_NAME requires input and output buffers to be different. * If there is an env variable present in the pathname, TRANS_LOG_NAME * expands it and return SS_NORMAL. Else it returns SS_NOLOGNAM. * Instead of checking 2 return values, better to check against SS_LOG2LONG * which occurs if the pathname is too long after any kind of expansion. */ if (SS_LOG2LONG == TRANS_LOG_NAME(&val, &trans, str_buffer, SIZEOF(str_buffer), dont_sendmsg_on_log2long)) { /* Env variable expansion in the pathname caused buffer overflow */ rts_error_csa(CSA_ARG(NULL) VARLSTCNT(5) ERR_LOGTOOLONG, 3, val.len, val.addr, SIZEOF(str_buffer) - 1); } pakhandle = fgn_getpak(str_buffer, INFO); if (NULL == pakhandle) { /* Unable to obtain handle to the shared library */ rts_error_csa(CSA_ARG(NULL) VARLSTCNT(4) ERR_ZCUNAVAIL, 2, package->str.len, package->str.addr); } pak = get_memory(SIZEOF(*pak)); pak->first_entry = 0; put_mstr(&package->str, &pak->package_name); pak->package_handle = pakhandle; pak->package_clnup_rtn = NULL; len = STRLEN("GTMSHLIBEXIT"); /* At this point, we have a valid package, pointed to by pak */ # ifdef DEBUG_EXTCALL FPRINTF(stderr, "GT.M external call opened package name: %s\n", pak->package_name.addr); # endif for (;;) { star_found = FALSE; tbp = read_table(LIT_AND_LEN(str_buffer), ext_table_file_handle); if (NULL == tbp) break; tbp = exttab_scan_space(str_buffer); /* Empty line? */ if (!*tbp) continue; /* No, must be entryref or keyword */ end = scan_ident(tbp); if (!end) ext_stx_error(ERR_ZCENTNAME, ext_table_file_name); keywordlen = end - tbp; end = exttab_scan_space(end); if ('=' == *end) { /* Keyword before '=' has a string of size == STRLEN("GTMSHLIBEXIT") */ if (keywordlen == len) { if (0 == MEMCMP_LIT(tbp, "GTMSHLIBEXIT")) { /* Skip past the '=' char */ tbp = exttab_scan_space(end + 1); if (*tbp) { /* We have a cleanup routine name */ clnuprtn.addr = tbp; clnuprtn.len = scan_ident(tbp) - tbp; clnuprtn.addr[clnuprtn.len] = 0; pak->package_clnup_rtn = (clnupfptr)fgn_getrtn(pak->package_handle, &clnuprtn, ERROR); } else ext_stx_error(ERR_ZCCLNUPRTNMISNG, ext_table_file_name); continue; } } ext_stx_error(ERR_ZCINVALIDKEYWORD, ext_table_file_name); continue; } if ('^' == *end) { end++; end = scan_ident(end); if (!end) ext_stx_error(ERR_ZCENTNAME, ext_table_file_name); } rtnnam.addr = tbp; rtnnam.len = INTCAST(end - tbp); tbp = exttab_scan_space(end); if (':' != *tbp++) ext_stx_error(ERR_ZCCOLON, ext_table_file_name); /* Get return type */ ret_tok = scan_keyword(&tbp); /* Check for legal return type */ switch (ret_tok) { case gtm_status: case gtm_void: case gtm_int: case gtm_uint: case gtm_long: case gtm_ulong: case gtm_char_star: case gtm_float_star: case gtm_string_star: case gtm_int_star: case gtm_uint_star: case gtm_long_star: case gtm_ulong_star: case gtm_double_star: case gtm_char_starstar: case gtm_pointertofunc: case gtm_pointertofunc_star: case gtm_jboolean: case gtm_jint: case gtm_jlong: case gtm_jfloat: case gtm_jdouble: case gtm_jstring: case gtm_jbyte_array: case gtm_jbig_decimal: break; default: ext_stx_error(ERR_ZCRTNTYP, ext_table_file_name); } got_status = (ret_tok == gtm_status); /* Get call name */ if ('[' == *tbp) { if (star_found) ret_pre_alloc_val = scan_array_bound(&tbp,ret_tok); else ext_stx_error(ERR_ZCPREALLVALPAR, ext_table_file_name); /* We should allow the pre-allocated value upto to the maximum string size (MAX_STRLEN) plus 1 for the * extra terminating NULL. Negative values would have been caught by scan_array_bound() above. */ if (ret_pre_alloc_val > MAX_STRLEN + 1) ext_stx_error(ERR_ZCPREALLVALINV, ext_table_file_name); } else ret_pre_alloc_val = -1; /* Fix C9E12-002681 */ if ('%' == *tbp) *tbp = '_'; end = scan_ident(tbp); if (!end) ext_stx_error(ERR_ZCRCALLNAME, ext_table_file_name); callnam.addr = tbp; callnam.len = INTCAST(end - tbp); tbp = exttab_scan_space(end); tbp = exttab_scan_space(tbp); for (parameter_count = 0;(MAX_ACTUALS > parameter_count) && (')' != *tbp); parameter_count++) { star_found = FALSE; /* Must have comma if this is not the first parameter, otherwise '(' */ if (((0 == parameter_count)?'(':',') != *tbp++) ext_stx_error(ERR_ZCRPARMNAME, ext_table_file_name); tbp = exttab_scan_space(tbp); /* Special case: () is ok */ if ((0 == parameter_count) && (*tbp == ')')) break; /* Looking for an I, an O or an IO */ is_input[parameter_count] = is_output[parameter_count] = FALSE; if ('I' == *tbp) { is_input[parameter_count] = TRUE; tbp++; } if ('O' == *tbp) { is_output[parameter_count] = TRUE; tbp++; } if (((FALSE == is_input[parameter_count]) && (FALSE == is_output[parameter_count])) ||(':' != *tbp++)) ext_stx_error(ERR_ZCRCALLNAME, ext_table_file_name); /* Scanned colon--now get type */ pr = scan_keyword(&tbp); if (gtm_notfound == pr) ext_stx_error(ERR_ZCUNTYPE, ext_table_file_name); if (gtm_status == pr) { /* Only one type "status" allowed per call */ if (got_status) ext_stx_error(ERR_ZCMLTSTATUS, ext_table_file_name); else got_status = TRUE; } parameter_types[parameter_count] = pr; if ('[' == *tbp) { if (star_found && !is_input[parameter_count]) parameter_alloc_values[parameter_count] = scan_array_bound(&tbp, pr); else ext_stx_error(ERR_ZCPREALLVALPAR, ext_table_file_name); /* We should allow the pre-allocated value upto to the maximum string size (MAX_STRLEN) plus 1 for * the extra terminating NULL. Negative values would have been caught by scan_array_bound() above. */ if (parameter_alloc_values[parameter_count] > MAX_STRLEN + 1) ext_stx_error(ERR_ZCPREALLVALINV, ext_table_file_name); } else parameter_alloc_values[parameter_count] = -1; tbp = exttab_scan_space(tbp); } entry_ptr = get_memory(SIZEOF(*entry_ptr)); entry_ptr->next_entry = pak->first_entry; pak->first_entry = entry_ptr; entry_ptr->return_type = ret_tok; entry_ptr->ret_pre_alloc_val = ret_pre_alloc_val; entry_ptr->argcnt = parameter_count; entry_ptr->input_mask = array_to_mask(is_input, parameter_count); entry_ptr->output_mask = array_to_mask(is_output, parameter_count); entry_ptr->parms = get_memory(parameter_count * SIZEOF(entry_ptr->parms[0])); entry_ptr->param_pre_alloc_size = get_memory(parameter_count * SIZEOF(intszofptr_t)); entry_ptr->parmblk_size = (SIZEOF(void *) * parameter_count) + SIZEOF(intszofptr_t); for (i = 0 ; i < parameter_count; i++) { entry_ptr->parms[i] = parameter_types[i]; assert(gtm_void != parameter_types[i]); entry_ptr->parmblk_size += parm_space_needed[parameter_types[i]]; entry_ptr->param_pre_alloc_size[i] = parameter_alloc_values[i]; } put_mstr(&rtnnam, &entry_ptr->entry_name); put_mstr(&callnam, &entry_ptr->call_name); /* The reason for passing INFO severity is that PROFILE has several routines listed in * the external call table that are not in the shared library. PROFILE folks would * rather see info/warning messages for such routines at shared library open time, * than error out. These unimplemented routines, they say were not being called from * the application and wouldn't cause any application failures. If we fail to open * the shared libary, or we fail to locate a routine that is called from the * application, we issue rts_error message (in extab_parse.c). */ entry_ptr->fcn = fgn_getrtn(pak->package_handle, &entry_ptr->call_name, INFO); # ifdef DEBUG_EXTCALL FPRINTF(stderr, " package entry point: %s, address: %x\n", entry_ptr->entry_name.addr, entry_ptr->fcn); # endif } FCLOSE(ext_table_file_handle, fclose_res); return pak; }
/* Note: need condition handler to clean-up allocated structures and close intput file in the event of an error */ struct extcall_package_list *exttab_parse(mval *package) { int parameter_alloc_values[MAXIMUM_PARAMETERS], parameter_count, ret_pre_alloc_val, i, fclose_res; boolean_t is_input[MAXIMUM_PARAMETERS], is_output[MAXIMUM_PARAMETERS], got_status; mstr callnam, rtnnam; void_ptr_t pakhandle; enum xc_types ret_tok, parameter_types[MAXIMUM_PARAMETERS], pr; char str_buffer[MAX_TABLINE_LEN], *tbp, *end; FILE *ext_table_file_handle; struct extcall_package_list *pak; struct extcall_entry_list *entry_ptr; error_def(ERR_ZCRTENOTF); error_def(ERR_ZCALLTABLE); error_def(ERR_ZCUSRRTN); error_def(ERR_ZCCTENV); error_def(ERR_ZCCTOPN); error_def(ERR_ZCCTNULLF); error_def(ERR_ZCUNAVAIL); error_def(ERR_ZCENTNAME); error_def(ERR_ZCCOLON); error_def(ERR_ZCRTNTYP); error_def(ERR_ZCRCALLNAME); error_def(ERR_ZCUNTYPE); error_def(ERR_ZCMLTSTATUS); error_def(ERR_ZCRPARMNAME); error_def(ERR_ZCPREALLVALPAR); error_def(ERR_ZCPREALLVALINV); /* First, construct package name environment variable */ memcpy(str_buffer, PACKAGE_ENV_PREFIX, sizeof(PACKAGE_ENV_PREFIX)); tbp = &str_buffer[sizeof(PACKAGE_ENV_PREFIX) - 1]; if (package->str.len) { /* guaranteed by compiler */ assert(package->str.len < MAX_NAME_LENGTH - sizeof(PACKAGE_ENV_PREFIX) - 1); *tbp++ = '_'; memcpy(tbp, package->str.addr, package->str.len); tbp += package->str.len; } *tbp = 0; /* Now we have the environment name, lookup file name */ ext_table_file_name = GETENV(str_buffer); if (NULL == ext_table_file_name) { /* Environment variable for the package not found */ rts_error(VARLSTCNT(4) ERR_ZCCTENV, 2, LEN_AND_STR(str_buffer)); } ext_table_file_handle = Fopen(ext_table_file_name, "r"); if (NULL == ext_table_file_handle) { /* Package's external call table could not be found */ rts_error(VARLSTCNT(4) ERR_ZCCTOPN, 2, LEN_AND_STR(ext_table_file_name)); } ext_source_line_num = 0; /* pick-up name of shareable library */ tbp = read_table(LIT_AND_LEN(str_buffer), ext_table_file_handle); if (NULL == tbp) { /* External call table is a null file */ rts_error(VARLSTCNT(4) ERR_ZCCTNULLF, 2, package->str.len, package->str.addr); } pakhandle = fgn_getpak(str_buffer, INFO); if (NULL == pakhandle) { /* Unable to obtain handle to the shared library */ rts_error(VARLSTCNT(4) ERR_ZCUNAVAIL, 2, package->str.len, package->str.addr); } pak = get_memory(sizeof(*pak)); pak->first_entry = 0; put_mstr(&package->str, &pak->package_name); pak->package_handle = pakhandle; /* At this point, we have a valid package, pointed to by pak */ #ifdef DEBUG_EXTCALL FPRINTF(stderr, "GT.M external call opened package name: %s\n", pak->package_name.addr); #endif for (;;) { star_found = FALSE; tbp = read_table(LIT_AND_LEN(str_buffer), ext_table_file_handle); if (NULL == tbp) break; tbp = scan_space(str_buffer); /* empty line? */ if (!*tbp) continue; /* No, must be entryref */ end = scan_ident(tbp); if (!end) ext_stx_error(ERR_ZCENTNAME, ext_table_file_name); if ('^' == *end) { end++; end = scan_ident(end); if (!end) ext_stx_error(ERR_ZCENTNAME, ext_table_file_name); } rtnnam.addr = tbp; rtnnam.len = INTCAST(end - tbp); tbp = scan_space(end); if (':' != *tbp++) ext_stx_error(ERR_ZCCOLON, ext_table_file_name); /* get return type */ ret_tok = scan_keyword(&tbp); /* check for legal return type */ switch (ret_tok) { case xc_status: case xc_void: case xc_int: case xc_uint: case xc_long: case xc_ulong: case xc_char_star: case xc_float_star: case xc_string_star: case xc_int_star: case xc_uint_star: case xc_long_star: case xc_ulong_star: case xc_double_star: case xc_char_starstar: case xc_pointertofunc: case xc_pointertofunc_star: break; default: ext_stx_error(ERR_ZCRTNTYP, ext_table_file_name); } got_status = (ret_tok == xc_status); /* get call name */ if ('[' == *tbp) { if (star_found) ret_pre_alloc_val = scan_array_bound(&tbp,ret_tok); else ext_stx_error(ERR_ZCPREALLVALPAR, ext_table_file_name); /* We should allow the pre-allocated value upto to the maximum string size (MAX_STRLEN) plus 1 for the * extra terminating NULL. Negative values would have been caught by scan_array_bound() above */ if (ret_pre_alloc_val > MAX_STRLEN + 1) ext_stx_error(ERR_ZCPREALLVALINV, ext_table_file_name); } else ret_pre_alloc_val = -1; end = scan_ident(tbp); if (!end) ext_stx_error(ERR_ZCRCALLNAME, ext_table_file_name); callnam.addr = tbp; callnam.len = INTCAST(end - tbp); tbp = scan_space(end); tbp = scan_space(tbp); for (parameter_count = 0;(MAXIMUM_PARAMETERS > parameter_count) && (')' != *tbp); parameter_count++) { star_found = FALSE; /* must have comma if this is not the first parameter, otherwise '(' */ if (((0 == parameter_count)?'(':',') != *tbp++) ext_stx_error(ERR_ZCRPARMNAME, ext_table_file_name); tbp = scan_space(tbp); /* special case: () is ok */ if ((0 == parameter_count) && (*tbp == ')')) break; /* looking for an I, an O or an IO */ is_input[parameter_count] = is_output[parameter_count] = FALSE; if ('I' == *tbp) { is_input[parameter_count] = TRUE; tbp++; } if ('O' == *tbp) { is_output[parameter_count] = TRUE; tbp++; } if (((FALSE == is_input[parameter_count]) && (FALSE == is_output[parameter_count])) ||(':' != *tbp++)) ext_stx_error(ERR_ZCRCALLNAME, ext_table_file_name); /* scanned colon--now get type */ pr = scan_keyword(&tbp); if (xc_notfound == pr) ext_stx_error(ERR_ZCUNTYPE, ext_table_file_name); if (xc_status == pr) { /* Only one type "status" allowed per call */ if (got_status) ext_stx_error(ERR_ZCMLTSTATUS, ext_table_file_name); else got_status = TRUE; } parameter_types[parameter_count] = pr; if ('[' == *tbp) { if (star_found && !is_input[parameter_count]) parameter_alloc_values[parameter_count] = scan_array_bound(&tbp, pr); else ext_stx_error(ERR_ZCPREALLVALPAR, ext_table_file_name); /* We should allow the pre-allocated value upto to the maximum string size (MAX_STRLEN) plus 1 for * the extra terminating NULL. Negative values would have been caught by scan_array_bound() above */ if (parameter_alloc_values[parameter_count] > MAX_STRLEN + 1) ext_stx_error(ERR_ZCPREALLVALINV, ext_table_file_name); } else parameter_alloc_values[parameter_count] = -1; tbp = scan_space(tbp); } entry_ptr = get_memory(sizeof(*entry_ptr)); entry_ptr->next_entry = pak->first_entry; pak->first_entry = entry_ptr; entry_ptr->return_type = ret_tok; entry_ptr->ret_pre_alloc_val = ret_pre_alloc_val; entry_ptr->argcnt = parameter_count; entry_ptr->input_mask = array_to_mask(is_input, parameter_count); entry_ptr->output_mask = array_to_mask(is_output, parameter_count); entry_ptr->parms = get_memory(parameter_count * sizeof(entry_ptr->parms[0])); entry_ptr->param_pre_alloc_size = get_memory(parameter_count * sizeof(intszofptr_t)); entry_ptr->parmblk_size = (SIZEOF(void *) * parameter_count) + SIZEOF(intszofptr_t); for (i = 0 ; i < parameter_count ; i++) { entry_ptr->parms[i] = parameter_types[i]; entry_ptr->parmblk_size += parm_space_needed[parameter_types[i]]; entry_ptr->param_pre_alloc_size[i] = parameter_alloc_values[i]; } put_mstr(&rtnnam, &entry_ptr->entry_name); put_mstr(&callnam, &entry_ptr->call_name); /* the reason for passing INFO severity is that PROFILE has several routines listed in * the external call table that are not in the shared library. PROFILE folks would * rather see info/warning messages for such routines at shared library open time, * than error out. These unimplemented routines, they say were not being called from * the application and wouldn't cause any application failures. If we fail to open * the shared libary, or we fail to locate a routine that is called from the * application, we issue rts_error message (in extab_parse.c) */ entry_ptr->fcn = fgn_getrtn(pak->package_handle, &entry_ptr->call_name, INFO); #ifdef DEBUG_EXTCALL FPRINTF(stderr, " package entry point: %s, address: %x\n", entry_ptr->entry_name.addr, entry_ptr->fcn); #endif } FCLOSE(ext_table_file_handle, fclose_res); return pak; }
void zro_load (mstr *str) { unsigned toktyp, status; mstr tok; char *lp, *top; zro_ent array[ZRO_MAX_ENTS], *op; int oi, si, total_ents; struct stat outbuf; int stat_res; char tranbuf[MAX_FBUFF + 1]; parse_blk pblk; error_def (ERR_DIRONLY); error_def (ERR_FILEPARSE); error_def (ERR_FSEXP); error_def (ERR_MAXARGCNT); error_def (ERR_QUALEXP); error_def (ERR_ZROSYNTAX); error_def (ERR_NOLBRSRC); error_def (ERR_INVZROENT); lp = str->addr; top = lp + str->len; while (lp < top && *lp == ZRO_DEL) lp++; array[0].type = ZRO_TYPE_COUNT; array[0].count = 0; memset(&pblk, 0, sizeof(pblk)); pblk.buffer = tranbuf; GETTOK; if (toktyp == ZRO_EOL) { array[0].count = 1; array[1].type = ZRO_TYPE_OBJECT; array[1].str.len = 0; array[2].type = ZRO_TYPE_COUNT; array[2].count = 1; array[3] = array[1]; array[3].type = ZRO_TYPE_SOURCE; si = 4; } else { for (oi = 1;;) { if (toktyp != ZRO_IDN) rts_error(VARLSTCNT(5) ERR_ZROSYNTAX, 2, str->len, str->addr, ERR_FSEXP); if (oi + 1 >= ZRO_MAX_ENTS) rts_error(VARLSTCNT(7) ERR_ZROSYNTAX, 2, str->len, str->addr, ERR_MAXARGCNT, 1, ZRO_MAX_ENTS); if (tok.len >= sizeof (tranbuf)) rts_error(VARLSTCNT(8) ERR_ZROSYNTAX, 2, str->len, str->addr, ERR_FILEPARSE, 2, tok.len, tok.addr); pblk.buff_size = MAX_FBUFF; pblk.fnb = 0; status = parse_file(&tok, &pblk); if (!(status & 1)) rts_error(VARLSTCNT(9) ERR_ZROSYNTAX, 2, str->len, str->addr, ERR_FILEPARSE, 2, tok.len, tok.addr, status); tranbuf[ pblk.b_esl ] = 0; STAT_FILE(tranbuf, &outbuf, stat_res); if (-1 == stat_res) rts_error(VARLSTCNT(9) ERR_ZROSYNTAX, 2, str->len, str->addr, ERR_FILEPARSE, 2, tok.len, tok.addr, errno); if (S_ISREG(outbuf.st_mode)) { /* regular file - a shared library file */ array[oi].shrlib = fgn_getpak(tranbuf, ERROR); array[oi].type = ZRO_TYPE_OBJLIB; si = oi + 1; } else { if (!S_ISDIR(outbuf.st_mode)) rts_error(VARLSTCNT(8) ERR_ZROSYNTAX, 2, str->len, str->addr, ERR_INVZROENT, 2, tok.len, tok.addr); array[oi].type = ZRO_TYPE_OBJECT; array[oi + 1].type = ZRO_TYPE_COUNT; si = oi + 2; } array[0].count++; array[oi].str = tok; GETTOK; if (toktyp == ZRO_LBR) { if (array[oi].type == ZRO_TYPE_OBJLIB) rts_error(VARLSTCNT(5) ERR_ZROSYNTAX, 2, str->len, str->addr, ERR_NOLBRSRC); GETTOK; if (toktyp == ZRO_DEL) GETTOK; if (toktyp != ZRO_IDN && toktyp != ZRO_RBR) rts_error(VARLSTCNT(5) ERR_ZROSYNTAX, 2, str->len, str->addr, ERR_QUALEXP); array[oi + 1].count = 0; for (;;) { if (toktyp == ZRO_RBR) break; if (toktyp != ZRO_IDN) rts_error(VARLSTCNT(5) ERR_ZROSYNTAX, 2, str->len, str->addr, ERR_FSEXP); if (si >= ZRO_MAX_ENTS) rts_error(VARLSTCNT(7) ERR_ZROSYNTAX, 2, str->len, str->addr, ERR_MAXARGCNT, 1, ZRO_MAX_ENTS); if (tok.len >= sizeof (tranbuf)) rts_error(VARLSTCNT(8) ERR_ZROSYNTAX, 2, str->len, str->addr, ERR_FILEPARSE, 2, tok.len, tok.addr); pblk.buff_size = MAX_FBUFF; pblk.fnb = 0; status = parse_file(&tok, &pblk); if (!(status & 1)) rts_error(VARLSTCNT(9) ERR_ZROSYNTAX, 2, str->len, str->addr, ERR_FILEPARSE, 2, tok.len, tok.addr, status); tranbuf[ pblk.b_esl ] = 0; STAT_FILE(tranbuf, &outbuf, stat_res); if (-1 == stat_res) rts_error(VARLSTCNT(9) ERR_ZROSYNTAX, 2, str->len, str->addr, ERR_FILEPARSE, 2, tok.len, tok.addr, errno); if (!S_ISDIR(outbuf.st_mode)) rts_error(VARLSTCNT(8) ERR_ZROSYNTAX, 2, str->len, str->addr, ERR_DIRONLY, 2, tok.len, tok.addr); array[oi + 1].count++; array[si].type = ZRO_TYPE_SOURCE; array[si].str = tok; si++; GETTOK; if (toktyp == ZRO_DEL) GETTOK; } GETTOK; } else { if ((array[oi].type != ZRO_TYPE_OBJLIB) && (toktyp == ZRO_DEL || toktyp == ZRO_EOL)) { if (si >= ZRO_MAX_ENTS) rts_error(VARLSTCNT(7) ERR_ZROSYNTAX, 2, str->len, str->addr, ERR_MAXARGCNT, 1, ZRO_MAX_ENTS); array[oi + 1].count = 1; array[si] = array[oi]; array[si].type = ZRO_TYPE_SOURCE; si++; } } if (toktyp == ZRO_EOL) break; if (toktyp == ZRO_DEL) GETTOK; else rts_error(VARLSTCNT(4) ERR_ZROSYNTAX, 2, str->len, str->addr); oi = si; } } total_ents = si; if (zro_root) { assert (zro_root->type == ZRO_TYPE_COUNT); oi = zro_root->count; assert (oi); for (op = zro_root + 1; oi-- > 0; ) { /* release space held by translated entries */ assert (op->type == ZRO_TYPE_OBJECT || op->type == ZRO_TYPE_OBJLIB); if (op->str.len) free(op->str.addr); if ((op++)->type == ZRO_TYPE_OBJLIB) continue; /* i.e. no sources for shared library */ assert (op->type == ZRO_TYPE_COUNT); si = (op++)->count; for ( ; si-- > 0; op++) { assert (op->type == ZRO_TYPE_SOURCE); if (op->str.len) free(op->str.addr); } } free (zro_root); } zro_root = (zro_ent *) malloc (total_ents * sizeof (zro_ent)); longcpy ((uchar_ptr_t)zro_root, (uchar_ptr_t)array, total_ents * sizeof (zro_ent)); assert (zro_root->type == ZRO_TYPE_COUNT); oi = zro_root->count; assert (oi); for (op = zro_root + 1; oi-- > 0; ) { assert (op->type == ZRO_TYPE_OBJECT || op->type == ZRO_TYPE_OBJLIB); if (op->str.len) { pblk.buff_size = MAX_FBUFF; pblk.fnb = 0; status = parse_file(&op->str, &pblk); if (!(status & 1)) rts_error(VARLSTCNT(9) ERR_ZROSYNTAX, 2, str->len, str->addr, ERR_FILEPARSE, 2, op->str.len, op->str.addr, status); op->str.addr = (char *)malloc(pblk.b_esl); op->str.len = pblk.b_esl; memcpy(op->str.addr, pblk.buffer, pblk.b_esl); } if ((op++)->type == ZRO_TYPE_OBJLIB) continue; assert (op->type == ZRO_TYPE_COUNT); si = (op++)->count; for ( ; si-- > 0; op++) { assert (op->type == ZRO_TYPE_SOURCE); if (op->str.len) { pblk.buff_size = MAX_FBUFF; pblk.fnb = 0; status = parse_file(&op->str, &pblk); if (!(status & 1)) rts_error(VARLSTCNT(9) ERR_ZROSYNTAX, 2, str->len, str->addr, ERR_FILEPARSE, 2, op->str.len, op->str.addr, status); op->str.addr = (char *)malloc(pblk.b_esl); op->str.len = pblk.b_esl; memcpy(op->str.addr, pblk.buffer, pblk.b_esl); } } } }
int gtm_event_log_init(void) { /* External log initializations */ mstr name, trans_name; char log_name[MAX_TRANS_NAME_LEN], shared_lib[MAX_TRANS_NAME_LEN], log_func[MAX_TRANS_NAME_LEN]; int status, index, save_errno; char print_msg[1024], *args; error_def(ERR_EVENTLOGERR); error_def(ERR_TEXT); if (gtm_do_event_log) /* Already initialized */ return(SS_NORMAL); name.len = sizeof(GTM_EVENT_LOG_LIB_ENV) - 1; name.addr = GTM_EVENT_LOG_LIB_ENV; if ((status = trans_log_name(&name, &trans_name, log_name)) != SS_NORMAL || trans_name.len == 0) return(status); memcpy(shared_lib, trans_name.addr, trans_name.len); shared_lib[trans_name.len] = '\0'; if (NULL == (gtm_event_log_handle = fgn_getpak(shared_lib, INFO))) { SPRINTF(print_msg, "Could not open shared library specified in %s - %s. No event logging done", GTM_EVENT_LOG_LIB_ENV, shared_lib); gtm_putmsg(VARLSTCNT(6) ERR_EVENTLOGERR, 0, ERR_TEXT, 2, LEN_AND_STR(print_msg)); return(-1); } #ifdef GTM_EVENT_LOG_HARDCODE_RTN_NAME trans_name.len = sizeof(GTM_EVENT_LOG_RTN) - 1; trans_name.addr = GTM_EVENT_LOG_RTN; #else name.len = sizeof(GTM_EVENT_LOG_RTN_ENV) - 1; name.addr = GTM_EVENT_LOG_RTN_ENV; if ((status = trans_log_name(&name, &trans_name, log_name)) != SS_NORMAL || trans_name.len == 0) { SPRINTF(print_msg, "%s not set or null. No event logging done", GTM_EVENT_LOG_RTN_ENV); gtm_putmsg(VARLSTCNT(6) ERR_EVENTLOGERR, 0, ERR_TEXT, 2, LEN_AND_STR(print_msg)); return(status); } #endif memcpy(log_func, trans_name.addr, trans_name.len); log_func[trans_name.len] = '\0'; if (NULL == (gtm_event_log_func = fgn_getrtn(gtm_event_log_handle, &trans_name, INFO))) { #ifdef GTM_EVENT_LOG_HARDCODE_RTN_NAME SPRINTF(print_msg, "Could not find function %s in shared library %s. No event logging done", log_func, shared_lib); #else SPRINTF(print_msg, "Could not find function specified in %s - %s in shared library %s. No event logging done", GTM_EVENT_LOG_RTN_ENV, log_func, shared_lib); #endif gtm_putmsg(VARLSTCNT(6) ERR_EVENTLOGERR, 0, ERR_TEXT, 2, LEN_AND_STR(print_msg)); return(-1); } gtm_do_event_log = TRUE; return(SS_NORMAL); }