use MAXPATHLEN instead of BUFSIZ where appropriate
[unix-history] / usr / src / sbin / restore / utilities.c
CommitLineData
e0519353
KM
1/* Copyright (c) 1983 Regents of the University of California */
2
3#ifndef lint
38bbfe41 4static char sccsid[] = "@(#)utilities.c 3.4 (Berkeley) 83/02/28";
e0519353
KM
5#endif
6
7#include "restore.h"
8
d2d742ce
KM
9/*
10 * Move the contents of a directory to a new directory.
11 */
12movecontents(from, to)
13 struct entry *from, *to;
14{
15 register struct entry *ep;
16 struct entry *np;
17 register char *targetp;
18 char target[BUFSIZ];
19
20 strcpy(target, myname(to));
21 targetp = &target[strlen(target)];
22 *targetp++ = '/';
23 for (ep = from->e_entries; ep != NIL; ) {
24 strcpy(targetp, ep->e_name);
25 if (ep->e_flags & TMPNAME)
26 badentry(ep, "movecontents: found TMPNAME");
27 np = lookupname(target);
28 if (np != NIL)
29 mktempname(np);
30 renameit(myname(ep), target);
31 np = ep->e_sibling;
32 moveentry(ep, target);
33 ep = np;
34 }
35}
36
e0519353
KM
37/*
38 * Insure that all the components of a pathname exist.
39 */
d2d742ce
KM
40struct entry *
41pathcheck(name, type)
e0519353 42 char *name;
d2d742ce 43 char type;
e0519353
KM
44{
45 register char *cp;
46 struct entry *ep;
9f13f26d 47 char *start;
e0519353
KM
48
49 start = index(name, '/');
9f13f26d 50 if (start == 0)
d2d742ce 51 return (lookupino(ROOTINO));
e0519353
KM
52 for (cp = start; *cp != '\0'; cp++) {
53 if (*cp != '/')
54 continue;
55 *cp = '\0';
56 ep = lookupname(name);
57 if (ep == NIL) {
d2d742ce
KM
58 ep = addentry(name, (ino_t)0, NODE);
59 ep->e_flags |= type;
e0519353
KM
60 newnode(ep);
61 }
62 *cp = '/';
63 }
d2d742ce 64 return (ep);
e0519353
KM
65}
66
67/*
68 * Change a name to a unique temporary name.
69 */
70mktempname(ep)
71 register struct entry *ep;
72{
73 char oldname[BUFSIZ];
74
75 if (ep->e_flags & TMPNAME)
76 badentry(ep, "mktempname: called with TMPNAME");
77 ep->e_flags |= TMPNAME;
78 strcpy(oldname, myname(ep));
79 ep->e_name[ep->e_namlen++] = TMPCHAR;
80 ep->e_name[ep->e_namlen] = '\0';
81 renameit(oldname, myname(ep));
82}
83
84/*
85 * Rename a file or directory.
86 */
87renameit(from, to)
88 char *from, *to;
89{
90 if (rename(from, to) < 0) {
91 perror("renameit");
92 panic("Cannot rename %s to %s\n", from, to);
93 }
94 vprintf(stdout, "rename %s to %s\n", from, to);
95}
96
97/*
98 * Create a new node (directory).
99 */
100newnode(np)
101 struct entry *np;
102{
103 char *cp;
104
105 if (np->e_type != NODE)
106 badentry(np, "newnode: not a node");
107 cp = myname(np);
9f13f26d 108 if (mkdir(cp, 0777) < 0) {
74025ab9
KM
109 if (command == 'x') {
110 perror(cp);
111 return;
112 }
e0519353
KM
113 perror("newnode");
114 panic("Cannot make node %s\n", cp);
115 }
116 vprintf(stdout, "Make node %s\n", cp);
117}
118
119/*
120 * Remove an old node (directory).
121 */
122removenode(ep)
123 register struct entry *ep;
124{
125 char *cp;
126
127 if (ep->e_type != NODE)
128 badentry(ep, "removenode: not a node");
129 if (ep->e_entries != NIL)
130 badentry(ep, "removenode: non-empty directory");
131 cp = myname(ep);
132 if (rmdir(cp) < 0) {
133 perror("removenode");
134 panic("Cannot remove node %s\n", cp);
135 }
136 ep->e_flags |= REMOVED;
d2d742ce 137 ep->e_flags &= ~(TMPNAME|TMPNODE);
e0519353
KM
138 vprintf(stdout, "Remove node %s\n", cp);
139}
140
141/*
142 * Remove a leaf.
143 */
144removeleaf(ep)
145 register struct entry *ep;
146{
147 char *cp;
148
149 if (ep->e_type != LEAF)
150 badentry(ep, "removeleaf: not a leaf");
151 cp = myname(ep);
152 if (unlink(cp) < 0) {
153 perror("removeleaf");
154 panic("Cannot remove leaf %s\n", cp);
155 }
156 ep->e_flags |= REMOVED;
157 ep->e_flags &= ~TMPNAME;
158 vprintf(stdout, "Remove leaf %s\n", cp);
159}
160
161/*
162 * Create a link.
163 */
164linkit(existing, new, type)
165 char *existing, *new;
166 int type;
167{
168
169 if (type == SYMLINK) {
170 if (symlink(existing, new) < 0) {
171 perror("linkit");
172 panic("Cannot create symbolic link %s->%s\n",
173 new, existing);
174 }
175 } else if (type == HARDLINK) {
176 if (link(existing, new) < 0) {
177 perror("linkit");
178 panic("Cannot create hard link %s->%s\n",
179 new, existing);
180 }
181 } else {
182 panic("linkit: unknown type %d\n", type);
183 }
184 vprintf(stdout, "Create %s link %s->%s\n",
185 type == SYMLINK ? "symbolic" : "hard", new, existing);
186}
187
188/*
189 * find lowest number file (above "start") that needs to be extracted
190 */
191ino_t
192lowerbnd(start)
193 ino_t start;
194{
195 register struct entry *ep;
196
197 for ( ; start < maxino; start++) {
198 ep = lookupino(start);
199 if (ep == NIL)
200 continue;
d2d742ce 201 if (ep->e_flags & (NEW|EXTRACT|CHANGE))
e0519353
KM
202 return (start);
203 }
204 return (start);
205}
206
207/*
208 * find highest number file (below "start") that needs to be extracted
209 */
210ino_t
211upperbnd(start)
212 ino_t start;
213{
214 register struct entry *ep;
215
216 for ( ; start > ROOTINO; start--) {
217 ep = lookupino(start);
218 if (ep == NIL)
219 continue;
d2d742ce 220 if (ep->e_flags & (NEW|EXTRACT|CHANGE))
e0519353
KM
221 return (start);
222 }
223 return (start);
224}
225
226/*
227 * report on a badly formed entry
228 */
229badentry(ep, msg)
230 register struct entry *ep;
231 char *msg;
232{
233 char flagbuf[BUFSIZ];
234
235 fprintf(stderr, "bad entry: %s\n", msg);
236 fprintf(stderr, "name: %s\n", myname(ep));
d2d742ce
KM
237 if (ep->e_newname != NULL)
238 fprintf(stderr, "new name: %s\n", ep->e_newname);
e0519353
KM
239 fprintf(stderr, "parent name %s\n", myname(ep->e_parent));
240 if (ep->e_sibling != NIL)
241 fprintf(stderr, "sibling name: %s\n", myname(ep->e_sibling));
242 if (ep->e_entries != NIL)
243 fprintf(stderr, "next entry name: %s\n", myname(ep->e_entries));
244 if (ep->e_links != NIL)
245 fprintf(stderr, "next link name: %s\n", myname(ep->e_links));
e0519353
KM
246 fprintf(stderr, "entry type: %s\n",
247 ep->e_type == NODE ? "NODE" : "LEAF");
248 fprintf(stderr, "inode number: %ld\n", ep->e_ino);
249 strcpy(flagbuf, "|NIL");
250 flagbuf[0] = '\0';
d2d742ce
KM
251 if (ep->e_flags & REMOVE)
252 strcat(flagbuf, "|REMOVE");
e0519353
KM
253 if (ep->e_flags & REMOVED)
254 strcat(flagbuf, "|REMOVED");
d2d742ce
KM
255 if (ep->e_flags & RENAME)
256 strcat(flagbuf, "|RENAME");
e0519353
KM
257 if (ep->e_flags & TMPNAME)
258 strcat(flagbuf, "|TMPNAME");
d2d742ce
KM
259 if (ep->e_flags & TMPNODE)
260 strcat(flagbuf, "|TMPNODE");
e0519353
KM
261 if (ep->e_flags & EXTRACT)
262 strcat(flagbuf, "|EXTRACT");
d2d742ce
KM
263 if (ep->e_flags & RENUMBER)
264 strcat(flagbuf, "|RENUMBER");
265 if (ep->e_flags & CHANGE)
266 strcat(flagbuf, "|CHANGE");
e0519353
KM
267 if (ep->e_flags & NEW)
268 strcat(flagbuf, "|NEW");
269 if (ep->e_flags & KEEP)
270 strcat(flagbuf, "|KEEP");
271 panic("flags: %s\n", &flagbuf[1]);
272}
273
38bbfe41
KM
274/*
275 * canonicalize file names to always start with ``./''
276 */
277canon(rawname, canonname)
278 char *rawname, *canonname;
279{
280 int len;
281
282 if (strcmp(rawname, ".") == 0 || strncmp(rawname, "./", 2) == 0)
283 strcpy(canonname, "");
284 else if (rawname[0] == '/')
285 strcpy(canonname, ".");
286 else
287 strcpy(canonname, "./");
288 strcat(canonname, rawname);
289 len = strlen(canonname) - 1;
290 if (canonname[len] == '/')
291 canonname[len] = '\0';
292}
293
e0519353
KM
294/*
295 * elicit a reply
296 */
297reply(question)
298 char *question;
299{
300 char c;
301
302 fprintf(stderr, "%s? ", question);
303 do {
304 fprintf(stderr, "[yn] ");
305 c = getchar();
306 while (c != '\n' && getchar() != '\n')
307 /* void */;
308 } while (c != 'y' && c != 'n');
309 if (c == 'y')
310 return (GOOD);
311 return (FAIL);
312}