aboutsummaryrefslogtreecommitdiff
path: root/unix/os/zfsubd.c
blob: fd9798bec7eb1a8aeb66c576972f38165a51edef (plain) (blame)
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
/* Copyright(c) 1986 Association of Universities for Research in Astronomy Inc.
 */

#include <stdio.h>
#include <ctype.h>
#define import_spp
#define	import_kernel
#define import_knames
#include <iraf.h>

/* ZFSUBD -- Fold a subdirectory into an OS directory.  If osdir is null the
 * current directory is assumed.  If subdir is null osdir is modified as
 * necessary to make it a legal directory prefix, e.g., if osdir = "/usr/iraf"
 * and subdir = "", we would return osdir = "/usr/iraf/".  The subdirectory
 * "." refers to the current directory and ".." to the previous directory,
 * but this is consistent with UNIX so we need not recognize these as special
 * cases.  The return OS directory prefix need not be an absolute pathname.
 */
int
ZFSUBD (
  XCHAR	 *osdir,		/* pathname		[NOT PACKED]	*/
  XINT	 *maxch,		/* max xchars in osdir			*/
  XCHAR	 *subdir,		/* subdirectory name	[NOT PACKED]	*/
  XINT	 *nchars		/* receives lenght of osdir		*/
)
{
	register XCHAR	*ip, *op;
	register int	n;
	PKCHAR	cwd[SZ_PATHNAME+1];
	XINT	x_maxch = SZ_PATHNAME;
	XCHAR	*slash;
	char	*cp;

	extern  int ZFGCWD();


	/* If osdir is null, use the current directory.
	 */
	if (osdir[0] == XEOS) {
	    ZFGCWD (cwd, &x_maxch, nchars);
	    if (*nchars == XERR)
		return (XERR);
	    n = *maxch;
	    for (cp=(char *)cwd, op=osdir;  --n >= 0 && (*op = *cp++);  op++)
		;
	    *op = XEOS;
	}

	/* Find the end of the OSDIR string and the index of the / preceeding
	 * the last directory name, e.g., if "a/b/", slash=2.
	 */
	slash = NULL;
	for (op=osdir;  *op != XEOS;  op++)
	    if (*op == '/' && *(op+1) != XEOS)
		slash = op;

	/* Make sure the OSDIR ends with a '/'.
	 */
	if (op > osdir && *(op-1) != '/')
	    *op++ = '/';

	n = *maxch - (op - osdir);

	/* Concatenate the subdirectory. The "subdirectories "." or ".." are
	 * special cases.
	 */
	for (ip=subdir;  *ip == ' ';  ip++)
	    ;

	if (*ip == '.') {
	    switch (*(ip+1)) {
	    case '.':
		if (*(ip+2) == XEOS && slash != NULL && *(slash+1) != '.') {
		    op = slash + 1;
		    n = *maxch - (op - osdir);
		} else
		    goto subdir_;
		break;
	    case EOS:
		break;
	    default:
		goto subdir_;
	    }
	} else {
subdir_:    while (--n >= 0 && (*op = *ip++) != XEOS)
		op++;
	}

	/* If OSDIR is the null string return the pathname of the current
	 * working directory, i.e., "./".
	 */
	if (op == osdir && --n >= 0)
	    *op++ = '.';

	/* Make sure the OSDIR ends with a '/'
	 */
	if (*(op-1) != '/' && --n >= 0)
	    *op++ = '/';

	*op = XEOS;
	*nchars = op - osdir;

	return (XOK);
}