date and time created 88/07/21 17:35:30 by marc
[unix-history] / usr / src / sbin / restore / utilities.c
CommitLineData
8c5eec2f
DF
1/*
2 * Copyright (c) 1983 Regents of the University of California.
3 * All rights reserved. The Berkeley software License Agreement
4 * specifies the terms and conditions for redistribution.
5 */
e0519353 6
8c5eec2f 7#ifndef lint
414c4f09 8static char sccsid[] = "@(#)utilities.c 5.3 (Berkeley) %G%";
8c5eec2f 9#endif not lint
ebd1f727 10
e0519353
KM
11#include "restore.h"
12
13/*
14 * Insure that all the components of a pathname exist.
15 */
16e2b8d5 16pathcheck(name)
e0519353
KM
17 char *name;
18{
19 register char *cp;
20 struct entry *ep;
9f13f26d 21 char *start;
e0519353
KM
22
23 start = index(name, '/');
9f13f26d 24 if (start == 0)
16e2b8d5 25 return;
e0519353
KM
26 for (cp = start; *cp != '\0'; cp++) {
27 if (*cp != '/')
28 continue;
29 *cp = '\0';
30 ep = lookupname(name);
31 if (ep == NIL) {
7432ff81 32 ep = addentry(name, psearch(name), NODE);
e0519353
KM
33 newnode(ep);
34 }
7fd6e445 35 ep->e_flags |= NEW|KEEP;
e0519353
KM
36 *cp = '/';
37 }
38}
39
40/*
41 * Change a name to a unique temporary name.
42 */
43mktempname(ep)
44 register struct entry *ep;
45{
16e2b8d5 46 char oldname[MAXPATHLEN];
e0519353
KM
47
48 if (ep->e_flags & TMPNAME)
49 badentry(ep, "mktempname: called with TMPNAME");
50 ep->e_flags |= TMPNAME;
7432ff81 51 (void) strcpy(oldname, myname(ep));
16e2b8d5
KM
52 freename(ep->e_name);
53 ep->e_name = savename(gentempname(ep));
54 ep->e_namlen = strlen(ep->e_name);
e0519353
KM
55 renameit(oldname, myname(ep));
56}
57
16e2b8d5
KM
58/*
59 * Generate a temporary name for an entry.
60 */
61char *
62gentempname(ep)
63 struct entry *ep;
64{
65 static char name[MAXPATHLEN];
66 struct entry *np;
67 long i = 0;
68
69 for (np = lookupino(ep->e_ino); np != NIL && np != ep; np = np->e_links)
70 i++;
71 if (np == NIL)
72 badentry(ep, "not on ino list");
e9a184e3 73 (void) sprintf(name, "%s%d%d", TMPHDR, i, ep->e_ino);
16e2b8d5
KM
74 return (name);
75}
76
e0519353
KM
77/*
78 * Rename a file or directory.
79 */
80renameit(from, to)
81 char *from, *to;
82{
414c4f09 83 if (!Nflag && rename(from, to) < 0) {
e9e7ecc4
KM
84 fprintf(stderr, "Warning: cannot rename %s to %s", from, to);
85 (void) fflush(stderr);
86 perror("");
d66e0e37 87 return;
e0519353
KM
88 }
89 vprintf(stdout, "rename %s to %s\n", from, to);
90}
91
92/*
93 * Create a new node (directory).
94 */
95newnode(np)
96 struct entry *np;
97{
98 char *cp;
99
100 if (np->e_type != NODE)
101 badentry(np, "newnode: not a node");
102 cp = myname(np);
414c4f09 103 if (!Nflag && mkdir(cp, 0777) < 0) {
a7d37956 104 np->e_flags |= EXISTED;
d4ca0635 105 fprintf(stderr, "Warning: ");
7432ff81 106 (void) fflush(stderr);
d4ca0635
KM
107 perror(cp);
108 return;
e0519353
KM
109 }
110 vprintf(stdout, "Make node %s\n", cp);
111}
112
113/*
114 * Remove an old node (directory).
115 */
116removenode(ep)
117 register struct entry *ep;
118{
119 char *cp;
120
121 if (ep->e_type != NODE)
122 badentry(ep, "removenode: not a node");
123 if (ep->e_entries != NIL)
124 badentry(ep, "removenode: non-empty directory");
d66e0e37
KM
125 ep->e_flags |= REMOVED;
126 ep->e_flags &= ~TMPNAME;
e0519353 127 cp = myname(ep);
414c4f09 128 if (!Nflag && rmdir(cp) < 0) {
d66e0e37 129 fprintf(stderr, "Warning: ");
7432ff81 130 (void) fflush(stderr);
d66e0e37
KM
131 perror(cp);
132 return;
e0519353 133 }
e0519353
KM
134 vprintf(stdout, "Remove node %s\n", cp);
135}
136
137/*
138 * Remove a leaf.
139 */
140removeleaf(ep)
141 register struct entry *ep;
142{
143 char *cp;
144
145 if (ep->e_type != LEAF)
146 badentry(ep, "removeleaf: not a leaf");
d66e0e37
KM
147 ep->e_flags |= REMOVED;
148 ep->e_flags &= ~TMPNAME;
e0519353 149 cp = myname(ep);
414c4f09 150 if (!Nflag && unlink(cp) < 0) {
d66e0e37 151 fprintf(stderr, "Warning: ");
7432ff81 152 (void) fflush(stderr);
d66e0e37
KM
153 perror(cp);
154 return;
e0519353 155 }
e0519353
KM
156 vprintf(stdout, "Remove leaf %s\n", cp);
157}
158
159/*
160 * Create a link.
161 */
162linkit(existing, new, type)
163 char *existing, *new;
164 int type;
165{
166
167 if (type == SYMLINK) {
414c4f09 168 if (!Nflag && symlink(existing, new) < 0) {
d66e0e37 169 fprintf(stderr,
2eba41cd 170 "Warning: cannot create symbolic link %s->%s: ",
e0519353 171 new, existing);
e9e7ecc4
KM
172 (void) fflush(stderr);
173 perror("");
2eba41cd 174 return (FAIL);
e0519353
KM
175 }
176 } else if (type == HARDLINK) {
414c4f09 177 if (!Nflag && link(existing, new) < 0) {
d66e0e37 178 fprintf(stderr,
2eba41cd 179 "Warning: cannot create hard link %s->%s: ",
e0519353 180 new, existing);
e9e7ecc4
KM
181 (void) fflush(stderr);
182 perror("");
2eba41cd 183 return (FAIL);
e0519353
KM
184 }
185 } else {
186 panic("linkit: unknown type %d\n", type);
2eba41cd 187 return (FAIL);
e0519353
KM
188 }
189 vprintf(stdout, "Create %s link %s->%s\n",
190 type == SYMLINK ? "symbolic" : "hard", new, existing);
2eba41cd 191 return (GOOD);
e0519353
KM
192}
193
194/*
195 * find lowest number file (above "start") that needs to be extracted
196 */
197ino_t
198lowerbnd(start)
199 ino_t start;
200{
201 register struct entry *ep;
202
203 for ( ; start < maxino; start++) {
204 ep = lookupino(start);
7432ff81 205 if (ep == NIL || ep->e_type == NODE)
e0519353 206 continue;
16e2b8d5 207 if (ep->e_flags & (NEW|EXTRACT))
e0519353
KM
208 return (start);
209 }
210 return (start);
211}
212
213/*
214 * find highest number file (below "start") that needs to be extracted
215 */
216ino_t
217upperbnd(start)
218 ino_t start;
219{
220 register struct entry *ep;
221
222 for ( ; start > ROOTINO; start--) {
223 ep = lookupino(start);
7432ff81 224 if (ep == NIL || ep->e_type == NODE)
e0519353 225 continue;
16e2b8d5 226 if (ep->e_flags & (NEW|EXTRACT))
e0519353
KM
227 return (start);
228 }
229 return (start);
230}
231
232/*
233 * report on a badly formed entry
234 */
235badentry(ep, msg)
236 register struct entry *ep;
237 char *msg;
238{
e0519353
KM
239
240 fprintf(stderr, "bad entry: %s\n", msg);
241 fprintf(stderr, "name: %s\n", myname(ep));
242 fprintf(stderr, "parent name %s\n", myname(ep->e_parent));
243 if (ep->e_sibling != NIL)
244 fprintf(stderr, "sibling name: %s\n", myname(ep->e_sibling));
245 if (ep->e_entries != NIL)
246 fprintf(stderr, "next entry name: %s\n", myname(ep->e_entries));
247 if (ep->e_links != NIL)
248 fprintf(stderr, "next link name: %s\n", myname(ep->e_links));
16e2b8d5
KM
249 if (ep->e_next != NIL)
250 fprintf(stderr, "next hashchain name: %s\n", myname(ep->e_next));
e0519353
KM
251 fprintf(stderr, "entry type: %s\n",
252 ep->e_type == NODE ? "NODE" : "LEAF");
253 fprintf(stderr, "inode number: %ld\n", ep->e_ino);
55f85ba7
KM
254 panic("flags: %s\n", flagvalues(ep));
255}
256
257/*
258 * Construct a string indicating the active flag bits of an entry.
259 */
260char *
261flagvalues(ep)
262 register struct entry *ep;
263{
264 static char flagbuf[BUFSIZ];
265
266 (void) strcpy(flagbuf, "|NIL");
e0519353
KM
267 flagbuf[0] = '\0';
268 if (ep->e_flags & REMOVED)
55f85ba7 269 (void) strcat(flagbuf, "|REMOVED");
e0519353 270 if (ep->e_flags & TMPNAME)
55f85ba7 271 (void) strcat(flagbuf, "|TMPNAME");
e0519353 272 if (ep->e_flags & EXTRACT)
55f85ba7 273 (void) strcat(flagbuf, "|EXTRACT");
e0519353 274 if (ep->e_flags & NEW)
55f85ba7 275 (void) strcat(flagbuf, "|NEW");
e0519353 276 if (ep->e_flags & KEEP)
55f85ba7 277 (void) strcat(flagbuf, "|KEEP");
a7d37956
KM
278 if (ep->e_flags & EXISTED)
279 (void) strcat(flagbuf, "|EXISTED");
55f85ba7 280 return (&flagbuf[1]);
e0519353
KM
281}
282
38bbfe41 283/*
7432ff81
KM
284 * Check to see if a name is on a dump tape.
285 */
286ino_t
287dirlookup(name)
288 char *name;
289{
290 ino_t ino;
291
292 ino = psearch(name);
293 if (ino == 0 || BIT(ino, dumpmap) == 0)
294 fprintf(stderr, "%s is not on tape\n", name);
295 return (ino);
296}
297
e0519353 298/*
7432ff81 299 * Elicit a reply.
e0519353
KM
300 */
301reply(question)
302 char *question;
303{
304 char c;
305
e0519353 306 do {
4af95b6b 307 fprintf(stderr, "%s? [yn] ", question);
e9e7ecc4 308 (void) fflush(stderr);
7432ff81
KM
309 c = getc(terminal);
310 while (c != '\n' && getc(terminal) != '\n')
b8eb5f1f 311 if (feof(terminal))
4af95b6b 312 return (FAIL);
e0519353
KM
313 } while (c != 'y' && c != 'n');
314 if (c == 'y')
315 return (GOOD);
316 return (FAIL);
317}
7432ff81 318
7432ff81
KM
319/*
320 * handle unexpected inconsistencies
321 */
322/* VARARGS1 */
323panic(msg, d1, d2)
324 char *msg;
325 long d1, d2;
326{
327
328 fprintf(stderr, msg, d1, d2);
329 if (reply("abort") == GOOD) {
330 if (reply("dump core") == GOOD)
331 abort();
332 done(1);
333 }
334}