This commit was generated by cvs2svn to track changes on a CVS vendor
[unix-history] / bin / cp / path.c
CommitLineData
15637ed4
RG
1/*-
2 * Copyright (c) 1991 The Regents of the University of California.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#ifndef lint
fc9e4a1c 35static char sccsid[] = "@(#)path.c 5.2 (Berkeley) 10/27/91";
15637ed4
RG
36#endif /* not lint */
37
38#include <sys/param.h>
15637ed4 39#include <string.h>
fc9e4a1c 40#include "extern.h"
15637ed4
RG
41
42/*
43 * These functions manipulate paths in PATH_T structures.
44 *
45 * They eliminate multiple slashes in paths when they notice them,
46 * and keep the path non-slash terminated.
47 *
48 * Both path_set() and path_append() return 0 if the requested name
49 * would be too long.
50 */
51
52#define STRIP_TRAILING_SLASH(p) { \
53 while ((p)->p_end > (p)->p_path && (p)->p_end[-1] == '/') \
54 *--(p)->p_end = 0; \
55}
56
57/*
58 * Move specified string into path. Convert "" to "." to handle BSD
59 * semantics for a null path. Strip trailing slashes.
60 */
fc9e4a1c 61int
15637ed4
RG
62path_set(p, string)
63 register PATH_T *p;
64 char *string;
65{
66 if (strlen(string) > MAXPATHLEN) {
fc9e4a1c 67 err("%s: name too long", string);
15637ed4
RG
68 return(0);
69 }
70
71 (void)strcpy(p->p_path, string);
72 p->p_end = p->p_path + strlen(p->p_path);
73
74 if (p->p_path == p->p_end) {
75 *p->p_end++ = '.';
76 *p->p_end = 0;
77 }
78
79 STRIP_TRAILING_SLASH(p);
80 return(1);
81}
82
83/*
84 * Append specified string to path, inserting '/' if necessary. Return a
85 * pointer to the old end of path for restoration.
86 */
87char *
88path_append(p, name, len)
89 register PATH_T *p;
90 char *name;
91 int len;
92{
93 char *old;
94
95 old = p->p_end;
96 if (len == -1)
97 len = strlen(name);
98
99 /* The "+ 1" accounts for the '/' between old path and name. */
100 if ((len + p->p_end - p->p_path + 1) > MAXPATHLEN) {
fc9e4a1c 101 err("%s/%s: name too long", p->p_path, name);
15637ed4
RG
102 return(0);
103 }
104
105 /*
106 * This code should always be executed, since paths shouldn't
107 * end in '/'.
108 */
109 if (p->p_end[-1] != '/') {
110 *p->p_end++ = '/';
111 *p->p_end = 0;
112 }
113
114 (void)strncat(p->p_end, name, len);
115 p->p_end += len;
116 *p->p_end = 0;
117
118 STRIP_TRAILING_SLASH(p);
119 return(old);
120}
121
122/*
123 * Restore path to previous value. (As returned by path_append.)
124 */
125void
126path_restore(p, old)
127 PATH_T *p;
128 char *old;
129{
130 p->p_end = old;
131 *p->p_end = 0;
132}
133
134/*
135 * Return basename of path.
136 */
137char *
138path_basename(p)
139 PATH_T *p;
140{
141 char *basename;
142
143 basename = rindex(p->p_path, '/');
144 return(basename ? basename + 1 : p->p_path);
145}