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