1 /*-
2 * Copyright (c) 1991 The Regents of the University of California.
3 * All rights reserved.
4 *
5 * %sccs.include.redist.c%
6 */
7
8 #ifndef lint
9 static char sccsid[] = "@(#)path.c 5.2 (Berkeley) 10/27/91";
10 #endif /* not lint */
11
12 #include <sys/param.h>
13 #include <string.h>
14 #include "extern.h"
15
16 /*
17 * These functions manipulate paths in PATH_T structures.
18 *
19 * They eliminate multiple slashes in paths when they notice them,
20 * and keep the path non-slash terminated.
21 *
22 * Both path_set() and path_append() return 0 if the requested name
23 * would be too long.
24 */
25
26 #define STRIP_TRAILING_SLASH(p) { \
27 while ((p)->p_end > (p)->p_path && (p)->p_end[-1] == '/') \
28 *--(p)->p_end = 0; \
29 }
30
31 /*
32 * Move specified string into path. Convert "" to "." to handle BSD
33 * semantics for a null path. Strip trailing slashes.
34 */
35 int
path_set(p,string)36 path_set(p, string)
37 register PATH_T *p;
38 char *string;
39 {
40 if (strlen(string) > MAXPATHLEN) {
41 err("%s: name too long", string);
42 return(0);
43 }
44
45 (void)strcpy(p->p_path, string);
46 p->p_end = p->p_path + strlen(p->p_path);
47
48 if (p->p_path == p->p_end) {
49 *p->p_end++ = '.';
50 *p->p_end = 0;
51 }
52
53 STRIP_TRAILING_SLASH(p);
54 return(1);
55 }
56
57 /*
58 * Append specified string to path, inserting '/' if necessary. Return a
59 * pointer to the old end of path for restoration.
60 */
61 char *
path_append(p,name,len)62 path_append(p, name, len)
63 register PATH_T *p;
64 char *name;
65 int len;
66 {
67 char *old;
68
69 old = p->p_end;
70 if (len == -1)
71 len = strlen(name);
72
73 /* The "+ 1" accounts for the '/' between old path and name. */
74 if ((len + p->p_end - p->p_path + 1) > MAXPATHLEN) {
75 err("%s/%s: name too long", p->p_path, name);
76 return(0);
77 }
78
79 /*
80 * This code should always be executed, since paths shouldn't
81 * end in '/'.
82 */
83 if (p->p_end[-1] != '/') {
84 *p->p_end++ = '/';
85 *p->p_end = 0;
86 }
87
88 (void)strncat(p->p_end, name, len);
89 p->p_end += len;
90 *p->p_end = 0;
91
92 STRIP_TRAILING_SLASH(p);
93 return(old);
94 }
95
96 /*
97 * Restore path to previous value. (As returned by path_append.)
98 */
99 void
path_restore(p,old)100 path_restore(p, old)
101 PATH_T *p;
102 char *old;
103 {
104 p->p_end = old;
105 *p->p_end = 0;
106 }
107
108 /*
109 * Return basename of path.
110 */
111 char *
path_basename(p)112 path_basename(p)
113 PATH_T *p;
114 {
115 char *basename;
116
117 basename = rindex(p->p_path, '/');
118 return(basename ? basename + 1 : p->p_path);
119 }
120