From baa953a2a5170d809cecfc08c7711a1e36308412 Mon Sep 17 00:00:00 2001 From: nwhitehorn Date: Sun, 13 Mar 2011 18:23:47 +0000 Subject: Use the manifest file count, if available, to determine the number of files in the archive instead of spinning through it to get a file count for the progress bar. This speeds up installation a lot on systems with slow CD drives. --- usr.sbin/bsdinstall/distextract/distextract.c | 81 ++++++++++++++++++++------- 1 file changed, 62 insertions(+), 19 deletions(-) (limited to 'usr.sbin') diff --git a/usr.sbin/bsdinstall/distextract/distextract.c b/usr.sbin/bsdinstall/distextract/distextract.c index c2c4884..c7eea9d 100644 --- a/usr.sbin/bsdinstall/distextract/distextract.c +++ b/usr.sbin/bsdinstall/distextract/distextract.c @@ -26,6 +26,7 @@ * $FreeBSD$ */ +#include #include #include #include @@ -78,6 +79,63 @@ main(void) } static int +count_files(const char *file) +{ + struct archive *archive; + struct archive_entry *entry; + static FILE *manifest = NULL; + char path[MAXPATHLEN]; + char errormsg[512]; + int file_count, err; + + if (manifest == NULL) { + sprintf(path, "%s/MANIFEST", getenv("BSDINSTALL_DISTDIR")); + manifest = fopen(path, "r"); + } + + if (manifest != NULL) { + char line[512]; + char *tok1, *tok2; + while (fgets(line, sizeof(line), manifest) != NULL) { + tok2 = line; + tok1 = strsep(&tok2, "\t"); + if (tok1 == NULL || strcmp(tok1, file) != 0) + continue; + + /* + * We're at the right manifest line. The file count is + * in the third element + */ + tok1 = strsep(&tok2, "\t"); + tok1 = strsep(&tok2, "\t"); + if (tok1 != NULL) + return atoi(tok1); + } + } + + /* Either we didn't have a manifest, or this archive wasn't there */ + archive = archive_read_new(); + archive_read_support_format_all(archive); + archive_read_support_compression_all(archive); + sprintf(path, "%s/%s", getenv("BSDINSTALL_DISTDIR"), file); + err = archive_read_open_filename(archive, path, 4096); + if (err != ARCHIVE_OK) { + snprintf(errormsg, sizeof(errormsg), + "Error while extracting %s: %s\n", file, + archive_error_string(archive)); + dialog_msgbox("Extract Error", errormsg, 0, 0, TRUE); + return (-1); + } + + file_count = 0; + while (archive_read_next_header(archive, &entry) == ARCHIVE_OK) + file_count++; + archive_read_free(archive); + + return (file_count); +} + +static int extract_files(int nfiles, const char **files) { const char *items[nfiles*2]; @@ -106,28 +164,13 @@ extract_files(int nfiles, const char **files) dialog_msgbox("", "Checking distribution archives.\nPlease wait...", 0, 0, FALSE); - /* Open all the archives */ + /* Count all the files */ total_files = 0; for (i = 0; i < nfiles; i++) { - archive = archive_read_new(); - archive_read_support_format_all(archive); - archive_read_support_compression_all(archive); - sprintf(path, "%s/%s", getenv("BSDINSTALL_DISTDIR"), files[i]); - err = archive_read_open_filename(archive, path, 4096); - if (err != ARCHIVE_OK) { - snprintf(errormsg, sizeof(errormsg), - "Error while extracting %s: %s\n", items[i*2], - archive_error_string(archive)); - items[i*2 + 1] = "Failed"; - dialog_msgbox("Extract Error", errormsg, 0, 0, - TRUE); - return (err); - } - archive_files[i] = 0; - while (archive_read_next_header(archive, &entry) == ARCHIVE_OK) - archive_files[i]++; + archive_files[i] = count_files(files[i]); + if (archive_files[i] < 0) + return (-1); total_files += archive_files[i]; - archive_read_free(archive); } current_files = 0; -- cgit v1.1