1
0
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:
Jordan K. Hubbard 1995-04-21 10:05:46 +00:00
parent 36034afc79
commit e722380a68
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=7973
9 changed files with 1006 additions and 341 deletions

View 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.

View File

@ -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
View 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.

View 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() */

View File

@ -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.

View File

@ -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() */

View File

@ -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);

View 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() */

View File

@ -0,0 +1 @@
char version[] = "pkg_manage version 1.0";