147746Sbostic /*-
247746Sbostic * Copyright (c) 1991 The Regents of the University of California.
347746Sbostic * All rights reserved.
447746Sbostic *
547746Sbostic * %sccs.include.redist.c%
647746Sbostic */
747746Sbostic
847746Sbostic #ifndef lint
9*51405Sbostic static char sccsid[] = "@(#)path.c 5.2 (Berkeley) 10/27/91";
1047746Sbostic #endif /* not lint */
1147746Sbostic
1247746Sbostic #include <sys/param.h>
1347746Sbostic #include <string.h>
14*51405Sbostic #include "extern.h"
1547746Sbostic
1647746Sbostic /*
1747746Sbostic * These functions manipulate paths in PATH_T structures.
1847746Sbostic *
1947746Sbostic * They eliminate multiple slashes in paths when they notice them,
2047746Sbostic * and keep the path non-slash terminated.
2147746Sbostic *
2247746Sbostic * Both path_set() and path_append() return 0 if the requested name
2347746Sbostic * would be too long.
2447746Sbostic */
2547746Sbostic
2647746Sbostic #define STRIP_TRAILING_SLASH(p) { \
2747746Sbostic while ((p)->p_end > (p)->p_path && (p)->p_end[-1] == '/') \
2847746Sbostic *--(p)->p_end = 0; \
2947746Sbostic }
3047746Sbostic
3147746Sbostic /*
3247746Sbostic * Move specified string into path. Convert "" to "." to handle BSD
3347746Sbostic * semantics for a null path. Strip trailing slashes.
3447746Sbostic */
35*51405Sbostic int
path_set(p,string)3647746Sbostic path_set(p, string)
3747746Sbostic register PATH_T *p;
3847746Sbostic char *string;
3947746Sbostic {
4047746Sbostic if (strlen(string) > MAXPATHLEN) {
41*51405Sbostic err("%s: name too long", string);
4247746Sbostic return(0);
4347746Sbostic }
4447746Sbostic
4547746Sbostic (void)strcpy(p->p_path, string);
4647746Sbostic p->p_end = p->p_path + strlen(p->p_path);
4747746Sbostic
4847746Sbostic if (p->p_path == p->p_end) {
4947746Sbostic *p->p_end++ = '.';
5047746Sbostic *p->p_end = 0;
5147746Sbostic }
5247746Sbostic
5347746Sbostic STRIP_TRAILING_SLASH(p);
5447746Sbostic return(1);
5547746Sbostic }
5647746Sbostic
5747746Sbostic /*
5847746Sbostic * Append specified string to path, inserting '/' if necessary. Return a
5947746Sbostic * pointer to the old end of path for restoration.
6047746Sbostic */
6147746Sbostic char *
path_append(p,name,len)6247746Sbostic path_append(p, name, len)
6347746Sbostic register PATH_T *p;
6447746Sbostic char *name;
6547746Sbostic int len;
6647746Sbostic {
6747746Sbostic char *old;
6847746Sbostic
6947746Sbostic old = p->p_end;
7047746Sbostic if (len == -1)
7147746Sbostic len = strlen(name);
7247746Sbostic
7347746Sbostic /* The "+ 1" accounts for the '/' between old path and name. */
7447746Sbostic if ((len + p->p_end - p->p_path + 1) > MAXPATHLEN) {
75*51405Sbostic err("%s/%s: name too long", p->p_path, name);
7647746Sbostic return(0);
7747746Sbostic }
7847746Sbostic
7947746Sbostic /*
8047746Sbostic * This code should always be executed, since paths shouldn't
8147746Sbostic * end in '/'.
8247746Sbostic */
8347746Sbostic if (p->p_end[-1] != '/') {
8447746Sbostic *p->p_end++ = '/';
8547746Sbostic *p->p_end = 0;
8647746Sbostic }
8747746Sbostic
8847746Sbostic (void)strncat(p->p_end, name, len);
8947746Sbostic p->p_end += len;
9047746Sbostic *p->p_end = 0;
9147746Sbostic
9247746Sbostic STRIP_TRAILING_SLASH(p);
9347746Sbostic return(old);
9447746Sbostic }
9547746Sbostic
9647746Sbostic /*
9747746Sbostic * Restore path to previous value. (As returned by path_append.)
9847746Sbostic */
9947746Sbostic void
path_restore(p,old)10047746Sbostic path_restore(p, old)
10147746Sbostic PATH_T *p;
10247746Sbostic char *old;
10347746Sbostic {
10447746Sbostic p->p_end = old;
10547746Sbostic *p->p_end = 0;
10647746Sbostic }
10747746Sbostic
10847746Sbostic /*
10947746Sbostic * Return basename of path.
11047746Sbostic */
11147746Sbostic char *
path_basename(p)11247746Sbostic path_basename(p)
11347746Sbostic PATH_T *p;
11447746Sbostic {
11547746Sbostic char *basename;
11647746Sbostic
11747746Sbostic basename = rindex(p->p_path, '/');
11847746Sbostic return(basename ? basename + 1 : p->p_path);
11947746Sbostic }
120