Thu Mar 11 01:13:11 2021 UTC ()
s/skiping/skipping/


(msaitoh)
diff -r1.2 -r1.3 src/lib/libc/gen/extattr_copy_file.3
diff -r1.69 -r1.70 src/sbin/restore/tape.c

cvs diff -r1.2 -r1.3 src/lib/libc/gen/extattr_copy_file.3 (switch to unified diff)

--- src/lib/libc/gen/extattr_copy_file.3 2011/12/16 15:21:13 1.2
+++ src/lib/libc/gen/extattr_copy_file.3 2021/03/11 01:13:11 1.3
@@ -1,105 +1,105 @@ @@ -1,105 +1,105 @@
1.\" $NetBSD: extattr_copy_file.3,v 1.2 2011/12/16 15:21:13 manu Exp $ 1.\" $NetBSD: extattr_copy_file.3,v 1.3 2021/03/11 01:13:11 msaitoh Exp $
2.\" 2.\"
3.\" Copyright (c) 2001 Dima Dorfman <dd@FreeBSD.org> 3.\" Copyright (c) 2001 Dima Dorfman <dd@FreeBSD.org>
4.\" Copyright (c) 2011 Emmanuel Dreyfus <manu@NetBSD.org> 4.\" Copyright (c) 2011 Emmanuel Dreyfus <manu@NetBSD.org>
5.\" All rights reserved. 5.\" All rights reserved.
6.\" 6.\"
7.\" Redistribution and use in source and binary forms, with or without 7.\" Redistribution and use in source and binary forms, with or without
8.\" modification, are permitted provided that the following conditions 8.\" modification, are permitted provided that the following conditions
9.\" are met: 9.\" are met:
10.\" 1. Redistributions of source code must retain the above copyright 10.\" 1. Redistributions of source code must retain the above copyright
11.\" notice, this list of conditions and the following disclaimer. 11.\" notice, this list of conditions and the following disclaimer.
12.\" 2. Redistributions in binary form must reproduce the above copyright 12.\" 2. Redistributions in binary form must reproduce the above copyright
13.\" notice, this list of conditions and the following disclaimer in the 13.\" notice, this list of conditions and the following disclaimer in the
14.\" documentation and/or other materials provided with the distribution. 14.\" documentation and/or other materials provided with the distribution.
15.\" 15.\"
16.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26.\" SUCH DAMAGE. 26.\" SUCH DAMAGE.
27.\" 27.\"
28.\" FreeBSD: src/lib/libc/posix1e/extattr.3,v 1.5 2002/12/12 17:25:53 ru Exp 28.\" FreeBSD: src/lib/libc/posix1e/extattr.3,v 1.5 2002/12/12 17:25:53 ru Exp
29.\" 29.\"
30.Dd December 16, 2011 30.Dd December 16, 2011
31.Dt EXTATTR_COPY_FILE 3 31.Dt EXTATTR_COPY_FILE 3
32.Os 32.Os
33.Sh NAME 33.Sh NAME
34.Nm extattr_copy_file , 34.Nm extattr_copy_file ,
35.Nm extattr_copy_fd , 35.Nm extattr_copy_fd ,
36.Nm extattr_copy_link , 36.Nm extattr_copy_link ,
37.Nm cpxattr , 37.Nm cpxattr ,
38.Nm fcpxattr , 38.Nm fcpxattr ,
39.Nm lcpxattr 39.Nm lcpxattr
40.Nd copy extended attributes from a file to another one 40.Nd copy extended attributes from a file to another one
41.Sh LIBRARY 41.Sh LIBRARY
42.Lb libc 42.Lb libc
43.Sh SYNOPSIS 43.Sh SYNOPSIS
44.In sys/extattr.h 44.In sys/extattr.h
45.Ft int 45.Ft int
46.Fn extattr_copy_file "const char *from" "const char *to" "int namespace" 46.Fn extattr_copy_file "const char *from" "const char *to" "int namespace"
47.Ft int 47.Ft int
48.Fn extattr_copy_fd "int from_fd" "int to_fd" "int namespace" 48.Fn extattr_copy_fd "int from_fd" "int to_fd" "int namespace"
49.Ft int 49.Ft int
50.Fn extattr_copy_link "const char *from" "const char *to" "int namespace" 50.Fn extattr_copy_link "const char *from" "const char *to" "int namespace"
51.Ft int 51.Ft int
52.Fn cpxattr "const char *from" "const char *to" 52.Fn cpxattr "const char *from" "const char *to"
53.Ft int 53.Ft int
54.Fn fcpxattr "int from_fd" "int to_fd" 54.Fn fcpxattr "int from_fd" "int to_fd"
55.Ft int 55.Ft int
56.Fn lcpxattr "const char *from" "const char *to" 56.Fn lcpxattr "const char *from" "const char *to"
57.Sh DESCRIPTION 57.Sh DESCRIPTION
58.Fn extattr_copy_file 58.Fn extattr_copy_file
59copies extended attributes of namespace 59copies extended attributes of namespace
60.Ar namespace 60.Ar namespace
61from a file to another one. 61from a file to another one.
62.Fn extattr_copy_fd 62.Fn extattr_copy_fd
63does the same using open file descriptors, and 63does the same using open file descriptors, and
64.Fn extattr_copy_link 64.Fn extattr_copy_link
65does the same as 65does the same as
66.Fn extattr_copy_file 66.Fn extattr_copy_file
67but operates on symbolic links themselves instead of their targets. 67but operates on symbolic links themselves instead of their targets.
68.Pp 68.Pp
69.Fn cpxattr , 69.Fn cpxattr ,
70.Fn fcpxattr , 70.Fn fcpxattr ,
71and 71and
72.Fn lcpxattr 72.Fn lcpxattr
73respectively work the same was as 73respectively work the same was as
74.Fn extattr_copy_file , 74.Fn extattr_copy_file ,
75.Fn extattr_copy_fd , 75.Fn extattr_copy_fd ,
76and 76and
77.Fn extattr_copy_link , 77.Fn extattr_copy_link ,
78but will copy extended attributes from all namespaces accessible to the user, 78but will copy extended attributes from all namespaces accessible to the user,
79silently skiping unaccessible namespaces. 79silently skipping unaccessible namespaces.
80.Pp 80.Pp
81Please note that none of the extended attribute copying functions are atomic. 81Please note that none of the extended attribute copying functions are atomic.
82.Sh RETURN VALUES 82.Sh RETURN VALUES
83If any of the calls are unsuccessful, the value \-1 is returned 83If any of the calls are unsuccessful, the value \-1 is returned
84and the global variable 84and the global variable
85.Va errno 85.Va errno
86is set to indicate the error. 86is set to indicate the error.
87.Sh ERRORS 87.Sh ERRORS
88Extended attribute copying functions may raise errors produced by 88Extended attribute copying functions may raise errors produced by
89.Xr extattr_list_file 2 89.Xr extattr_list_file 2
90and 90and
91.Xr extattr_get_file 2 . 91.Xr extattr_get_file 2 .
92.Sh SEE ALSO 92.Sh SEE ALSO
93.Xr getextattr 1 , 93.Xr getextattr 1 ,
94.Xr extattr_get_file 2 , 94.Xr extattr_get_file 2 ,
95.Xr extattr_namespace_to_string 3 , 95.Xr extattr_namespace_to_string 3 ,
96.Xr extattr 9 96.Xr extattr 9
97.Sh HISTORY 97.Sh HISTORY
98Extended attribute support was developed as part of the 98Extended attribute support was developed as part of the
99.Tn TrustedBSD 99.Tn TrustedBSD
100Project, and introduced in 100Project, and introduced in
101.Fx 5.0 101.Fx 5.0
102and 102and
103.Nx 3.0 . 103.Nx 3.0 .
104It was developed to support security extensions requiring additional labels 104It was developed to support security extensions requiring additional labels
105to be associated with each file or directory. 105to be associated with each file or directory.

cvs diff -r1.69 -r1.70 src/sbin/restore/tape.c (switch to unified diff)

