|
|
1.1 root 1: /* $Source: /src386/usr/bin/pax/pathname.c,v $
2: *
3: * $Revision: 1.1 $
4: *
5: * pathname.c - directory/pathname support functions
6: *
7: * DESCRIPTION
8: *
9: * These functions provide directory/pathname support for PAX
10: *
11: * AUTHOR
12: *
13: * Mark H. Colburn, NAPS International ([email protected])
14: *
15: * Sponsored by The USENIX Association for public distribution.
16: *
17: * Copyright (c) 1989 Mark H. Colburn.
18: * All rights reserved.
19: *
20: * Redistribution and use in source and binary forms are permitted
21: * provided that the above copyright notice is duplicated in all such
22: * forms and that any documentation, advertising materials, and other
23: * materials related to such distribution and use acknowledge that the
24: * software was developed * by Mark H. Colburn and sponsored by The
25: * USENIX Association.
26: *
27: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
28: * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
29: * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
30: *
31: * $Log: pathname.c,v $
32: * Revision 1.1 92/08/28 08:02:47 bin
33: * Initial revision
34: *
35: * Revision 1.1 89/02/14 16:48:23 jep
36: * Initial revision
37: *
38: * Revision 1.1 88/12/23 18:02:21 mark
39: * Initial revision
40: *
41: */
42:
43: #ifndef lint
44: static char *ident = "$Id: pathname.c,v 1.1 92/08/28 08:02:47 bin Exp Locker: bin $";
45: static char *copyright = "Copyright (c) 1989 Mark H. Colburn.\nAll rights reserved.\n";
46: #endif /* ! lint */
47:
48:
49: /* Headers */
50:
51: #include "pax.h"
52:
53:
54: /* dirneed - checks for the existance of directories and possibly create
55: *
56: * DESCRIPTION
57: *
58: * Dirneed checks to see if a directory of the name pointed to by name
59: * exists. If the directory does exist, then dirneed returns 0. If
60: * the directory does not exist and the f_dir_create flag is set,
61: * then dirneed will create the needed directory, recursively creating
62: * any needed intermediate directory.
63: *
64: * If f_dir_create is not set, then no directories will be created
65: * and a value of -1 will be returned if the directory does not
66: * exist.
67: *
68: * PARAMETERS
69: *
70: * name - name of the directory to create
71: *
72: * RETURNS
73: *
74: * Returns a 0 if the creation of the directory succeeded or if the
75: * directory already existed. If the f_dir_create flag was not set
76: * and the named directory does not exist, or the directory creation
77: * failed, a -1 will be returned to the calling routine.
78: */
79:
80: #if __STDC__
81:
82: int dirneed(char *name)
83:
84: #else
85:
86: int dirneed(name)
87: char *name;
88:
89: #endif
90: {
91: char *cp;
92: char *last;
93: int ok;
94: static Stat sb;
95:
96: last = (char *)NULL;
97: for (cp = name; *cp;) {
98: if (*cp++ == '/') {
99: last = cp;
100: }
101: }
102: if (last == (char *)NULL) {
103: return (STAT(".", &sb));
104: }
105: *--last = '\0';
106: ok = STAT(*name ? name : ".", &sb) == 0
107: ? ((sb.sb_mode & S_IFMT) == S_IFDIR)
108: : (f_dir_create && dirneed(name) == 0 && dirmake(name, &sb) == 0);
109: *last = '/';
110: return (ok ? 0 : -1);
111: }
112:
113:
114: /* nameopt - optimize a pathname
115: *
116: * DESCRIPTION
117: *
118: * Confused by "<symlink>/.." twistiness. Returns the number of final
119: * pathname elements (zero for "/" or ".") or -1 if unsuccessful.
120: *
121: * PARAMETERS
122: *
123: * char *begin - name of the path to optimize
124: *
125: * RETURNS
126: *
127: * Returns 0 if successful, non-zero otherwise.
128: *
129: */
130:
131: #if __STDC__
132:
133: int nameopt(char *begin)
134:
135: #else
136:
137: int nameopt(begin)
138: char *begin;
139:
140: #endif
141: {
142: char *name;
143: char *item;
144: int idx;
145: int absolute;
146: char *element[PATHELEM];
147:
148: absolute = (*(name = begin) == '/');
149: idx = 0;
150: for (;;) {
151: if (idx == PATHELEM) {
152: warn(begin, "Too many elements");
153: return (-1);
154: }
155: while (*name == '/') {
156: ++name;
157: }
158: if (*name == '\0') {
159: break;
160: }
161: element[idx] = item = name;
162: while (*name && *name != '/') {
163: ++name;
164: }
165: if (*name) {
166: *name++ = '\0';
167: }
168: if (strcmp(item, "..") == 0) {
169: if (idx == 0) {
170: if (!absolute) {
171: ++idx;
172: }
173: } else if (strcmp(element[idx - 1], "..") == 0) {
174: ++idx;
175: } else {
176: --idx;
177: }
178: } else if (strcmp(item, ".") != 0) {
179: ++idx;
180: }
181: }
182: if (idx == 0) {
183: element[idx++] = absolute ? "" : ".";
184: }
185: element[idx] = (char *)NULL;
186: name = begin;
187: if (absolute) {
188: *name++ = '/';
189: }
190: for (idx = 0; item = element[idx]; ++idx, *name++ = '/') {
191: while (*item) {
192: *name++ = *item++;
193: }
194: }
195: *--name = '\0';
196: return (idx);
197: }
198:
199:
200: /* dirmake - make a directory
201: *
202: * DESCRIPTION
203: *
204: * Dirmake makes a directory with the appropritate permissions.
205: *
206: * PARAMETERS
207: *
208: * char *name - Name of directory make
209: * Stat *asb - Stat structure of directory to make
210: *
211: * RETURNS
212: *
213: * Returns zero if successful, -1 otherwise.
214: *
215: */
216:
217: #if __STDC__
218:
219: int dirmake(char *name, Stat *asb)
220:
221: #else
222:
223: int dirmake(name, asb)
224: char *name;
225: Stat *asb;
226:
227: #endif
228: {
229: if (mkdir(name, (int) (asb->sb_mode & S_IPOPN)) < 0) {
230: return (-1);
231: }
232: if (asb->sb_mode & S_IPEXE) {
233: chmod(name, (int) (asb->sb_mode & S_IPERM));
234: }
235: if (f_owner) {
236: chown(name, (int) asb->sb_uid, (int) asb->sb_gid);
237: }
238: return (0);
239: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.