]>
git.wh0rd.org - dump.git/blob - restore/utilities.c
54b7dc1fbc547538ad82714e2cb529af7c78a0ba
2 * Ported to Linux's Second Extended File System as part of the
3 * dump and restore backup suit
4 * Remy Card <card@Linux.EU.Org>, 1994, 1995, 1996
9 * Copyright (c) 1983, 1993
10 * The Regents of the University of California. All rights reserved.
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
15 * 1. Redistributions of source code must retain the above copyright
16 * notice, this list of conditions and the following disclaimer.
17 * 2. Redistributions in binary form must reproduce the above copyright
18 * notice, this list of conditions and the following disclaimer in the
19 * documentation and/or other materials provided with the distribution.
20 * 3. All advertising materials mentioning features or use of this software
21 * must display the following acknowledgement:
22 * This product includes software developed by the University of
23 * California, Berkeley and its contributors.
24 * 4. Neither the name of the University nor the names of its contributors
25 * may be used to endorse or promote products derived from this software
26 * without specific prior written permission.
28 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
29 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
30 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
31 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
32 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
33 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
34 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
35 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
36 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
37 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
42 static char sccsid
[] = "@(#)utilities.c 8.5 (Berkeley) 4/28/95";
45 #include <sys/param.h>
50 #include <linux/ext2_fs.h>
51 #include <bsdcompat.h>
53 #include <ufs/ufs/dinode.h>
54 #include <ufs/ufs/dir.h>
55 #endif /* __linux__ */
64 #include <ext2fs/ext2fs.h>
71 * Insure that all the components of a pathname exist.
81 start
= strrchr(name
, '/');
84 for (cp
= start
; *cp
!= '\0'; cp
++) {
88 ep
= lookupname(name
);
90 /* Safe; we know the pathname exists in the dump. */
91 ep
= addentry(name
, pathsearch(name
)->d_ino
, NODE
);
94 ep
->e_flags
|= NEW
|KEEP
;
100 * Change a name to a unique temporary name.
104 register struct entry
*ep
;
106 char oldname
[MAXPATHLEN
];
108 if (ep
->e_flags
& TMPNAME
)
109 badentry(ep
, "mktempname: called with TMPNAME");
110 ep
->e_flags
|= TMPNAME
;
111 (void) strcpy(oldname
, myname(ep
));
112 freename(ep
->e_name
);
113 ep
->e_name
= savename(gentempname(ep
));
114 ep
->e_namlen
= strlen(ep
->e_name
);
115 renameit(oldname
, myname(ep
));
119 * Generate a temporary name for an entry.
125 static char name
[MAXPATHLEN
];
129 for (np
= lookupino(ep
->e_ino
);
130 np
!= NULL
&& np
!= ep
; np
= np
->e_links
)
133 badentry(ep
, "not on ino list");
134 (void) sprintf(name
, "%s%d%d", TMPHDR
, i
, ep
->e_ino
);
139 * Rename a file or directory.
145 if (!Nflag
&& rename(from
, to
) < 0) {
146 fprintf(stderr
, "warning: cannot rename %s to %s: %s\n",
147 from
, to
, strerror(errno
));
150 vprintf(stdout
, "rename %s to %s\n", from
, to
);
154 * Create a new node (directory).
162 if (np
->e_type
!= NODE
)
163 badentry(np
, "newnode: not a node");
165 if (command
== 'C') return;
166 if (!Nflag
&& mkdir(cp
, 0777) < 0) {
167 np
->e_flags
|= EXISTED
;
168 fprintf(stderr
, "warning: %s: %s\n", cp
, strerror(errno
));
171 vprintf(stdout
, "Make node %s\n", cp
);
175 * Remove an old node (directory).
179 register struct entry
*ep
;
183 if (ep
->e_type
!= NODE
)
184 badentry(ep
, "removenode: not a node");
185 if (ep
->e_entries
!= NULL
)
186 badentry(ep
, "removenode: non-empty directory");
187 ep
->e_flags
|= REMOVED
;
188 ep
->e_flags
&= ~TMPNAME
;
190 if (!Nflag
&& rmdir(cp
) < 0) {
191 fprintf(stderr
, "warning: %s: %s\n", cp
, strerror(errno
));
194 vprintf(stdout
, "Remove node %s\n", cp
);
202 register struct entry
*ep
;
206 if (command
== 'C') return;
208 if (ep
->e_type
!= LEAF
)
209 badentry(ep
, "removeleaf: not a leaf");
210 ep
->e_flags
|= REMOVED
;
211 ep
->e_flags
&= ~TMPNAME
;
213 if (!Nflag
&& unlink(cp
) < 0) {
214 fprintf(stderr
, "warning: %s: %s\n", cp
, strerror(errno
));
217 vprintf(stdout
, "Remove leaf %s\n", cp
);
224 linkit(existing
, new, type
)
225 char *existing
, *new;
229 if (type
== SYMLINK
) {
230 if (!Nflag
&& symlink(existing
, new) < 0) {
232 "warning: cannot create symbolic link %s->%s: %s\n",
233 new, existing
, strerror(errno
));
236 } else if (type
== HARDLINK
) {
237 if (!Nflag
&& link(existing
, new) < 0) {
239 "warning: cannot create hard link %s->%s: %s\n",
240 new, existing
, strerror(errno
));
244 panic("linkit: unknown type %d\n", type
);
247 vprintf(stdout
, "Create %s link %s->%s\n",
248 type
== SYMLINK
? "symbolic" : "hard", new, existing
);
261 if (!Nflag
&& mknod(name
, S_IFWHT
, 0) < 0) {
262 fprintf(stderr
, "warning: cannot create whiteout %s: %s\n",
263 name
, strerror(errno
));
266 vprintf(stdout
, "Create whiteout %s\n", name
);
275 register struct entry
*ep
;
279 if (ep
->e_type
!= LEAF
)
280 badentry(ep
, "delwhiteout: not a leaf");
281 ep
->e_flags
|= REMOVED
;
282 ep
->e_flags
&= ~TMPNAME
;
284 if (!Nflag
&& undelete(name
) < 0) {
285 fprintf(stderr
, "warning: cannot delete whiteout %s: %s\n",
286 name
, strerror(errno
));
289 vprintf(stdout
, "Delete whiteout %s\n", name
);
294 * find lowest number file (above "start") that needs to be extracted
300 register struct entry
*ep
;
302 for ( ; start
< maxino
; start
++) {
303 ep
= lookupino(start
);
304 if (ep
== NULL
|| ep
->e_type
== NODE
)
306 if (ep
->e_flags
& (NEW
|EXTRACT
))
313 * find highest number file (below "start") that needs to be extracted
319 register struct entry
*ep
;
321 for ( ; start
> ROOTINO
; start
--) {
322 ep
= lookupino(start
);
323 if (ep
== NULL
|| ep
->e_type
== NODE
)
325 if (ep
->e_flags
& (NEW
|EXTRACT
))
332 * report on a badly formed entry
336 register struct entry
*ep
;
340 fprintf(stderr
, "bad entry: %s\n", msg
);
341 fprintf(stderr
, "name: %s\n", myname(ep
));
342 fprintf(stderr
, "parent name %s\n", myname(ep
->e_parent
));
343 if (ep
->e_sibling
!= NULL
)
344 fprintf(stderr
, "sibling name: %s\n", myname(ep
->e_sibling
));
345 if (ep
->e_entries
!= NULL
)
346 fprintf(stderr
, "next entry name: %s\n", myname(ep
->e_entries
));
347 if (ep
->e_links
!= NULL
)
348 fprintf(stderr
, "next link name: %s\n", myname(ep
->e_links
));
349 if (ep
->e_next
!= NULL
)
351 "next hashchain name: %s\n", myname(ep
->e_next
));
352 fprintf(stderr
, "entry type: %s\n",
353 ep
->e_type
== NODE
? "NODE" : "LEAF");
354 fprintf(stderr
, "inode number: %ld\n", ep
->e_ino
);
355 panic("flags: %s\n", flagvalues(ep
));
359 * Construct a string indicating the active flag bits of an entry.
363 register struct entry
*ep
;
365 static char flagbuf
[BUFSIZ
];
367 (void) strcpy(flagbuf
, "|NIL");
369 if (ep
->e_flags
& REMOVED
)
370 (void) strcat(flagbuf
, "|REMOVED");
371 if (ep
->e_flags
& TMPNAME
)
372 (void) strcat(flagbuf
, "|TMPNAME");
373 if (ep
->e_flags
& EXTRACT
)
374 (void) strcat(flagbuf
, "|EXTRACT");
375 if (ep
->e_flags
& NEW
)
376 (void) strcat(flagbuf
, "|NEW");
377 if (ep
->e_flags
& KEEP
)
378 (void) strcat(flagbuf
, "|KEEP");
379 if (ep
->e_flags
& EXISTED
)
380 (void) strcat(flagbuf
, "|EXISTED");
381 return (&flagbuf
[1]);
385 * Check to see if a name is on a dump tape.
394 ino
= ((dp
= pathsearch(name
)) == NULL
) ? 0 : dp
->d_ino
;
396 if (ino
== 0 || TSTINO(ino
, dumpmap
) == 0)
397 fprintf(stderr
, "%s is not on the tape\n", name
);
411 fprintf(stderr
, "%s? [yn] ", question
);
412 (void) fflush(stderr
);
414 while (c
!= '\n' && getc(terminal
) != '\n')
417 } while (c
!= 'y' && c
!= 'n');
424 * handle unexpected inconsistencies
434 panic(const char *fmt
, ...)
448 vfprintf(stderr
, fmt
, ap
);
451 if (reply("abort") == GOOD
) {
452 if (reply("dump core") == GOOD
)