File: trans_log_name.c

package info (click to toggle)
fis-gtm 7.1-006-1
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 32,908 kB
  • sloc: ansic: 344,906; asm: 5,184; csh: 4,859; sh: 2,000; awk: 294; makefile: 73; sed: 13
file content (133 lines) | stat: -rwxr-xr-x 5,035 bytes parent folder | download | duplicates (3)
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;
}