Ejemplo n.º 1
0
/* 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;
}
Ejemplo n.º 2
0
/* 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;
}
Ejemplo n.º 3
0
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);
			}
		}
	}
}
Ejemplo n.º 4
0
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);
}