Files
Arquivotheca.SunOS-4.1.3/sys/boot/os/vfs_pathname.c
seta75D 2e8a93c394 Init
2021-10-11 18:20:23 -03:00

192 lines
3.9 KiB
C

#ifndef lint
static char sccsid[] = "@(#)vfs_pathname.c 1.1 92/07/30 Copyr 1986 Sun Micro";
#endif
/*
* Copyright (c) 1986 by Sun Microsystems, Inc.
*/
#include <sys/param.h>
#include "boot/systm.h"
#include <sys/dir.h>
#include <sys/uio.h>
#include <sys/errno.h>
#include <sys/pathname.h>
/*
* Pathname utilities.
*
* In translating file names we copy each argument file
* name into a pathname structure where we operate on it.
* Each pathname structure can hold MAXPATHLEN characters
* including a terminating null, and operations here support
* allocating and freeing pathname structures, fetching
* strings from user space, getting the next character from
* a pathname, combining two pathnames (used in symbolic
* link processing), and peeling off the first component
* of a pathname.
*/
static char *pn_freelist;
/*
* Allocate contents of pathname structure.
* Structure itself is typically automatic
* variable in calling routine for convenience.
*/
pn_alloc(pnp)
register struct pathname *pnp;
{
if (pn_freelist) {
pnp->pn_buf = pn_freelist;
pn_freelist = *(char **) pnp->pn_buf;
} else {
pnp->pn_buf = (char *)kmem_alloc((u_int)MAXPATHLEN);
}
pnp->pn_path = (char *)pnp->pn_buf;
pnp->pn_pathlen = 0;
}
/*
* Pull a pathname from user user or kernel space
*/
int
pn_get(str, seg, pnp)
register char *str;
int seg;
register struct pathname *pnp;
{
register int error;
pn_alloc(pnp);
if (seg == UIOSEG_USER) {
#ifdef NEVER
error =
copyinstr(str, pnp->pn_path, MAXPATHLEN, &pnp->pn_pathlen);
#endif /* NEVER */
} else {
error =
copystr(str, pnp->pn_path, MAXPATHLEN, &pnp->pn_pathlen);
}
pnp->pn_pathlen--; /* don't count null byte */
if (error)
pn_free(pnp);
return (error);
}
#ifdef notneeded
/*
* Get next character from a path.
* Return null at end forever.
*/
pn_getchar(pnp)
register struct pathname *pnp;
{
if (pnp->pn_pathlen == 0)
return (0);
pnp->pn_pathlen--;
return (*pnp->pn_path++);
}
#endif notneeded
/*
* Set pathname to argument string.
*/
pn_set(pnp, path)
register struct pathname *pnp;
register char *path;
{
register int error;
pnp->pn_path = pnp->pn_buf;
error = copystr(path, pnp->pn_path, MAXPATHLEN, &pnp->pn_pathlen);
pnp->pn_pathlen--; /* don't count null byte */
return (error);
}
/*
* Combine two argument pathnames by putting
* second argument before first in first's buffer,
* and freeing second argument.
* This isn't very general: it is designed specifically
* for symbolic link processing.
*/
pn_combine(pnp, sympnp)
register struct pathname *pnp;
register struct pathname *sympnp;
{
if (pnp->pn_pathlen + sympnp->pn_pathlen >= MAXPATHLEN)
return (ENAMETOOLONG);
ovbcopy(pnp->pn_path, pnp->pn_buf + sympnp->pn_pathlen,
(u_int)pnp->pn_pathlen);
bcopy(sympnp->pn_path, pnp->pn_buf, (u_int)sympnp->pn_pathlen);
pnp->pn_pathlen += sympnp->pn_pathlen;
pnp->pn_path = pnp->pn_buf;
return (0);
}
/*
* Strip next component off a pathname and leave in
* buffer comoponent which should have room for
* MAXNAMLEN bytes and a null terminator character.
*/
pn_getcomponent(pnp, component)
register struct pathname *pnp;
register char *component;
{
register char *cp;
register int l;
register int n;
register char c;
cp = pnp->pn_path;
l = pnp->pn_pathlen;
n = MAXNAMLEN;
while ((l > 0) && (*cp != '/')) {
if (--n < 0)
return(ENAMETOOLONG);
c = *cp++;
if (c & 0x80)
return (EINVAL);
*component++ = c;
--l;
}
pnp->pn_path = cp;
pnp->pn_pathlen = l;
*component = 0;
return (0);
}
/*
* skip over consecutive slashes in the pathname
*/
void
pn_skipslash(pnp)
register struct pathname *pnp;
{
while ((pnp->pn_pathlen > 0) && (*pnp->pn_path == '/')) {
pnp->pn_path++;
pnp->pn_pathlen--;
}
}
/*
* Free pathname resources.
*/
void
pn_free(pnp)
register struct pathname *pnp;
{
/* kmem_free((caddr_t)pnp->pn_buf, (u_int)MAXPATHLEN); */
*(char **) pnp->pn_buf = pn_freelist;
pn_freelist = pnp->pn_buf;
pnp->pn_buf = 0;
}