mirror of
https://git.FreeBSD.org/src.git
synced 2024-12-14 10:09:48 +00:00
Bring this up to date with Marc van Kempen's latest version (1.0) now
that the libdialog changes have gone in to support it. Submitted by: Marc van Kempen <wmbfmk@urc.tue.nl>
This commit is contained in:
parent
36034afc79
commit
e722380a68
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=7973
7
usr.sbin/pkg_manage/CHANGES
Normal file
7
usr.sbin/pkg_manage/CHANGES
Normal file
@ -0,0 +1,7 @@
|
||||
- fixed a bug with respect to the parsing of the pkg_info output
|
||||
- implemented get_desc() which extracts +DESC and +COMMENT from the
|
||||
packages. This is still done the stupid way (slow).
|
||||
- install_batch(): two lists, one containing the to be installed
|
||||
packages from the chosen directory, the other containing the
|
||||
allready installed packages.
|
||||
|
@ -1,11 +1,14 @@
|
||||
# $Id$
|
||||
# $Id: Makefile,v 1.1.1.1 1995/02/15 20:47:56 ache Exp $
|
||||
|
||||
PROG= pkg_manage
|
||||
LDADD+= -ldialog -lncurses -lmytinfo
|
||||
DPADD+= ${LIBDIALOG} ${LIBNCURSES} ${LIBMYTINFO}
|
||||
CFLAGS+= -Wall -Wstrict-prototypes -DHELP_PATH=\"${HELPDIR}/\"
|
||||
SRCS= pkg_main.c pkg_manage.c pkg_ui.c version.c
|
||||
LDADD+= ../libdialog/libdialog.a ../libncurses/libncurses.a -lmytinfo
|
||||
DPADD+= ${LIBDIALOG} ${LIBNCURSES} ${LIBMYTINFO}
|
||||
CFLAGS+= -Wall -Wstrict-prototypes -DHELP_PATH=\"${HELPDIR}/\" \
|
||||
-I../libdialog -I../libncurses -g
|
||||
|
||||
HELPDIR = /usr/share/misc/pkg_manage
|
||||
#HELPDIR = /usr/share/misc/pkg_manage
|
||||
HELPDIR = /home/marc/src/dialog/pkg_manage
|
||||
|
||||
HELPS= pkg_view-inst.hlp pkg_del-inst.hlp pkg_preview.hlp \
|
||||
pkg_install.hlp pkg_main.hlp
|
||||
@ -20,3 +23,4 @@ afterinstall:
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
|
||||
pkg_manage: ../libdialog/libdialog.a
|
||||
|
87
usr.sbin/pkg_manage/TODO
Normal file
87
usr.sbin/pkg_manage/TODO
Normal file
@ -0,0 +1,87 @@
|
||||
TODO list for pkg_manage:
|
||||
|
||||
|
||||
- check for expections, catch error output from pkg_* tools
|
||||
check all i/o operations for error capture.
|
||||
done 6Apr95
|
||||
|
||||
- implement better (faster) way of getting the +* out of the
|
||||
tar files, or use an index file for this.
|
||||
done 9Apr95, modified tar to stop after having extracted all
|
||||
fnames listed on the commandline.
|
||||
|
||||
- add extra option to have a user select a directory and then display
|
||||
all packages in that directory with a descriptive line, one should be
|
||||
able to select a whole bunch of packages and then select GO.
|
||||
Maybe review the whole concept. Perhaps something like this:
|
||||
done 5Apr95
|
||||
|
||||
NOTE:
|
||||
Have two windows, one containing the installed packages, the other
|
||||
containing the *to be* installed packages. Packages listed in this
|
||||
last window depend upon the directory chosen. One can delete
|
||||
packages in the left window, or move packages from the right window
|
||||
to the left, that is install them.
|
||||
Coupling deletion from the left window to inclusion in the right
|
||||
window will be difficult, since one cannot be sure that the list
|
||||
one sees in the right window are all the packages available.
|
||||
Furthermore deleting a package does not give one a package file
|
||||
to store in a central place.
|
||||
This coupling should not be suggested.
|
||||
|
||||
- when deleting the last package in the list, adjust the cursor-pointer
|
||||
done 6Apr95
|
||||
|
||||
- check if a package is already installed when installing it.
|
||||
done 7Apr95
|
||||
|
||||
- Read also +CONTENTS from pkg when scanning directory to extract
|
||||
the package name from it.
|
||||
done 7Apr95
|
||||
|
||||
- should I check for uid being root before installing anything?
|
||||
|
||||
|
||||
- Make sure that the process can continue as a batch process.
|
||||
Accumulate all error messages and show them after processing.
|
||||
Before beginning with a batch install, check if any packages are
|
||||
already installed, if so pop up message suggesting to delete
|
||||
the package first before installing the new one.
|
||||
done 7apr95
|
||||
|
||||
- make a dialog in which the comment information is printed, and
|
||||
which has a button for displaying the description information.
|
||||
done 6Apr95, no button, but key F2 for description
|
||||
|
||||
- when selecting the directory to install multiple packages
|
||||
print a helpline about what to do.
|
||||
done 6Apr95
|
||||
|
||||
- limit the width of the info-popup when selecting multiple
|
||||
packages.
|
||||
done 6Apr95
|
||||
|
||||
- make sure that the popup's dont get too big.
|
||||
done 6Apr95
|
||||
|
||||
- add progress indication when scanning packages and installing them.
|
||||
done 6Apr95, added a dialog_gauge to libdialog.
|
||||
|
||||
- check for delwin's whenever a newwin was called
|
||||
done 6Apr95
|
||||
|
||||
- when an error occurs in get_desc, because it can't stat the temporary
|
||||
file, then there is an seg-fault in draw_box in RefreshListObj() ?????
|
||||
Low priority, because something fishy is going on then anyway
|
||||
|
||||
- use $TMPDIR to create tmp directory into
|
||||
|
||||
- make sure that when calling help, the helplines are disabled.
|
||||
done 11Apr95, also implemented a different mechanism to save and
|
||||
restore helplines
|
||||
|
||||
- do a size calculation for the selected packages
|
||||
done 11Apr95
|
||||
|
||||
- (next version?) implement exec_catch_errors with popen(), I think
|
||||
this will speed up things quite a bit.
|
49
usr.sbin/pkg_manage/pkg_main.c
Normal file
49
usr.sbin/pkg_manage/pkg_main.c
Normal file
@ -0,0 +1,49 @@
|
||||
/***************************************************************
|
||||
*
|
||||
* Program: pkg_main.c
|
||||
* Author: Marc van Kempen
|
||||
* Desc: main routine for pkg_manage
|
||||
*
|
||||
* Copyright (c) 1995, Marc van Kempen
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software may be used, modified, copied, distributed, and
|
||||
* sold, in both source and binary form provided that the above
|
||||
* copyright and these terms are retained, verbatim, as the first
|
||||
* lines of this file. Under no circumstances is the author
|
||||
* responsible for the proper functioning of this software, nor does
|
||||
* the author assume any responsibility for damages incurred with
|
||||
* its use.
|
||||
*
|
||||
***************************************************************/
|
||||
|
||||
#include "pkg_manage.h"
|
||||
#include "ui_objects.h"
|
||||
|
||||
extern PKG_info p_inf;
|
||||
|
||||
/*
|
||||
* Main
|
||||
*/
|
||||
|
||||
void
|
||||
main(void)
|
||||
{
|
||||
init_dialog();
|
||||
|
||||
p_inf.Nitems = 0; /* Initialize p_inf */
|
||||
|
||||
get_pkginfo();
|
||||
run_menu();
|
||||
|
||||
if (p_inf.Nitems > 0) {
|
||||
FreeInfo();
|
||||
}
|
||||
|
||||
clear();
|
||||
dialog_update();
|
||||
end_dialog();
|
||||
|
||||
return;
|
||||
} /* main() */
|
@ -11,7 +11,8 @@ delete and view packages. It is a
|
||||
front-end to the pkg_add(1), pkg_info(1) and pkg_delete(1) programs.
|
||||
|
||||
Pressing F1 (or '?') at anytime during the program will bring up
|
||||
online-help. (Pressing '?' will not work in character input fields)
|
||||
online-help. (Pressing '?' will not invoke help when in character
|
||||
input fields)
|
||||
|
||||
.SH NAVIGATING THE MENU
|
||||
When starting pkg_manage you will be put in a menu with the following
|
||||
@ -154,7 +155,7 @@ button and press enter. If you want to back out, move the cursor to the
|
||||
button and press enter.
|
||||
|
||||
.SH SEE ALSO
|
||||
pkg_add(1), pkg_info(1), pkg_delete(1), pkg_create.
|
||||
pkg_add(1), pkg_info(1), pkg_delete(1), pkg_create(1).
|
||||
|
||||
.SH BUGS
|
||||
Haven't met them yet.
|
||||
|
@ -8,11 +8,7 @@
|
||||
*
|
||||
* 1. View installed packages
|
||||
* 2. Delete installed packages
|
||||
* 3. View package files
|
||||
* 4. Install packages files.
|
||||
*
|
||||
* Installation and deletion of packages should be previewable
|
||||
*
|
||||
* 3. Install packages
|
||||
*
|
||||
* Copyright (c) 1995, Marc van Kempen
|
||||
*
|
||||
@ -32,54 +28,38 @@
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/stat.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "pkg_manage.h"
|
||||
#include "ui_objects.h"
|
||||
#include "dialog.priv.h"
|
||||
#include "dir.h"
|
||||
|
||||
static PKG_info p_inf;
|
||||
static int got_info;
|
||||
PKG_info p_inf = { 0, 0, NULL, NULL, NULL, NULL, NULL };
|
||||
|
||||
/*******************************************************************
|
||||
*
|
||||
* Misc Functions
|
||||
*
|
||||
*******************************************************************/
|
||||
|
||||
void
|
||||
FreeInfo(void)
|
||||
/*
|
||||
* Local prototypes
|
||||
* Desc: free the space allocated to p_inf
|
||||
*/
|
||||
|
||||
void run_menu(void);
|
||||
void get_pkginfo(void);
|
||||
void FreeMnu(unsigned char **mnu, int n);
|
||||
void FreeInfo(void);
|
||||
|
||||
/*
|
||||
* Main
|
||||
*/
|
||||
|
||||
void
|
||||
main(void)
|
||||
{
|
||||
init_dialog();
|
||||
|
||||
get_pkginfo();
|
||||
run_menu();
|
||||
|
||||
if (got_info)
|
||||
FreeInfo();
|
||||
|
||||
clear();
|
||||
dialog_update();
|
||||
end_dialog();
|
||||
free(p_inf.buf);
|
||||
free(p_inf.name);
|
||||
free(p_inf.comment);
|
||||
free(p_inf.description);
|
||||
p_inf.Nitems = 0;
|
||||
FreeMnu(p_inf.mnu, 2*p_inf.Nitems);
|
||||
|
||||
return;
|
||||
} /* main() */
|
||||
|
||||
void FreeInfo(void)
|
||||
{
|
||||
free(p_inf.buf);
|
||||
free(p_inf.name);
|
||||
free(p_inf.comment);
|
||||
free(p_inf.description);
|
||||
FreeMnu(p_inf.mnu, 2*p_inf.Nitems);
|
||||
got_info = FALSE;
|
||||
}
|
||||
} /* FreeInfo() */
|
||||
|
||||
void
|
||||
FreeMnu(unsigned char **mnu, int n)
|
||||
@ -91,7 +71,7 @@ FreeMnu(unsigned char **mnu, int n)
|
||||
|
||||
for (i=0; i<n; i++) {
|
||||
free(mnu[i]);
|
||||
}
|
||||
}
|
||||
free(mnu);
|
||||
|
||||
return;
|
||||
@ -117,68 +97,135 @@ file_exists(char *fname)
|
||||
} /* file_exists() */
|
||||
|
||||
|
||||
int
|
||||
exec_catch_errors(char *prog, char *arg, char *fout)
|
||||
/*
|
||||
* Desc: run the program <prog> with arguments <arg> and catch its output
|
||||
* in <fout> and display it in case of an error. specify NULL,
|
||||
* if you don't want output.
|
||||
*/
|
||||
{
|
||||
char *execstr, *tmp;
|
||||
int ret, yesno, unlink_fout;
|
||||
|
||||
execstr = (char *) malloc( strlen(prog) + strlen(arg) + 30 );
|
||||
if (!execstr) {
|
||||
fprintf(stderr, "exec_catch_errors: Error while mallocing memory\n");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
/* when fout == NULL, allocate a temporary file name and unlink it */
|
||||
/* when done */
|
||||
if (!fout) {
|
||||
fout = tempnam(NULL, "pkg.");
|
||||
if (!fout) {
|
||||
fprintf(stderr, "exec_catch_errors: Error allocating temp.name\n");
|
||||
exit(-1);
|
||||
}
|
||||
unlink_fout = TRUE;
|
||||
} else {
|
||||
unlink_fout = FALSE;
|
||||
}
|
||||
|
||||
sprintf(execstr, "%s %s > %s 2>&1", prog, arg, fout);
|
||||
ret = system(execstr);
|
||||
if (ret) {
|
||||
|
||||
yesno = dialog_yesno("Error", "An error occured, view output?", 8, 40);
|
||||
if (yesno == 0) {
|
||||
/* disable helpline */
|
||||
tmp = get_helpline();
|
||||
use_helpline("use arrowkeys, PgUp, PgDn to move, press enter when done");
|
||||
dialog_textbox("Error output from pkg_add", fout, LINES-2, COLS-4);
|
||||
restore_helpline(tmp);
|
||||
}
|
||||
}
|
||||
|
||||
if (unlink_fout) {
|
||||
unlink(fout);
|
||||
free(fout);
|
||||
}
|
||||
free(execstr);
|
||||
|
||||
return(ret);
|
||||
} /* exec_catch_errors() */
|
||||
|
||||
void
|
||||
get_pkginfo(void)
|
||||
/*
|
||||
* Desc: get info about installed packages
|
||||
*/
|
||||
{
|
||||
FILE *f;
|
||||
char *p;
|
||||
char prog[512];
|
||||
struct stat sb;
|
||||
int i, j, n, lsize;
|
||||
int newline;
|
||||
int newline, ret;
|
||||
int state;
|
||||
char *tmp_file;
|
||||
#define R_NAME 1
|
||||
#define R_COMMENT 2
|
||||
#define R_DESC 3
|
||||
|
||||
if (got_info)
|
||||
if (p_inf.Nitems > 0) {
|
||||
FreeInfo();
|
||||
}
|
||||
/* p_inf.Nitems == 0 */
|
||||
|
||||
dialog_msgbox("PKG INFO", "Reading info, please wait ...", 4, 35, FALSE);
|
||||
|
||||
tmp_file = tempnam(NULL, "pkg.");
|
||||
|
||||
sprintf(prog, "%s -a > %s", PKG_INFO, tmp_file);
|
||||
system(prog);
|
||||
dialog_clear_norefresh();
|
||||
|
||||
f = fopen(tmp_file, "r");
|
||||
if (!f) {
|
||||
dialog_notify("Could not open temporary file");
|
||||
goto err1;
|
||||
}
|
||||
|
||||
if (stat(tmp_file, &sb)) { /* stat file to get filesize */
|
||||
dialog_notify("Could not stat temporary file");
|
||||
goto err2;
|
||||
}
|
||||
|
||||
if (sb.st_size == 0) {
|
||||
dialog_notify("No packages info available");
|
||||
goto err2;
|
||||
}
|
||||
|
||||
/* Allocate a buffer with sufficient space to hold the entire file */
|
||||
p_inf.buf = (char *) malloc( sb.st_size );
|
||||
p_inf.N = sb.st_size;
|
||||
if (fread(p_inf.buf, 1, p_inf.N, f) != p_inf.N) {
|
||||
dialog_notify("Could not read from temporary file");
|
||||
free(p_inf.buf);
|
||||
err2:
|
||||
fclose(f);
|
||||
err1:
|
||||
got_info = FALSE;
|
||||
tmp_file = tempnam(NULL, "pkg.");
|
||||
ret = exec_catch_errors(PKG_INFO, "-a", tmp_file);
|
||||
if (ret) {
|
||||
dialog_notify("Could not get package info\nexiting!");
|
||||
unlink(tmp_file);
|
||||
free(tmp_file);
|
||||
return;
|
||||
}
|
||||
dialog_clear_norefresh();
|
||||
|
||||
f = fopen(tmp_file, "r");
|
||||
if (!f) {
|
||||
dialog_notify("Could not open temporary file");
|
||||
unlink(tmp_file);
|
||||
free(tmp_file);
|
||||
return;
|
||||
}
|
||||
|
||||
if (stat(tmp_file, &sb)) { /* stat file to get filesize */
|
||||
dialog_notify("Could not stat temporary file");
|
||||
fclose(f);
|
||||
unlink(tmp_file);
|
||||
free(tmp_file);
|
||||
return;
|
||||
}
|
||||
|
||||
if (sb.st_size == 0) {
|
||||
dialog_notify("No packages installed or no info available");
|
||||
fclose(f);
|
||||
unlink(tmp_file);
|
||||
free(tmp_file);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Allocate a buffer with sufficient space to hold the entire file */
|
||||
p_inf.buf = (char *) malloc( sb.st_size + 1);
|
||||
p_inf.N = sb.st_size;
|
||||
if (fread(p_inf.buf, 1, p_inf.N, f) != p_inf.N) {
|
||||
dialog_notify("Could not read entire temporary file");
|
||||
free(p_inf.buf);
|
||||
fclose(f);
|
||||
unlink(tmp_file);
|
||||
free(tmp_file);
|
||||
return;
|
||||
}
|
||||
p_inf.buf[p_inf.N] = 0;
|
||||
fclose(f);
|
||||
unlink(tmp_file);
|
||||
free(tmp_file);
|
||||
|
||||
/* make one sweep through the buffer to determine the # of entries */
|
||||
/* Look for "Information for" in the first column */
|
||||
|
||||
i = p_inf.N - strlen("Information for") - 1;
|
||||
p = p_inf.buf;
|
||||
if (strncmp(p_inf.buf, "Information for", 15) == 0) {
|
||||
@ -186,7 +233,7 @@ get_pkginfo(void)
|
||||
} else {
|
||||
n = 0;
|
||||
}
|
||||
while (i--) {
|
||||
while (i-- > 0) {
|
||||
if (*p == '\n') {
|
||||
if (strncmp(p+1, "Information for", 15) == 0) {
|
||||
n++;
|
||||
@ -210,6 +257,7 @@ get_pkginfo(void)
|
||||
state = R_NAME;
|
||||
while (*p) {
|
||||
if (newline) {
|
||||
newline = FALSE;
|
||||
switch(state) {
|
||||
case R_NAME:
|
||||
if (strncmp(p, "Information for", 15) == 0) {
|
||||
@ -226,21 +274,25 @@ get_pkginfo(void)
|
||||
if (*p) p_inf.comment[i] = (char *) p+1;
|
||||
p++;
|
||||
while (*p && *p != '\n') p++;
|
||||
if (*p) *p = '\0';
|
||||
p++;
|
||||
if (*p) {
|
||||
*p = '\0';
|
||||
newline = TRUE;
|
||||
}
|
||||
state = R_DESC;
|
||||
}
|
||||
break;
|
||||
case R_DESC:
|
||||
if (strncmp(p, "Description:", 12) == 0) {
|
||||
while (*p && *p != '\n') p++;
|
||||
if (*p) p_inf.description[i] = (char *) p+1;
|
||||
if (*p) {
|
||||
p_inf.description[i] = (char *) p+1;
|
||||
newline = TRUE;
|
||||
}
|
||||
state = R_NAME;
|
||||
i++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
newline = FALSE;
|
||||
}
|
||||
if (*p == '\n') newline = TRUE;
|
||||
p++;
|
||||
@ -262,8 +314,7 @@ get_pkginfo(void)
|
||||
strncpy(p_inf.mnu[j], p_inf.comment[i], lsize-1);
|
||||
p_inf.mnu[j++][lsize-1] = 0;
|
||||
}
|
||||
|
||||
got_info = TRUE;
|
||||
|
||||
return;
|
||||
} /* get_pkginfo() */
|
||||
|
||||
@ -275,268 +326,220 @@ get_pkg_index(char *selection)
|
||||
{
|
||||
int i, found = FALSE, index = -1;
|
||||
|
||||
if (got_info)
|
||||
for (i=0; i<p_inf.Nitems && !found; i++) {
|
||||
if (strcmp(selection, p_inf.name[i]) == 0) {
|
||||
found = TRUE;
|
||||
index = i;
|
||||
}
|
||||
for (i=0; i<p_inf.Nitems && !found; i++) {
|
||||
if (strcmp(selection, p_inf.name[i]) == 0) {
|
||||
found = TRUE;
|
||||
index = i;
|
||||
}
|
||||
}
|
||||
|
||||
return(index);
|
||||
} /* get_pkg_index() */
|
||||
|
||||
void
|
||||
view_installed(void)
|
||||
/*
|
||||
* Desc: View the installed packages
|
||||
*/
|
||||
{
|
||||
int i, quit_view, sc=0, ch=0;
|
||||
char selection[1024];
|
||||
|
||||
if (!got_info) {
|
||||
use_helpfile(NULL);
|
||||
use_helpline(NULL);
|
||||
dialog_notify("No packages info available");
|
||||
return;
|
||||
}
|
||||
use_helpfile(VIEW_INST_HLP);
|
||||
quit_view = FALSE;
|
||||
while (!quit_view) {
|
||||
use_helpline("use arrow-keys or character to select option and press enter");
|
||||
if (dialog_menu("View installed packages",
|
||||
"Press enter to see the package descriptions",
|
||||
LINES, COLS, LINES-5, p_inf.Nitems,
|
||||
p_inf.mnu, selection, &ch, &sc )) {
|
||||
quit_view = TRUE;
|
||||
} else {
|
||||
i = get_pkg_index(selection);
|
||||
use_helpline("use PgUp and PgDn and arrow-keys to move throught the text");
|
||||
dialog_mesgbox(p_inf.comment[i], p_inf.description[i], LINES, COLS);
|
||||
}
|
||||
}
|
||||
use_helpfile(NULL);
|
||||
use_helpline(NULL);
|
||||
|
||||
return;
|
||||
} /* view_installed() */
|
||||
|
||||
void
|
||||
delete_installed(void)
|
||||
/*
|
||||
* Desc: Delete an installed package
|
||||
*/
|
||||
{
|
||||
unsigned char *mnu[] = {
|
||||
"1. Simulate delete", "Display commands that are going to be executed",
|
||||
"2. Delete", "Execute commands to delete the package",
|
||||
"3. Cancel", "Do NOT delete the package"
|
||||
};
|
||||
char tmp[512], selection[512], *tmp_file;
|
||||
int quit_view, quit_del;
|
||||
int i, sel, ch=0, sc=0, ch0=0, sc0=0;
|
||||
|
||||
if (!got_info) {
|
||||
use_helpfile(NULL);
|
||||
use_helpline(NULL);
|
||||
dialog_notify("No packages info available");
|
||||
return;
|
||||
}
|
||||
quit_view = FALSE;
|
||||
while (!quit_view) {
|
||||
use_helpline("use arrow-keys or character to select option and press enter");
|
||||
use_helpfile(DEL_INST_HLP);
|
||||
if (dialog_menu("DELETE an installed package",
|
||||
"Press enter to select a package",
|
||||
LINES, COLS, LINES-5, p_inf.Nitems,
|
||||
p_inf.mnu, selection, &ch, &sc)) {
|
||||
quit_view = TRUE;
|
||||
} else {
|
||||
quit_del = FALSE;
|
||||
i = get_pkg_index(selection);
|
||||
while (!quit_del) {
|
||||
sprintf(tmp, "Delete <%s>", p_inf.name[i]);
|
||||
use_helpline("use arrow-keys or digit to select option and press enter");
|
||||
if (dialog_menu("Delete a package", tmp, 10, COLS-6,
|
||||
3, 3, mnu, selection, &ch0, &sc0)) {
|
||||
quit_del = TRUE;
|
||||
} else {
|
||||
sel = atoi(selection);
|
||||
switch(sel) {
|
||||
case 1:
|
||||
tmp_file = tempnam(NULL, "pkg.");
|
||||
sprintf(tmp, "%s -n %s > %s",
|
||||
PKG_DELETE, p_inf.name[i], tmp_file);
|
||||
system(tmp);
|
||||
dialog_textbox("Package deletion commands",
|
||||
tmp_file, LINES, COLS);
|
||||
unlink(tmp_file);
|
||||
free(tmp_file);
|
||||
break;
|
||||
case 2:
|
||||
sprintf(tmp, "%s %s", PKG_DELETE, p_inf.name[i]);
|
||||
system(tmp);
|
||||
get_pkginfo();
|
||||
quit_del = TRUE;
|
||||
break;
|
||||
case 3:
|
||||
quit_del = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
use_helpfile(NULL);
|
||||
use_helpline(NULL);
|
||||
|
||||
return;
|
||||
} /* delete_installed() */
|
||||
|
||||
void
|
||||
preview_pkg(void)
|
||||
install_package(char *fname)
|
||||
/*
|
||||
* Desc: View the package description and comment before installation
|
||||
* Desc: install the package <fname>
|
||||
*/
|
||||
{
|
||||
char *fname;
|
||||
char *tmp_file;
|
||||
char prog[512], title[512];
|
||||
char *tmp_file;
|
||||
|
||||
use_helpfile(PREVIEW_HLP);
|
||||
fname = dialog_fselect(".", "*.tgz");
|
||||
while (fname) {
|
||||
use_helpfile(PREVIEW_HLP);
|
||||
use_helpline("use PgUp and PgDn and arrow-keys to move through the text");
|
||||
tmp_file = tempnam(NULL, "pkg.");
|
||||
sprintf(prog, "%s zxOf %s +COMMENT +DESC > %s", TAR, fname, tmp_file);
|
||||
system(prog);
|
||||
sprintf(title, "Preview package <%s>", fname);
|
||||
dialog_textbox(title, tmp_file, LINES, COLS);
|
||||
unlink(tmp_file);
|
||||
free(fname);
|
||||
free(tmp_file);
|
||||
fname = dialog_fselect(".", "*.tgz");
|
||||
tmp_file = tempnam(NULL, "pkg.");
|
||||
if (!tmp_file) {
|
||||
fprintf(stderr, "install_package(): Error malloc'ing tmp_file\n");
|
||||
exit(-1);
|
||||
}
|
||||
if (fname) free(fname);
|
||||
use_helpfile(NULL);
|
||||
use_helpline(NULL);
|
||||
exec_catch_errors(PKG_ADD, fname, tmp_file);
|
||||
|
||||
unlink(tmp_file);
|
||||
free(tmp_file);
|
||||
|
||||
return;
|
||||
} /* preview_pkg() */
|
||||
} /* install_package() */
|
||||
|
||||
void
|
||||
install_new(void)
|
||||
|
||||
|
||||
int
|
||||
get_desc(char *fname, char **name, char **comment,
|
||||
char **desc, long *size, char *tmp_dir)
|
||||
/*
|
||||
* Desc: Install a new package
|
||||
* Desc: get the description and comment from the files
|
||||
* DESC, CONTENT and COMMENT from fname
|
||||
* Pre: the current working directory is a temporary,
|
||||
* empty directory.
|
||||
* Post: name = the name of the package
|
||||
* comment = the comment for the package
|
||||
* desc = the description for the package
|
||||
*/
|
||||
{
|
||||
char *fname;
|
||||
char *tmp_file;
|
||||
char tmp[512], selection[40];
|
||||
unsigned char *mnu[] = {
|
||||
"1. Simulate install", "Display commands that are going to be executed",
|
||||
"2. Install", "Execute commands to install the package",
|
||||
"3. Cancel", "Do NOT install the package"
|
||||
};
|
||||
int sel, quit_inst, ch=0, sc=0;
|
||||
|
||||
use_helpfile(INSTALL_HLP);
|
||||
fname = dialog_fselect(".", "*.tgz");
|
||||
if (!fname) {
|
||||
quit_inst = TRUE;
|
||||
char msg[80], args[512], *buf, *p, tmp[MAXPATHLEN];
|
||||
FILE *f, *pf;
|
||||
struct stat sb;
|
||||
int i, N, ret, found;
|
||||
|
||||
*comment = NULL;
|
||||
*desc = NULL;
|
||||
*name = NULL;
|
||||
|
||||
sprintf(args, "--fast-read -zxvf %s -C %s %s %s %s", fname,
|
||||
tmp_dir, CONTENTS, DESC, COMMENT);
|
||||
ret = exec_catch_errors(TAR, args, NULL);
|
||||
if (ret) {
|
||||
sprintf(msg, "Could not get info for <%s>", fname);
|
||||
dialog_notify(msg);
|
||||
return(FALSE);
|
||||
}
|
||||
/* Read CONTENTS */
|
||||
sprintf(tmp, "%s/%s", tmp_dir, CONTENTS);
|
||||
f = fopen(tmp, "r");
|
||||
if (f == NULL) {
|
||||
/* No contents file in package, propably not a package */
|
||||
return(FALSE);
|
||||
}
|
||||
if (stat(tmp, &sb)) { /* stat file to get filesize */
|
||||
dialog_notify("Could not stat CONTENTS file");
|
||||
fclose(f);
|
||||
return(FALSE);
|
||||
}
|
||||
if (sb.st_size == 0) {
|
||||
dialog_notify("CONTENTS file has zero length");
|
||||
fclose(f);
|
||||
return(FALSE);
|
||||
}
|
||||
|
||||
/* Allocate a buffer with sufficient space to hold the entire file */
|
||||
buf = (char *) malloc( sb.st_size + 1);
|
||||
N = sb.st_size;
|
||||
if (fread(buf, 1, N, f) != N) {
|
||||
sprintf(msg, "Could not read CONTENT file for <%s>", fname);
|
||||
dialog_notify(msg);
|
||||
free(buf);
|
||||
fclose(f);
|
||||
return(FALSE);
|
||||
}
|
||||
fclose(f);
|
||||
buf[N] = 0;
|
||||
|
||||
/* look for the name of the package */
|
||||
p = buf;
|
||||
found = FALSE;
|
||||
while (*p && !found) {
|
||||
if (strncmp(p, "@name ", 6) == 0) {
|
||||
i=0;
|
||||
p += 6;
|
||||
while (*p && p[i] != '\n' && p[i] != '\r') i++;
|
||||
*name = (char *) malloc( i+1 );
|
||||
strncpy(*name, p, i);
|
||||
(*name)[i] = 0;
|
||||
found = TRUE;
|
||||
} else {
|
||||
p++;
|
||||
}
|
||||
}
|
||||
unlink(tmp);
|
||||
|
||||
/* Read COMMENT file */
|
||||
sprintf(tmp, "%s/%s", tmp_dir, COMMENT);
|
||||
f = fopen(tmp, "r");
|
||||
if (f == NULL) {
|
||||
/* No comment file in package, propably not a package */
|
||||
return(FALSE);
|
||||
}
|
||||
if (stat(tmp, &sb)) { /* stat file to get filesize */
|
||||
dialog_notify("Could not stat COMMENT file");
|
||||
fclose(f);
|
||||
return(FALSE);
|
||||
}
|
||||
if (sb.st_size == 0) {
|
||||
dialog_notify("COMMENT file has zero length");
|
||||
fclose(f);
|
||||
return(FALSE);
|
||||
}
|
||||
|
||||
/* Allocate a buffer with sufficient space to hold the entire file */
|
||||
*comment = (char *) malloc( sb.st_size + 1);
|
||||
N = sb.st_size;
|
||||
if (fread(*comment, 1, N, f) != N) {
|
||||
sprintf(msg, "Could not read COMMENT file for <%s>", fname);
|
||||
dialog_notify(msg);
|
||||
free(*comment);
|
||||
fclose(f);
|
||||
return(FALSE);
|
||||
}
|
||||
fclose(f);
|
||||
(*comment)[N] = 0;
|
||||
unlink(tmp);
|
||||
|
||||
/* Read DESC */
|
||||
sprintf(tmp, "%s/%s", tmp_dir, DESC);
|
||||
f = fopen(tmp, "r");
|
||||
if (f == NULL) {
|
||||
/* No description file in package, propably not a package */
|
||||
return(FALSE);
|
||||
}
|
||||
if (stat(tmp, &sb)) { /* stat file to get filesize */
|
||||
dialog_notify("Could not stat DESC file");
|
||||
fclose(f);
|
||||
return(FALSE);
|
||||
}
|
||||
if (sb.st_size == 0) {
|
||||
dialog_notify("DESC file has zero length");
|
||||
fclose(f);
|
||||
return(FALSE);
|
||||
}
|
||||
|
||||
/* Allocate a buffer with sufficient space to hold the entire file */
|
||||
*desc = (char *) malloc( sb.st_size + 1);
|
||||
N = sb.st_size;
|
||||
if (fread(*desc, 1, N, f) != N) {
|
||||
sprintf(msg, "Could not read CONTENT file for <%s>", fname);
|
||||
dialog_notify(msg);
|
||||
free(*desc);
|
||||
fclose(f);
|
||||
return(FALSE);
|
||||
}
|
||||
fclose(f);
|
||||
(*desc)[N] = 0;
|
||||
unlink(tmp);
|
||||
|
||||
/* get the size from the uncompressed package */
|
||||
sprintf(tmp, "%s -l %s", GUNZIP, fname);
|
||||
pf = popen(tmp, "r");
|
||||
if (!pf) {
|
||||
dialog_notify("Could not popen gunzip to get package size");
|
||||
*size = 0;
|
||||
} else {
|
||||
quit_inst = FALSE;
|
||||
}
|
||||
while (!quit_inst) {
|
||||
use_helpfile(INSTALL_HLP);
|
||||
use_helpline("use arrow-keys or digit to select option and press enter");
|
||||
sprintf(tmp, "Install package <%s>", fname);
|
||||
if (dialog_menu("Install a package", tmp, 10, COLS-5,
|
||||
3, 3, mnu, selection, &ch, &sc)) {
|
||||
quit_inst = TRUE;
|
||||
} else {
|
||||
sel = atoi(selection);
|
||||
switch(sel) {
|
||||
case 1:
|
||||
tmp_file = tempnam(NULL, "*.pkg");
|
||||
sprintf(tmp, "%s -n %s 2>&1 | cat > %s", PKG_ADD, fname, tmp_file);
|
||||
system(tmp);
|
||||
dialog_textbox("Package installation commands",
|
||||
tmp_file, LINES, COLS);
|
||||
unlink(tmp_file);
|
||||
free(tmp_file);
|
||||
break;
|
||||
case 2:
|
||||
sprintf(tmp, "%s %s", PKG_ADD, fname);
|
||||
system(tmp);
|
||||
get_pkginfo();
|
||||
quit_inst = TRUE;
|
||||
break;
|
||||
case 3:
|
||||
quit_inst = TRUE;
|
||||
break;
|
||||
}
|
||||
while (!feof(pf)) {
|
||||
fgets(tmp, 80, pf);
|
||||
}
|
||||
sscanf(tmp, "%*s %ld", size);
|
||||
pclose(pf);
|
||||
}
|
||||
if (fname) free(fname);
|
||||
use_helpfile(NULL);
|
||||
use_helpline(NULL);
|
||||
|
||||
if (found) {
|
||||
return(TRUE);
|
||||
} else {
|
||||
return(FALSE);
|
||||
}
|
||||
} /* get_desc() */
|
||||
|
||||
return;
|
||||
} /* install_new() */
|
||||
|
||||
void
|
||||
run_menu(void)
|
||||
/*
|
||||
* Desc: display/choose from menu
|
||||
int
|
||||
already_installed(char *name)
|
||||
/*
|
||||
* Desc: check if <name> is already installed as a package
|
||||
*/
|
||||
{
|
||||
int quit_pkg, sel, ch=0, sc=0;
|
||||
char selection[30];
|
||||
unsigned char *pkg_menu[] = {
|
||||
"1. View installed", "Overview of the installed packages",
|
||||
"2. Delete installed", "Delete an installed package",
|
||||
"3. View pkg files", "Preview about to be installed packages",
|
||||
"4. Install pkg files", "Install new packages",
|
||||
"5. Quit", "Leave the program",
|
||||
};
|
||||
int i, found;
|
||||
|
||||
quit_pkg = FALSE;
|
||||
while (!quit_pkg) {
|
||||
use_helpline("use arrow-keys or digit to select option and press enter");
|
||||
use_helpfile(MAIN_HLP);
|
||||
if (dialog_menu("Package Manager", "Choose one of the options",
|
||||
LINES, COLS, 5, 5, pkg_menu, selection, &ch, &sc)) {
|
||||
sel = 0;
|
||||
quit_pkg = TRUE;
|
||||
} else {
|
||||
sel = atoi(selection);
|
||||
}
|
||||
|
||||
switch(sel) {
|
||||
case 0: /* Quit */
|
||||
break;
|
||||
case 1: /* View installed packages */
|
||||
view_installed();
|
||||
break;
|
||||
case 2: /* Delete installed package */
|
||||
delete_installed();
|
||||
break;
|
||||
case 3: /* Preview new package file */
|
||||
preview_pkg();
|
||||
break;
|
||||
case 4: /* Install new package */
|
||||
install_new();
|
||||
break;
|
||||
case 5: /* Quit */
|
||||
quit_pkg = TRUE;
|
||||
break;
|
||||
found = FALSE;
|
||||
for (i=0; i<p_inf.Nitems && !found; i++) {
|
||||
if (strcmp(name, p_inf.name[i]) == 0) {
|
||||
found = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
} /* run_menu() */
|
||||
|
||||
return(found);
|
||||
} /* already_installed() */
|
||||
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* include file for pkg.c
|
||||
* include file for pkg_manage
|
||||
*
|
||||
*
|
||||
* Copyright (c) 1995, Marc van Kempen
|
||||
@ -39,24 +39,41 @@ typedef struct {
|
||||
unsigned char **mnu; /* pointers to be used with dialog_menu() */
|
||||
} PKG_info;
|
||||
|
||||
typedef struct DirList { /* structure to hold the directory entries */
|
||||
char filename[MAXNAMLEN]; /* together with the stat-info per file */
|
||||
struct stat filestatus; /* filename, or the name to which it points */
|
||||
int link; /* is it a link ? */
|
||||
char *linkname; /* the name of the file the link points to */
|
||||
} DirList;
|
||||
/* Names of the description and comment files in the package */
|
||||
#define DESC "+DESC"
|
||||
#define COMMENT "+COMMENT"
|
||||
#define CONTENTS "+CONTENTS"
|
||||
|
||||
/* some programs */
|
||||
#define PKG_DELETE "/usr/sbin/pkg_delete"
|
||||
#define PKG_INFO "/usr/sbin/pkg_info"
|
||||
#define PKG_ADD "/usr/sbin/pkg_add"
|
||||
#define TAR "/usr/bin/tar"
|
||||
#define TAR "/usr/bin/tar"
|
||||
#define GUNZIP "/usr/bin/gunzip"
|
||||
|
||||
/* HELP_PATH must have a trailing '/' */
|
||||
#ifndef HELP_PATH
|
||||
#define HELP_PATH "/home/marc/src/pkg_manage/"
|
||||
#define HELP_PATH "/home/marc/src/dialog/pkg_manage/"
|
||||
#endif
|
||||
#define VIEW_INST_HLP HELP_PATH##"pkg_view-inst.hlp"
|
||||
#define DEL_INST_HLP HELP_PATH##"pkg_del-inst.hlp"
|
||||
#define PREVIEW_HLP HELP_PATH##"pkg_preview.hlp"
|
||||
#define VIEW_INST_HLP HELP_PATH##"pkg_view_inst.hlp"
|
||||
#define DEL_INST_HLP HELP_PATH##"pkg_del_inst.hlp"
|
||||
#define INSTALL_HLP HELP_PATH##"pkg_install.hlp"
|
||||
#define MAIN_HLP HELP_PATH##"pkg_main.hlp"
|
||||
#define DS_INSTALL_HLP HELP_PATH##"pkg_ds_install.hlp"
|
||||
|
||||
|
||||
/*
|
||||
* prototypes
|
||||
*/
|
||||
|
||||
void run_menu(void);
|
||||
void get_pkginfo(void);
|
||||
void FreeMnu(unsigned char **mnu, int n);
|
||||
void FreeInfo(void);
|
||||
void install_package(char *fname);
|
||||
int get_pkg_index(char *selection);
|
||||
void install_batch(void);
|
||||
int get_desc(char *fname, char **name, char **comment,
|
||||
char **desc, long *size, char *tmp_file);
|
||||
int exec_catch_errors(char *prog, char *arg, char *fout);
|
||||
int already_installed(char *name);
|
||||
|
496
usr.sbin/pkg_manage/pkg_ui.c
Normal file
496
usr.sbin/pkg_manage/pkg_ui.c
Normal file
@ -0,0 +1,496 @@
|
||||
/***************************************************************
|
||||
*
|
||||
* Program: pkg_ui.c
|
||||
* Author: Marc van Kempen
|
||||
* Desc: user interface parts of pkg_manage
|
||||
*
|
||||
* Copyright (c) 1995, Marc van Kempen
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software may be used, modified, copied, distributed, and
|
||||
* sold, in both source and binary form provided that the above
|
||||
* copyright and these terms are retained, verbatim, as the first
|
||||
* lines of this file. Under no circumstances is the author
|
||||
* responsible for the proper functioning of this software, nor does
|
||||
* the author assume any responsibility for damages incurred with
|
||||
* its use.
|
||||
*
|
||||
***************************************************************/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/param.h>
|
||||
#include "pkg_manage.h"
|
||||
#include "dir.h"
|
||||
#include "dialog.priv.h"
|
||||
#include "ui_objects.h"
|
||||
|
||||
extern PKG_info p_inf;
|
||||
|
||||
|
||||
void
|
||||
view_installed(void)
|
||||
/*
|
||||
* Desc: View the installed packages
|
||||
*/
|
||||
{
|
||||
int i, quit_view, sc=0, ch=0;
|
||||
char selection[1024];
|
||||
|
||||
if (p_inf.Nitems == 0) {
|
||||
use_helpfile(NULL);
|
||||
use_helpline(NULL);
|
||||
dialog_notify("No packages installed or no info available");
|
||||
return;
|
||||
}
|
||||
use_helpfile(VIEW_INST_HLP);
|
||||
quit_view = FALSE;
|
||||
while (!quit_view) {
|
||||
use_helpline("F1=help, use arrow-keys or character to select option and press enter");
|
||||
if (dialog_menu("View installed packages",
|
||||
"Press enter to see the package descriptions",
|
||||
LINES, COLS, LINES-5, p_inf.Nitems,
|
||||
p_inf.mnu, selection, &ch, &sc )) {
|
||||
quit_view = TRUE;
|
||||
} else {
|
||||
i = get_pkg_index(selection);
|
||||
use_helpline("F1=help, use PgUp and PgDn and arrow-keys to move through the text");
|
||||
dialog_mesgbox(p_inf.comment[i], p_inf.description[i], LINES, COLS);
|
||||
}
|
||||
}
|
||||
|
||||
use_helpfile(NULL);
|
||||
use_helpline(NULL);
|
||||
|
||||
return;
|
||||
} /* view_installed() */
|
||||
|
||||
void
|
||||
delete_installed(void)
|
||||
/*
|
||||
* Desc: Delete an installed package
|
||||
*/
|
||||
{
|
||||
unsigned char *mnu[] = {
|
||||
"1. Simulate delete", "Display commands that are going to be executed",
|
||||
"2. Delete", "Execute commands to delete the package",
|
||||
"3. Cancel", "Do NOT delete the package"
|
||||
};
|
||||
char tmp[512], args[512], selection[512], *tmp_file;
|
||||
int quit_view, quit_del;
|
||||
int i, sel, ch=0, sc=0, ch0=0, sc0=0, ret;
|
||||
|
||||
if (p_inf.Nitems == 0) {
|
||||
use_helpfile(NULL);
|
||||
use_helpline(NULL);
|
||||
dialog_notify("No packages installed or no info available");
|
||||
return;
|
||||
}
|
||||
quit_view = FALSE;
|
||||
while (!quit_view) {
|
||||
use_helpline("F1=help, use arrow-keys or character to select option and press enter");
|
||||
use_helpfile(DEL_INST_HLP);
|
||||
if (dialog_menu("DELETE an installed package",
|
||||
"Press enter to select a package",
|
||||
LINES, COLS, LINES-5, p_inf.Nitems,
|
||||
p_inf.mnu, selection, &ch, &sc)) {
|
||||
quit_view = TRUE;
|
||||
} else {
|
||||
quit_del = FALSE;
|
||||
i = get_pkg_index(selection);
|
||||
while (!quit_del) {
|
||||
sprintf(tmp, "Delete <%s>", p_inf.name[i]);
|
||||
use_helpline("F1=help, use arrow-keys or digit to select option and press enter");
|
||||
if (dialog_menu("Delete a package", tmp, 10, COLS-6,
|
||||
3, 3, mnu, selection, &ch0, &sc0)) {
|
||||
quit_del = TRUE;
|
||||
} else {
|
||||
sel = atoi(selection);
|
||||
switch(sel) {
|
||||
case 1:
|
||||
tmp_file = tempnam(NULL, "pkg.");
|
||||
sprintf(args, "-n %s", p_inf.name[i]);
|
||||
ret = exec_catch_errors(PKG_DELETE, args, tmp_file);
|
||||
if (!ret) {
|
||||
dialog_textbox("Package deletion commands",
|
||||
tmp_file, LINES, COLS);
|
||||
}
|
||||
unlink(tmp_file);
|
||||
free(tmp_file);
|
||||
break;
|
||||
case 2:
|
||||
exec_catch_errors(PKG_DELETE, p_inf.name[i], NULL);
|
||||
get_pkginfo();
|
||||
if (ch >= p_inf.Nitems) { /* adjust pointers */
|
||||
ch = p_inf.Nitems-1;
|
||||
if (sc>ch) sc=ch;
|
||||
}
|
||||
quit_del = TRUE;
|
||||
if (p_inf.Nitems == 0) {
|
||||
/* Quit 'delete-installed' when no packages available */
|
||||
quit_view = TRUE;
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
quit_del = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
use_helpfile(NULL);
|
||||
use_helpline(NULL);
|
||||
|
||||
return;
|
||||
} /* delete_installed() */
|
||||
|
||||
void
|
||||
install_batch(void)
|
||||
/*
|
||||
* Desc: install several packages.
|
||||
*/
|
||||
{
|
||||
WINDOW *pkg_win, *w;
|
||||
DirList *d = NULL;
|
||||
char **fnames, o_pkg[MAXPATHLEN], o_pkgi[MAXPATHLEN],
|
||||
**comment, **desc, **names, msg[512];
|
||||
int n, nf, i, p, quit, j, *a, recalc;
|
||||
struct ComposeObj *obj = NULL;
|
||||
ListObj *pkg_obj, *pkgi_obj;
|
||||
ButtonObj *installbut_obj, *cancelbut_obj;
|
||||
int o_installbut, o_cancelbut, install;
|
||||
long total_marked = 0, *sizes;
|
||||
char *tmp_file, tmp_dir[MAXPATHLEN];
|
||||
|
||||
/* first go to the directory where the packages are installed, then
|
||||
list all packages in that directory with a short description of
|
||||
the package. Pressing enter should give more info about a specific
|
||||
package. */
|
||||
|
||||
use_helpfile(DS_INSTALL_HLP);
|
||||
use_helpline("Select the directory where the pkg's reside");
|
||||
if (dialog_dselect()) {
|
||||
/* cancel button was pressed */
|
||||
return;
|
||||
}
|
||||
use_helpline(NULL);
|
||||
|
||||
pkg_win = newwin(LINES-4, COLS-12, 2, 5);
|
||||
if (pkg_win == NULL) {
|
||||
endwin();
|
||||
fprintf(stderr, "\nnewwin(%d,%d,%d,%d) failed, maybe wrong dims\n",
|
||||
LINES-4, COLS-10, 2, 5);
|
||||
exit(1);
|
||||
}
|
||||
draw_box(pkg_win, 0, 0, LINES-4, COLS-12, dialog_attr, border_attr);
|
||||
wattrset(pkg_win, dialog_attr);
|
||||
mvwaddstr(pkg_win, 0, (COLS-12)/2 - 12, " Install multiple packages ");
|
||||
draw_shadow(stdscr, 2, 5, LINES-4, COLS-12);
|
||||
use_helpline("Enter,F2=info, Space=mark, *=mark all, -=unmark all, TAB=move");
|
||||
display_helpline(pkg_win, LINES-5, COLS-12);
|
||||
wrefresh(pkg_win);
|
||||
|
||||
/* now build a list of the packages in the chosen directory */
|
||||
/* and display them in a list */
|
||||
|
||||
get_dir(".", "*.tgz", &d, &n);
|
||||
get_filenames(d, n, &fnames, &nf);
|
||||
FreeDir(d, n); /* free the space allocated to d */
|
||||
|
||||
/* now get the description and comment and the name from the packages. */
|
||||
/* If there is no +COMMENT or +DESC in the package, then it's propably */
|
||||
/* not a package */
|
||||
|
||||
if (nf == 0) {
|
||||
dialog_notify("No installable packages in this directory");
|
||||
return;
|
||||
}
|
||||
|
||||
names = (char **) malloc( sizeof(char *) * nf);
|
||||
comment = (char **) malloc( sizeof(char *) * nf );
|
||||
desc = (char **) malloc( sizeof(char *) * nf );
|
||||
sizes = (long *) malloc( sizeof(long) * nf );
|
||||
|
||||
/* get_desc extracts the info from the file names[i] and puts the */
|
||||
/* comment in comment[i] and the description in desc[i], space is */
|
||||
/* malloc'ed as needed, and should be freed when done with it. */
|
||||
/* get_desc() returns FALSE when fnames[i] is not a package */
|
||||
/* the name of the package is extracted from CONTENT and put in */
|
||||
/* names */
|
||||
|
||||
/* create a tmp directory in which the files will be extracted */
|
||||
|
||||
tmp_file = tempnam("", "pkg.");
|
||||
if (!tmp_file) {
|
||||
fprintf(stderr, "install_batch(): Error malloc'ing space for tmpfile\n");
|
||||
exit(1);
|
||||
}
|
||||
sprintf(tmp_dir, "/tmp/%s", tmp_file);
|
||||
free(tmp_file);
|
||||
if (mkdir(tmp_dir, S_IRWXU)) {
|
||||
dialog_notify("Could not create temporary directory in /tmp, exiting");
|
||||
free(names);
|
||||
free(comment);
|
||||
free(desc);
|
||||
for (i=0; i<nf; i++) free(fnames[i]);
|
||||
free(fnames);
|
||||
delwin(pkg_win);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
w = dupwin(curscr);
|
||||
a = (int *) malloc( nf * sizeof(int) );
|
||||
j = 0;
|
||||
for (i=0; i<nf; i++) {
|
||||
dialog_gauge("Scanning directory:", fnames[i], LINES/2-3, COLS/2-30,
|
||||
7, 60, (int) ((float) (i+1)/nf*100));
|
||||
if (get_desc(fnames[i], &(names[i]), &(comment[i]),
|
||||
&(desc[i]), &(sizes[i]), tmp_dir) == FALSE) {
|
||||
a[j] = i;
|
||||
j++;
|
||||
}
|
||||
}
|
||||
wrefresh(w);
|
||||
delwin(w);
|
||||
|
||||
/* remove the tmp directory and change to the previous directory */
|
||||
if (rmdir(tmp_dir)) {
|
||||
dialog_notify("install_batch(): Error removing temporary directory");
|
||||
for (i=0; i<nf; i++) {
|
||||
free(fnames[i]);
|
||||
free(names[i]);
|
||||
free(comment[i]);
|
||||
free(desc[i]);
|
||||
}
|
||||
free(fnames);
|
||||
free(names);
|
||||
free(comment);
|
||||
free(desc);
|
||||
free(sizes);
|
||||
delwin(pkg_win);
|
||||
}
|
||||
|
||||
/* Now we should have an array with indices of filenames that are not */
|
||||
/* packages, say a[0..k), 0<=k<=n, and the filenames itself */
|
||||
/* remove the non-packages from the array */
|
||||
|
||||
i=0;
|
||||
p=0;
|
||||
while (i+p < nf) {
|
||||
if ((i+p == a[p]) && (p<j)) {
|
||||
free(fnames[i+p]);
|
||||
free(names[i+p]);
|
||||
free(comment[i+p]);
|
||||
free(desc[i+p]);
|
||||
p++;
|
||||
} else {
|
||||
fnames[i] = fnames[i+p];
|
||||
names[i] = names[i+p];
|
||||
comment[i] = comment[i+p];
|
||||
desc[i] = desc[i+p];
|
||||
sizes[i] = sizes[i+p];
|
||||
i++;
|
||||
}
|
||||
}
|
||||
nf = nf - j;
|
||||
free(a);
|
||||
|
||||
o_pkg[0] = '0';
|
||||
pkg_obj = NewListObj(pkg_win, "To be installed", names, o_pkg,
|
||||
1, 2, LINES-11, COLS-50, nf);
|
||||
AddObj(&obj, LISTOBJ, (void *) pkg_obj);
|
||||
|
||||
o_pkgi[0] = '0';
|
||||
pkgi_obj = NewListObj(pkg_win, "Already Installed", p_inf.name, o_pkgi,
|
||||
1, COLS-45, LINES-11, COLS-50, p_inf.Nitems);
|
||||
AddObj(&obj, LISTOBJ, (void *) pkgi_obj);
|
||||
|
||||
o_installbut = FALSE;
|
||||
installbut_obj = NewButtonObj(pkg_win, "Install marked", &o_installbut,
|
||||
LINES-8, (COLS-12)/2 - 22);
|
||||
AddObj(&obj, BUTTONOBJ, (void *) installbut_obj);
|
||||
|
||||
o_cancelbut = FALSE;
|
||||
cancelbut_obj = NewButtonObj(pkg_win, "Cancel", &o_cancelbut,
|
||||
LINES-8, (COLS-12)/2 + 2);
|
||||
AddObj(&obj, BUTTONOBJ, (void *) cancelbut_obj);
|
||||
|
||||
/* print total_marked in window */
|
||||
wmove(pkg_win, LINES-9, 2);
|
||||
wattrset(pkg_win, dialog_attr);
|
||||
waddstr(pkg_win, "Total marked = 0 kB");
|
||||
total_marked = 0;
|
||||
|
||||
recalc = FALSE;
|
||||
quit = FALSE;
|
||||
install = FALSE;
|
||||
while (!quit) {
|
||||
use_helpfile(INSTALL_HLP);
|
||||
switch(PollObj(&obj)) {
|
||||
case SEL_CR:
|
||||
/* first move back one list object */
|
||||
if (obj->prev) obj=obj->prev;
|
||||
|
||||
if ((ListObj *) obj->obj == pkg_obj) {
|
||||
dialog_notify(comment[pkg_obj->sel]);
|
||||
}
|
||||
if ((ListObj *) obj->obj == pkgi_obj) {
|
||||
dialog_notify(p_inf.comment[pkgi_obj->sel]);
|
||||
}
|
||||
break;
|
||||
case SEL_BUTTON:
|
||||
if (o_installbut) {
|
||||
install = TRUE;
|
||||
quit = TRUE;
|
||||
}
|
||||
if (o_cancelbut) {
|
||||
quit = TRUE;
|
||||
}
|
||||
break;
|
||||
case SEL_ESC:
|
||||
quit = TRUE;
|
||||
break;
|
||||
case ' ':
|
||||
if ((ListObj *) obj->obj == pkg_obj) {
|
||||
MarkCurrentListObj(pkg_obj);
|
||||
}
|
||||
recalc = TRUE;
|
||||
wrefresh(pkg_win);
|
||||
break;
|
||||
case '*':
|
||||
if ((ListObj *) obj->obj == pkg_obj) {
|
||||
MarkAllListObj(pkg_obj);
|
||||
}
|
||||
recalc = TRUE;
|
||||
break;
|
||||
case '-':
|
||||
if ((ListObj *) obj->obj == pkg_obj) {
|
||||
UnMarkAllListObj(pkg_obj);
|
||||
}
|
||||
recalc = TRUE;
|
||||
break;
|
||||
case KEY_F(1):
|
||||
display_helpfile();
|
||||
break;
|
||||
case KEY_F(2):
|
||||
if ((ListObj *) obj->obj == pkg_obj) {
|
||||
dialog_notify(desc[pkg_obj->sel]);
|
||||
}
|
||||
if ((ListObj *) obj->obj == pkgi_obj) {
|
||||
dialog_notify(p_inf.description[pkgi_obj->sel]);
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (recalc) {
|
||||
total_marked = 0;
|
||||
for (i=0; i<nf; i++) {
|
||||
if (pkg_obj->seld[i]) {
|
||||
total_marked += sizes[i];
|
||||
}
|
||||
}
|
||||
recalc = FALSE;
|
||||
/* print total_marked in window */
|
||||
wmove(pkg_win, LINES-9, 2);
|
||||
wattrset(pkg_win, dialog_attr);
|
||||
sprintf(msg, "Total marked = %6ld kB", (long) (total_marked / 1024));
|
||||
waddstr(pkg_win, msg);
|
||||
wrefresh(pkg_win);
|
||||
}
|
||||
}
|
||||
|
||||
if (install) {
|
||||
/* check if any of the packages marked for installation are */
|
||||
/* already installed */
|
||||
i=0;
|
||||
n=0;
|
||||
while (i < nf) {
|
||||
if ((pkg_obj->seld[i]) && (already_installed(names[i+p]))) {
|
||||
/* popup a warning and remove the package from the */
|
||||
/* packages that are going to be installed */
|
||||
sprintf(msg, " The following package is already installed:\n %s (%s)\n",
|
||||
names[i], fnames[i]);
|
||||
strcat(msg, " This package will be skipped\n");
|
||||
strcat(msg, " If you want to install it anyway, remove it first");
|
||||
dialog_notify(msg);
|
||||
pkg_obj->seld[i] = FALSE;
|
||||
}
|
||||
if (pkg_obj->seld[i]) n++; /* count selected packages */
|
||||
i++;
|
||||
}
|
||||
/* now install whatever is left */
|
||||
for (i=0; i<nf; i++) {
|
||||
if (pkg_obj->seld[i]) {
|
||||
dialog_gauge("Installing packages:", names[i], LINES/2-3,
|
||||
COLS/2-30, 7, 60, (int) ((float) i/n*100));
|
||||
install_package(fnames[i]);
|
||||
}
|
||||
}
|
||||
if (n>0) get_pkginfo();
|
||||
}
|
||||
|
||||
/* clean up */
|
||||
for (i=0; i<nf; i++) {
|
||||
free(fnames[i]);
|
||||
free(names[i]);
|
||||
free(comment[i]);
|
||||
free(desc[i]);
|
||||
}
|
||||
free(fnames);
|
||||
free(names);
|
||||
free(comment);
|
||||
free(desc);
|
||||
free(sizes);
|
||||
DelObj(obj);
|
||||
use_helpfile(NULL);
|
||||
use_helpline(NULL);
|
||||
delwin(pkg_win);
|
||||
|
||||
return;
|
||||
} /* install_batch() */
|
||||
|
||||
void
|
||||
run_menu(void)
|
||||
/*
|
||||
* Desc: display/choose from menu
|
||||
*/
|
||||
{
|
||||
int quit_pkg, sel, ch=0, sc=0;
|
||||
char selection[30];
|
||||
unsigned char *pkg_menu[] = {
|
||||
"1. View installed", "Overview of the installed packages",
|
||||
"2. Delete installed", "Delete an installed package",
|
||||
"3. Install packages", "Install one or more packages",
|
||||
"4. Quit", "Leave the program",
|
||||
};
|
||||
|
||||
quit_pkg = FALSE;
|
||||
while (!quit_pkg) {
|
||||
use_helpline("F1=help, use arrow-keys or digit to select option and press enter");
|
||||
use_helpfile(MAIN_HLP);
|
||||
if (dialog_menu("Package Manager", "Choose one of the options",
|
||||
LINES, COLS, 4, 4, pkg_menu, selection, &ch, &sc)) {
|
||||
quit_pkg = TRUE;
|
||||
} else {
|
||||
sel = atoi(selection);
|
||||
switch(sel) {
|
||||
case 1: /* View installed packages */
|
||||
view_installed();
|
||||
break;
|
||||
case 2: /* Delete installed package */
|
||||
delete_installed();
|
||||
break;
|
||||
case 3: /* Install multiple packages */
|
||||
install_batch();
|
||||
break;
|
||||
case 4: /* Quit */
|
||||
quit_pkg = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
} /* run_menu() */
|
1
usr.sbin/pkg_manage/version.c
Normal file
1
usr.sbin/pkg_manage/version.c
Normal file
@ -0,0 +1 @@
|
||||
char version[] = "pkg_manage version 1.0";
|
Loading…
Reference in New Issue
Block a user