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