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.1 (Berkeley) 04/03/91"; 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 */ 36 path_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 */ 62 char * 63 path_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 */ 101 void 102 path_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 */ 113 char * 114 path_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 } 122