Browse Source

all very experimental, and does nothing yet

r24
keep-around/c8703c509368e1805e513d61f98a9d17d2cdd9cc
Joey Hess 22 years ago
commit
b3bf723c4d
  1. 11
      Makefile
  2. 64
      main-menu.c
  3. 25
      main-menu.h
  4. 115
      status.c

11
Makefile

@ -0,0 +1,11 @@
CFLAGS=-Wall -g
OBJS=$(subst .c,.o,$(wildcard *.c))
BIN=main-menu
all: $(BIN)
$(BIN): $(OBJS)
$(CC) -o $(BIN) $(OBJS) $(LIBS)
clean:
-rm -f $(BIN) $(OBJS) *~

64
main-menu.c

@ -0,0 +1,64 @@
#include "main-menu.h"
#include <stdio.h>
#include <search.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
static void depends_sort_visit(struct package_t **ordered,
struct package_t *pkgs, struct package_t *pkg) {
/* Topological sort algorithm:
* ordered is the output list, pkgs is the dependency graph, pkg is
* the current node
*
* recursively add all the adjacent nodes to the ordered list,
* marking each one as visited along the way
*
* yes, this algorithm looks a bit odd when all the params have the
* same type :-)
*/
unsigned short i;
struct package_t *newnode;
/* mark node as processing */
pkg->color = COLOR_GRAY;
/* visit each not-yet-visited node */
for (i = 0; i < pkg->requiredcount; i++)
if (pkg->requiredfor[i]->color == COLOR_WHITE)
depends_sort_visit(ordered, pkgs, pkg->requiredfor[i]);
/* add it to the list */
newnode = (struct package_t *)malloc(sizeof(struct package_t));
/* make a shallow copy */
*newnode = *pkg;
newnode->next = *ordered;
*ordered = newnode;
/* mark node as done */
pkg->color = COLOR_BLACK;
}
static struct package_t *depends_sort(struct package_t *pkgs) {
struct package_t *ordered = NULL;
struct package_t *pkg;
for (pkg = pkgs; pkg != 0; pkg = pkg->next)
pkg->color = COLOR_WHITE;
for (pkg = pkgs; pkg != 0; pkg = pkg->next)
if (pkg->color == COLOR_WHITE)
depends_sort_visit(&ordered, pkgs, pkg);
/* Leaks the old list... return the new one... */
return ordered;
}
int main (int argc, char **argv) {
void *status;
status = status_read();
return(0);
}

25
main-menu.h

@ -0,0 +1,25 @@
#define BUFSIZE 4096
#define STATUSFILE "/var/lib/dpkg/status"
#define DEPENDSMAX 64 /* maximum number of depends we can handle */
#define COLOR_WHITE 0
#define COLOR_GRAY 1
#define COLOR_BLACK 2
/* data structures */
struct package_t {
char *package;
char *provides;
int installer_menu_item;
char *description; /* short only */
char color; /* for topo-sort */
char refcount;
struct package_t *requiredfor[DEPENDSMAX];
unsigned short requiredcount;
struct package_t *next;
};
int package_compare(const void *p1, const void *p2);
void *status_read(void);

115
status.c

@ -0,0 +1,115 @@
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <search.h>
#include "main-menu.h"
static char **depends_split(const char *dependsstr) {
static char *dependsvec[DEPENDSMAX];
char *p;
int i = 0;
dependsvec[0] = 0;
if (dependsstr != 0) {
p = strdup(dependsstr);
while (*p != 0 && *p != '\n') {
if (*p != ' ') {
if (*p == ',') {
*p = 0;
dependsvec[++i] = 0;
}
else if (dependsvec[i] == 0)
dependsvec[i] = p;
}
else
*p = 0; /* eat the space... */
p++;
}
*p = 0;
}
dependsvec[i+1] = 0;
return dependsvec;
}
int package_compare(const void *p1, const void *p2) {
return strcmp(((struct package_t *)p1)->package,
((struct package_t *)p2)->package);
}
/* Adds a new package to the tree, unless it already exists. */
struct package_t *_newpackage (const char *packagename, void *status) {
struct package_t *p, *t = 0;
p = (struct package_t *)malloc(sizeof(struct package_t));
memset(p, 0, sizeof(struct package_t));
p->package = strdup(packagename);
t = *(struct package_t **)tsearch(p, &status, package_compare);
if (t->refcount++ > 0) {
free(p->package);
free(p);
printf("dup! %s\n", t->package);
}
return t;
}
/*
* Read status file into memory as a binary tree, preserving only those
* fields that are needed.
*/
void *status_read(void) {
FILE *f;
char buf[BUFSIZE];
void *status = 0;
struct package_t *p = 0, *t = 0;
char **dependsvec;
int i;
if ((f = fopen(STATUSFILE, "r")) == NULL) {
perror(STATUSFILE);
return 0;
}
while (fgets(buf, BUFSIZE, f) && !feof(f)) {
buf[strlen(buf)-1] = 0;
if (*buf == 0) {
p = 0;
}
else if (strstr(buf, "Package: ") == buf) {
p = _newpackage(buf+9, status);
printf("%s %i\n", p->package, p->refcount);
}
else if (strstr(buf, "Installer-Menu-Item: ") == buf) {
p->installer_menu_item=atoi(buf+21);
}
else if (strstr(buf, "Description: ") == buf) {
/* Short description only. */
p->description = strdup(buf+13);
}
else if (strstr(buf, "Depends: ") == buf) {
/*
* A "Depends" triggers the insertation of
* stub packages into the status binary-tree (if
* the depended-upon package doesn't already exist).
* The stubs will be filled out in due course.
*
* This assumes that the status database is
* consistent.
*/
dependsvec = depends_split(buf+9);
i=0;
while (dependsvec[i] != 0) {
t = _newpackage(dependsvec[i], status);
t->requiredfor[t->requiredcount++] = p;
printf("%s required for %s\n", t->package, p->package);
i++;
}
}
else if (strstr(buf, "Provides: ") == buf) {
/* Um, how do we handle provides? TODO */
}
}
fclose(f);
return status;
}
Loading…
Cancel
Save