File: get_full_path.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 (111 lines) | stat: -rwxr-xr-x 3,060 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
/****************************************************************
 *								*
 * Copyright (c) 2001-2022 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 "rmv_mul_slsh.h"

#include <sys/param.h>
#include <errno.h>
#include "gtm_unistd.h"
#include "gtm_string.h"
#include "gtm_limits.h"

#include "gdsroot.h"
#include "gdsbt.h"
#include "have_crit.h"

error_def(ERR_FILENAMETOOLONG);

/* Gets the full path name for a given file name. Prepends the CWD, even if the file does not exist. */
boolean_t get_full_path(char *orig_fn, unsigned int orig_len, char *full_fn, unsigned int *full_len,
		unsigned int max_len, uint4 *status)
{
	char		*cptr, *c1;
	char		cwdbuf[GTM_PATH_MAX];
	unsigned int	cwd_len, dir_len, newfn_len, trim_len;
	int		i;
	char		*getcwd_res;
	unsigned int	length;

	if ('/' == *orig_fn)
	{	/* The original path is already complete */
		if (max_len < orig_len)
		{
			*status = ERR_FILENAMETOOLONG;
			return FALSE;

		}
		length = orig_len;
		memcpy(full_fn, orig_fn, length);
	} else
	{
		GETCWD(cwdbuf, SIZEOF(cwdbuf), getcwd_res);
		if (NULL == getcwd_res)
		{
			*status = errno;
			return FALSE;
		}
		cwd_len = strlen(cwdbuf);
		cptr = orig_fn;
		if (('.' == *cptr)  &&  ('.' == *(cptr + 1)))
		{
			for (i = 1;  ;  ++i)
			{
				cptr += 2;
				if (('.' != *(cptr + 1))  ||  ('.' != *(cptr + 2)))
					break;
				++cptr;
			}
			for (c1 = &cwdbuf[cwd_len - 1];  i > 0;  --i)
				while ('/' != *c1)
					--c1;
			assert(c1 >= cwdbuf);
			dir_len = (unsigned int)(c1 - cwdbuf);
			assert(cptr >= orig_fn);
			assert((0 <= (unsigned int)(cptr - orig_fn)) && (max_len > (unsigned int)(cptr - orig_fn)));
			trim_len = (unsigned int)(cptr - orig_fn);
			assert(orig_len >= trim_len);
			newfn_len = orig_len - trim_len;
			length = dir_len + newfn_len;
			if (max_len < (length + 1))
			{
				*status = ERR_FILENAMETOOLONG;
				return FALSE;
			}
			memcpy(full_fn, cwdbuf, dir_len);
			memcpy(full_fn + dir_len, cptr, newfn_len);
		} else
		{
			if ('.' == *cptr && '/' == (*(cptr + 1)))
				cptr += 2;
			assert(cptr >= orig_fn);
			assert((0 <= (unsigned int)(cptr - orig_fn)) && (max_len > (unsigned int)(cptr - orig_fn)));
			trim_len = (unsigned int)(cptr - orig_fn);
			assert(orig_len >= trim_len);
			newfn_len = orig_len - trim_len;
			length = cwd_len + 1 + newfn_len;
			if (max_len < (length + 1))
			{
				*status = ERR_FILENAMETOOLONG;
				return FALSE;
			}
			memcpy(full_fn, cwdbuf, cwd_len);
			full_fn[cwd_len++] = '/';
			memcpy(full_fn + cwd_len, cptr, newfn_len);
		}
	}
	*full_len = length;
	/*Remove multiple slash occurances*/
        *full_len = rmv_mul_slsh(full_fn, *full_len);
	full_fn[*full_len] = '\0';
	return TRUE;
}