Browse Source

Use new linked list stuff and package functions from libdebian-installer3

Comment out the toposort stuff for the main menu, do we really want to do it? It rearranges the menu and ignores installer-menu-item.

r1421
keep-around/c8703c509368e1805e513d61f98a9d17d2cdd9cc
Martin Sjögren 20 years ago
parent
commit
16d4719142
  1. 9
      debian/changelog
  2. 2
      debian/control
  3. 132
      main-menu.c
  4. 6
      main-menu.h
  5. 36
      status.c
  6. 100
      tree.c

9
debian/changelog

@ -1,3 +1,12 @@
main-menu (0.019) UNRELEASED; urgency=low
* Martin Sjögren
- Use new linked list stuff and package functions from libdebian-installer3
- Comment out the toposort stuff for the main menu, do we really want to
do it? It rearranges the menu and ignores installer-menu-item.
-- Martin Sjogren <md9ms@mdstud.chalmers.se> Sat, 30 Nov 2002 16:30:26 +0100
main-menu (0.018) unstable; urgency=low
* Martin Sjögren

2
debian/control

@ -2,7 +2,7 @@ Source: main-menu
Section: debian-installer
Priority: standard
Maintainer: Joey Hess <joeyh@debian.org>
Build-Depends: debhelper (>= 4.1.13), dpkg-dev (>= 1.7.0), libcdebconf-dev, dpkg-dev (>= 1.9), libdebian-installer2-dev (>= 0.06), po-debconf (>= 0.5.0)
Build-Depends: debhelper (>= 4.1.13), dpkg-dev (>= 1.7.0), libcdebconf-dev, dpkg-dev (>= 1.9), libdebian-installer3-dev (>= 0.07), po-debconf (>= 0.5.0)
Standards-Version: 3.5.6.1
Package: main-menu

132
main-menu.c

