Commit | Line | Data |
---|---|---|
e0519353 KM |
1 | /* Copyright (c) 1983 Regents of the University of California */ |
2 | ||
3 | #ifndef lint | |
74025ab9 | 4 | static char sccsid[] = "@(#)utilities.c 3.3 (Berkeley) 83/02/27"; |
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 | */ | |
12 | movecontents(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 |
40 | struct entry * |
41 | pathcheck(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 | */ | |
70 | mktempname(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 | */ | |
87 | renameit(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 | */ | |
100 | newnode(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 | */ | |
122 | removenode(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 | */ | |
144 | removeleaf(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 | */ | |
164 | linkit(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 | */ | |
191 | ino_t | |
192 | lowerbnd(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 | */ | |
210 | ino_t | |
211 | upperbnd(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 | */ | |
229 | badentry(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 | ||
e0519353 KM |
274 | /* |
275 | * elicit a reply | |
276 | */ | |
277 | reply(question) | |
278 | char *question; | |
279 | { | |
280 | char c; | |
281 | ||
282 | fprintf(stderr, "%s? ", question); | |
283 | do { | |
284 | fprintf(stderr, "[yn] "); | |
285 | c = getchar(); | |
286 | while (c != '\n' && getchar() != '\n') | |
287 | /* void */; | |
288 | } while (c != 'y' && c != 'n'); | |
289 | if (c == 'y') | |
290 | return (GOOD); | |
291 | return (FAIL); | |
292 | } |