2 * Copyright (c) 2007 Kai Wang
3 * Copyright (c) 2007 Tim Kientzle
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer
11 * in this position and unchanged.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 #include <sys/cdefs.h>
29 __FBSDID("$FreeBSD$");
31 #include <sys/queue.h>
34 #include <archive_entry.h>
43 static void read_archive(struct bsdar
*bsdar
, char mode
);
46 ar_mode_p(struct bsdar
*bsdar
)
49 read_archive(bsdar
, 'p');
53 ar_mode_t(struct bsdar
*bsdar
)
56 read_archive(bsdar
, 't');
60 ar_mode_x(struct bsdar
*bsdar
)
63 read_archive(bsdar
, 'x');
67 * Handle read modes: 'x', 't' and 'p'.
70 read_archive(struct bsdar
*bsdar
, char mode
)
73 struct archive_entry
*entry
;
88 if ((a
= archive_read_new()) == NULL
)
89 bsdar_errc(bsdar
, EX_SOFTWARE
, 0, "archive_read_new failed");
90 archive_read_support_compression_all(a
);
91 archive_read_support_format_all(a
);
92 AC(archive_read_open_file(a
, bsdar
->filename
, DEF_BLKSZ
));
95 r
= archive_read_next_header(a
, &entry
);
96 if (r
== ARCHIVE_WARN
|| r
== ARCHIVE_RETRY
||
98 bsdar_warnc(bsdar
, 0, "%s", archive_error_string(a
));
99 if (r
== ARCHIVE_EOF
|| r
== ARCHIVE_FATAL
)
101 if (r
== ARCHIVE_RETRY
) {
102 bsdar_warnc(bsdar
, 0, "Retrying...");
106 name
= archive_entry_pathname(entry
);
108 /* Skip pseudo members. */
109 if (strcmp(name
, "/") == 0 || strcmp(name
, "//") == 0)
112 if (bsdar
->argc
> 0) {
114 for(i
= 0; i
< bsdar
->argc
; i
++) {
115 av
= &bsdar
->argv
[i
];
118 if ((bname
= basename(*av
)) == NULL
)
119 bsdar_errc(bsdar
, EX_SOFTWARE
, errno
,
121 if (strcmp(bname
, name
) != 0)
133 if (bsdar
->options
& AR_V
) {
134 md
= archive_entry_mode(entry
);
135 uid
= archive_entry_uid(entry
);
136 gid
= archive_entry_gid(entry
);
137 size
= archive_entry_size(entry
);
138 mtime
= archive_entry_mtime(entry
);
139 (void)strmode(md
, buf
);
140 (void)fprintf(stdout
, "%s %6d/%-6d %8ju ",
141 buf
+ 1, uid
, gid
, (uintmax_t)size
);
142 tp
= localtime(&mtime
);
143 (void)strftime(buf
, sizeof(buf
),
144 "%b %e %H:%M %Y", tp
);
145 (void)fprintf(stdout
, "%s %s", buf
, name
);
147 (void)fprintf(stdout
, "%s", name
);
148 r
= archive_read_data_skip(a
);
149 if (r
== ARCHIVE_WARN
|| r
== ARCHIVE_RETRY
||
150 r
== ARCHIVE_FATAL
) {
151 (void)fprintf(stdout
, "\n");
152 bsdar_warnc(bsdar
, 0, "%s",
153 archive_error_string(a
));
156 if (r
== ARCHIVE_FATAL
)
159 (void)fprintf(stdout
, "\n");
161 /* mode == 'x' || mode = 'p' */
163 if (bsdar
->options
& AR_V
) {
164 (void)fprintf(stdout
, "\n<%s>\n\n",
168 r
= archive_read_data_into_fd(a
, 1);
171 if (stat(name
, &sb
) != 0) {
172 if (errno
!= ENOENT
) {
173 bsdar_warnc(bsdar
, 0,
179 /* stat success, file exist */
180 if (bsdar
->options
& AR_CC
)
182 if (bsdar
->options
& AR_U
&&
183 archive_entry_mtime(entry
) <=
188 if (bsdar
->options
& AR_V
)
189 (void)fprintf(stdout
, "x - %s\n", name
);
191 if (bsdar
->options
& AR_O
)
192 flags
|= ARCHIVE_EXTRACT_TIME
;
194 r
= archive_read_extract(a
, entry
, flags
);
198 bsdar_warnc(bsdar
, 0, "%s",
199 archive_error_string(a
));
202 AC(archive_read_close(a
));
203 AC(archive_read_finish(a
));