129 lines
4.6 KiB
C
129 lines
4.6 KiB
C
|
/****************************************************************
|
||
|
* *
|
||
|
* Copyright 2001, 2010 Fidelity Information Services, Inc *
|
||
|
* *
|
||
|
* This source code contains the intellectual property *
|
||
|
* of its copyright holder(s), and is made available *
|
||
|
* under a license. If you do not know the terms of *
|
||
|
* the license, please stop and do not read further. *
|
||
|
* *
|
||
|
****************************************************************/
|
||
|
|
||
|
#include "mdef.h"
|
||
|
|
||
|
#include "gtm_ctype.h"
|
||
|
|
||
|
#include "gtm_string.h"
|
||
|
#include "gtm_stdlib.h"
|
||
|
|
||
|
#include "io.h"
|
||
|
#include "iosp.h"
|
||
|
#include "trans_log_name.h"
|
||
|
#include "send_msg.h"
|
||
|
|
||
|
/* Allocate a buffer to be used for passing a null-terminated environment-variable to GETENV.
|
||
|
* If more space is needed, we will expand later. Need to statically allocate space to hold "$gtmdbglvl"
|
||
|
* since this is the first environment variable that will be passed to trans_log_name and needs
|
||
|
* to be translated BEFORE doing any mallocs hence the initial static allocation of MAX_TRANS_NAME_LEN bytes.
|
||
|
*/
|
||
|
STATICDEF char trans_log_name_startbuff[MAX_TRANS_NAME_LEN];
|
||
|
STATICDEF int trans_log_name_buflen = MAX_TRANS_NAME_LEN - 1; /* length of buffer currently allocated */
|
||
|
STATICDEF char *trans_log_name_buff = &trans_log_name_startbuff[0];
|
||
|
|
||
|
int4 trans_log_name(mstr *log, mstr *trans, char *buffer, int4 buffer_len, translog_act do_sendmsg)
|
||
|
{
|
||
|
char *s_start, *s_ptr, *s_top, *tran_buff, *b_ptr, *b_top, ch;
|
||
|
int len, s_len;
|
||
|
int4 ret;
|
||
|
|
||
|
error_def(ERR_LOGTOOLONG);
|
||
|
|
||
|
ret = SS_NOLOGNAM; /* assume we don't find it */
|
||
|
b_ptr = buffer; /* b_ptr is points to next place to fill in in output buffer */
|
||
|
b_top = buffer + buffer_len;
|
||
|
s_start = log->addr;
|
||
|
s_top = s_start + log->len;
|
||
|
for (s_ptr = s_start; s_ptr < s_top; )
|
||
|
{
|
||
|
assert(s_ptr != buffer); /* should be no intersections between input and output buffer at any point of processing */
|
||
|
if ('$' == *s_ptr)
|
||
|
{ /* We hit a env var that needs to be translated - they start with $ */
|
||
|
|
||
|
/* For non-initial pass copy any non-env var text that we have passed over into output buffer
|
||
|
* and update output buffer pointer. Before that check if output buffer can hold that data.
|
||
|
*/
|
||
|
s_len = (int)(s_ptr - s_start);
|
||
|
if ((b_ptr + s_len) >= b_top)
|
||
|
{
|
||
|
ret = SS_LOG2LONG;
|
||
|
break;
|
||
|
}
|
||
|
memcpy(b_ptr, s_start, s_len);
|
||
|
b_ptr += s_len;
|
||
|
assert(b_ptr < b_top);
|
||
|
/* Move forward in input buffer (over text just processed) */
|
||
|
s_start = s_ptr++;
|
||
|
/* Get the env var name. Take care not to exceed input string length */
|
||
|
for ( ; (s_ptr < s_top) && (ch = *s_ptr, ('_' == ch) || ISALNUM_ASCII(ch)); s_ptr++)
|
||
|
;
|
||
|
s_len = (int)(s_ptr - s_start) - 1;
|
||
|
/* Copy it into "temporary-buffer" so we can null-terminate it and pass to GETENV */
|
||
|
if (trans_log_name_buflen <= s_len)
|
||
|
{ /* Currently allocated buffer is not enough. Expand it. */
|
||
|
assert(NULL != trans_log_name_buff);
|
||
|
if (trans_log_name_buff != trans_log_name_startbuff) /* do not free static starting buffer */
|
||
|
free(trans_log_name_buff);
|
||
|
trans_log_name_buff = malloc(s_len + 1);
|
||
|
trans_log_name_buflen = s_len + 1;
|
||
|
}
|
||
|
memcpy(trans_log_name_buff, s_start + 1, s_len);
|
||
|
trans_log_name_buff[s_len] = 0;
|
||
|
/* try to convert it */
|
||
|
if (NULL != (tran_buff = GETENV(trans_log_name_buff)))
|
||
|
{
|
||
|
s_start = tran_buff;
|
||
|
s_len = STRLEN(tran_buff);
|
||
|
ret = SS_NORMAL;
|
||
|
} else
|
||
|
{ /* if there is no env var then just copy the name of the env var name including $ */
|
||
|
s_len = (int)(s_ptr - s_start);
|
||
|
}
|
||
|
if ((b_ptr + s_len) >= b_top)
|
||
|
{
|
||
|
ret = SS_LOG2LONG;
|
||
|
break;
|
||
|
}
|
||
|
memcpy(b_ptr, s_start, s_len);
|
||
|
b_ptr += s_len;
|
||
|
assert(b_ptr < b_top);
|
||
|
/* move over env var just processed */
|
||
|
s_start = s_ptr;
|
||
|
} else
|
||
|
s_ptr++; /* keep going until you either hit end of string or $ */
|
||
|
}
|
||
|
if (SS_LOG2LONG != ret)
|
||
|
{ /* if there is anything left after the last env var name, copy it */
|
||
|
s_len = (int)(s_ptr - s_start);
|
||
|
if ((b_ptr + s_len) >= b_top)
|
||
|
ret = SS_LOG2LONG;
|
||
|
else
|
||
|
{
|
||
|
memcpy(b_ptr, s_start, s_len);
|
||
|
b_ptr += s_len;
|
||
|
assert(b_ptr < b_top);
|
||
|
}
|
||
|
}
|
||
|
assert(b_ptr < b_top); /* "<" instead of "<=" so it is safe to write the termination '\0' character */
|
||
|
/* create the return mstr */
|
||
|
trans->addr = buffer;
|
||
|
trans->len = INTCAST(b_ptr - buffer);
|
||
|
assert(trans->len < buffer_len);
|
||
|
/* Null-terminate returned string (even though an mstr), as this is relied upon
|
||
|
* by callers who do ATOI etc. directly on the return string.
|
||
|
*/
|
||
|
trans->addr[trans->len] = '\0';
|
||
|
if (do_sendmsg && (SS_LOG2LONG == ret))
|
||
|
send_msg(VARLSTCNT(5) ERR_LOGTOOLONG, 3, log->len, log->addr, buffer_len - 1); /* - 1 for terminating null byte */
|
||
|
return ret;
|
||
|
}
|