--- src/sbin/restore/tape.c 2020/09/03 19:31:34 1.69
+++ src/sbin/restore/tape.c 2021/03/11 01:13:11 1.70
@@ -1,1560 +1,1560 @@ @@ -1,1560 +1,1560 @@
1/* $NetBSD: tape.c,v 1.69 2020/09/03 19:31:34 bouyer Exp $ */ 1/* $NetBSD: tape.c,v 1.70 2021/03/11 01:13:11 msaitoh Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 1983, 1993 4 * Copyright (c) 1983, 1993
5 * The Regents of the University of California. All rights reserved. 5 * The Regents of the University of California. All rights reserved.
6 * (c) UNIX System Laboratories, Inc. 6 * (c) UNIX System Laboratories, Inc.
7 * All or some portions of this file are derived from material licensed 7 * All or some portions of this file are derived from material licensed
8 * to the University of California by American Telephone and Telegraph 8 * to the University of California by American Telephone and Telegraph
9 * Co. or Unix System Laboratories, Inc. and are reproduced herein with 9 * Co. or Unix System Laboratories, Inc. and are reproduced herein with
10 * the permission of UNIX System Laboratories, Inc. 10 * the permission of UNIX System Laboratories, Inc.
11 * 11 *
12 * Redistribution and use in source and binary forms, with or without 12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions 13 * modification, are permitted provided that the following conditions
14 * are met: 14 * are met:
15 * 1. Redistributions of source code must retain the above copyright 15 * 1. Redistributions of source code must retain the above copyright
16 * notice, this list of conditions and the following disclaimer. 16 * notice, this list of conditions and the following disclaimer.
17 * 2. Redistributions in binary form must reproduce the above copyright 17 * 2. Redistributions in binary form must reproduce the above copyright
18 * notice, this list of conditions and the following disclaimer in the 18 * notice, this list of conditions and the following disclaimer in the
19 * documentation and/or other materials provided with the distribution. 19 * documentation and/or other materials provided with the distribution.
20 * 3. Neither the name of the University nor the names of its contributors 20 * 3. Neither the name of the University nor the names of its contributors
21 * may be used to endorse or promote products derived from this software 21 * may be used to endorse or promote products derived from this software
22 * without specific prior written permission. 22 * without specific prior written permission.
23 * 23 *
24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 * SUCH DAMAGE. 34 * SUCH DAMAGE.
35 */ 35 */
36 36
37#include <sys/cdefs.h> 37#include <sys/cdefs.h>
38#ifndef lint 38#ifndef lint
39#if 0 39#if 0
40static char sccsid[] = "@(#)tape.c 8.9 (Berkeley) 5/1/95"; 40static char sccsid[] = "@(#)tape.c 8.9 (Berkeley) 5/1/95";
41#else 41#else
42__RCSID("$NetBSD: tape.c,v 1.69 2020/09/03 19:31:34 bouyer Exp $"); 42__RCSID("$NetBSD: tape.c,v 1.70 2021/03/11 01:13:11 msaitoh Exp $");
43#endif 43#endif
44#endif /* not lint */ 44#endif /* not lint */
45 45
46#include <sys/param.h> 46#include <sys/param.h>
47#include <sys/file.h> 47#include <sys/file.h>
48#include <sys/ioctl.h> 48#include <sys/ioctl.h>
49#include <sys/mtio.h> 49#include <sys/mtio.h>
50#include <sys/stat.h> 50#include <sys/stat.h>
51 51
52#include <ufs/ufs/dinode.h> 52#include <ufs/ufs/dinode.h>
53#include <protocols/dumprestore.h> 53#include <protocols/dumprestore.h>
54 54
55#include <err.h> 55#include <err.h>
56#include <errno.h> 56#include <errno.h>
57#include <paths.h> 57#include <paths.h>
58#include <setjmp.h> 58#include <setjmp.h>
59#include <stdio.h> 59#include <stdio.h>
60#include <stdlib.h> 60#include <stdlib.h>
61#include <string.h> 61#include <string.h>
62#include <time.h> 62#include <time.h>
63#include <unistd.h> 63#include <unistd.h>
64 64
65#include <md5.h> 65#include <md5.h>
66#include <rmd160.h> 66#include <rmd160.h>
67#include <sha1.h> 67#include <sha1.h>
68 68
69#include "restore.h" 69#include "restore.h"
70#include "extern.h" 70#include "extern.h"
71 71
72static u_int32_t fssize = MAXBSIZE; 72static u_int32_t fssize = MAXBSIZE;
73static int mt = -1; 73static int mt = -1;
74static int pipein = 0; 74static int pipein = 0;
75static char magtape[BUFSIZ]; 75static char magtape[BUFSIZ];
76static int blkcnt; 76static int blkcnt;
77static int numtrec; 77static int numtrec;
78static char *tapebuf; 78static char *tapebuf;
79static union u_spcl endoftapemark; 79static union u_spcl endoftapemark;
80static int blksread; /* blocks read since last header */ 80static int blksread; /* blocks read since last header */
81static int tpblksread = 0; /* TP_BSIZE blocks read */ 81static int tpblksread = 0; /* TP_BSIZE blocks read */
82static int tapesread; 82static int tapesread;
83static jmp_buf restart; 83static jmp_buf restart;
84static int gettingfile = 0; /* restart has a valid frame */ 84static int gettingfile = 0; /* restart has a valid frame */
85#ifdef RRESTORE 85#ifdef RRESTORE
86static const char *host = NULL; 86static const char *host = NULL;
87#endif 87#endif
88 88
89static int ofile; 89static int ofile;
90static char lnkbuf[MAXPATHLEN + 1]; 90static char lnkbuf[MAXPATHLEN + 1];
91static int pathlen; 91static int pathlen;
92 92
93int oldinofmt; /* old inode format conversion required */ 93int oldinofmt; /* old inode format conversion required */
94int Bcvt; /* Swap Bytes (for CCI or sun) */ 94int Bcvt; /* Swap Bytes (for CCI or sun) */
95 95
96const struct digest_desc *ddesc; 96const struct digest_desc *ddesc;
97 97
98static union digest_context { 98static union digest_context {
99 MD5_CTX dc_MD5; 99 MD5_CTX dc_MD5;
100 SHA1_CTX dc_SHA1; 100 SHA1_CTX dc_SHA1;
101 RMD160_CTX dc_RMD160; 101 RMD160_CTX dc_RMD160;
102} dcontext; 102} dcontext;
103 103
104/* 104/*
105 * 32 for md5; 40 for sha1 and rmd160 105 * 32 for md5; 40 for sha1 and rmd160
106 * plus a null terminator. 106 * plus a null terminator.
107 */ 107 */
108#define DIGEST_BUFFER_SIZE (40 + 1) 108#define DIGEST_BUFFER_SIZE (40 + 1)
109 109
110#define FLUSHTAPEBUF() blkcnt = ntrec + 1 110#define FLUSHTAPEBUF() blkcnt = ntrec + 1
111 111
112union u_ospcl { 112union u_ospcl {
113 char dummy[TP_BSIZE]; 113 char dummy[TP_BSIZE];
114 struct s_ospcl { 114 struct s_ospcl {
115 int32_t c_type; 115 int32_t c_type;
116 int32_t c_date; 116 int32_t c_date;
117 int32_t c_ddate; 117 int32_t c_ddate;
118 int32_t c_volume; 118 int32_t c_volume;
119 int32_t c_tapea; 119 int32_t c_tapea;
120 u_int16_t c_inumber; 120 u_int16_t c_inumber;
121 int32_t c_magic; 121 int32_t c_magic;
122 int32_t c_checksum; 122 int32_t c_checksum;
123 struct odinode { 123 struct odinode {
124 unsigned short odi_mode; 124 unsigned short odi_mode;
125 u_int16_t odi_nlink; 125 u_int16_t odi_nlink;
126 u_int16_t odi_uid; 126 u_int16_t odi_uid;
127 u_int16_t odi_gid; 127 u_int16_t odi_gid;
128 int32_t odi_size; 128 int32_t odi_size;
129 int32_t odi_rdev; 129 int32_t odi_rdev;
130 char odi_addr[36]; 130 char odi_addr[36];
131 int32_t odi_atime; 131 int32_t odi_atime;
132 int32_t odi_mtime; 132 int32_t odi_mtime;
133 int32_t odi_ctime; 133 int32_t odi_ctime;
134 } c_odinode; 134 } c_odinode;
135 int32_t c_count; 135 int32_t c_count;
136 char c_addr[256]; 136 char c_addr[256];
137 } s_ospcl; 137 } s_ospcl;
138}; 138};
139 139
140static void accthdr(struct s_spcl *); 140static void accthdr(struct s_spcl *);
141static int checksum(int *); 141static int checksum(int *);
142static void findinode(struct s_spcl *); 142static void findinode(struct s_spcl *);
143static void findtapeblksize(void); 143static void findtapeblksize(void);
144static void getbitmap(char **); 144static void getbitmap(char **);
145static int gethead(struct s_spcl *); 145static int gethead(struct s_spcl *);
146static void readtape(char *); 146static void readtape(char *);
147static void setdumpnum(void); 147static void setdumpnum(void);
148static void terminateinput(void); 148static void terminateinput(void);
149static void xtrfile(char *, long); 149static void xtrfile(char *, long);
150static void xtrlnkfile(char *, long); 150static void xtrlnkfile(char *, long);
151__dead static void xtrlnkskip(char *, long); 151__dead static void xtrlnkskip(char *, long);
152static void xtrskip(char *, long); 152static void xtrskip(char *, long);
153static void swap_header(struct s_spcl *); 153static void swap_header(struct s_spcl *);
154static void swap_old_header(struct s_ospcl *); 154static void swap_old_header(struct s_ospcl *);
155 155
156//////////////////////////////////////////////////////////// 156////////////////////////////////////////////////////////////
157// thunks for type correctness 157// thunks for type correctness
158 158
159#define WRAP(alg) \ 159#define WRAP(alg) \
160 static void \ 160 static void \
161 do_##alg##Init(void *ctx) \ 161 do_##alg##Init(void *ctx) \
162 { \ 162 { \
163 alg##Init(ctx); \ 163 alg##Init(ctx); \
164 } \ 164 } \
165 \ 165 \
166 static void \ 166 static void \
167 do_##alg##Update(union digest_context *ctx, \ 167 do_##alg##Update(union digest_context *ctx, \
168 const void *buf, unsigned len) \ 168 const void *buf, unsigned len) \
169 { \ 169 { \
170 alg##Update(&ctx->dc_##alg, buf, len); \ 170 alg##Update(&ctx->dc_##alg, buf, len); \
171 } \ 171 } \
172 \ 172 \
173 static char * \ 173 static char * \
174 do_##alg##End(void *ctx, char *str) \ 174 do_##alg##End(void *ctx, char *str) \
175 { \ 175 { \
176 return alg##End(ctx, str); \ 176 return alg##End(ctx, str); \
177 } 177 }
178 178
179WRAP(MD5); 179WRAP(MD5);
180WRAP(SHA1); 180WRAP(SHA1);
181WRAP(RMD160); 181WRAP(RMD160);
182 182
183static const struct digest_desc digest_descs[] = { 183static const struct digest_desc digest_descs[] = {
184 { "MD5", 184 { "MD5",
185 do_MD5Init, 185 do_MD5Init,
186 do_MD5Update, 186 do_MD5Update,
187 do_MD5End, }, 187 do_MD5End, },
188 { "SHA1", 188 { "SHA1",
189 do_SHA1Init, 189 do_SHA1Init,
190 do_SHA1Update, 190 do_SHA1Update,
191 do_SHA1End, }, 191 do_SHA1End, },
192 { "RMD160", 192 { "RMD160",
193 do_RMD160Init, 193 do_RMD160Init,
194 do_RMD160Update, 194 do_RMD160Update,
195 do_RMD160End, }, 195 do_RMD160End, },
196 { .dd_name = NULL }, 196 { .dd_name = NULL },
197}; 197};
198 198
199//////////////////////////////////////////////////////////// 199////////////////////////////////////////////////////////////
200 200
201const struct digest_desc * 201const struct digest_desc *
202digest_lookup(const char *name) 202digest_lookup(const char *name)
203{ 203{
204 const struct digest_desc *dd; 204 const struct digest_desc *dd;
205 205
206 for (dd = digest_descs; dd->dd_name != NULL; dd++) 206 for (dd = digest_descs; dd->dd_name != NULL; dd++)
207 if (strcasecmp(dd->dd_name, name) == 0) 207 if (strcasecmp(dd->dd_name, name) == 0)
208 return (dd); 208 return (dd);
209 209
210 return (NULL); 210 return (NULL);
211} 211}
212 212
213/* 213/*
214 * Set up an input source 214 * Set up an input source
215 */ 215 */
216void 216void
217setinput(const char *source) 217setinput(const char *source)
218{ 218{
219 char *cp; 219 char *cp;
220 FLUSHTAPEBUF(); 220 FLUSHTAPEBUF();
221 if (bflag) 221 if (bflag)
222 newtapebuf(ntrec); 222 newtapebuf(ntrec);
223 else 223 else
224 newtapebuf(NTREC > HIGHDENSITYTREC ? NTREC : HIGHDENSITYTREC); 224 newtapebuf(NTREC > HIGHDENSITYTREC ? NTREC : HIGHDENSITYTREC);
225 terminal = stdin; 225 terminal = stdin;
226 226
227#ifdef RRESTORE 227#ifdef RRESTORE
228 if ((cp = strchr(source, ':')) != NULL) { 228 if ((cp = strchr(source, ':')) != NULL) {
229 host = source; 229 host = source;
230 /* Ok, because const strings don't have : */ 230 /* Ok, because const strings don't have : */
231 *cp++ = '\0'; 231 *cp++ = '\0';
232 source = cp; 232 source = cp;
233 if (rmthost(host) == 0) 233 if (rmthost(host) == 0)
234 exit(1); 234 exit(1);
235 } else 235 } else
236#endif 236#endif
237 if (strcmp(source, "-") == 0) { 237 if (strcmp(source, "-") == 0) {
238 /* 238 /*
239 * Since input is coming from a pipe we must establish 239 * Since input is coming from a pipe we must establish
240 * our own connection to the terminal. 240 * our own connection to the terminal.
241 */ 241 */
242 terminal = fopen(_PATH_TTY, "r"); 242 terminal = fopen(_PATH_TTY, "r");
243 if (terminal == NULL) { 243 if (terminal == NULL) {
244 (void)fprintf(stderr, "cannot open %s: %s\n", 244 (void)fprintf(stderr, "cannot open %s: %s\n",
245 _PATH_TTY, strerror(errno)); 245 _PATH_TTY, strerror(errno));
246 terminal = fopen(_PATH_DEVNULL, "r"); 246 terminal = fopen(_PATH_DEVNULL, "r");
247 if (terminal == NULL) { 247 if (terminal == NULL) {
248 (void)fprintf(stderr, "cannot open %s: %s\n", 248 (void)fprintf(stderr, "cannot open %s: %s\n",
249 _PATH_DEVNULL, strerror(errno)); 249 _PATH_DEVNULL, strerror(errno));
250 exit(1); 250 exit(1);
251 } 251 }
252 } 252 }
253 pipein++; 253 pipein++;
254 } 254 }
255 (void) strcpy(magtape, source); 255 (void) strcpy(magtape, source);
256} 256}
257 257
258void 258void
259newtapebuf(long size) 259newtapebuf(long size)
260{ 260{
261 static int tapebufsize = -1; 261 static int tapebufsize = -1;
262 262
263 ntrec = size; 263 ntrec = size;
264 if (size <= tapebufsize) 264 if (size <= tapebufsize)
265 return; 265 return;
266 if (tapebuf != NULL) 266 if (tapebuf != NULL)
267 free(tapebuf); 267 free(tapebuf);
268 tapebuf = malloc(size * TP_BSIZE); 268 tapebuf = malloc(size * TP_BSIZE);
269 if (tapebuf == NULL) { 269 if (tapebuf == NULL) {
270 fprintf(stderr, "Cannot allocate space for tape buffer\n"); 270 fprintf(stderr, "Cannot allocate space for tape buffer\n");
271 exit(1); 271 exit(1);
272 } 272 }
273 tapebufsize = size; 273 tapebufsize = size;
274} 274}
275 275
276/* 276/*
277 * Verify that the tape drive can be accessed and 277 * Verify that the tape drive can be accessed and
278 * that it actually is a dump tape. 278 * that it actually is a dump tape.
279 */ 279 */
280void 280void
281setup(void) 281setup(void)
282{ 282{
283 int i, j, *ip; 283 int i, j, *ip;
284 struct stat stbuf; 284 struct stat stbuf;
285 285
286 vprintf(stdout, "Verify tape and initialize maps\n"); 286 vprintf(stdout, "Verify tape and initialize maps\n");
287#ifdef RRESTORE 287#ifdef RRESTORE
288 if (host) 288 if (host)
289 mt = rmtopen(magtape, 0, 0); 289 mt = rmtopen(magtape, 0, 0);
290 else 290 else
291#endif 291#endif
292 if (pipein) 292 if (pipein)
293 mt = 0; 293 mt = 0;
294 else 294 else
295 mt = open(magtape, O_RDONLY, 0); 295 mt = open(magtape, O_RDONLY, 0);
296 if (mt < 0) { 296 if (mt < 0) {
297 fprintf(stderr, "%s: %s\n", magtape, strerror(errno)); 297 fprintf(stderr, "%s: %s\n", magtape, strerror(errno));
298 exit(1); 298 exit(1);
299 } 299 }
300 volno = 1; 300 volno = 1;
301 setdumpnum(); 301 setdumpnum();
302 FLUSHTAPEBUF(); 302 FLUSHTAPEBUF();
303 if (!pipein && !bflag) 303 if (!pipein && !bflag)
304 findtapeblksize(); 304 findtapeblksize();
305 if (gethead(&spcl) == FAIL) { 305 if (gethead(&spcl) == FAIL) {
306 blkcnt--; /* push back this block */ 306 blkcnt--; /* push back this block */
307 blksread--; 307 blksread--;
308 tpblksread--; 308 tpblksread--;
309 cvtflag++; 309 cvtflag++;
310 if (gethead(&spcl) == FAIL) { 310 if (gethead(&spcl) == FAIL) {
311 fprintf(stderr, "Tape is not a dump tape\n"); 311 fprintf(stderr, "Tape is not a dump tape\n");
312 exit(1); 312 exit(1);
313 } 313 }
314 fprintf(stderr, "Converting to new file system format.\n"); 314 fprintf(stderr, "Converting to new file system format.\n");
315 } 315 }
316 if (pipein) { 316 if (pipein) {
317 endoftapemark.s_spcl.c_magic = cvtflag ? OFS_MAGIC : 317 endoftapemark.s_spcl.c_magic = cvtflag ? OFS_MAGIC :
318 FS_UFS2_MAGIC; 318 FS_UFS2_MAGIC;
319 endoftapemark.s_spcl.c_type = TS_END; 319 endoftapemark.s_spcl.c_type = TS_END;
320 ip = (int *)&endoftapemark; 320 ip = (int *)&endoftapemark;
321 j = sizeof(union u_spcl) / sizeof(int); 321 j = sizeof(union u_spcl) / sizeof(int);
322 i = 0; 322 i = 0;
323 do 323 do
324 i += *ip++; 324 i += *ip++;
325 while (--j); 325 while (--j);
326 endoftapemark.s_spcl.c_checksum = CHECKSUM - i; 326 endoftapemark.s_spcl.c_checksum = CHECKSUM - i;
327 } 327 }
328 if (vflag || command == 't') 328 if (vflag || command == 't')
329 printdumpinfo(); 329 printdumpinfo();
330 dumptime = spcl.c_ddate; 330 dumptime = spcl.c_ddate;
331 dumpdate = spcl.c_date; 331 dumpdate = spcl.c_date;
332 if (stat(".", &stbuf) < 0) { 332 if (stat(".", &stbuf) < 0) {
333 fprintf(stderr, "cannot stat .: %s\n", strerror(errno)); 333 fprintf(stderr, "cannot stat .: %s\n", strerror(errno));
334 exit(1); 334 exit(1);
335 } 335 }
336 if (stbuf.st_blksize >= TP_BSIZE && stbuf.st_blksize <= MAXBSIZE) 336 if (stbuf.st_blksize >= TP_BSIZE && stbuf.st_blksize <= MAXBSIZE)
337 fssize = stbuf.st_blksize; 337 fssize = stbuf.st_blksize;
338 if (((fssize - 1) & fssize) != 0) { 338 if (((fssize - 1) & fssize) != 0) {
339 fprintf(stderr, "bad block size %d\n", fssize); 339 fprintf(stderr, "bad block size %d\n", fssize);
340 exit(1); 340 exit(1);
341 } 341 }
342 if (spcl.c_volume != 1) { 342 if (spcl.c_volume != 1) {
343 fprintf(stderr, "Tape is not volume 1 of the dump\n"); 343 fprintf(stderr, "Tape is not volume 1 of the dump\n");
344 exit(1); 344 exit(1);
345 } 345 }
346 if (gethead(&spcl) == FAIL) { 346 if (gethead(&spcl) == FAIL) {
347 dprintf(stdout, "header read failed at %d blocks\n", blksread); 347 dprintf(stdout, "header read failed at %d blocks\n", blksread);
348 panic("no header after volume mark!\n"); 348 panic("no header after volume mark!\n");
349 } 349 }
350 findinode(&spcl); 350 findinode(&spcl);
351 if (spcl.c_type != TS_CLRI) { 351 if (spcl.c_type != TS_CLRI) {
352 fprintf(stderr, "Cannot find file removal list\n"); 352 fprintf(stderr, "Cannot find file removal list\n");
353 exit(1); 353 exit(1);
354 } 354 }
355 getbitmap(&usedinomap); 355 getbitmap(&usedinomap);
356 getbitmap(&dumpmap); 356 getbitmap(&dumpmap);
357 /* 357 /*
358 * If there may be whiteout entries on the tape, pretend that the 358 * If there may be whiteout entries on the tape, pretend that the
359 * whiteout inode exists, so that the whiteout entries can be 359 * whiteout inode exists, so that the whiteout entries can be
360 * extracted. 360 * extracted.
361 */ 361 */
362 if (oldinofmt == 0) 362 if (oldinofmt == 0)
363 SETINO(UFS_WINO, dumpmap); 363 SETINO(UFS_WINO, dumpmap);
364} 364}
365 365
366/* 366/*
367 * Prompt user to load a new dump volume. 367 * Prompt user to load a new dump volume.
368 * "Nextvol" is the next suggested volume to use. 368 * "Nextvol" is the next suggested volume to use.
369 * This suggested volume is enforced when doing full 369 * This suggested volume is enforced when doing full
370 * or incremental restores, but can be overrridden by 370 * or incremental restores, but can be overrridden by
371 * the user when only extracting a subset of the files. 371 * the user when only extracting a subset of the files.
372 */ 372 */
373void 373void
374getvol(int nextvol) 374getvol(int nextvol)
375{ 375{
376 int newvol, savecnt, wantnext, i; 376 int newvol, savecnt, wantnext, i;
377 union u_spcl tmpspcl; 377 union u_spcl tmpspcl;
378# define tmpbuf tmpspcl.s_spcl 378# define tmpbuf tmpspcl.s_spcl
379 char buf[TP_BSIZE]; 379 char buf[TP_BSIZE];
380 380
381 newvol = savecnt = wantnext = 0; 381 newvol = savecnt = wantnext = 0;
382 if (nextvol == 1) { 382 if (nextvol == 1) {
383 tapesread = 0; 383 tapesread = 0;
384 gettingfile = 0; 384 gettingfile = 0;
385 } 385 }
386 if (pipein) { 386 if (pipein) {
387 if (nextvol != 1) 387 if (nextvol != 1)
388 panic("Changing volumes on pipe input?\n"); 388 panic("Changing volumes on pipe input?\n");
389 if (volno == 1) 389 if (volno == 1)
390 return; 390 return;
391 goto gethdr; 391 goto gethdr;
392 } 392 }
393 savecnt = blksread; 393 savecnt = blksread;
394again: 394again:
395 if (pipein) 395 if (pipein)
396 exit(1); /* pipes do not get a second chance */ 396 exit(1); /* pipes do not get a second chance */
397 if (command == 'R' || command == 'r' || curfile.action != SKIP) { 397 if (command == 'R' || command == 'r' || curfile.action != SKIP) {
398 newvol = nextvol; 398 newvol = nextvol;
399 wantnext = 1; 399 wantnext = 1;
400 } else {  400 } else {
401 newvol = 0; 401 newvol = 0;
402 wantnext = 0; 402 wantnext = 0;
403 } 403 }
404 while (newvol <= 0) { 404 while (newvol <= 0) {
405 if (tapesread == 0) { 405 if (tapesread == 0) {
406 fprintf(stderr, "%s%s%s%s%s", 406 fprintf(stderr, "%s%s%s%s%s",
407 "You have not read any tapes yet.\n", 407 "You have not read any tapes yet.\n",
408 "Unless you know which volume your", 408 "Unless you know which volume your",
409 " file(s) are on you should start\n", 409 " file(s) are on you should start\n",
410 "with the last volume and work", 410 "with the last volume and work",
411 " towards the first.\n"); 411 " towards the first.\n");
412 fprintf(stderr, 412 fprintf(stderr,
413 "(Use 1 for the first volume/tape, etc.)\n"); 413 "(Use 1 for the first volume/tape, etc.)\n");
414 } else { 414 } else {
415 fprintf(stderr, "You have read volumes"); 415 fprintf(stderr, "You have read volumes");
416 strcpy(buf, ": "); 416 strcpy(buf, ": ");
417 for (i = 1; i < 32; i++) 417 for (i = 1; i < 32; i++)
418 if (tapesread & (1 << i)) { 418 if (tapesread & (1 << i)) {
419 fprintf(stderr, "%s%d", buf, i); 419 fprintf(stderr, "%s%d", buf, i);
420 strcpy(buf, ", "); 420 strcpy(buf, ", ");
421 } 421 }
422 fprintf(stderr, "\n"); 422 fprintf(stderr, "\n");
423 } 423 }
424 do { 424 do {
425 fprintf(stderr, "Specify next volume #: "); 425 fprintf(stderr, "Specify next volume #: ");
426 (void) fflush(stderr); 426 (void) fflush(stderr);
427 (void) fgets(buf, BUFSIZ, terminal); 427 (void) fgets(buf, BUFSIZ, terminal);
428 } while (!feof(terminal) && buf[0] == '\n'); 428 } while (!feof(terminal) && buf[0] == '\n');
429 if (feof(terminal)) 429 if (feof(terminal))
430 exit(1); 430 exit(1);
431 newvol = atoi(buf); 431 newvol = atoi(buf);
432 if (newvol <= 0) { 432 if (newvol <= 0) {
433 fprintf(stderr, 433 fprintf(stderr,
434 "Volume numbers are positive numerics\n"); 434 "Volume numbers are positive numerics\n");
435 } 435 }
436 } 436 }
437 if (newvol == volno) { 437 if (newvol == volno) {
438 tapesread |= 1 << volno; 438 tapesread |= 1 << volno;
439 return; 439 return;
440 } 440 }
441 closemt(); 441 closemt();
442 fprintf(stderr, "Mount tape volume %d\n", newvol); 442 fprintf(stderr, "Mount tape volume %d\n", newvol);
443 fprintf(stderr, "Enter ``none'' if there are no more tapes\n"); 443 fprintf(stderr, "Enter ``none'' if there are no more tapes\n");
444 fprintf(stderr, "otherwise enter tape name (default: %s) ", magtape); 444 fprintf(stderr, "otherwise enter tape name (default: %s) ", magtape);
445 (void) fflush(stderr); 445 (void) fflush(stderr);
446 (void) fgets(buf, BUFSIZ, terminal); 446 (void) fgets(buf, BUFSIZ, terminal);
447 if (feof(terminal)) 447 if (feof(terminal))
448 exit(1); 448 exit(1);
449 if (!strcmp(buf, "none\n")) { 449 if (!strcmp(buf, "none\n")) {
450 terminateinput(); 450 terminateinput();
451 return; 451 return;
452 } 452 }
453 if (buf[0] != '\n') { 453 if (buf[0] != '\n') {
454 (void) strcpy(magtape, buf); 454 (void) strcpy(magtape, buf);
455 magtape[strlen(magtape) - 1] = '\0'; 455 magtape[strlen(magtape) - 1] = '\0';
456 } 456 }
457#ifdef RRESTORE 457#ifdef RRESTORE
458 if (host) 458 if (host)
459 mt = rmtopen(magtape, 0, 0); 459 mt = rmtopen(magtape, 0, 0);
460 else 460 else
461#endif 461#endif
462 mt = open(magtape, O_RDONLY, 0); 462 mt = open(magtape, O_RDONLY, 0);
463 463
464 if (mt == -1) { 464 if (mt == -1) {
465 fprintf(stderr, "Cannot open %s\n", magtape); 465 fprintf(stderr, "Cannot open %s\n", magtape);
466 volno = -1; 466 volno = -1;
467 goto again; 467 goto again;
468 } 468 }
469gethdr: 469gethdr:
470 volno = newvol; 470 volno = newvol;
471 setdumpnum(); 471 setdumpnum();
472 FLUSHTAPEBUF(); 472 FLUSHTAPEBUF();
473 if (gethead(&tmpbuf) == FAIL) { 473 if (gethead(&tmpbuf) == FAIL) {
474 dprintf(stdout, "header read failed at %d blocks\n", blksread); 474 dprintf(stdout, "header read failed at %d blocks\n", blksread);
475 fprintf(stderr, "tape is not dump tape\n"); 475 fprintf(stderr, "tape is not dump tape\n");
476 volno = 0; 476 volno = 0;
477 goto again; 477 goto again;
478 } 478 }
479 if (tmpbuf.c_volume != volno) { 479 if (tmpbuf.c_volume != volno) {
480 fprintf(stderr, 480 fprintf(stderr,
481 "Volume mismatch: expecting %d, tape header claims it is %d\n", 481 "Volume mismatch: expecting %d, tape header claims it is %d\n",
482 volno, tmpbuf.c_volume); 482 volno, tmpbuf.c_volume);
483 volno = 0; 483 volno = 0;
484 goto again; 484 goto again;
485 } 485 }
486 if (tmpbuf.c_date != dumpdate || tmpbuf.c_ddate != dumptime) { 486 if (tmpbuf.c_date != dumpdate || tmpbuf.c_ddate != dumptime) {
487 time_t ttime = tmpbuf.c_date; 487 time_t ttime = tmpbuf.c_date;
488 fprintf(stderr, "Wrong dump date\n\tgot: %s", 488 fprintf(stderr, "Wrong dump date\n\tgot: %s",
489 ctime(&ttime)); 489 ctime(&ttime));
490 fprintf(stderr, "\twanted: %s", ctime(&dumpdate)); 490 fprintf(stderr, "\twanted: %s", ctime(&dumpdate));
491 volno = 0; 491 volno = 0;
492 goto again; 492 goto again;
493 } 493 }
494 tapesread |= 1 << volno; 494 tapesread |= 1 << volno;
495 blksread = savecnt; 495 blksread = savecnt;
496 /* 496 /*
497 * If continuing from the previous volume, skip over any 497 * If continuing from the previous volume, skip over any
498 * blocks read already at the end of the previous volume. 498 * blocks read already at the end of the previous volume.
499 * 499 *
500 * If coming to this volume at random, skip to the beginning 500 * If coming to this volume at random, skip to the beginning
501 * of the next record. 501 * of the next record.
502 */ 502 */
503 dprintf(stdout, "read %ld recs, tape starts with %ld\n",  503 dprintf(stdout, "read %ld recs, tape starts with %ld\n",
504 (long)tpblksread, (long)tmpbuf.c_firstrec); 504 (long)tpblksread, (long)tmpbuf.c_firstrec);
505 if (tmpbuf.c_type == TS_TAPE && (tmpbuf.c_flags & DR_NEWHEADER)) { 505 if (tmpbuf.c_type == TS_TAPE && (tmpbuf.c_flags & DR_NEWHEADER)) {
506 if (!wantnext) { 506 if (!wantnext) {
507 tpblksread = tmpbuf.c_firstrec; 507 tpblksread = tmpbuf.c_firstrec;
508 for (i = tmpbuf.c_count; i > 0; i--) 508 for (i = tmpbuf.c_count; i > 0; i--)
509 readtape(buf); 509 readtape(buf);
510 } else if (tmpbuf.c_firstrec > 0 && 510 } else if (tmpbuf.c_firstrec > 0 &&
511 tmpbuf.c_firstrec < tpblksread - 1) { 511 tmpbuf.c_firstrec < tpblksread - 1) {
512 /* 512 /*
513 * -1 since we've read the volume header 513 * -1 since we've read the volume header
514 */ 514 */
515 i = tpblksread - tmpbuf.c_firstrec - 1; 515 i = tpblksread - tmpbuf.c_firstrec - 1;
516 dprintf(stderr, "Skipping %d duplicate record%s.\n", 516 dprintf(stderr, "Skipping %d duplicate record%s.\n",
517 i, i > 1 ? "s" : ""); 517 i, i > 1 ? "s" : "");
518 while (--i >= 0) 518 while (--i >= 0)
519 readtape(buf); 519 readtape(buf);
520 } 520 }
521 } 521 }
522 if (curfile.action == USING) { 522 if (curfile.action == USING) {
523 if (volno == 1) 523 if (volno == 1)
524 panic("active file into volume 1\n"); 524 panic("active file into volume 1\n");
525 return; 525 return;
526 } 526 }
527 /* 527 /*
528 * Skip up to the beginning of the next record 528 * Skip up to the beginning of the next record
529 */ 529 */
530 if (tmpbuf.c_type == TS_TAPE && (tmpbuf.c_flags & DR_NEWHEADER)) 530 if (tmpbuf.c_type == TS_TAPE && (tmpbuf.c_flags & DR_NEWHEADER))
531 for (i = tmpbuf.c_count; i > 0; i--) 531 for (i = tmpbuf.c_count; i > 0; i--)
532 readtape(buf); 532 readtape(buf);
533 (void) gethead(&spcl); 533 (void) gethead(&spcl);
534 findinode(&spcl); 534 findinode(&spcl);
535 if (gettingfile) { 535 if (gettingfile) {
536 gettingfile = 0; 536 gettingfile = 0;
537 longjmp(restart, 1); 537 longjmp(restart, 1);
538 } 538 }
539} 539}
540 540
541/* 541/*
542 * Handle unexpected EOF. 542 * Handle unexpected EOF.
543 */ 543 */
544static void 544static void
545terminateinput(void) 545terminateinput(void)
546{ 546{
547 547
548 if (gettingfile && curfile.action == USING) { 548 if (gettingfile && curfile.action == USING) {
549 printf("Warning: %s %s\n", 549 printf("Warning: %s %s\n",
550 "End-of-input encountered while extracting", curfile.name); 550 "End-of-input encountered while extracting", curfile.name);
551 } 551 }
552 curfile.name = "<name unknown>"; 552 curfile.name = "<name unknown>";
553 curfile.action = UNKNOWN; 553 curfile.action = UNKNOWN;
554 curfile.mode = 0; 554 curfile.mode = 0;
555 curfile.ino = maxino; 555 curfile.ino = maxino;
556 if (gettingfile) { 556 if (gettingfile) {
557 gettingfile = 0; 557 gettingfile = 0;
558 longjmp(restart, 1); 558 longjmp(restart, 1);
559 } 559 }
560} 560}
561 561
562/* 562/*
563 * handle multiple dumps per tape by skipping forward to the 563 * handle multiple dumps per tape by skipping forward to the
564 * appropriate one. 564 * appropriate one.
565 */ 565 */
566static void 566static void
567setdumpnum(void) 567setdumpnum(void)
568{ 568{
569 struct mtop tcom; 569 struct mtop tcom;
570 570
571 if (dumpnum == 1 || volno != 1) 571 if (dumpnum == 1 || volno != 1)
572 return; 572 return;
573 if (pipein) { 573 if (pipein) {
574 fprintf(stderr, "Cannot have multiple dumps on pipe input\n"); 574 fprintf(stderr, "Cannot have multiple dumps on pipe input\n");
575 exit(1); 575 exit(1);
576 } 576 }
577 tcom.mt_op = MTFSF; 577 tcom.mt_op = MTFSF;
578 tcom.mt_count = dumpnum - 1; 578 tcom.mt_count = dumpnum - 1;
579#ifdef RRESTORE 579#ifdef RRESTORE
580 if (host) 580 if (host)
581 rmtioctl(MTFSF, dumpnum - 1); 581 rmtioctl(MTFSF, dumpnum - 1);
582 else  582 else
583#endif 583#endif
584 if (ioctl(mt, (int)MTIOCTOP, (char *)&tcom) < 0) 584 if (ioctl(mt, (int)MTIOCTOP, (char *)&tcom) < 0)
585 fprintf(stderr, "ioctl MTFSF: %s\n", strerror(errno)); 585 fprintf(stderr, "ioctl MTFSF: %s\n", strerror(errno));
586} 586}
587 587
588void 588void
589printdumpinfo(void) 589printdumpinfo(void)
590{ 590{
591 time_t ttime; 591 time_t ttime;
592 592
593 ttime = spcl.c_date; 593 ttime = spcl.c_date;
594 fprintf(stdout, "Dump date: %s", ctime(&ttime)); 594 fprintf(stdout, "Dump date: %s", ctime(&ttime));
595 ttime = spcl.c_ddate; 595 ttime = spcl.c_ddate;
596 fprintf(stdout, "Dumped from: %s", 596 fprintf(stdout, "Dumped from: %s",
597 (spcl.c_ddate == 0) ? "the epoch\n" : ctime(&ttime)); 597 (spcl.c_ddate == 0) ? "the epoch\n" : ctime(&ttime));
598 fprintf(stderr, "Level %d dump of %s on %s:%s\n", 598 fprintf(stderr, "Level %d dump of %s on %s:%s\n",
599 spcl.c_level, spcl.c_filesys,  599 spcl.c_level, spcl.c_filesys,
600 *spcl.c_host? spcl.c_host: "[unknown]", spcl.c_dev); 600 *spcl.c_host? spcl.c_host: "[unknown]", spcl.c_dev);
601 fprintf(stderr, "Label: %s\n", spcl.c_label); 601 fprintf(stderr, "Label: %s\n", spcl.c_label);
602 602
603 if (Mtreefile) { 603 if (Mtreefile) {
604 ttime = spcl.c_date; 604 ttime = spcl.c_date;
605 fprintf(Mtreefile, "#Dump date: %s", ctime(&ttime)); 605 fprintf(Mtreefile, "#Dump date: %s", ctime(&ttime));
606 ttime = spcl.c_ddate; 606 ttime = spcl.c_ddate;
607 fprintf(Mtreefile, "#Dumped from: %s", 607 fprintf(Mtreefile, "#Dumped from: %s",
608 (spcl.c_ddate == 0) ? "the epoch\n" : ctime(&ttime)); 608 (spcl.c_ddate == 0) ? "the epoch\n" : ctime(&ttime));
609 fprintf(Mtreefile, "#Level %d dump of %s on %s:%s\n", 609 fprintf(Mtreefile, "#Level %d dump of %s on %s:%s\n",
610 spcl.c_level, spcl.c_filesys,  610 spcl.c_level, spcl.c_filesys,
611 *spcl.c_host? spcl.c_host: "[unknown]", spcl.c_dev); 611 *spcl.c_host? spcl.c_host: "[unknown]", spcl.c_dev);
612 fprintf(Mtreefile, "#Label: %s\n", spcl.c_label); 612 fprintf(Mtreefile, "#Label: %s\n", spcl.c_label);
613 fprintf(Mtreefile, "/set uname=root gname=wheel\n"); 613 fprintf(Mtreefile, "/set uname=root gname=wheel\n");
614 if (ferror(Mtreefile)) 614 if (ferror(Mtreefile))
615 err(1, "error writing to mtree file"); 615 err(1, "error writing to mtree file");
616 } 616 }
617} 617}
618 618
619int 619int
620extractfile(char *name) 620extractfile(char *name)
621{ 621{
622 char dbuffer[DIGEST_BUFFER_SIZE]; 622 char dbuffer[DIGEST_BUFFER_SIZE];
623 int flags; 623 int flags;
624 uid_t uid; 624 uid_t uid;
625 gid_t gid; 625 gid_t gid;
626 mode_t mode; 626 mode_t mode;
627 struct timespec mtimep[2], ctimep[2]; 627 struct timespec mtimep[2], ctimep[2];
628 struct entry *ep; 628 struct entry *ep;
629 int setbirth; 629 int setbirth;
630 630
631 curfile.name = name; 631 curfile.name = name;
632 curfile.action = USING; 632 curfile.action = USING;
633 mtimep[0].tv_sec = curfile.atime_sec; 633 mtimep[0].tv_sec = curfile.atime_sec;
634 mtimep[0].tv_nsec = curfile.atime_nsec; 634 mtimep[0].tv_nsec = curfile.atime_nsec;
635 mtimep[1].tv_sec = curfile.mtime_sec; 635 mtimep[1].tv_sec = curfile.mtime_sec;
636 mtimep[1].tv_nsec = curfile.mtime_nsec; 636 mtimep[1].tv_nsec = curfile.mtime_nsec;
637 637
638 setbirth = curfile.birthtime_sec != 0; 638 setbirth = curfile.birthtime_sec != 0;
639 639
640 if (setbirth) { 640 if (setbirth) {
641 ctimep[0].tv_sec = curfile.atime_sec; 641 ctimep[0].tv_sec = curfile.atime_sec;
642 ctimep[0].tv_nsec = curfile.atime_nsec; 642 ctimep[0].tv_nsec = curfile.atime_nsec;
643 ctimep[1].tv_sec = curfile.birthtime_sec; 643 ctimep[1].tv_sec = curfile.birthtime_sec;
644 ctimep[1].tv_nsec = curfile.birthtime_nsec; 644 ctimep[1].tv_nsec = curfile.birthtime_nsec;
645 } 645 }
646 uid = curfile.uid; 646 uid = curfile.uid;
647 gid = curfile.gid; 647 gid = curfile.gid;
648 mode = curfile.mode; 648 mode = curfile.mode;
649 flags = curfile.file_flags; 649 flags = curfile.file_flags;
650 switch (mode & IFMT) { 650 switch (mode & IFMT) {
651 651
652 default: 652 default:
653 fprintf(stderr, "%s: unknown file mode 0%o\n", name, mode); 653 fprintf(stderr, "%s: unknown file mode 0%o\n", name, mode);
654 skipfile(); 654 skipfile();
655 return (FAIL); 655 return (FAIL);
656 656
657 case IFSOCK: 657 case IFSOCK:
658 vprintf(stdout, "skipped socket %s\n", name); 658 vprintf(stdout, "skipped socket %s\n", name);
659 skipfile(); 659 skipfile();
660 return (GOOD); 660 return (GOOD);
661 661
662 case IFDIR: 662 case IFDIR:
663 if (mflag) { 663 if (mflag) {
664 ep = lookupname(name); 664 ep = lookupname(name);
665 if (ep == NULL || ep->e_flags & EXTRACT) 665 if (ep == NULL || ep->e_flags & EXTRACT)
666 panic("unextracted directory %s\n", name); 666 panic("unextracted directory %s\n", name);
667 skipfile(); 667 skipfile();
668 return (GOOD); 668 return (GOOD);
669 } 669 }
670 vprintf(stdout, "extract file %s\n", name); 670 vprintf(stdout, "extract file %s\n", name);
671 return (genliteraldir(name, curfile.ino)); 671 return (genliteraldir(name, curfile.ino));
672 672
673 case IFLNK: 673 case IFLNK:
674 lnkbuf[0] = '\0'; 674 lnkbuf[0] = '\0';
675 pathlen = 0; 675 pathlen = 0;
676 getfile(xtrlnkfile, xtrlnkskip); 676 getfile(xtrlnkfile, xtrlnkskip);
677 if (pathlen == 0) { 677 if (pathlen == 0) {
678 vprintf(stdout, 678 vprintf(stdout,
679 "%s: zero length symbolic link (ignored)\n", name); 679 "%s: zero length symbolic link (ignored)\n", name);
680 return (GOOD); 680 return (GOOD);
681 } 681 }
682 if (uflag) 682 if (uflag)
683 (void) unlink(name); 683 (void) unlink(name);
684 if (linkit(lnkbuf, name, SYMLINK) == GOOD) { 684 if (linkit(lnkbuf, name, SYMLINK) == GOOD) {
685 if (setbirth) 685 if (setbirth)
686 (void) lutimens(name, ctimep); 686 (void) lutimens(name, ctimep);
687 (void) lutimens(name, mtimep); 687 (void) lutimens(name, mtimep);
688 (void) lchown(name, uid, gid); 688 (void) lchown(name, uid, gid);
689 (void) lchmod(name, mode); 689 (void) lchmod(name, mode);
690 if (Mtreefile) { 690 if (Mtreefile) {
691 writemtree(name, "link", 691 writemtree(name, "link",
692 uid, gid, mode, flags); 692 uid, gid, mode, flags);
693 } else  693 } else
694 (void) lchflags(name, flags); 694 (void) lchflags(name, flags);
695 return (GOOD); 695 return (GOOD);
696 } 696 }
697 return (FAIL); 697 return (FAIL);
698 698
699 case IFCHR: 699 case IFCHR:
700 case IFBLK: 700 case IFBLK:
701 vprintf(stdout, "extract special file %s\n", name); 701 vprintf(stdout, "extract special file %s\n", name);
702 if (Nflag) { 702 if (Nflag) {
703 skipfile(); 703 skipfile();
704 return (GOOD); 704 return (GOOD);
705 } 705 }
706 if (uflag) 706 if (uflag)
707 (void) unlink(name); 707 (void) unlink(name);
708 if (mknod(name, (mode & (IFCHR | IFBLK)) | 0600, 708 if (mknod(name, (mode & (IFCHR | IFBLK)) | 0600,
709 (int)curfile.rdev) < 0) { 709 (int)curfile.rdev) < 0) {
710 fprintf(stderr, "%s: cannot create special file: %s\n", 710 fprintf(stderr, "%s: cannot create special file: %s\n",
711 name, strerror(errno)); 711 name, strerror(errno));
712 skipfile(); 712 skipfile();
713 return (FAIL); 713 return (FAIL);
714 } 714 }
715 skipfile(); 715 skipfile();
716 if (setbirth) 716 if (setbirth)
717 (void) utimens(name, ctimep); 717 (void) utimens(name, ctimep);
718 (void) utimens(name, mtimep); 718 (void) utimens(name, mtimep);
719 (void) chown(name, uid, gid); 719 (void) chown(name, uid, gid);
720 (void) chmod(name, mode); 720 (void) chmod(name, mode);
721 if (Mtreefile) { 721 if (Mtreefile) {
722 writemtree(name, 722 writemtree(name,
723 ((mode & (S_IFBLK | IFCHR)) == IFBLK) ? 723 ((mode & (S_IFBLK | IFCHR)) == IFBLK) ?
724 "block" : "char", 724 "block" : "char",
725 uid, gid, mode, flags); 725 uid, gid, mode, flags);
726 } else  726 } else
727 (void) chflags(name, flags); 727 (void) chflags(name, flags);
728 return (GOOD); 728 return (GOOD);
729 729
730 case IFIFO: 730 case IFIFO:
731 vprintf(stdout, "extract fifo %s\n", name); 731 vprintf(stdout, "extract fifo %s\n", name);
732 if (Nflag) { 732 if (Nflag) {
733 skipfile(); 733 skipfile();
734 return (GOOD); 734 return (GOOD);
735 } 735 }
736 if (uflag) 736 if (uflag)
737 (void) unlink(name); 737 (void) unlink(name);
738 if (mkfifo(name, 0600) < 0) { 738 if (mkfifo(name, 0600) < 0) {
739 fprintf(stderr, "%s: cannot create fifo: %s\n", 739 fprintf(stderr, "%s: cannot create fifo: %s\n",
740 name, strerror(errno)); 740 name, strerror(errno));
741 skipfile(); 741 skipfile();
742 return (FAIL); 742 return (FAIL);
743 } 743 }
744 skipfile(); 744 skipfile();
745 if (setbirth) 745 if (setbirth)
746 (void) utimens(name, ctimep); 746 (void) utimens(name, ctimep);
747 (void) utimens(name, mtimep); 747 (void) utimens(name, mtimep);
748 (void) chown(name, uid, gid); 748 (void) chown(name, uid, gid);
749 (void) chmod(name, mode); 749 (void) chmod(name, mode);
750 if (Mtreefile) { 750 if (Mtreefile) {
751 writemtree(name, "fifo", 751 writemtree(name, "fifo",
752 uid, gid, mode, flags); 752 uid, gid, mode, flags);
753 } else  753 } else
754 (void) chflags(name, flags); 754 (void) chflags(name, flags);
755 return (GOOD); 755 return (GOOD);
756 756
757 case IFREG: 757 case IFREG:
758 vprintf(stdout, "extract file %s\n", name); 758 vprintf(stdout, "extract file %s\n", name);
759 if (uflag) 759 if (uflag)
760 (void) unlink(name); 760 (void) unlink(name);
761 if (!Nflag && (ofile = open(name, O_WRONLY | O_CREAT | O_TRUNC, 761 if (!Nflag && (ofile = open(name, O_WRONLY | O_CREAT | O_TRUNC,
762 0600)) < 0) { 762 0600)) < 0) {
763 fprintf(stderr, "%s: cannot create file: %s\n", 763 fprintf(stderr, "%s: cannot create file: %s\n",
764 name, strerror(errno)); 764 name, strerror(errno));
765 skipfile(); 765 skipfile();
766 return (FAIL); 766 return (FAIL);
767 } 767 }
768 if (Dflag) 768 if (Dflag)
769 (*ddesc->dd_init)(&dcontext); 769 (*ddesc->dd_init)(&dcontext);
770 getfile(xtrfile, xtrskip); 770 getfile(xtrfile, xtrskip);
771 if (Dflag) { 771 if (Dflag) {
772 (*ddesc->dd_end)(&dcontext, dbuffer); 772 (*ddesc->dd_end)(&dcontext, dbuffer);
773 for (ep = lookupname(name); ep != NULL; 773 for (ep = lookupname(name); ep != NULL;
774 ep = ep->e_links) 774 ep = ep->e_links)
775 fprintf(stdout, "%s (%s) = %s\n", 775 fprintf(stdout, "%s (%s) = %s\n",
776 ddesc->dd_name, myname(ep), 776 ddesc->dd_name, myname(ep),
777 dbuffer); 777 dbuffer);
778 } 778 }
779 if (Nflag) 779 if (Nflag)
780 return (GOOD); 780 return (GOOD);
781 if (setbirth) 781 if (setbirth)
782 (void) futimens(ofile, ctimep); 782 (void) futimens(ofile, ctimep);
783 (void) futimens(ofile, mtimep); 783 (void) futimens(ofile, mtimep);
784 (void) fchown(ofile, uid, gid); 784 (void) fchown(ofile, uid, gid);
785 (void) fchmod(ofile, mode); 785 (void) fchmod(ofile, mode);
786 if (Mtreefile) { 786 if (Mtreefile) {
787 writemtree(name, "file", 787 writemtree(name, "file",
788 uid, gid, mode, flags); 788 uid, gid, mode, flags);
789 } else  789 } else
790 (void) fchflags(ofile, flags); 790 (void) fchflags(ofile, flags);
791 (void) close(ofile); 791 (void) close(ofile);
792 return (GOOD); 792 return (GOOD);
793 } 793 }
794 /* NOTREACHED */ 794 /* NOTREACHED */
795} 795}
796 796
797/* 797/*
798 * skip over bit maps on the tape 798 * skip over bit maps on the tape
799 */ 799 */
800void 800void
801skipmaps(void) 801skipmaps(void)
802{ 802{
803 803
804 while (spcl.c_type == TS_BITS || spcl.c_type == TS_CLRI) 804 while (spcl.c_type == TS_BITS || spcl.c_type == TS_CLRI)
805 skipfile(); 805 skipfile();
806} 806}
807 807
808/* 808/*
809 * skip over a file on the tape 809 * skip over a file on the tape
810 */ 810 */
811void 811void
812skipfile(void) 812skipfile(void)
813{ 813{
814 814
815 curfile.action = SKIP; 815 curfile.action = SKIP;
816 getfile(xtrnull, xtrnull); 816 getfile(xtrnull, xtrnull);
817} 817}
818 818
819/* 819/*
820 * Extract a bitmap from the tape. 820 * Extract a bitmap from the tape.
821 * The first bitmap sets maxino; 821 * The first bitmap sets maxino;
822 * other bitmaps must be of same size. 822 * other bitmaps must be of same size.
823 */ 823 */
824void 824void
825getbitmap(char **map) 825getbitmap(char **map)
826{ 826{
827 int i; 827 int i;
828 size_t volatile size = spcl.c_size; 828 size_t volatile size = spcl.c_size;
829 size_t volatile mapsize = size; 829 size_t volatile mapsize = size;
830 char *mapptr; 830 char *mapptr;
831 831
832 curfile.action = USING; 832 curfile.action = USING;
833 if (spcl.c_type == TS_END) 833 if (spcl.c_type == TS_END)
834 panic("ran off end of tape\n"); 834 panic("ran off end of tape\n");
835 if (spcl.c_magic != FS_UFS2_MAGIC) 835 if (spcl.c_magic != FS_UFS2_MAGIC)
836 panic("not at beginning of a file\n"); 836 panic("not at beginning of a file\n");
837 if (!gettingfile && setjmp(restart) != 0) 837 if (!gettingfile && setjmp(restart) != 0)
838 return; 838 return;
839 gettingfile++; 839 gettingfile++;
840 mapptr = *map = malloc(size); 840 mapptr = *map = malloc(size);
841loop: 841loop:
842 if (*map == NULL) 842 if (*map == NULL)
843 panic("no memory for %s\n", curfile.name); 843 panic("no memory for %s\n", curfile.name);
844 for (i = 0; i < spcl.c_count && size >= TP_BSIZE; i++) { 844 for (i = 0; i < spcl.c_count && size >= TP_BSIZE; i++) {
845 readtape(mapptr); 845 readtape(mapptr);
846 mapptr += TP_BSIZE; 846 mapptr += TP_BSIZE;
847 size -= TP_BSIZE; 847 size -= TP_BSIZE;
848 } 848 }
849 if (size != 0 || i != spcl.c_count) 849 if (size != 0 || i != spcl.c_count)
850 panic("%s: inconsistent map size\n", curfile.name); 850 panic("%s: inconsistent map size\n", curfile.name);
851 if (gethead(&spcl) == GOOD && spcl.c_type == TS_ADDR) { 851 if (gethead(&spcl) == GOOD && spcl.c_type == TS_ADDR) {
852 size = spcl.c_count * TP_BSIZE; 852 size = spcl.c_count * TP_BSIZE;
853 *map = realloc(*map, mapsize + size); 853 *map = realloc(*map, mapsize + size);
854 mapptr = *map + mapsize; 854 mapptr = *map + mapsize;
855 mapsize += size; 855 mapsize += size;
856 goto loop; 856 goto loop;
857 } 857 }
858 if (maxino == 0) 858 if (maxino == 0)
859 maxino = mapsize * NBBY + 1; 859 maxino = mapsize * NBBY + 1;
860 else if (maxino != mapsize * NBBY + 1) 860 else if (maxino != mapsize * NBBY + 1)
861 panic("%s: map size changed\n", curfile.name); 861 panic("%s: map size changed\n", curfile.name);
862 findinode(&spcl); 862 findinode(&spcl);
863 gettingfile = 0; 863 gettingfile = 0;
864} 864}
865 865
866/* 866/*
867 * Extract a file from the tape. 867 * Extract a file from the tape.
868 * When an allocated block is found it is passed to the fill function; 868 * When an allocated block is found it is passed to the fill function;
869 * when an unallocated block (hole) is found, a zeroed buffer is passed 869 * when an unallocated block (hole) is found, a zeroed buffer is passed
870 * to the skip function. 870 * to the skip function.
871 */ 871 */
872void 872void
873getfile(void (*fill)(char *buf, long size), 873getfile(void (*fill)(char *buf, long size),
874 void (*skip)(char *buf, long size)) 874 void (*skip)(char *buf, long size))
875{ 875{
876 int i; 876 int i;
877 int volatile curblk; 877 int volatile curblk;
878 quad_t volatile size; 878 quad_t volatile size;
879 static char clearedbuf[MAXBSIZE]; 879 static char clearedbuf[MAXBSIZE];
880 char buf[MAXBSIZE / TP_BSIZE][TP_BSIZE]; 880 char buf[MAXBSIZE / TP_BSIZE][TP_BSIZE];
881 char junk[TP_BSIZE]; 881 char junk[TP_BSIZE];
882 882
883 curblk = 0; 883 curblk = 0;
884 size = spcl.c_size; 884 size = spcl.c_size;
885 885
886 if (spcl.c_type == TS_END) 886 if (spcl.c_type == TS_END)
887 panic("ran off end of tape\n"); 887 panic("ran off end of tape\n");
888 if (spcl.c_magic != FS_UFS2_MAGIC) 888 if (spcl.c_magic != FS_UFS2_MAGIC)
889 panic("not at beginning of a file\n"); 889 panic("not at beginning of a file\n");
890 if (!gettingfile && setjmp(restart) != 0) 890 if (!gettingfile && setjmp(restart) != 0)
891 return; 891 return;
892 gettingfile++; 892 gettingfile++;
893loop: 893loop:
894 for (i = 0; i < spcl.c_count; i++) { 894 for (i = 0; i < spcl.c_count; i++) {
895 if (spcl.c_addr[i]) { 895 if (spcl.c_addr[i]) {
896 readtape(&buf[curblk++][0]); 896 readtape(&buf[curblk++][0]);
897 if ((uint32_t)curblk == fssize / TP_BSIZE) { 897 if ((uint32_t)curblk == fssize / TP_BSIZE) {
898 (*fill)((char *)buf, (long)(size > TP_BSIZE ? 898 (*fill)((char *)buf, (long)(size > TP_BSIZE ?
899 fssize : (curblk - 1) * TP_BSIZE + size)); 899 fssize : (curblk - 1) * TP_BSIZE + size));
900 curblk = 0; 900 curblk = 0;
901 } 901 }
902 } else { 902 } else {
903 if (curblk > 0) { 903 if (curblk > 0) {
904 (*fill)((char *)buf, (long)(size > TP_BSIZE ? 904 (*fill)((char *)buf, (long)(size > TP_BSIZE ?
905 curblk * TP_BSIZE : 905 curblk * TP_BSIZE :
906 (curblk - 1) * TP_BSIZE + size)); 906 (curblk - 1) * TP_BSIZE + size));
907 curblk = 0; 907 curblk = 0;
908 } 908 }
909 (*skip)(clearedbuf, (long)(size > TP_BSIZE ? 909 (*skip)(clearedbuf, (long)(size > TP_BSIZE ?
910 TP_BSIZE : size)); 910 TP_BSIZE : size));
911 } 911 }
912 if ((size -= TP_BSIZE) <= 0) { 912 if ((size -= TP_BSIZE) <= 0) {
913 for (i++; i < spcl.c_count; i++) 913 for (i++; i < spcl.c_count; i++)
914 if (spcl.c_addr[i]) 914 if (spcl.c_addr[i])
915 readtape(junk); 915 readtape(junk);
916 break; 916 break;
917 } 917 }
918 } 918 }
919 if (gethead(&spcl) == GOOD && size > 0) { 919 if (gethead(&spcl) == GOOD && size > 0) {
920 if (spcl.c_type == TS_ADDR) 920 if (spcl.c_type == TS_ADDR)
921 goto loop; 921 goto loop;
922 dprintf(stdout, 922 dprintf(stdout,
923 "Missing address (header) block for %s at %d blocks\n", 923 "Missing address (header) block for %s at %d blocks\n",
924 curfile.name, blksread); 924 curfile.name, blksread);
925 } 925 }
926 if (curblk > 0) 926 if (curblk > 0)
927 (*fill)((char *)buf, (long)((curblk * TP_BSIZE) + size)); 927 (*fill)((char *)buf, (long)((curblk * TP_BSIZE) + size));
928 /* Skip over Linux extended attributes. */ 928 /* Skip over Linux extended attributes. */
929 if (spcl.c_type == TS_INODE && (spcl.c_flags & DR_EXTATTRIBUTES)) { 929 if (spcl.c_type == TS_INODE && (spcl.c_flags & DR_EXTATTRIBUTES)) {
930 for (i = 0; i < spcl.c_count; i++) 930 for (i = 0; i < spcl.c_count; i++)
931 readtape(junk); 931 readtape(junk);
932 (void)gethead(&spcl); 932 (void)gethead(&spcl);
933 } 933 }
934 findinode(&spcl); 934 findinode(&spcl);
935 gettingfile = 0; 935 gettingfile = 0;
936} 936}
937 937
938/* 938/*
939 * Write out the next block of a file. 939 * Write out the next block of a file.
940 */ 940 */
941static void 941static void
942xtrfile(char *buf, long size) 942xtrfile(char *buf, long size)
943{ 943{
944 944
945 if (Dflag) 945 if (Dflag)
946 (*ddesc->dd_update)(&dcontext, buf, size); 946 (*ddesc->dd_update)(&dcontext, buf, size);
947 if (Nflag) 947 if (Nflag)
948 return; 948 return;
949 if (write(ofile, buf, (int) size) == -1) { 949 if (write(ofile, buf, (int) size) == -1) {
950 fprintf(stderr, 950 fprintf(stderr,
951 "write error extracting inode %llu, name %s\nwrite: %s\n", 951 "write error extracting inode %llu, name %s\nwrite: %s\n",
952 (unsigned long long)curfile.ino, curfile.name, 952 (unsigned long long)curfile.ino, curfile.name,
953 strerror(errno)); 953 strerror(errno));
954 exit(1); 954 exit(1);
955 } 955 }
956} 956}
957 957
958/* 958/*
959 * Skip over a hole in a file. 959 * Skip over a hole in a file.
960 */ 960 */
961/* ARGSUSED */ 961/* ARGSUSED */
962static void 962static void
963xtrskip(char *buf, long size) 963xtrskip(char *buf, long size)
964{ 964{
965 965
966 if (Dflag) 966 if (Dflag)
967 (*ddesc->dd_update)(&dcontext, buf, size); 967 (*ddesc->dd_update)(&dcontext, buf, size);
968 if (Nflag) 968 if (Nflag)
969 return; 969 return;
970 if (lseek(ofile, size, SEEK_CUR) == -1) { 970 if (lseek(ofile, size, SEEK_CUR) == -1) {
971 fprintf(stderr, 971 fprintf(stderr,
972 "seek error extracting inode %llu, name %s\nlseek: %s\n", 972 "seek error extracting inode %llu, name %s\nlseek: %s\n",
973 (unsigned long long)curfile.ino, curfile.name, 973 (unsigned long long)curfile.ino, curfile.name,
974 strerror(errno)); 974 strerror(errno));
975 exit(1); 975 exit(1);
976 } 976 }
977} 977}
978 978
979/* 979/*
980 * Collect the next block of a symbolic link. 980 * Collect the next block of a symbolic link.
981 */ 981 */
982static void 982static void
983xtrlnkfile(char *buf, long size) 983xtrlnkfile(char *buf, long size)
984{ 984{
985 985
986 pathlen += size; 986 pathlen += size;
987 if (pathlen > MAXPATHLEN) { 987 if (pathlen > MAXPATHLEN) {
988 fprintf(stderr, "symbolic link name: %s->%s%s; too long %d\n", 988 fprintf(stderr, "symbolic link name: %s->%s%s; too long %d\n",
989 curfile.name, lnkbuf, buf, pathlen); 989 curfile.name, lnkbuf, buf, pathlen);
990 exit(1); 990 exit(1);
991 } 991 }
992 (void) strcat(lnkbuf, buf); 992 (void) strcat(lnkbuf, buf);
993} 993}
994 994
995/* 995/*
996 * Skip over a hole in a symbolic link (should never happen). 996 * Skip over a hole in a symbolic link (should never happen).
997 */ 997 */
998/* ARGSUSED */ 998/* ARGSUSED */
999static void 999static void
1000xtrlnkskip(char *buf __unused, long size __unused) 1000xtrlnkskip(char *buf __unused, long size __unused)
1001{ 1001{
1002 1002
1003 fprintf(stderr, "unallocated block in symbolic link %s\n", 1003 fprintf(stderr, "unallocated block in symbolic link %s\n",
1004 curfile.name); 1004 curfile.name);
1005 exit(1); 1005 exit(1);
1006} 1006}
1007 1007
1008/* 1008/*
1009 * Noop, when an extraction function is not needed. 1009 * Noop, when an extraction function is not needed.
1010 */ 1010 */
1011/* ARGSUSED */ 1011/* ARGSUSED */
1012void 1012void
1013xtrnull(char *buf __unused, long size __unused) 1013xtrnull(char *buf __unused, long size __unused)
1014{ 1014{
1015 1015
1016 return; 1016 return;
1017} 1017}
1018 1018
1019/* 1019/*
1020 * Read TP_BSIZE blocks from the input. 1020 * Read TP_BSIZE blocks from the input.
1021 * Handle read errors, and end of media. 1021 * Handle read errors, and end of media.
1022 */ 1022 */
1023static void 1023static void
1024readtape(char *buf) 1024readtape(char *buf)
1025{ 1025{
1026 int rd, newvol, i; 1026 int rd, newvol, i;
1027 int cnt, seek_failed; 1027 int cnt, seek_failed;
1028 1028
1029 if (blkcnt < numtrec) { 1029 if (blkcnt < numtrec) {
1030 memmove(buf, &tapebuf[(blkcnt++ * TP_BSIZE)], (long)TP_BSIZE); 1030 memmove(buf, &tapebuf[(blkcnt++ * TP_BSIZE)], (long)TP_BSIZE);
1031 blksread++; 1031 blksread++;
1032 tpblksread++; 1032 tpblksread++;
1033 return; 1033 return;
1034 } 1034 }
1035 for (i = 0; i < ntrec; i++) 1035 for (i = 0; i < ntrec; i++)
1036 ((struct s_spcl *)&tapebuf[i * TP_BSIZE])->c_magic = 0; 1036 ((struct s_spcl *)&tapebuf[i * TP_BSIZE])->c_magic = 0;
1037 if (numtrec == 0) 1037 if (numtrec == 0)
1038 numtrec = ntrec; 1038 numtrec = ntrec;
1039 cnt = ntrec * TP_BSIZE; 1039 cnt = ntrec * TP_BSIZE;
1040 rd = 0; 1040 rd = 0;
1041getmore: 1041getmore:
1042#ifdef RRESTORE 1042#ifdef RRESTORE
1043 if (host) 1043 if (host)
1044 i = rmtread(&tapebuf[rd], cnt); 1044 i = rmtread(&tapebuf[rd], cnt);
1045 else 1045 else
1046#endif 1046#endif
1047 i = read(mt, &tapebuf[rd], cnt); 1047 i = read(mt, &tapebuf[rd], cnt);
1048 /* 1048 /*
1049 * Check for mid-tape short read error. 1049 * Check for mid-tape short read error.
1050 * If found, skip rest of buffer and start with the next. 1050 * If found, skip rest of buffer and start with the next.
1051 */ 1051 */
1052 if (!pipein && numtrec < ntrec && i > 0) { 1052 if (!pipein && numtrec < ntrec && i > 0) {
1053 dprintf(stdout, "mid-media short read error.\n"); 1053 dprintf(stdout, "mid-media short read error.\n");
1054 numtrec = ntrec; 1054 numtrec = ntrec;
1055 } 1055 }
1056 /* 1056 /*
1057 * Handle partial block read. 1057 * Handle partial block read.
1058 */ 1058 */
1059 if (pipein && i == 0 && rd > 0) 1059 if (pipein && i == 0 && rd > 0)
1060 i = rd; 1060 i = rd;
1061 else if (i > 0 && i != ntrec * TP_BSIZE) { 1061 else if (i > 0 && i != ntrec * TP_BSIZE) {
1062 if (pipein) { 1062 if (pipein) {
1063 rd += i; 1063 rd += i;
1064 cnt -= i; 1064 cnt -= i;
1065 if (cnt > 0) 1065 if (cnt > 0)
1066 goto getmore; 1066 goto getmore;
1067 i = rd; 1067 i = rd;
1068 } else { 1068 } else {
1069 /* 1069 /*
1070 * Short read. Process the blocks read. 1070 * Short read. Process the blocks read.
1071 */ 1071 */
1072 if (i % TP_BSIZE != 0) 1072 if (i % TP_BSIZE != 0)
1073 vprintf(stdout, 1073 vprintf(stdout,
1074 "partial block read: %d should be %d\n", 1074 "partial block read: %d should be %d\n",
1075 i, ntrec * TP_BSIZE); 1075 i, ntrec * TP_BSIZE);
1076 numtrec = i / TP_BSIZE; 1076 numtrec = i / TP_BSIZE;
1077 } 1077 }
1078 } 1078 }
1079 /* 1079 /*
1080 * Handle read error. 1080 * Handle read error.
1081 */ 1081 */
1082 if (i < 0) { 1082 if (i < 0) {
1083 fprintf(stderr, "Tape read error while "); 1083 fprintf(stderr, "Tape read error while ");
1084 switch (curfile.action) { 1084 switch (curfile.action) {
1085 default: 1085 default:
1086 fprintf(stderr, "trying to set up tape\n"); 1086 fprintf(stderr, "trying to set up tape\n");
1087 break; 1087 break;
1088 case UNKNOWN: 1088 case UNKNOWN:
1089 fprintf(stderr, "trying to resynchronize\n"); 1089 fprintf(stderr, "trying to resynchronize\n");
1090 break; 1090 break;
1091 case USING: 1091 case USING:
1092 fprintf(stderr, "restoring %s\n", curfile.name); 1092 fprintf(stderr, "restoring %s\n", curfile.name);
1093 break; 1093 break;
1094 case SKIP: 1094 case SKIP:
1095 fprintf(stderr, "skipping over inode %llu\n", 1095 fprintf(stderr, "skipping over inode %llu\n",
1096 (unsigned long long)curfile.ino); 1096 (unsigned long long)curfile.ino);
1097 break; 1097 break;
1098 } 1098 }
1099 if (!yflag && !reply("continue")) 1099 if (!yflag && !reply("continue"))
1100 exit(1); 1100 exit(1);
1101 i = ntrec * TP_BSIZE; 1101 i = ntrec * TP_BSIZE;
1102 memset(tapebuf, 0, i); 1102 memset(tapebuf, 0, i);
1103#ifdef RRESTORE 1103#ifdef RRESTORE
1104 if (host) 1104 if (host)
1105 seek_failed = (rmtseek(i, 1) < 0); 1105 seek_failed = (rmtseek(i, 1) < 0);
1106 else 1106 else
1107#endif 1107#endif
1108 seek_failed = (lseek(mt, i, SEEK_CUR) == (off_t)-1); 1108 seek_failed = (lseek(mt, i, SEEK_CUR) == (off_t)-1);
1109 1109
1110 if (seek_failed) { 1110 if (seek_failed) {
1111 fprintf(stderr, 1111 fprintf(stderr,
1112 "continuation failed: %s\n", strerror(errno)); 1112 "continuation failed: %s\n", strerror(errno));
1113 exit(1); 1113 exit(1);
1114 } 1114 }
1115 } 1115 }
1116 /* 1116 /*
1117 * Handle end of tape. 1117 * Handle end of tape.
1118 */ 1118 */
1119 if (i == 0) { 1119 if (i == 0) {
1120 vprintf(stdout, "End-of-tape encountered\n"); 1120 vprintf(stdout, "End-of-tape encountered\n");
1121 if (!pipein) { 1121 if (!pipein) {
1122 newvol = volno + 1; 1122 newvol = volno + 1;
1123 volno = 0; 1123 volno = 0;
1124 numtrec = 0; 1124 numtrec = 0;
1125 getvol(newvol); 1125 getvol(newvol);
1126 readtape(buf); 1126 readtape(buf);
1127 return; 1127 return;
1128 } 1128 }
1129 if (rd % TP_BSIZE != 0) 1129 if (rd % TP_BSIZE != 0)
1130 panic("partial block read: %d should be %d\n", 1130 panic("partial block read: %d should be %d\n",
1131 rd, ntrec * TP_BSIZE); 1131 rd, ntrec * TP_BSIZE);
1132 terminateinput(); 1132 terminateinput();
1133 memmove(&tapebuf[rd], &endoftapemark, (long)TP_BSIZE); 1133 memmove(&tapebuf[rd], &endoftapemark, (long)TP_BSIZE);
1134 } 1134 }
1135 blkcnt = 0; 1135 blkcnt = 0;
1136 memmove(buf, &tapebuf[(blkcnt++ * TP_BSIZE)], (long)TP_BSIZE); 1136 memmove(buf, &tapebuf[(blkcnt++ * TP_BSIZE)], (long)TP_BSIZE);
1137 blksread++; 1137 blksread++;
1138 tpblksread++; 1138 tpblksread++;
1139} 1139}
1140 1140
1141static void 1141static void
1142findtapeblksize(void) 1142findtapeblksize(void)
1143{ 1143{
1144 long i; 1144 long i;
1145 1145
1146 for (i = 0; i < ntrec; i++) 1146 for (i = 0; i < ntrec; i++)
1147 ((struct s_spcl *)&tapebuf[i * TP_BSIZE])->c_magic = 0; 1147 ((struct s_spcl *)&tapebuf[i * TP_BSIZE])->c_magic = 0;
1148 blkcnt = 0; 1148 blkcnt = 0;
1149#ifdef RRESTORE 1149#ifdef RRESTORE
1150 if (host) 1150 if (host)
1151 i = rmtread(tapebuf, ntrec * TP_BSIZE); 1151 i = rmtread(tapebuf, ntrec * TP_BSIZE);
1152 else 1152 else
1153#endif 1153#endif
1154 i = read(mt, tapebuf, ntrec * TP_BSIZE); 1154 i = read(mt, tapebuf, ntrec * TP_BSIZE);
1155 1155
1156 if (i <= 0) { 1156 if (i <= 0) {
1157 fprintf(stderr, "tape read error: %s\n", strerror(errno)); 1157 fprintf(stderr, "tape read error: %s\n", strerror(errno));
1158 exit(1); 1158 exit(1);
1159 } 1159 }
1160 if (i % TP_BSIZE != 0) { 1160 if (i % TP_BSIZE != 0) {
1161 fprintf(stderr, "Tape block size (%ld) %s (%ld)\n", 1161 fprintf(stderr, "Tape block size (%ld) %s (%ld)\n",
1162 (long)i, "is not a multiple of dump block size", 1162 (long)i, "is not a multiple of dump block size",
1163 (long)TP_BSIZE); 1163 (long)TP_BSIZE);
1164 exit(1); 1164 exit(1);
1165 } 1165 }
1166 ntrec = i / TP_BSIZE; 1166 ntrec = i / TP_BSIZE;
1167 numtrec = ntrec; 1167 numtrec = ntrec;
1168 vprintf(stdout, "Tape block size is %d\n", ntrec); 1168 vprintf(stdout, "Tape block size is %d\n", ntrec);
1169} 1169}
1170 1170
1171void 1171void
1172closemt(void) 1172closemt(void)
1173{ 1173{
1174 1174
1175 if (mt < 0) 1175 if (mt < 0)
1176 return; 1176 return;
1177#ifdef RRESTORE 1177#ifdef RRESTORE
1178 if (host) 1178 if (host)
1179 rmtclose(); 1179 rmtclose();
1180 else 1180 else
1181#endif 1181#endif
1182 (void) close(mt); 1182 (void) close(mt);
1183} 1183}
1184 1184
1185/* 1185/*
1186 * Read the next block from the tape. 1186 * Read the next block from the tape.
1187 * Check to see if it is one of several vintage headers. 1187 * Check to see if it is one of several vintage headers.
1188 * If it is an old style header, convert it to a new style header. 1188 * If it is an old style header, convert it to a new style header.
1189 * If it is not any valid header, return an error. 1189 * If it is not any valid header, return an error.
1190 */ 1190 */
1191static int 1191static int
1192gethead(struct s_spcl *buf) 1192gethead(struct s_spcl *buf)
1193{ 1193{
1194 union u_ospcl u_ospcl; 1194 union u_ospcl u_ospcl;
1195 1195
1196 if (!cvtflag) { 1196 if (!cvtflag) {
1197 readtape((char *)buf); 1197 readtape((char *)buf);
1198 if (buf->c_magic != NFS_MAGIC && 1198 if (buf->c_magic != NFS_MAGIC &&
1199 buf->c_magic != FS_UFS2_MAGIC) { 1199 buf->c_magic != FS_UFS2_MAGIC) {
1200 if (bswap32(buf->c_magic) != NFS_MAGIC && 1200 if (bswap32(buf->c_magic) != NFS_MAGIC &&
1201 bswap32(buf->c_magic) != FS_UFS2_MAGIC) 1201 bswap32(buf->c_magic) != FS_UFS2_MAGIC)
1202 return (FAIL); 1202 return (FAIL);
1203 if (!Bcvt) { 1203 if (!Bcvt) {
1204 vprintf(stdout, "Note: Doing Byte swapping\n"); 1204 vprintf(stdout, "Note: Doing Byte swapping\n");
1205 Bcvt = 1; 1205 Bcvt = 1;
1206 } 1206 }
1207 } 1207 }
1208 if (checksum((int *)buf) == FAIL) 1208 if (checksum((int *)buf) == FAIL)
1209 return (FAIL); 1209 return (FAIL);
1210 if (Bcvt) 1210 if (Bcvt)
1211 swap_header(buf); 1211 swap_header(buf);
1212 goto good; 1212 goto good;
1213 } 1213 }
1214 1214
1215 readtape((char *)(&u_ospcl.s_ospcl)); 1215 readtape((char *)(&u_ospcl.s_ospcl));
1216 if (checksum((int *)(&u_ospcl.s_ospcl)) == FAIL) 1216 if (checksum((int *)(&u_ospcl.s_ospcl)) == FAIL)
1217 return (FAIL); 1217 return (FAIL);
1218 if (u_ospcl.s_ospcl.c_magic != OFS_MAGIC) { 1218 if (u_ospcl.s_ospcl.c_magic != OFS_MAGIC) {
1219 if (bswap32(u_ospcl.s_ospcl.c_magic) != OFS_MAGIC) 1219 if (bswap32(u_ospcl.s_ospcl.c_magic) != OFS_MAGIC)
1220 return (FAIL); 1220 return (FAIL);
1221 if (!Bcvt) { 1221 if (!Bcvt) {
1222 vprintf(stdout, "Note: Doing Byte swapping\n"); 1222 vprintf(stdout, "Note: Doing Byte swapping\n");
1223 Bcvt = 1; 1223 Bcvt = 1;
1224 } 1224 }
1225 swap_old_header(&u_ospcl.s_ospcl); 1225 swap_old_header(&u_ospcl.s_ospcl);
1226 } 1226 }
1227 1227
1228 memset(buf, 0, TP_BSIZE); 1228 memset(buf, 0, TP_BSIZE);
1229 buf->c_type = u_ospcl.s_ospcl.c_type; 1229 buf->c_type = u_ospcl.s_ospcl.c_type;
1230 buf->c_date = u_ospcl.s_ospcl.c_date; 1230 buf->c_date = u_ospcl.s_ospcl.c_date;
1231 buf->c_ddate = u_ospcl.s_ospcl.c_ddate; 1231 buf->c_ddate = u_ospcl.s_ospcl.c_ddate;
1232 buf->c_volume = u_ospcl.s_ospcl.c_volume; 1232 buf->c_volume = u_ospcl.s_ospcl.c_volume;
1233 buf->c_tapea = u_ospcl.s_ospcl.c_tapea; 1233 buf->c_tapea = u_ospcl.s_ospcl.c_tapea;
1234 buf->c_inumber = u_ospcl.s_ospcl.c_inumber; 1234 buf->c_inumber = u_ospcl.s_ospcl.c_inumber;
1235 buf->c_checksum = u_ospcl.s_ospcl.c_checksum; 1235 buf->c_checksum = u_ospcl.s_ospcl.c_checksum;
1236 buf->c_mode = u_ospcl.s_ospcl.c_odinode.odi_mode; 1236 buf->c_mode = u_ospcl.s_ospcl.c_odinode.odi_mode;
1237 buf->c_uid = u_ospcl.s_ospcl.c_odinode.odi_uid; 1237 buf->c_uid = u_ospcl.s_ospcl.c_odinode.odi_uid;
1238 buf->c_gid = u_ospcl.s_ospcl.c_odinode.odi_gid; 1238 buf->c_gid = u_ospcl.s_ospcl.c_odinode.odi_gid;
1239 buf->c_size = u_ospcl.s_ospcl.c_odinode.odi_size; 1239 buf->c_size = u_ospcl.s_ospcl.c_odinode.odi_size;
1240 buf->c_rdev = u_ospcl.s_ospcl.c_odinode.odi_rdev; 1240 buf->c_rdev = u_ospcl.s_ospcl.c_odinode.odi_rdev;
1241 buf->c_atime = u_ospcl.s_ospcl.c_odinode.odi_atime; 1241 buf->c_atime = u_ospcl.s_ospcl.c_odinode.odi_atime;
1242 buf->c_mtime = u_ospcl.s_ospcl.c_odinode.odi_mtime; 1242 buf->c_mtime = u_ospcl.s_ospcl.c_odinode.odi_mtime;
1243 buf->c_count = u_ospcl.s_ospcl.c_count; 1243 buf->c_count = u_ospcl.s_ospcl.c_count;
1244 memmove(buf->c_addr, u_ospcl.s_ospcl.c_addr, (long)256); 1244 memmove(buf->c_addr, u_ospcl.s_ospcl.c_addr, (long)256);
1245 buf->c_magic = FS_UFS2_MAGIC; 1245 buf->c_magic = FS_UFS2_MAGIC;
1246good: 1246good:
1247 switch (buf->c_type) { 1247 switch (buf->c_type) {
1248 1248
1249 case TS_CLRI: 1249 case TS_CLRI:
1250 case TS_BITS: 1250 case TS_BITS:
1251 /* 1251 /*
1252 * Have to patch up missing information in bit map headers 1252 * Have to patch up missing information in bit map headers
1253 */ 1253 */
1254 buf->c_inumber = 0; 1254 buf->c_inumber = 0;
1255 buf->c_size = buf->c_count * TP_BSIZE; 1255 buf->c_size = buf->c_count * TP_BSIZE;
1256 break; 1256 break;
1257 1257
1258 case TS_TAPE: 1258 case TS_TAPE:
1259 if ((buf->c_flags & DR_NEWINODEFMT) == 0) 1259 if ((buf->c_flags & DR_NEWINODEFMT) == 0)
1260 oldinofmt = 1; 1260 oldinofmt = 1;
1261 /* fall through */ 1261 /* fall through */
1262 case TS_END: 1262 case TS_END:
1263 buf->c_inumber = 0; 1263 buf->c_inumber = 0;
1264 break; 1264 break;
1265 1265
1266 case TS_INODE: 1266 case TS_INODE:
1267 if (buf->c_magic == NFS_MAGIC) { 1267 if (buf->c_magic == NFS_MAGIC) {
1268 buf->c_tapea = buf->c_old_tapea; 1268 buf->c_tapea = buf->c_old_tapea;
1269 buf->c_firstrec = buf->c_old_firstrec; 1269 buf->c_firstrec = buf->c_old_firstrec;
1270 buf->c_date = buf->c_old_date; 1270 buf->c_date = buf->c_old_date;
1271 buf->c_ddate = buf->c_old_ddate; 1271 buf->c_ddate = buf->c_old_ddate;
1272 buf->c_atime = buf->c_old_atime; 1272 buf->c_atime = buf->c_old_atime;
1273 buf->c_mtime = buf->c_old_mtime; 1273 buf->c_mtime = buf->c_old_mtime;
1274 buf->c_birthtime = 0; 1274 buf->c_birthtime = 0;
1275 buf->c_birthtimensec = 0; 1275 buf->c_birthtimensec = 0;
1276 buf->c_atimensec = buf->c_mtimensec = 0; 1276 buf->c_atimensec = buf->c_mtimensec = 0;
1277 } 1277 }
1278  1278
1279 case TS_ADDR: 1279 case TS_ADDR:
1280 break; 1280 break;
1281 1281
1282 default: 1282 default:
1283 panic("gethead: unknown inode type %d\n", buf->c_type); 1283 panic("gethead: unknown inode type %d\n", buf->c_type);
1284 break; 1284 break;
1285 } 1285 }
1286 1286
1287 buf->c_magic = FS_UFS2_MAGIC; 1287 buf->c_magic = FS_UFS2_MAGIC;
1288 1288
1289 /* 1289 /*
1290 * If we are restoring a filesystem with old format inodes,  1290 * If we are restoring a filesystem with old format inodes,
1291 * copy the uid/gid to the new location. 1291 * copy the uid/gid to the new location.
1292 */ 1292 */
1293 if (oldinofmt) { 1293 if (oldinofmt) {
1294 buf->c_uid = buf->c_spare1[1]; 1294 buf->c_uid = buf->c_spare1[1];
1295 buf->c_gid = buf->c_spare1[2]; 1295 buf->c_gid = buf->c_spare1[2];
1296 } 1296 }
1297 if (dflag) 1297 if (dflag)
1298 accthdr(buf); 1298 accthdr(buf);
1299 return(GOOD); 1299 return(GOOD);
1300} 1300}
1301 1301
1302/* 1302/*
1303 * Check that a header is where it belongs and predict the next header 1303 * Check that a header is where it belongs and predict the next header
1304 */ 1304 */
1305static void 1305static void
1306accthdr(struct s_spcl *header) 1306accthdr(struct s_spcl *header)
1307{ 1307{
1308 static ino_t previno = 0x7fffffff; 1308 static ino_t previno = 0x7fffffff;
1309 static int prevtype; 1309 static int prevtype;
1310 static long predict; 1310 static long predict;
1311 long blks, i; 1311 long blks, i;
1312 1312
1313 if (header->c_type == TS_TAPE) { 1313 if (header->c_type == TS_TAPE) {
1314 fprintf(stderr, "Volume header (%s inode format) ", 1314 fprintf(stderr, "Volume header (%s inode format) ",
1315 oldinofmt ? "old" : "new"); 1315 oldinofmt ? "old" : "new");
1316 if (header->c_firstrec) 1316 if (header->c_firstrec)
1317 fprintf(stderr, "begins with record %lld", 1317 fprintf(stderr, "begins with record %lld",
1318 (long long)header->c_firstrec); 1318 (long long)header->c_firstrec);
1319 fprintf(stderr, "\n"); 1319 fprintf(stderr, "\n");
1320 previno = 0x7fffffff; 1320 previno = 0x7fffffff;
1321 return; 1321 return;
1322 } 1322 }
1323 if (previno == 0x7fffffff) 1323 if (previno == 0x7fffffff)
1324 goto newcalc; 1324 goto newcalc;
1325 switch (prevtype) { 1325 switch (prevtype) {
1326 case TS_BITS: 1326 case TS_BITS:
1327 fprintf(stderr, "Dumped inodes map header"); 1327 fprintf(stderr, "Dumped inodes map header");
1328 break; 1328 break;
1329 case TS_CLRI: 1329 case TS_CLRI:
1330 fprintf(stderr, "Used inodes map header"); 1330 fprintf(stderr, "Used inodes map header");
1331 break; 1331 break;
1332 case TS_INODE: 1332 case TS_INODE:
1333 fprintf(stderr, "File header, ino %llu", 1333 fprintf(stderr, "File header, ino %llu",
1334 (unsigned long long)previno); 1334 (unsigned long long)previno);
1335 break; 1335 break;
1336 case TS_ADDR: 1336 case TS_ADDR:
1337 fprintf(stderr, "File continuation header, ino %llu", 1337 fprintf(stderr, "File continuation header, ino %llu",
1338 (unsigned long long)previno); 1338 (unsigned long long)previno);
1339 break; 1339 break;
1340 case TS_END: 1340 case TS_END:
1341 fprintf(stderr, "End of tape header"); 1341 fprintf(stderr, "End of tape header");
1342 break; 1342 break;
1343 } 1343 }
1344 if (predict != blksread - 1) 1344 if (predict != blksread - 1)
1345 fprintf(stderr, "; predicted %ld blocks, got %ld blocks", 1345 fprintf(stderr, "; predicted %ld blocks, got %ld blocks",
1346 (long)predict, (long)(blksread - 1)); 1346 (long)predict, (long)(blksread - 1));
1347 fprintf(stderr, "\n"); 1347 fprintf(stderr, "\n");
1348newcalc: 1348newcalc:
1349 blks = 0; 1349 blks = 0;
1350 switch (header->c_type) { 1350 switch (header->c_type) {
1351 case TS_END: 1351 case TS_END:
1352 break; 1352 break;
1353 case TS_CLRI: 1353 case TS_CLRI:
1354 case TS_BITS: 1354 case TS_BITS:
1355 blks = header->c_count; 1355 blks = header->c_count;
1356 break; 1356 break;
1357 default: 1357 default:
1358 for (i = 0; i < header->c_count; i++) 1358 for (i = 0; i < header->c_count; i++)
1359 if (header->c_addr[i] != 0) 1359 if (header->c_addr[i] != 0)
1360 blks++; 1360 blks++;
1361 break; 1361 break;
1362 } 1362 }
1363 predict = blks; 1363 predict = blks;
1364 blksread = 0; 1364 blksread = 0;
1365 prevtype = header->c_type; 1365 prevtype = header->c_type;
1366 previno = header->c_inumber; 1366 previno = header->c_inumber;
1367} 1367}
1368 1368
1369/* 1369/*
1370 * Find an inode header. 1370 * Find an inode header.
1371 * Complain if had to skip, and complain is set. 1371 * Complain if had to skip, and complain is set.
1372 */ 1372 */
1373static void 1373static void
1374findinode(struct s_spcl *header) 1374findinode(struct s_spcl *header)
1375{ 1375{
1376 static long skipcnt = 0; 1376 static long skipcnt = 0;
1377 long i; 1377 long i;
1378 char buf[TP_BSIZE]; 1378 char buf[TP_BSIZE];
1379 1379
1380 curfile.name = "<name unknown>"; 1380 curfile.name = "<name unknown>";
1381 curfile.action = UNKNOWN; 1381 curfile.action = UNKNOWN;
1382 curfile.mode = 0; 1382 curfile.mode = 0;
1383 curfile.ino = 0; 1383 curfile.ino = 0;
1384 top: 1384 top:
1385 do { 1385 do {
1386 if (header->c_magic != FS_UFS2_MAGIC) { 1386 if (header->c_magic != FS_UFS2_MAGIC) {
1387skip: 1387skip:
1388 skipcnt++; 1388 skipcnt++;
1389 while (gethead(header) == FAIL || 1389 while (gethead(header) == FAIL ||
1390 header->c_date != dumpdate) 1390 header->c_date != dumpdate)
1391 skipcnt++; 1391 skipcnt++;
1392 } 1392 }
1393 switch (header->c_type) { 1393 switch (header->c_type) {
1394 1394
1395 case TS_ADDR: 1395 case TS_ADDR:
1396 /* 1396 /*
1397 * Skip up to the beginning of the next record 1397 * Skip up to the beginning of the next record
1398 */ 1398 */
1399 for (i = 0; i < header->c_count; i++) 1399 for (i = 0; i < header->c_count; i++)
1400 if (header->c_addr[i]) 1400 if (header->c_addr[i])
1401 readtape(buf); 1401 readtape(buf);
1402 while (gethead(header) == FAIL || 1402 while (gethead(header) == FAIL ||
1403 header->c_date != dumpdate) 1403 header->c_date != dumpdate)
1404 skipcnt++; 1404 skipcnt++;
1405 /* We've read a header; don't drop it. */ 1405 /* We've read a header; don't drop it. */
1406 goto top; 1406 goto top;
1407 1407
1408 case TS_INODE: 1408 case TS_INODE:
1409 curfile.mode = header->c_mode; 1409 curfile.mode = header->c_mode;
1410 curfile.uid = header->c_uid; 1410 curfile.uid = header->c_uid;
1411 curfile.gid = header->c_gid; 1411 curfile.gid = header->c_gid;
1412 curfile.file_flags = header->c_file_flags; 1412 curfile.file_flags = header->c_file_flags;
1413 curfile.rdev = header->c_rdev; 1413 curfile.rdev = header->c_rdev;
1414 curfile.atime_sec = header->c_atime; 1414 curfile.atime_sec = header->c_atime;
1415 curfile.atime_nsec = header->c_atimensec; 1415 curfile.atime_nsec = header->c_atimensec;
1416 curfile.mtime_sec = header->c_mtime; 1416 curfile.mtime_sec = header->c_mtime;
1417 curfile.mtime_nsec = header->c_mtimensec; 1417 curfile.mtime_nsec = header->c_mtimensec;
1418 curfile.birthtime_sec = header->c_birthtime; 1418 curfile.birthtime_sec = header->c_birthtime;
1419 curfile.birthtime_nsec = header->c_birthtimensec; 1419 curfile.birthtime_nsec = header->c_birthtimensec;
1420 curfile.size = header->c_size; 1420 curfile.size = header->c_size;
1421 curfile.ino = header->c_inumber; 1421 curfile.ino = header->c_inumber;
1422 break; 1422 break;
1423 1423
1424 case TS_END: 1424 case TS_END:
1425 curfile.ino = maxino; 1425 curfile.ino = maxino;
1426 break; 1426 break;
1427 1427
1428 case TS_CLRI: 1428 case TS_CLRI:
1429 curfile.name = "<file removal list>"; 1429 curfile.name = "<file removal list>";
1430 break; 1430 break;
1431 1431
1432 case TS_BITS: 1432 case TS_BITS:
1433 curfile.name = "<file dump list>"; 1433 curfile.name = "<file dump list>";
1434 break; 1434 break;
1435 1435
1436 case TS_TAPE: 1436 case TS_TAPE:
1437 panic("unexpected tape header\n"); 1437 panic("unexpected tape header\n");
1438 break; 1438 break;
1439 1439
1440 default: 1440 default:
1441 panic("unknown tape header type %d\n", spcl.c_type); 1441 panic("unknown tape header type %d\n", spcl.c_type);
1442 fprintf(stderr, "skiping to next header\n"); 1442 fprintf(stderr, "skipping to next header\n");
1443 goto skip; 1443 goto skip;
1444 1444
1445 } 1445 }
1446 } while (header->c_type == TS_ADDR); 1446 } while (header->c_type == TS_ADDR);
1447 if (skipcnt > 0) 1447 if (skipcnt > 0)
1448 fprintf(stderr, "resync restore, skipped %ld blocks\n", 1448 fprintf(stderr, "resync restore, skipped %ld blocks\n",
1449 (long)skipcnt); 1449 (long)skipcnt);
1450 skipcnt = 0; 1450 skipcnt = 0;
1451} 1451}
1452 1452
1453static int 1453static int
1454checksum(int *buf) 1454checksum(int *buf)
1455{ 1455{
1456 int i, j; 1456 int i, j;
1457 1457
1458 j = sizeof(union u_spcl) / sizeof(int); 1458 j = sizeof(union u_spcl) / sizeof(int);
1459 i = 0; 1459 i = 0;
1460 if(!Bcvt) { 1460 if(!Bcvt) {
1461 do 1461 do
1462 i += *buf++; 1462 i += *buf++;
1463 while (--j); 1463 while (--j);
1464 } else { 1464 } else {
1465 do  1465 do
1466 i += bswap32(*buf++); 1466 i += bswap32(*buf++);
1467 while (--j); 1467 while (--j);
1468 } 1468 }
1469  1469
1470 if (i != CHECKSUM) { 1470 if (i != CHECKSUM) {
1471 fprintf(stderr, "Checksum error %o, inode %llu file %s\n", i, 1471 fprintf(stderr, "Checksum error %o, inode %llu file %s\n", i,
1472 (unsigned long long)curfile.ino, curfile.name); 1472 (unsigned long long)curfile.ino, curfile.name);
1473 return(FAIL); 1473 return(FAIL);
1474 } 1474 }
1475 return(GOOD); 1475 return(GOOD);
1476} 1476}
1477 1477
1478#ifdef RRESTORE 1478#ifdef RRESTORE
1479#include <stdarg.h> 1479#include <stdarg.h>
1480 1480
1481void 1481void
1482msg(const char *fmt, ...) 1482msg(const char *fmt, ...)
1483{ 1483{
1484 va_list ap; 1484 va_list ap;
1485 1485
1486 va_start(ap, fmt); 1486 va_start(ap, fmt);
1487 (void)vfprintf(stderr, fmt, ap); 1487 (void)vfprintf(stderr, fmt, ap);
1488 va_end(ap); 1488 va_end(ap);
1489} 1489}
1490#endif /* RRESTORE */ 1490#endif /* RRESTORE */
1491 1491
1492static void 1492static void
1493swap_header(struct s_spcl *s) 1493swap_header(struct s_spcl *s)
1494{ 1494{
1495 s->c_type = bswap32(s->c_type); 1495 s->c_type = bswap32(s->c_type);
1496 s->c_old_date = bswap32(s->c_old_date); 1496 s->c_old_date = bswap32(s->c_old_date);
1497 s->c_old_ddate = bswap32(s->c_old_ddate); 1497 s->c_old_ddate = bswap32(s->c_old_ddate);
1498 s->c_volume = bswap32(s->c_volume); 1498 s->c_volume = bswap32(s->c_volume);
1499 s->c_old_tapea = bswap32(s->c_old_tapea); 1499 s->c_old_tapea = bswap32(s->c_old_tapea);
1500 s->c_inumber = bswap32(s->c_inumber); 1500 s->c_inumber = bswap32(s->c_inumber);
1501 s->c_magic = bswap32(s->c_magic); 1501 s->c_magic = bswap32(s->c_magic);
1502 s->c_checksum = bswap32(s->c_checksum); 1502 s->c_checksum = bswap32(s->c_checksum);
1503 1503
1504 s->c_mode = bswap16(s->c_mode); 1504 s->c_mode = bswap16(s->c_mode);
1505 s->c_size = bswap64(s->c_size); 1505 s->c_size = bswap64(s->c_size);
1506 s->c_old_atime = bswap32(s->c_old_atime); 1506 s->c_old_atime = bswap32(s->c_old_atime);
1507 s->c_atimensec = bswap32(s->c_atimensec); 1507 s->c_atimensec = bswap32(s->c_atimensec);
1508 s->c_old_mtime = bswap32(s->c_old_mtime); 1508 s->c_old_mtime = bswap32(s->c_old_mtime);
1509 s->c_mtimensec = bswap32(s->c_mtimensec); 1509 s->c_mtimensec = bswap32(s->c_mtimensec);
1510 s->c_rdev = bswap32(s->c_rdev); 1510 s->c_rdev = bswap32(s->c_rdev);
1511 s->c_birthtimensec = bswap32(s->c_birthtimensec); 1511 s->c_birthtimensec = bswap32(s->c_birthtimensec);
1512 s->c_birthtime = bswap64(s->c_birthtime); 1512 s->c_birthtime = bswap64(s->c_birthtime);
1513 s->c_atime = bswap64(s->c_atime); 1513 s->c_atime = bswap64(s->c_atime);
1514 s->c_mtime = bswap64(s->c_mtime); 1514 s->c_mtime = bswap64(s->c_mtime);
1515 s->c_file_flags = bswap32(s->c_file_flags); 1515 s->c_file_flags = bswap32(s->c_file_flags);
1516 s->c_uid = bswap32(s->c_uid); 1516 s->c_uid = bswap32(s->c_uid);
1517 s->c_gid = bswap32(s->c_gid); 1517 s->c_gid = bswap32(s->c_gid);
1518 1518
1519 s->c_count = bswap32(s->c_count); 1519 s->c_count = bswap32(s->c_count);
1520 s->c_level = bswap32(s->c_level); 1520 s->c_level = bswap32(s->c_level);
1521 s->c_flags = bswap32(s->c_flags); 1521 s->c_flags = bswap32(s->c_flags);
1522 s->c_old_firstrec = bswap32(s->c_old_firstrec); 1522 s->c_old_firstrec = bswap32(s->c_old_firstrec);
1523 1523
1524 s->c_date = bswap64(s->c_date); 1524 s->c_date = bswap64(s->c_date);
1525 s->c_ddate = bswap64(s->c_ddate); 1525 s->c_ddate = bswap64(s->c_ddate);
1526 s->c_tapea = bswap64(s->c_tapea); 1526 s->c_tapea = bswap64(s->c_tapea);
1527 s->c_firstrec = bswap64(s->c_firstrec); 1527 s->c_firstrec = bswap64(s->c_firstrec);
1528 1528
1529 /* 1529 /*
1530 * These are ouid and ogid. 1530 * These are ouid and ogid.
1531 */ 1531 */
1532 s->c_spare1[1] = bswap16(s->c_spare1[1]); 1532 s->c_spare1[1] = bswap16(s->c_spare1[1]);
1533 s->c_spare1[2] = bswap16(s->c_spare1[2]); 1533 s->c_spare1[2] = bswap16(s->c_spare1[2]);
1534} 1534}
1535 1535
1536static void 1536static void
1537swap_old_header(struct s_ospcl *os) 1537swap_old_header(struct s_ospcl *os)
1538{ 1538{
1539 os->c_type = bswap32(os->c_type); 1539 os->c_type = bswap32(os->c_type);
1540 os->c_date = bswap32(os->c_date); 1540 os->c_date = bswap32(os->c_date);
1541 os->c_ddate = bswap32(os->c_ddate); 1541 os->c_ddate = bswap32(os->c_ddate);
1542 os->c_volume = bswap32(os->c_volume); 1542 os->c_volume = bswap32(os->c_volume);
1543 os->c_tapea = bswap32(os->c_tapea); 1543 os->c_tapea = bswap32(os->c_tapea);
1544 os->c_inumber = bswap16(os->c_inumber); 1544 os->c_inumber = bswap16(os->c_inumber);
1545 os->c_magic = bswap32(os->c_magic); 1545 os->c_magic = bswap32(os->c_magic);
1546 os->c_checksum = bswap32(os->c_checksum); 1546 os->c_checksum = bswap32(os->c_checksum);
1547 1547
1548 os->c_odinode.odi_mode = bswap16(os->c_odinode.odi_mode); 1548 os->c_odinode.odi_mode = bswap16(os->c_odinode.odi_mode);
1549 os->c_odinode.odi_nlink = bswap16(os->c_odinode.odi_nlink); 1549 os->c_odinode.odi_nlink = bswap16(os->c_odinode.odi_nlink);
1550 os->c_odinode.odi_uid = bswap16(os->c_odinode.odi_uid); 1550 os->c_odinode.odi_uid = bswap16(os->c_odinode.odi_uid);
1551 os->c_odinode.odi_gid = bswap16(os->c_odinode.odi_gid); 1551 os->c_odinode.odi_gid = bswap16(os->c_odinode.odi_gid);
1552 1552
1553 os->c_odinode.odi_size = bswap32(os->c_odinode.odi_size); 1553 os->c_odinode.odi_size = bswap32(os->c_odinode.odi_size);
1554 os->c_odinode.odi_rdev = bswap32(os->c_odinode.odi_rdev); 1554 os->c_odinode.odi_rdev = bswap32(os->c_odinode.odi_rdev);
1555 os->c_odinode.odi_atime = bswap32(os->c_odinode.odi_atime); 1555 os->c_odinode.odi_atime = bswap32(os->c_odinode.odi_atime);
1556 os->c_odinode.odi_mtime = bswap32(os->c_odinode.odi_mtime); 1556 os->c_odinode.odi_mtime = bswap32(os->c_odinode.odi_mtime);
1557 os->c_odinode.odi_ctime = bswap32(os->c_odinode.odi_ctime); 1557 os->c_odinode.odi_ctime = bswap32(os->c_odinode.odi_ctime);
1558 1558
1559 os->c_count = bswap32(os->c_count); 1559 os->c_count = bswap32(os->c_count);
1560} 1560}