xref: /csrg-svn/bin/cp/path.c (revision 51405)
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