1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133
|
/****************************************************************
* *
* Copyright (c) 2001-2021 Fidelity National Information *
* Services, Inc. and/or its subsidiaries. All rights reserved. *
* *
* 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 unsigned 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];
error_def(ERR_LOGTOOLONG);
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;
unsigned int s_len;
int4 ret;
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 = (unsigned int)(s_ptr - s_start);
if ((b_ptr + s_len) >= b_top)
{
ret = SS_LOG2LONG;
break;
}
assert(s_len <= buffer_len);
memcpy(b_ptr, s_start, s_len);
b_ptr += s_len;
/* 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 = (unsigned 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; /* preserve our initial condition that buflen == bufsize -1 */
}
assert(NULL != trans_log_name_buff); /* gird against malloc failure */
assert((0 <= s_len) && (s_len < trans_log_name_buflen));
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 = (unsigned int)(s_ptr - s_start);
}
if ((b_ptr + s_len) >= b_top)
{
ret = SS_LOG2LONG;
break;
}
assert(s_len <= buffer_len);
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 = (unsigned 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_csa(CSA_ARG(NULL) VARLSTCNT(5) ERR_LOGTOOLONG,
3, log->len, log->addr, buffer_len - 1); /* - 1 for terminating null byte */
return ret;
}
|