@ -23,6 +23,8 @@
#include <stdlib.h>
#include <string.h>
static struct linkedlist_t *packages;
#ifdef DODEBUG
static int do_system(const char *cmd) {
DPRINTF("cmd is %s\n", cmd);
@ -43,6 +45,8 @@ int compare (const void *a, const void *b) {
(*(struct package_t **)a)->package);
}
#if 0
// This is commented out becuase I'm not sure we want to do this
/*
* Builds a linked list of packages, ordered by dependencies, so
* depended-upon packages come first. Pass the package to start ordering
@ -82,6 +86,7 @@ void order_done(struct package_t *head) {
for (p=head; p; p=p->next)
p->processed = 0;
}
#endif
/* Returns true if the given package could be the default menu item. */
int isdefault(struct package_t *p) {
@ -106,10 +111,11 @@ int isdefault(struct package_t *p) {
}
/* Displays the main menu via debconf and returns the selected menu item. */
struct package_t *show_main_menu(struct package_t *packages) {
struct package_t *show_main_menu(struct linkedlist_t *list) {
static struct debconfclient *debconf = NULL;
char *language = NULL;
struct package_t **package_list, *p, *head = NULL, *tail = NULL;
struct package_t **package_list, *p;
struct list_node *node;
struct package_t *menudefault = NULL;
struct language_description *langdesc;
int i = 0, num = 0;
@ -125,12 +131,18 @@ struct package_t *show_main_menu(struct package_t *packages) {
if (debconf->value)
language = strdup(debconf->value);
/* Make a flat list of the packages. */
for (p = packages; p; p = p->next)
num++;
for (node = list->head; node; node = node->next) {
p = (struct package_t *)node->data;
if (p->installer_menu_item)
num++;
}
package_list = malloc(num * sizeof(struct package_t *));
for (p = packages; p; p = p->next) {
package_list[i] = p;
i++;
for (node = list->head; node; node = node->next) {
p = (struct package_t *)node->data;
if (p->installer_menu_item) {
package_list[i] = (struct package_t *)node->data;
i++;
}
}
/* Sort by menu number. */
@ -138,52 +150,54 @@ struct package_t *show_main_menu(struct package_t *packages) {
/* Order menu so depended-upon packages come first. */
/* The menu number is really only used to break ties. */
#if 0
//I'm not sure this is a good idea... Maybe it's better to highlight the
//default choice in some other way instead?
for (i = 0; i < num ; i++) {
if (package_list[i]->installer_menu_item) {
order(package_list[i], &head, &tail);
}
}
order_done(head);
free(package_list);
#endif
/*
* Generate list of menu choices for debconf. Also figure out which
* is the default.
*/
s = menutext;
for (p = head; p; p = p->next) {
if (p->installer_menu_item) {
int ok = 0;
if (language) {
langdesc = p->localized_descriptions;
while (langdesc) {
if (strcmp(langdesc->language,language) == 0) {
/* Use this description */
strcpy(s,langdesc->description);
s += strlen(langdesc->description);
ok = 1;
break;
}
langdesc = langdesc->next;
for (i = 0; i < num; i++) {
int ok = 0;
p = package_list[i];
if (language) {
langdesc = p->localized_descriptions;
while (langdesc) {
if (strcmp(langdesc->language,language) == 0) {
/* Use this description */
strcpy(s,langdesc->description);
s += strlen(langdesc->description);
ok = 1;
break;
}
langdesc = langdesc->next;
}
if (ok == 0) {
strcpy(s, p->description);
s += strlen(p->description);
}
*s++ = ',';
*s++ = ' ';
}
if (ok == 0) {
strcpy(s, p->description);
s += strlen(p->description);
}
*s++ = ',';
*s++ = ' ';
if (isdefault(p)) {
if (menudefault) {
if (menudefault->installer_menu_item > p->installer_menu_item) {
menudefault = p;
}
} else {
menudefault = p;
}
}
if (isdefault(p)) {
if (menudefault) {
if (menudefault->installer_menu_item > p->installer_menu_item) {
menudefault = p;
}
} else {
menudefault = p;
}
}
}
/* Trim trailing ", " */
@ -206,7 +220,8 @@ struct package_t *show_main_menu(struct package_t *packages) {
s=debconf->value;
/* Figure out which menu item was selected. */
for (p = head; p; p = p->next) {
for (i = 0; i < num; i++) {
p = package_list[i];
if (p->installer_menu_item && strcmp(p->description, s) == 0)
return p;
else if (p->installer_menu_item && language) {
@ -222,16 +237,6 @@ struct package_t *show_main_menu(struct package_t *packages) {
static int config_package(struct package_t *);
static int provides(struct package_t *p, const char *what)
{
int i;
for (i = 0; p->provides[i] != 0; i++)
if (strcmp(p->provides[i], what) == 0)
return 1;
return 0;
}
/*
* Satisfy the dependencies of a virtual package. Its dependencies that actually
* provide the package are presented in a debconf select question for the user
@ -252,9 +257,9 @@ static int satisfy_virtual(struct package_t *p) {
* package with highest priority. If we have ties, menu items are
* preferred. If we still have ties, the default choice is arbitrary */
for (i = 0; p->depends[i] != 0; i++) {
if ((dep = tree_find(p->depends[i])) == NULL)
if ((dep = p->depends[i]->ptr) == NULL)
continue;
if (!provides(dep, p->package)) {
if (!di_pkg_provides(dep, p)) {
/* Non-providing dependency */
if (dep->status != installed && !config_package(dep))
return 0;
@ -300,9 +305,9 @@ static int satisfy_virtual(struct package_t *p) {
}
/* Go through the dependencies again */
for (i = 0; p->depends[i] != 0; i++) {
if ((dep = tree_find(p->depends[i])) == NULL)
if ((dep = p->depends[i]->ptr) == NULL)
continue;
if (!provides(dep, p->package))
if (!di_pkg_provides(dep, p))
continue;
if (!is_menu_item || strcmp(debconf->value, dep->description) == 0) {
/* Ick. If we have a menu item it has to match the
@ -322,23 +327,6 @@ static int satisfy_virtual(struct package_t *p) {
return 1;
}
/*
* Simplistic test for virtual packages. A package is virtual if any
* of its dependencies provides it.
*/
static int is_virtual(struct package_t *p) {
int i;
struct package_t *dep;
for (i = 0; p->depends[i] != 0; i++) {
if ((dep = tree_find(p->depends[i])) == NULL)
continue;
if (provides(dep, p->package))
return 1;
}
return 0;
}
/*
* Configure all dependencies, special case for virtual packages.
* This is done depth-first.
@ -350,11 +338,11 @@ config_package(struct package_t *p) {
struct package_t *dep;
for (i = 0; p->depends[i] != 0; i++) {
if ((dep = tree_find(p->depends[i])) == NULL)
if ((dep = p->depends[i]->ptr) == NULL)
continue;
if (dep->status == installed)
continue;
if (is_virtual(dep)) {
if (di_pkg_is_virtual(dep)) {
if (!satisfy_virtual(dep))
return 0;
} else {
@ -389,7 +377,7 @@ int do_menu_item(struct package_t *p) {
}
int main (int argc, char **argv) {
struct package_t *p, *packages;
struct package_t *p;
/* Tell udpkg to shut up. */
setenv("UDPKG_QUIET", "y", 1);

6
main-menu.h

@ -20,9 +20,5 @@
#include <debian-installer.h>
/* status.c */
struct package_t *status_read(void);
struct linkedlist_t *status_read(void);
/* tree.c */
struct package_t *tree_find(char *);
struct package_t *tree_add(struct package_t *);
void tree_clear();

36
status.c

@ -13,12 +13,9 @@
/*
* Read status file and generate and return a linked list of packages.
*/
struct package_t *status_read(void) {
struct linkedlist_t *status_read(void) {
FILE *f;
int i, k;
struct package_t *found, *plist, *p;
tree_clear();
struct linkedlist_t *plist;
if ((f = fopen(STATUSFILE, "r")) == NULL) {
perror(STATUSFILE);
@ -26,34 +23,7 @@ struct package_t *status_read(void) {
}
plist = di_pkg_parse(f);
fclose(f);
for (p = plist; p != NULL; p = p->next)
{
tree_add(p);
}
for (p = plist; p != NULL; p = p->next)
{
for (k = 0; p->provides[k] != 0; k++)
{
found = tree_find(p->provides[k]);
if (found == NULL)
{
found = (struct package_t *)malloc(sizeof(struct package_t));
memset(found, 0, sizeof(struct package_t));
found->package = strdup(p->provides[k]);
tree_add(found);
/* TODO: Do we want the virtual packages in the list
* or just the tree? */
found->next = plist;
plist = found;
}
for (i = 0; found->depends[i] != 0; i++)
;
found->depends[i] = p->package;
found->depends[i+1] = 0;
}
}
di_pkg_resolve_deps(plist);
return plist;
}

100
tree.c

@ -1,100 +0,0 @@
/*
* Package btree routines.
*/
#include "main-menu.h"
#include <search.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void *root=NULL;
int _tree_compare (const void *p1, const void *p2) {
return strcmp(((struct package_t *)p1)->package,
((struct package_t *)p2)->package);
}
/* Find a package. */
struct package_t *tree_find(char *packagename) {
struct package_t find;
void *ret;
find.package = packagename;
ret=tfind(&find, &root, _tree_compare);
if (ret)
return *(struct package_t **)ret;
return NULL;
}
/*
* Adds a package to the tree. Note that the structure is now created
* by e.g. di_pkg_parse.
*/
struct package_t *tree_add(struct package_t *pkg) {
/*
* I should just be able to return tsearch's return code, but this
* makes my code fail horribly later on. I think tsearch has
* issues.
*/
tsearch(pkg, &root, _tree_compare);
return pkg;
}
#if DODEBUG
void _tree_dump(const void *nodep, const VISIT which, const int depth) {
int i;
struct package_t *p = *(struct package_t **)nodep;
for (i=0; i < depth; i++)
fprintf(stderr, " ");
switch(which) {
case postorder:
fprintf(stderr, " at"); /* false indent */
break;
case preorder:
fprintf(stderr, "begin");
break;
case endorder:
fprintf(stderr, "end");
break;
case leaf:
fprintf(stderr, "leaf");
break;
}
fprintf(stderr, " %s\n", p->package);
}
/* Dump out the tree. */
void tree_dump() {
twalk(root, _tree_dump);
}
#endif
void _tree_free(void *nodep) {
struct package_t *p = (struct package_t *)nodep;
if (p->description)
free(p->description);
if (p->package)
free(p->package);
free(p);
}
/* Clears out the entire tree, freeing all package stucts contained it in. */
void tree_clear() {
/*
* The correct way to do this is explained in the tsearch() man
* page in the example. Unfortunatly, glibc is broken, and using a
* twalk() with nested tdelete() calls will not delete the whole
* tree (see Debian bug #63575).
*
* So what I do instead is use glibc's tdestroy function.
* WARNING: probably not portable!
*/
tdestroy(root, _tree_free);
root = NULL;
}
Loading…
Cancel
Save