1
0
Files
irix-657m-src/eoe/cmd/uucp/expfile.c
2022-09-29 17:59:04 +03:00

238 lines
4.8 KiB
C

/* Copyright (c) 1984 AT&T */
/* All Rights Reserved */
/* THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T */
/* The copyright notice above does not evidence any */
/* actual or intended publication of such source code. */
#ident "$Revision: 1.5 $"
#include "uucp.h"
/*
* expand file name expansion is based on first characters
* / -> fully qualified pathname. no
* processing necessary
* ~ -> prepended with login directory
* ~/ -> prepended with Pubdir
* default -> prepended with current directory
* file -> filename to expand
* returns:
* 0 -> ok
* FAIL -> no Wrkdir name available
*/
expfile(file)
register char *file;
{
register char *fpart, *up;
int uid;
char user[NAMESIZE], save[MAXFULLNAME];
strcpy(save, file);
if (*file == '/')
;
else if (*file == '~') {
/* find / and copy user part */
for (fpart = save + 1, up = user; *fpart != '\0'
&& *fpart != '/'; fpart++)
*up++ = *fpart;
*up = '\0';
if ((user[0]=='\0') || (gninfo(user, &uid, file) != 0)){
(void) strcpy(file, Pubdir);
}
(void) strcat(file, fpart);
}
else {
(void) sprintf(file, "%s/%s", Wrkdir, save);
if (Wrkdir[0] == '\0')
return(FAIL);
}
if (canPath(file) != 0) { /* I don't think this will ever fail */
(void) strcpy(file, CORRUPTDIR);
return(FAIL);
}
else
return(0);
}
/*
* make all necessary directories
* name -> directory to make
* return:
* 0 -> success
* FAIL -> failure
*/
int
mkdirs(name)
register char *name;
{
register char *p;
char dir[MAXFULLNAME];
strcpy(dir, name);
if (*LASTCHAR(dir) != '/')
(void) strcat(dir, "/");
p = dir + 1;
for (;;) {
if ((p = strchr(p, '/')) == NULL)
return(0);
*p = '\0';
DEBUG(4, "mkdir - %s\n", dir);
if (mkdirs2(dir, 0) == FAIL)
return (FAIL);
*p++ = '/';
}
}
#ifdef ATTSV
/*
* Make name a directory if it is not already a directory
* ATTSV handling of setuid is less than convenient ...
* return:
* 0 -> ok
* FAIL -> failed
*/
mkdirs2(name, mask)
register char *name;
register int mask;
{
int status;
if (DIRECTORY(name))
return(0); /* directory exists */
status = mkdir(name,0770);
if (status != 0) {
errent(Ct_CREATE, name, status, __FILE__, __LINE__);
return(FAIL);
}
if ( chmod(name, (mask ^ 0777) & 0777) != 0) {
errent(Ct_CHMOD, name, errno, __FILE__, __LINE__);
setuid(Euid);
return(FAIL);
};
if (chown(name, UUCPUID, getgid()) != 0) {
DEBUG(5, "CHOWN FAILED %s ", name);
DEBUG(5, "errno %d\n", errno);
errent(Ct_CHOWN, name, errno, __FILE__, __LINE__);
setuid(Euid);
return(FAIL);
}
setuid(Euid);
return(0);
}
#endif /* ATTSV */
#ifdef V7
mkdirs2(name, mask)
register char *name;
register int mask;
{
int ret;
if (DIRECTORY(name))
return(0); /* directory exists */
if (vfork() == 0) {
setuid(Euid); /* this makes it trivial in V7 */
umask(mask);
/* close stdout and stderr to fail quietly */
close(1);
close(2);
execl("/bin/mkdir", "mkdir", name, (char *) 0);
_exit(1);
}
wait(&ret);
if (ret != 0) /* why should we abort if some remote tries */
return(FAIL); /* to make a garbage directory */
return(0);
}
#endif /* V7 */
/*
* expand file name and check return
* print error if it failed.
* file -> file name to check
* returns:
* 0 -> ok
* FAIL -> if expfile failed
*/
ckexpf(file)
char *file;
{
if (expfile(file) == 0)
return(0);
fprintf(stderr, "Illegal filename (%s).\n", file);
return(FAIL);
}
/*
* make canonical path out of path passed as argument.
*
* Eliminate redundant self-references like // or /./
* (A single terminal / will be preserved, however.)
* Dispose of references to .. in the path names.
* In relative path names, this means that .. or a/../..
* will be treated as an illegal reference.
* In full paths, .. is always allowed, with /.. treated as /
*
* returns:
* 0 -> path is now in canonical form
* FAIL -> relative path contained illegal .. reference
*/
int
canPath(path)
register char *path; /* path is modified in place */
{
register char *to, *fr;
to = fr = path;
if (*fr == '/') *to++ = *fr++;
for (;;) {
/* skip past references to self and validate references to .. */
for (;;) {
if (*fr == '/') {
fr++;
continue;
}
if ((strncmp(fr, "./", 2) == SAME) || EQUALS(fr, ".")) {
fr++;
continue;
}
if ((strncmp(fr, "../", 3) == SAME) || EQUALS(fr, "..")) {
fr += 2;
/* /.. is / */
if (((to - 1) == path) && (*path == '/')) continue;
/* error if no previous component */
if (to <= path) return (FAIL);
/* back past previous component */
while ((--to > path) && (to[-1] != '/'));
continue;
}
break;
}
/*
* What follows is a legitimate component,
* terminated by a null or a /
*/
if (*fr == '\0') break;
while ((*to++ = *fr) && (*fr++ != '/'));
}
/* null path is . */
if (to == path) *to++ = '.';
*to = '\0';
return (0);
}