/* pathcode/fget_cleanpath.c. Generated from cleanpath.c.in by configure. */
/*
** Copyright 1998-2002 University of Illinois Board of Trustees
** Copyright 1998-2002 Mark D. Roth
** All rights reserved.
**
** fget_cleanpath.c - function to clean up path names
**
** Mark D. Roth <roth@uiuc.edu>
** Campus Information Technologies and Educational Services
** University of Illinois at Urbana-Champaign
*/
#include <fget_pathcode.h>
#include <stdio.h>
#include <sys/param.h>
#include <errno.h>
#ifdef STDC_HEADERS
# include <string.h>
#endif
/*
** fget_cleanpath() - create a clean representation of path via string manipulation:
** - squeezes multiple '/' characters
** - removes previous directory with ".." (except at start of relative path)
** - removes "." (except where all path components cancel)
*/
int
fget_cleanpath(char *path, char *buf, size_t bufsize)
{
char work[MAXPATHLEN];
char *cp, *thisp, *nextp = work;
#ifdef DEBUG
printf("==> fget_cleanpath(path=\"%s\", buf=0x%lx, bufsize=%d)\n",
path, buf, bufsize);
#endif
cp = strchr(path, '/');
/* no '/' characters - return as-is */
if (cp == NULL)
{
strlcpy(buf, (path[0] != '\0' ? path : "."), bufsize);
return 0;
}
/* copy leading slash if present */
if (cp == path)
strlcpy(buf, "/", bufsize);
else
buf[0] = '\0';
/* tokenization */
strlcpy(work, path, sizeof(work));
while ((thisp = strsep(&nextp, "/")) != NULL)
{
if (*thisp == '\0')
continue;
if (strcmp(thisp, ".") == 0)
continue;
if (strcmp(thisp, "..") == 0)
{
cp = strrchr(buf, '/');
if (cp == buf) /* "/" or "/foo" */
{
buf[1] = '\0';
continue;
}
else if (cp == NULL) /* "..", "foo", or "" */
{
if (buf[0] != '\0' && strcmp(buf, "..") != 0)
{
buf[0] = '\0';
continue;
}
}
else /* ".../foo" */
{
*cp = '\0';
continue;
}
}
if (buf[0] != '\0' && buf[strlen(buf) - 1] != '/')
{
if (strlcat(buf, "/", bufsize) > bufsize)
{
errno = ENAMETOOLONG;
return -1;
}
}
if (strlcat(buf, thisp, bufsize) > bufsize)
{
errno = ENAMETOOLONG;
return -1;
}
}
if (buf[0] == '\0')
strlcpy(buf, ".", bufsize);
#ifdef DEBUG
printf("<== fget_cleanpath(): buf=\"%s\"\n", buf);
#endif
return 0;
}
#ifdef TEST_CLEANPATH
int
main(int argc, char *argv[])
{
char buf[MAXPATHLEN];
printf("fget_cleanpath(\"%s\") == ", argv[1]);
fget_cleanpath(argv[1], buf, sizeof(buf));
printf("\"%s\"\n", buf);
exit(0);
}
#endif /* TEST_CLEANPATH */
syntax highlighted by Code2HTML, v. 0.9.1