4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
22 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
23 /* All Rights Reserved */
26 * Copyright (c) 2001 by Sun Microsystems, Inc.
27 * All rights reserved.
30 #ident "%Z%%M% %I% %E% SMI" /* from SVR4 bnu:expfile.c 2.10 */
35 * expand file name expansion is based on first characters
36 * / -> fully qualified pathname. no
37 * processing necessary
38 * ~ -> prepended with login directory
39 * ~/ -> prepended with Pubdir
40 * default -> prepended with current directory
41 * file -> filename to expand
44 * FAIL -> no Wrkdir name available
50 register char *fpart
, *up
;
52 char user
[NAMESIZE
], save
[MAXFULLNAME
];
53 extern int gninfo(), canPath();
55 if (strlcpy(save
, file
, sizeof (save
)) >= sizeof (save
))
59 /* find / and copy user part */
60 for (fpart
= save
+ 1, up
= user
; *fpart
!= '\0'
61 && *fpart
!= '/'; fpart
++)
64 if ((user
[0]=='\0') || (gninfo(user
, &uid
, file
) != 0)){
65 (void) strcpy(file
, Pubdir
);
67 if (strlen(file
) + strlen(fpart
) + 1 > (unsigned)MAXFULLNAME
)
69 (void) strcat(file
, fpart
);
71 if (strlen(Wrkdir
) + strlen(save
) + 2 > (unsigned)MAXFULLNAME
)
73 (void) sprintf(file
, "%s/%s", Wrkdir
, save
);
74 if (Wrkdir
[0] == '\0')
78 if (canPath(file
) != 0) { /* I don't think this will ever fail */
79 (void) strcpy(file
, CORRUPTDIR
);
87 * make all necessary directories
88 * name -> directory to make
89 * mask -> mask to use during directory creation
101 char dir
[MAXFULLNAME
];
104 if (*LASTCHAR(dir
) != '/')
105 (void) strcat(dir
, "/");
108 if ((p
= strchr(p
, '/')) == NULL
)
111 if (DIRECTORY(dir
)) {
112 /* if directory exists and is owned by uucp, child's
113 permissions should be no more open than parent */
114 if (__s_
.st_uid
== UUCPUID
)
115 mask
|= ((~__s_
.st_mode
) & PUB_DIRMODE
);
117 DEBUG(4, "mkdir - %s\n", dir
);
119 if (mkdir(dir
, PUB_DIRMODE
) == FAIL
) {
131 * expand file name and check return
132 * print error if it failed.
133 * file -> file name to check
136 * FAIL -> if expfile failed
142 if (expfile(file
) == 0)
145 fprintf(stderr
, gettext("Illegal filename (%s).\n"), file
);
151 * make canonical path out of path passed as argument.
153 * Eliminate redundant self-references like // or /./
154 * (A single terminal / will be preserved, however.)
155 * Dispose of references to .. in the path names.
156 * In relative path names, this means that .. or a/../..
157 * will be treated as an illegal reference.
158 * In full paths, .. is always allowed, with /.. treated as /
161 * 0 -> path is now in canonical form
162 * FAIL -> relative path contained illegal .. reference
167 register char *path
; /* path is modified in place */
169 register char *to
, *fr
;
172 if (*fr
== '/') *to
++ = *fr
++;
174 /* skip past references to self and validate references to .. */
180 if ((strncmp(fr
, "./", 2) == SAME
) || EQUALS(fr
, ".")) {
184 if ((strncmp(fr
, "../", 3) == SAME
) || EQUALS(fr
, "..")) {
187 if (((to
- 1) == path
) && (*path
== '/')) continue;
188 /* error if no previous component */
189 if (to
<= path
) return (FAIL
);
190 /* back past previous component */
191 while ((--to
> path
) && (to
[-1] != '/'));
197 * What follows is a legitimate component,
198 * terminated by a null or a /
200 if (*fr
== '\0') break;
201 while (((*to
++ = *fr
) != '\0') && (*fr
++ != '/'));
204 if (to
== path
) *to
++ = '.';