bsddialog: convert bsdinstall/distextract
Differential Revision: https://reviews.freebsd.org/D33581
This commit is contained in:
parent
502d5e8500
commit
18f20d5d96
@ -2,7 +2,8 @@
|
||||
|
||||
BINDIR= ${LIBEXECDIR}/bsdinstall
|
||||
PROG= distextract
|
||||
LIBADD= archive dpv dialog m
|
||||
CFLAGS+= -I${SRCTOP}/contrib/bsddialog/lib
|
||||
LIBADD= archive bsddialog m
|
||||
|
||||
MAN=
|
||||
|
||||
|
@ -33,11 +33,12 @@ __FBSDID("$FreeBSD$");
|
||||
#include <sys/param.h>
|
||||
#include <archive.h>
|
||||
#include <ctype.h>
|
||||
#include <dialog.h>
|
||||
#include <dpv.h>
|
||||
#include <bsddialog.h>
|
||||
#include <bsddialog_progressview.h>
|
||||
#include <err.h>
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
#include <signal.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@ -46,30 +47,27 @@ __FBSDID("$FreeBSD$");
|
||||
/* Data to process */
|
||||
static char *distdir = NULL;
|
||||
static struct archive *archive = NULL;
|
||||
static struct dpv_file_node *dists = NULL;
|
||||
|
||||
/* Function prototypes */
|
||||
static void sig_int(int sig);
|
||||
static int count_files(const char *file);
|
||||
static int extract_files(struct dpv_file_node *file, int out);
|
||||
static int extract_files(struct bsddialog_fileminibar *file);
|
||||
|
||||
#define _errx(...) (end_dialog(), errx(__VA_ARGS__))
|
||||
#define _errx(...) (bsddialog_end(), errx(__VA_ARGS__))
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
char *chrootdir;
|
||||
char *distributions;
|
||||
unsigned int i;
|
||||
int retval;
|
||||
size_t config_size = sizeof(struct dpv_config);
|
||||
size_t file_node_size = sizeof(struct dpv_file_node);
|
||||
size_t minibar_size = sizeof(struct bsddialog_fileminibar);
|
||||
size_t span;
|
||||
struct dpv_config *config;
|
||||
struct dpv_file_node *dist = dists;
|
||||
static char backtitle[] = "FreeBSD Installer";
|
||||
static char title[] = "Archive Extraction";
|
||||
static char aprompt[] = "\n Overall Progress:";
|
||||
static char pprompt[] = "Extracting distribution files...\n";
|
||||
unsigned int nminibars;
|
||||
struct bsddialog_fileminibar *dists;
|
||||
struct bsddialog_progviewconf pvconf;
|
||||
struct bsddialog_conf conf;
|
||||
struct sigaction act;
|
||||
char error[PATH_MAX + 512];
|
||||
|
||||
@ -78,17 +76,17 @@ main(void)
|
||||
if ((distdir = getenv("BSDINSTALL_DISTDIR")) == NULL)
|
||||
distdir = __DECONST(char *, "");
|
||||
|
||||
/* Initialize dialog(3) */
|
||||
init_dialog(stdin, stdout);
|
||||
dialog_vars.backtitle = backtitle;
|
||||
dlg_put_backtitle();
|
||||
if (bsddialog_init() == BSDDIALOG_ERROR)
|
||||
errx(EXIT_FAILURE, "Cannot init libbsdialog");
|
||||
bsddialog_initconf(&conf);
|
||||
bsddialog_backtitle(&conf, __DECONST(char *, "FreeBSD Installer"));
|
||||
bsddialog_infobox(&conf,
|
||||
__DECONST(char *, "Checking distribution archives.\n"
|
||||
"Please wait..."), 4, 35);
|
||||
|
||||
dialog_msgbox("",
|
||||
"Checking distribution archives.\nPlease wait...", 4, 35, FALSE);
|
||||
|
||||
/*
|
||||
* Parse $DISTRIBUTIONS into dpv(3) linked-list
|
||||
*/
|
||||
/* Parse $DISTRIBUTIONS */
|
||||
nminibars = 0;
|
||||
dists = NULL;
|
||||
while (*distributions != '\0') {
|
||||
span = strcspn(distributions, "\t\n\v\f\r ");
|
||||
if (span < 1) { /* currently on whitespace */
|
||||
@ -97,36 +95,36 @@ main(void)
|
||||
}
|
||||
|
||||
/* Allocate a new struct for the distribution */
|
||||
if (dist == NULL) {
|
||||
if ((dist = calloc(1, file_node_size)) == NULL)
|
||||
_errx(EXIT_FAILURE, "Out of memory!");
|
||||
dists = dist;
|
||||
} else {
|
||||
dist->next = calloc(1, file_node_size);
|
||||
if (dist->next == NULL)
|
||||
_errx(EXIT_FAILURE, "Out of memory!");
|
||||
dist = dist->next;
|
||||
}
|
||||
|
||||
/* Set path */
|
||||
if ((dist->path = malloc(span + 1)) == NULL)
|
||||
dists = realloc(dists, (nminibars + 1) * minibar_size);
|
||||
if (dists == NULL)
|
||||
_errx(EXIT_FAILURE, "Out of memory!");
|
||||
snprintf(dist->path, span + 1, "%s", distributions);
|
||||
dist->path[span] = '\0';
|
||||
|
||||
/* Set display name */
|
||||
dist->name = strrchr(dist->path, '/');
|
||||
if (dist->name == NULL)
|
||||
dist->name = dist->path;
|
||||
/* Set file path */
|
||||
if ((dists[nminibars].path = malloc(span + 1)) == NULL)
|
||||
_errx(EXIT_FAILURE, "Out of memory!");
|
||||
snprintf(dists[nminibars].path, span + 1, "%s", distributions);
|
||||
dists[nminibars].path[span] = '\0';
|
||||
|
||||
/* Set mini bar label */
|
||||
dists[nminibars].label = strrchr(dists[nminibars].path, '/');
|
||||
if (dists[nminibars].label == NULL)
|
||||
dists[nminibars].label = dists[nminibars].path;
|
||||
|
||||
/* Set initial length in files (-1 == error) */
|
||||
dist->length = count_files(dist->path);
|
||||
if (dist->length < 0) {
|
||||
end_dialog();
|
||||
dists[nminibars].size = count_files(dists[nminibars].path);
|
||||
if (dists[nminibars].size < 0) {
|
||||
bsddialog_end();
|
||||
return (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/* Set initial status to pending */
|
||||
/* dists[nminibars].status = 10; */
|
||||
|
||||
/* Set initial read */
|
||||
dists[nminibars].read = 0;
|
||||
|
||||
distributions += span;
|
||||
nminibars += 1;
|
||||
}
|
||||
|
||||
/* Optionally chdir(2) into $BSDINSTALL_CHROOT */
|
||||
@ -135,8 +133,9 @@ main(void)
|
||||
snprintf(error, sizeof(error),
|
||||
"Could not change to directory %s: %s\n",
|
||||
chrootdir, strerror(errno));
|
||||
dialog_msgbox("Error", error, 0, 0, TRUE);
|
||||
end_dialog();
|
||||
conf.title = __DECONST(char *, "Error");
|
||||
bsddialog_msgbox(&conf, error, 0, 0);
|
||||
bsddialog_end();
|
||||
return (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
@ -144,32 +143,23 @@ main(void)
|
||||
act.sa_handler = sig_int;
|
||||
sigaction(SIGINT, &act, 0);
|
||||
|
||||
/*
|
||||
* Hand off to dpv(3)
|
||||
*/
|
||||
if ((config = calloc(1, config_size)) == NULL)
|
||||
_errx(EXIT_FAILURE, "Out of memory!");
|
||||
config->backtitle = backtitle;
|
||||
config->title = title;
|
||||
config->pprompt = pprompt;
|
||||
config->aprompt = aprompt;
|
||||
config->options |= DPV_WIDE_MODE;
|
||||
config->label_size = -1;
|
||||
config->action = extract_files;
|
||||
config->status_solo =
|
||||
"%10lli files read @ %'9.1f files/sec.";
|
||||
config->status_many =
|
||||
"%10lli files read @ %'9.1f files/sec. [%i/%i busy/wait]";
|
||||
end_dialog();
|
||||
retval = dpv(config, dists);
|
||||
conf.title = __DECONST(char *, "Archive Extraction");
|
||||
pvconf.callback = extract_files;
|
||||
pvconf.refresh = 1;
|
||||
pvconf.fmtbottomstr = __DECONST(char *, "%10lli files read @ %'9.1f files/sec.");
|
||||
bsddialog_total_progview = 0;
|
||||
bsddialog_interruptprogview = bsddialog_abortprogview = false;
|
||||
retval = bsddialog_progressview(&conf,
|
||||
__DECONST(char *, "Extracting distribution files..."), 0, 0, &pvconf, nminibars, dists);
|
||||
|
||||
dpv_free();
|
||||
while ((dist = dists) != NULL) {
|
||||
dists = dist->next;
|
||||
if (dist->path != NULL)
|
||||
free(dist->path);
|
||||
free(dist);
|
||||
bsddialog_end();
|
||||
|
||||
for (i=0; i<nminibars; i++) {
|
||||
if (dists[i].path != NULL)
|
||||
free(dists[i].path);
|
||||
}
|
||||
if (dists != NULL)
|
||||
free(dists);
|
||||
|
||||
return (retval);
|
||||
}
|
||||
@ -177,7 +167,7 @@ main(void)
|
||||
static void
|
||||
sig_int(int sig __unused)
|
||||
{
|
||||
dpv_interrupt = TRUE;
|
||||
bsddialog_interruptprogview = true;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -196,6 +186,7 @@ count_files(const char *file)
|
||||
char line[512];
|
||||
char path[PATH_MAX];
|
||||
char errormsg[PATH_MAX + 512];
|
||||
struct bsddialog_conf conf;
|
||||
|
||||
if (manifest == NULL) {
|
||||
snprintf(path, sizeof(path), "%s/MANIFEST", distdir);
|
||||
@ -229,10 +220,12 @@ count_files(const char *file)
|
||||
* Either no manifest, or manifest didn't mention this archive.
|
||||
* Use archive(3) to read the archive, counting files within.
|
||||
*/
|
||||
bsddialog_initconf(&conf);
|
||||
if ((archive = archive_read_new()) == NULL) {
|
||||
snprintf(errormsg, sizeof(errormsg),
|
||||
"Error: %s\n", archive_error_string(NULL));
|
||||
dialog_msgbox("Extract Error", errormsg, 0, 0, TRUE);
|
||||
conf.title = __DECONST(char *, "Extract Error");
|
||||
bsddialog_msgbox(&conf, errormsg, 0, 0);
|
||||
return (-1);
|
||||
}
|
||||
archive_read_support_format_all(archive);
|
||||
@ -243,7 +236,8 @@ count_files(const char *file)
|
||||
snprintf(errormsg, sizeof(errormsg),
|
||||
"Error while extracting %s: %s\n", file,
|
||||
archive_error_string(archive));
|
||||
dialog_msgbox("Extract Error", errormsg, 0, 0, TRUE);
|
||||
conf.title = __DECONST(char *, "Extract Error");
|
||||
bsddialog_msgbox(&conf, errormsg, 0, 0);
|
||||
archive = NULL;
|
||||
return (-1);
|
||||
}
|
||||
@ -258,20 +252,24 @@ count_files(const char *file)
|
||||
}
|
||||
|
||||
static int
|
||||
extract_files(struct dpv_file_node *file, int out __unused)
|
||||
extract_files(struct bsddialog_fileminibar *file)
|
||||
{
|
||||
int retval;
|
||||
struct archive_entry *entry;
|
||||
char path[PATH_MAX];
|
||||
char errormsg[PATH_MAX + 512];
|
||||
struct bsddialog_conf conf;
|
||||
|
||||
bsddialog_initconf(&conf);
|
||||
|
||||
/* Open the archive if necessary */
|
||||
if (archive == NULL) {
|
||||
if ((archive = archive_read_new()) == NULL) {
|
||||
snprintf(errormsg, sizeof(errormsg),
|
||||
"Error: %s\n", archive_error_string(NULL));
|
||||
dialog_msgbox("Extract Error", errormsg, 0, 0, TRUE);
|
||||
dpv_abort = 1;
|
||||
conf.title = __DECONST(char *, "Extract Error");
|
||||
bsddialog_msgbox(&conf, errormsg, 0, 0);
|
||||
bsddialog_abortprogview = true;
|
||||
return (-1);
|
||||
}
|
||||
archive_read_support_format_all(archive);
|
||||
@ -280,11 +278,12 @@ extract_files(struct dpv_file_node *file, int out __unused)
|
||||
retval = archive_read_open_filename(archive, path, 4096);
|
||||
if (retval != 0) {
|
||||
snprintf(errormsg, sizeof(errormsg),
|
||||
"Error opening %s: %s\n", file->name,
|
||||
"Error opening %s: %s\n", file->label,
|
||||
archive_error_string(archive));
|
||||
dialog_msgbox("Extract Error", errormsg, 0, 0, TRUE);
|
||||
file->status = DPV_STATUS_FAILED;
|
||||
dpv_abort = 1;
|
||||
conf.title = __DECONST(char *, "Extract Error");
|
||||
bsddialog_msgbox(&conf, errormsg, 0, 0);
|
||||
file->status = 1; /* Failed */
|
||||
bsddialog_abortprogview = true;
|
||||
return (-1);
|
||||
}
|
||||
}
|
||||
@ -303,7 +302,7 @@ extract_files(struct dpv_file_node *file, int out __unused)
|
||||
if (retval == ARCHIVE_EOF) {
|
||||
archive_read_free(archive);
|
||||
archive = NULL;
|
||||
file->status = DPV_STATUS_DONE;
|
||||
file->status = 5; /*Done*/;
|
||||
return (100);
|
||||
} else if (retval != ARCHIVE_OK &&
|
||||
!(retval == ARCHIVE_WARN &&
|
||||
@ -315,20 +314,21 @@ extract_files(struct dpv_file_node *file, int out __unused)
|
||||
* option.
|
||||
*/
|
||||
snprintf(errormsg, sizeof(errormsg),
|
||||
"Error while extracting %s: %s\n", file->name,
|
||||
"Error while extracting %s: %s\n", file->label,
|
||||
archive_error_string(archive));
|
||||
dialog_msgbox("Extract Error", errormsg, 0, 0, TRUE);
|
||||
file->status = DPV_STATUS_FAILED;
|
||||
dpv_abort = 1;
|
||||
conf.title = __DECONST(char *, "Extract Error");
|
||||
bsddialog_msgbox(&conf, errormsg, 0, 0);
|
||||
file->status = 1; /* Failed */
|
||||
bsddialog_abortprogview = true;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
dpv_overall_read++;
|
||||
bsddialog_total_progview++;
|
||||
file->read++;
|
||||
|
||||
/* Calculate [overall] percentage of completion (if possible) */
|
||||
if (file->length >= 0)
|
||||
return (file->read * 100 / file->length);
|
||||
if (file->size >= 0)
|
||||
return (file->read * 100 / file->size);
|
||||
else
|
||||
return (-1);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user