PERFORCE change 163636 for review
David Forsythe
dforsyth at FreeBSD.org
Sat Jun 6 09:03:47 UTC 2009
http://perforce.freebsd.org/chv.cgi?CH=163636
Change 163636 by dforsyth at squirrel on 2009/06/06 09:03:23
Added incomplete parsing mechanism. Data is not organized in
pkg_plist yet.
Affected files ...
.. //depot/projects/soc2009/dforsyth_libpkg/libpkg/pkg.c#8 edit
.. //depot/projects/soc2009/dforsyth_libpkg/libpkg/pkg.h#8 edit
.. //depot/projects/soc2009/dforsyth_libpkg/libpkg/pkg_plist.c#3 edit
.. //depot/projects/soc2009/dforsyth_libpkg/libpkg/pkg_plist.h#3 edit
.. //depot/projects/soc2009/dforsyth_libpkg/libpkg/pkg_private.h#4 edit
.. //depot/projects/soc2009/dforsyth_libpkg/libpkg/pkgdb.c#9 edit
.. //depot/projects/soc2009/dforsyth_libpkg/libpkg/pkgdb.h#6 edit
.. //depot/projects/soc2009/dforsyth_libpkg/pkg_info/main.c#3 edit
Differences ...
==== //depot/projects/soc2009/dforsyth_libpkg/libpkg/pkg.c#8 (text+ko) ====
@@ -28,7 +28,7 @@
}
p->ident = new_ident;
p->comment = NULL;
- p->contents = NULL;
+ p->plist = NULL;
return (p);
}
@@ -65,15 +65,17 @@
return (p);
}
-#if 0
struct pkg *
-pkg_set_pkg_plist(struct pkg *p, struct pkg_plist *pc)
+pkg_set_pkg_plist(struct pkg *p, struct pkg_plist *pl)
{
+ if (p == NULL)
+ return (NULL);
+
+ p->plist = pl;
return (p);
}
-#endif
-
+/* ident and name are different, even though they might be the same. */
char *
pkg_ident(struct pkg *p)
{
@@ -92,9 +94,43 @@
return (p->comment);
}
-/* TODO: Make an explicit note in the manual for libpkg that pkg_free
- * should NOT be called called on pkgs that are not explicitly created by
- * the user. */
+/* Function to access information stored in the pkg_plist. */
+char *
+pkg_name(struct pkg *p)
+{
+ char *name;
+ name = pkg_plist_name(p->plist);
+
+ return (name);
+}
+
+/* Temporarily void. */
+void
+pkg_pkg_plist_init(struct pkg *p)
+{
+ if (p == NULL)
+ return;
+
+ pkg_plist_init(p->plist);
+ return;
+}
+
+/* Temporarily char. */
+char *
+pkg_pkg_plist_next(struct pkg *p)
+{
+ char *file_name;
+
+ if (p == NULL)
+ return (NULL);
+
+ file_name = pkg_plist_next(p->plist);
+
+ return (file_name);
+}
+
+/* TODO: Make an note in the manual for libpkg that pkg_free should not be
+ * called on pkgs that are not explicitly created by the client. */
void
pkg_free(struct pkg *p)
==== //depot/projects/soc2009/dforsyth_libpkg/libpkg/pkg.h#8 (text+ko) ====
@@ -11,12 +11,18 @@
struct pkg *pkg_set_comment(struct pkg *p, const char *comment);
+struct pkg *pkg_set_pkg_plist(struct pkg *p, struct pkg_plist *pl);
+
char *pkg_ident(struct pkg *p);
char *pkg_name(struct pkg *p);
char *pkg_comment(struct pkg *p);
+void pkg_pkg_plist_init(struct pkg *p);
+
+char *pkg_pkg_plist_next(struct pkg *p);
+
void pkg_free(struct pkg *p);
/* pkgdb */
@@ -25,7 +31,7 @@
struct pkgdb *pkgdb_read_db_hierdb(const char *db_root);
-int pkgdb_refresh_db_hierdb(struct pkgdb *db);
+int pkgdb_init_db_hierdb(struct pkgdb *db);
struct pkg *pkgdb_read_pkg_hierdb(struct pkgdb *db, const char *ident);
==== //depot/projects/soc2009/dforsyth_libpkg/libpkg/pkg_plist.c#3 (text+ko) ====
@@ -13,6 +13,20 @@
#include "pkgdb.h"
#include "pkg.h"
+/* For tracking mode, if the last file needs an MD5, owner, and group. */
+
+struct file_state {
+ int last_needs_md5;
+ char *mode;
+ char *owner;
+ char *group;
+};
+
+struct pl_file {
+ /* Need a specific type for files because there so much stuff I can
+ * set... */
+};
+
struct pl_entry {
enum plist_elem type;
char *info;
@@ -23,13 +37,31 @@
struct pkg_plist {
int rev;
+ char *cwd;
+ char *srcdir;
char *name;
char *orgin;
- char *cwd;
- char *conflicts;
+ char *display;
+ char *mtree_file;
+
+ char *text; /* The entire plist */
+
+ struct file_state f_s;
+
+ struct pl_entry *file_curr;
+
+ /* Use these lists here so that appending to our list doesnt need a
+ * bunch of realloc procedures. This will be convenient for clients
+ * that want to build plists on the fly, modify plists, etc. */
+
+ TAILQ_HEAD(file_head, pl_entry) file_head; /* File list. */
- char *text;
- TAILQ_HEAD(pl_head, pl_entry) pl_head;
+ /* This list organization needs to be sorted out... */
+
+ TAILQ_HEAD(exex_head, pl_entry) exec_head; /* Exec list. */
+ TAILQ_HEAD(unexex_head, pl_entry) unexec_head; /* Unexec/dirrm list. */
+ TAILQ_HEAD(cfl_head, pl_entry) cfl_head; /* Conflict list. */
+ TAILQ_HEAD(opt_head, pl_entry) opt_head; /* Options list (for all 2) */
};
struct pkg_plist *
@@ -50,6 +82,21 @@
return (pl);
}
+struct pl_entry *
+pl_entry_new(enum plist_elem elem, char *info, char *option)
+{
+ struct pl_entry *ent;
+
+ ent = calloc(1, sizeof(*ent));
+ if (ent != NULL) {
+ ent->type = elem;
+ ent->info = info;
+ ent->option = option;
+ }
+
+ return (ent);
+}
+
struct pkg_plist *
pkg_plist_parse_contents_from_text(const char *text)
{
@@ -80,7 +127,8 @@
if (*p == '\n') {
line = textp;
line[p - textp] = '\0';
- ent = pkg_plist_parse_line(line);
+ ent = pkg_plist_parse_line(pl, line);
+ /* For now, just shove everything onto the main list. */
if (ent != NULL)
pkg_plist_plist_append(pl, ent);
textp = p + 1;
@@ -90,45 +138,142 @@
return (pl);
}
+/* Parse a command sequence and and entry based on the findings. */
struct pl_entry *
-pkg_plist_parse_line(char *line) {
+pkg_plist_parse_line(struct pkg_plist *pl, char *line) {
+ char *command;
+ char *argument;
+ char *sep;
struct pl_entry *ent;
if (line == NULL)
return (NULL);
+ /*
ent = calloc(1, sizeof(*ent));
if (ent == NULL)
return (NULL);
-
- if (line[0] == '@') {
- ent->type = PLIST_CWD; /* Just set this to something */
+ */
+ if (*line == '@') {
+ sep = strchr(line, ' ');
+ if (sep == NULL)
+ sep = strchr(line, '\0');
+ *sep = '\0'; /* chop. */
+ command = line + 1;
+ argument = sep + 1;
+ // ent->option = NULL;
+ /* Until I have the list organization sorted, just return entries
+ * and plop them on the main list. */
+ if (strcmp(command, PLIST_CMD_CWD) == 0 ||
+ strcmp(command, PLIST_CMD_CD) == 0)
+ pl->cwd = argument;
+ else if (strcmp(command, PLIST_CMD_SRCDIR) == 0)
+ pl->srcdir = argument;
+ else if (strcmp(command, PLIST_CMD_EXEC) == 0)
+ ent = pl_entry_new(PLIST_EXEC, argument, NULL);
+ else if (strcmp(command, PLIST_CMD_UNEXEC) == 0)
+ ent = pl_entry_new(PLIST_UNEXEC, argument, NULL);
+ else if (strcmp(command, PLIST_CMD_MODE) == 0)
+ ent = pl_entry_new(PLIST_MODE, argument, NULL);
+ else if (strcmp(command, PLIST_CMD_OPTION) == 0)
+ ent = pl_entry_new(PLIST_OPTION, argument, NULL);
+ else if (strcmp(command, PLIST_CMD_OWNER) == 0)
+ ent = pl_entry_new(PLIST_OWNER, argument, NULL);
+ else if (strcmp(command, PLIST_CMD_GROUP) == 0)
+ ent = pl_entry_new(PLIST_GROUP, argument, NULL);
+ else if (strcmp(command, PLIST_CMD_COMMENT) == 0)
+ ent = pl_entry_new(PLIST_COMMENT, argument, NULL);
+ else if (strcmp(command, PLIST_CMD_NOINST) == 0) {
+ if ((sep = strchr(argument, ' ')) != NULL)
+ *sep = '\0';
+ ent = pl_entry_new(PLIST_NOINST, argument, sep + 1);
+ } else if (strcmp(command, PLIST_CMD_IGNORE) == 0)
+ ent = pl_entry_new(PLIST_IGNORE, argument, NULL);
+ else if (strcmp(command, PLIST_CMD_IGNORE_INST) == 0)
+ ent = pl_entry_new(PLIST_IGNORE_INST, argument, NULL);
+ else if (strcmp(command, PLIST_CMD_NAME) == 0)
+ pl->name = argument;
+ else if (strcmp(command, PLIST_CMD_DIRRM) == 0)
+ ent = pl_entry_new(PLIST_DIRRM, argument, NULL);
+ else if (strcmp(command, PLIST_CMD_MTREE) == 0)
+ pl->mtree_file = argument;
+ else if (strcmp(command, PLIST_CMD_DISPLAY) == 0)
+ pl->display = argument;
+ else {
+ /* If we cant identify the command, set it unknown and gather
+ * whatever information we can. */
+ /*
+ ent->type = PLIST_UNKNOWN;
+ ent->info = command;
+ */
+ ent = pl_entry_new(PLIST_UNKNOWN, argument, NULL);
+ }
} else {
- ent->type = PLIST_FILE;
- ent->info = line;
+ ent = pl_entry_new(PLIST_FILE, argument, NULL);
}
return (ent);
}
+/* Temporarily void. */
+void
+pkg_plist_init(struct pkg_plist *pl)
+{
+ /* Available to the client. */
+ pkg_plist_plist_init(pl);
+ pl->file_curr = NULL;
+}
+
+/* Temporarily char. At this point, only return file names of PLIST_FILE
+ * entries, just for some basic testing. */
+char *
+pkg_plist_next(struct pkg_plist *pl)
+{
+ struct pl_entry *ent;
+
+ if (pl == NULL)
+ return (NULL);
+
+ if (pl->file_curr == NULL)
+ ent = pkg_plist_plist_first(pl);
+ else
+ ent = TAILQ_NEXT(pl->file_curr, next);
+
+ if (ent != NULL) {
+ pl->file_curr = ent;
+ return (ent->info);
+ }
+
+ return (NULL);
+}
+
+char *
+pkg_plist_name(struct pkg_plist *pl)
+{
+ if (pl == NULL)
+ return (NULL);
+
+ return (pl->name);
+}
+
+/* Don't know if I'll be sticking with this, so... */
+
void
pkg_plist_plist_init(struct pkg_plist *pl)
{
if (pl == NULL)
return;
- TAILQ_INIT(&pl->pl_head);
+ TAILQ_INIT(&pl->file_head);
}
struct pl_entry *
pkg_plist_plist_first(struct pkg_plist *pl)
{
- struct pl_entry *ent;
if (pl == NULL)
return (NULL);
- ent = TAILQ_FIRST(&pl->pl_head);
- return (ent);
+ return (TAILQ_FIRST(&pl->file_head));
}
void
@@ -137,5 +282,6 @@
if (pl == NULL || ent == NULL)
return;
- TAILQ_INSERT_TAIL(&pl->pl_head, ent, next);
+ TAILQ_INSERT_TAIL(&pl->file_head, ent, next);
}
+
==== //depot/projects/soc2009/dforsyth_libpkg/libpkg/pkg_plist.h#3 (text+ko) ====
@@ -1,13 +1,14 @@
#ifndef __PKG_INFO_H__
#define __PKG_INFO_H__
-#define COMMENT_FILE "+COMMENT"
-#define CONTENTS_FILE "+CONTENTS"
-#define DESC_FILE "+DESC"
-#define DISPLAY_FILE "+DISPLAY"
-#define MTREE_DIRS_FILE "+MTREE_DIRS"
-#define REQUIRED_BY_FILE "+REQUIRED_BY"
+#define COMMENT_FILE "+COMMENT"
+#define CONTENTS_FILE "+CONTENTS"
+#define DESC_FILE "+DESC"
+#define DISPLAY_FILE "+DISPLAY"
+#define MTREE_DIRS_FILE "+MTREE_DIRS"
+#define REQUIRED_BY_FILE "+REQUIRED_BY"
+/* Make these visible to the client. */
enum plist_elem {
PLIST_CWD,
PLIST_SRCDIR,
@@ -27,13 +28,39 @@
PLIST_DISPLAY,
PLIST_PKGDEP,
PLIST_CONLICTS,
- PLIST_FILE
+ PLIST_FILE,
+ PLIST_UNKNOWN
};
+#define PLIST_CMD_CWD "cwd"
+#define PLIST_CMD_CD "cd"
+#define PLIST_CMD_SRCDIR "srcdir"
+#define PLIST_CMD_EXEC "exec"
+#define PLIST_CMD_UNEXEC "unexec"
+#define PLIST_CMD_MODE "mode"
+#define PLIST_CMD_OPTION "option"
+#define PLIST_CMD_OWNER "owner"
+#define PLIST_CMD_GROUP "group"
+#define PLIST_CMD_COMMENT "comment"
+#define PLIST_CMD_NOINST "noinst"
+#define PLIST_CMD_IGNORE "ignore"
+#define PLIST_CMD_IGNORE_INST "ignore_inst"
+#define PLIST_CMD_NAME "name"
+#define PLIST_CMD_DIRRM "dirrm"
+#define PLIST_CMD_MTREE "mtree"
+#define PLIST_CMD_DISPLAY "display"
+#define PLIST_CMD_PKGDEG "pkgdep"
+#define PLIST_CMD_CONFLICTS "conflicts"
+
struct pl_entry;
struct pkg_plist *pkg_plist_parse_contents_from_text(const char *text);
-struct pl_entry *pkg_plist_parse_line(char *line);
+struct pl_entry *pkg_plist_parse_line(struct pkg_plist *pl, char *line);
+
+void pkg_plist_init(struct pkg_plist *pl);
+char *pkg_plist_next(struct pkg_plist *pl);
+
+char *pkg_plist_name(struct pkg_plist *pl);
void pkg_plist_plist_init(struct pkg_plist *pl);
struct pl_entry *pkg_plist_plist_first(struct pkg_plist *pl);
==== //depot/projects/soc2009/dforsyth_libpkg/libpkg/pkg_private.h#4 (text+ko) ====
@@ -7,7 +7,7 @@
char *ident; /* User given name for this pkg. */
char *comment; /* Mmmmm, should be 70 or less, right? */
- struct pkg_plist *contents;
+ struct pkg_plist *plist;
};
#endif
==== //depot/projects/soc2009/dforsyth_libpkg/libpkg/pkgdb.c#9 (text+ko) ====
@@ -49,7 +49,7 @@
}
db->db_root = new_db_root;
- db->p_count = 0;
+ db->pkg_count = 0;
db->dirty = 1;
/* Set the callbacks for database access */
@@ -63,32 +63,32 @@
* number of subdirectories in the database. */
int
-pkgdb_refresh_db_hierdb(struct pkgdb *db)
+pkgdb_init_db_hierdb(struct pkgdb *db)
{
int i;
- int p_count;
+ int pkg_count;
struct pkg *p;
struct dirent **ents;
if (db == NULL)
return (-1);
- pkgdb_pkg_list_init(db);
if (db->dirty == 0) {
/* No changes since the last init, don't bother walking the
* database again. */
- db->p_curr = pkgdb_pkg_list_first(db);;
- return (db->p_count);
+ db->pkg_curr = pkgdb_pkg_list_first(db);;
+ return (db->pkg_count);
}
- p_count = scandir(db->db_root, &ents, subdir_sel, alphasort);
+ pkg_count = scandir(db->db_root, &ents, subdir_sel, alphasort);
/* Clear out old list. */
pkgdb_free_pkg_list(db);
/* Later on I should look into inserting changes into the existing
* list, rather than just bombing the whole thing. */
- for (i = 0; i < p_count; ++i) {
+ pkgdb_pkg_list_init(db);
+ for (i = 0; i < pkg_count; ++i) {
p = pkgdb_read_pkg_hierdb(db, ents[i]->d_name);
if (p == NULL) {
pkgdb_free_pkg_list(db);
@@ -100,11 +100,12 @@
}
free(ents);
- db->p_curr = pkgdb_pkg_list_first(db);
- db->p_count = p_count;
+ /* db->pkg_curr = pkgdb_pkg_list_first(db); */
+ db->pkg_curr = NULL;
+ db->pkg_count = pkg_count;
db->dirty = 0;
- return (db->p_count);
+ return (db->pkg_count);
}
/* Read in all the package information we can right here. */
@@ -117,7 +118,7 @@
char *text;
struct stat sb;
struct pkg *p;
- struct pkg_plist *pc;
+ struct pkg_plist *pl;
p = pkg_new(ident);
path = pkgdb_pkg_path(db, p);
@@ -137,7 +138,8 @@
pkg_set_comment(p, text);
free(text);
text = pkgdb_read_file_to_text(db, p, CONTENTS_FILE);
- pc = pkg_plist_parse_contents_from_text(text);
+ pl = pkg_plist_parse_contents_from_text(text);
+ pkg_set_pkg_plist(p, pl);
free(text);
return (p);
@@ -194,10 +196,15 @@
if (db == NULL)
return (NULL);
- if ((p = db->p_curr) == NULL)
- return (NULL);
+ /* If we're at the end of the list, pkg_curr will remain as the last
+ * element. */
+ if (db->pkg_curr == NULL)
+ p = pkgdb_pkg_list_first(db);
+ else
+ p = TAILQ_NEXT(db->pkg_curr, next);
+ if (p != NULL)
+ db->pkg_curr = p;
- db->p_curr = TAILQ_NEXT(db->p_curr, next);
return (p);
}
@@ -257,7 +264,7 @@
if (db == NULL)
return;
- TAILQ_INIT(&db->p_head);
+ TAILQ_INIT(&db->pkg_head);
}
struct pkg *
@@ -265,7 +272,7 @@
if (db == NULL)
return (NULL);
- return (TAILQ_FIRST(&db->p_head));
+ return (TAILQ_FIRST(&db->pkg_head));
}
void
@@ -273,7 +280,7 @@
if (db == NULL || p == NULL)
return;
- TAILQ_INSERT_TAIL(&db->p_head, p, next);
+ TAILQ_INSERT_TAIL(&db->pkg_head, p, next);
}
/* Free a hierdb. */
@@ -295,11 +302,11 @@
struct pkg *p;
struct pkg *pn;
- p = TAILQ_FIRST(&db->p_head);
+ p = TAILQ_FIRST(&db->pkg_head);
while (p != NULL) {
pn = TAILQ_NEXT(p, next);
pkg_free(p);
p = pn;
}
- TAILQ_INIT(&db->p_head);
+ TAILQ_INIT(&db->pkg_head);
}
==== //depot/projects/soc2009/dforsyth_libpkg/libpkg/pkgdb.h#6 (text+ko) ====
@@ -10,10 +10,11 @@
char *db_root;
- int p_count;
- struct pkg *p_curr;
+ int pkg_count;
+ struct pkg *pkg_curr;
- TAILQ_HEAD(pkg_head, pkg) p_head;
+ /* TODO: Convert to an array. */
+ TAILQ_HEAD(pkg_head, pkg) pkg_head;
/* Callbacks */
};
==== //depot/projects/soc2009/dforsyth_libpkg/pkg_info/main.c#3 (text+ko) ====
@@ -3,6 +3,7 @@
#include <getopt.h>
#include "pkg.h"
+#include "pkg_info.h"
#define PKG_DBDIR_DEFAULT "/var/db/pkg" /* Move this. */
@@ -23,11 +24,6 @@
/* Mock pkg_info for testing, */
-void perform_on_db(struct pkgdb *db);
-void print_pkg_information(struct pkg *p);
-void parse_opts(int argc, char **argv);
-void usage(int exit_val);
-
int
main (int argc, char **argv)
{
@@ -37,8 +33,9 @@
if (argc == 1 && argv != NULL /* Giving argv something to do */) {
opt_all = 1;
}
-
- /* parse_opts(argc, argv); */
+
+ /* Just check for any argument to trigger file list vomit. */
+ parse_opts(argc, argv);
db_root = getenv("PKG_DBDIR"); /* User set it */
if (db_root == NULL)
@@ -62,14 +59,16 @@
exit(exit_val);
}
-#if 0
void
parse_opts(int argc, char **argv)
{
- /* Ehh... Worthless to write this at this point. */
+ /* pointlessly set this. */
opt_all = 1;
+
+ if (argc == 1)
+ return;
+ opt_show_all_info = 1;
}
-#endif
void
perform_on_db(struct pkgdb *db)
@@ -81,7 +80,7 @@
/* There will be cases where an init is useless, but since I haven't
* written that much yet, init regardless. */
- count = pkgdb_refresh_db_hierdb(db);
+ count = pkgdb_init_db_hierdb(db);
if (count < 0)
exit(1);
@@ -98,9 +97,19 @@
void
print_pkg_information(struct pkg *p)
{
+ char *file_name;
+
/* Just print the basic PKGNAME COMMENT scheme right now. Other
* information isn't collected by the library yet. */
- if (!opt_show_all_info)
- printf("%s %s\n", pkg_ident(p), pkg_comment(p));
+ if (!opt_show_all_info)
+ printf("%s %s\n", pkg_name(p), pkg_comment(p));
+ else {
+ /* Testing plist interaction. */
+ printf("Package %s contains:\n", pkg_name(p));
+ pkg_pkg_plist_init(p);
+ while ((file_name = pkg_pkg_plist_next(p)) != NULL) {
+ printf("\t%s\n", file_name);
+ }
+ }
}
More information about the p4-projects
mailing list