PERFORCE change 82892 for review
soc-andrew
soc-andrew at FreeBSD.org
Wed Aug 31 09:25:09 GMT 2005
http://perforce.freebsd.org/chv.cgi?CH=82892
Change 82892 by soc-andrew at soc-andrew_serv on 2005/08/31 09:24:19
Mark and install package dependencies. Delete unselected packages
Affected files ...
.. //depot/projects/soc2005/bsdinstaller/src/usr.sbin/bsdinstaller/backend/fn_install_freebsd.c#9 edit
Differences ...
==== //depot/projects/soc2005/bsdinstaller/src/usr.sbin/bsdinstaller/backend/fn_install_freebsd.c#9 (text+ko) ====
@@ -47,6 +47,8 @@
#include <sys/types.h>
#include <sys/utsname.h>
+#include <archive.h>
+#include <archive_entry.h>
#include <dirent.h>
#include <limits.h>
#include <string.h>
@@ -63,6 +65,7 @@
#include <installer/commands.h>
#include <installer/dist.h>
+#include <installer/package.h>
#include <installer/uiutil.h>
char *mtree_file[] = { "root", "var", "usr", "sendmail", NULL };
@@ -97,6 +100,10 @@
static int post_install(struct i_fn_args *);
void fn_install_os(struct i_fn_args *);
void fn_select_packages(struct i_fn_args*, struct aura_dict*, char*);
+void fn_add_remove_packages(struct i_fn_args *, struct aura_dict *,
+ struct dfui_response *);
+void fn_package_mark_dependencies(struct aura_dict *, char *);
+void fn_package_install_dependencies(struct i_fn_args *, struct aura_dict *installed, char *, struct commands *);
static int
pre_install(struct i_fn_args *a)
@@ -197,8 +204,8 @@
char base[PATH_MAX];
/* This should be big enough as the largest dist name is ~9 */
char dist_name[32];
- void *rv, *rk;
- size_t rv_len, rk_len;
+ void *rk;
+ size_t rk_len;
int i;
struct commands *cmds;
struct utsname name;
@@ -462,7 +469,6 @@
void
fn_install_packages(struct i_fn_args *a)
{
- struct dfui_field *fi;
struct dfui_form *f;
struct dfui_response *r;
DIR *d;
@@ -470,6 +476,38 @@
struct aura_dict *packages;
int done = 0;
+ packages = aura_dict_new(13, AURA_DICT_LIST);
+
+ /* Add all installed packages to the dictonary */
+
+ d = opendir("/mnt/var/db/pkg");
+ if (d != NULL) {
+ /* loop through all sub-directories to the package dir */
+ while ((de = readdir(d)) != NULL) {
+ /*
+ * I tried to check if (de->d_type == DT_DIR) here
+ * but d_type was always 0
+ */
+ struct stat sb;
+ char file[PATH_MAX];
+
+ if (de->d_name[0] == '.')
+ continue;
+
+ snprintf(file, PATH_MAX, "/mnt/var/db/pkg/%s",
+ de->d_name);
+ stat(file, &sb);
+
+ if (!S_ISDIR(sb.st_mode))
+ continue;
+
+ aura_dict_store(packages,
+ de->d_name, strlen(de->d_name),
+ de->d_name, strlen(de->d_name));
+ }
+ closedir(d);
+ }
+
f = dfui_form_create(
"install_packages",
_("Install Packages"),
@@ -517,8 +555,6 @@
dfui_form_action_add(f, "cancel",
dfui_info_new(_("Cancel"), "", ""));
- packages = aura_dict_new(13, AURA_DICT_LIST);
-
while (done == 0)
{
if (!dfui_be_present(a->c, f, &r))
@@ -528,33 +564,49 @@
done = 1;
} else if (strcmp(dfui_response_get_action_id(r), "ok") == 0) {
/* Install the packages */
- char *key;
- int key_len;
+ char *key, *data;
+ size_t key_len, data_len;
+ struct commands *cmds;
+ struct aura_dict *installed;
+
+ cmds = commands_new();
+ installed = aura_dict_new(13, AURA_DICT_LIST);
aura_dict_rewind(packages);
+
+ /* Install all selected packages */
while (!aura_dict_eof(packages)) {
- struct commands *cmds;
/* Set dist_name */
aura_dict_get_current_key(packages, (void*)&key,
&key_len);
- key[key_len] = '\0';
- cmds = commands_new();
+ aura_dict_fetch(packages, key, key_len,
+ &data, &data_len);
- command_add(cmds,
- "cp /usr/packages/All/%s.tbz /mnt/tmp",
- key);
- command_add(cmds,
- "pkg_add -C /mnt /tmp/%s.tbz", key);
- command_add(cmds, "rm /mnt/tmp/%s.tbz", key);
+ key[key_len] = '\0';
+ data[data_len] = '\0';
- commands_execute(a, cmds);
- commands_free(cmds);
-
+ /*
+ * If the package is marked as to be deleted
+ * and is installed then remove it.
+ */
+ if (strncmp("deleted", data, 8) == 0) {
+ if (pkg_exists(a, key)) {
+ printf("Delete %s\n", key);
+ command_add(cmds, "chroot /mnt"
+ " pkg_delete %s", key);
+ }
+ } else {
+ fn_package_install_dependencies(a, installed, key, cmds);
+ }
aura_dict_next(packages);
}
+ aura_dict_free(installed);
+ commands_execute(a, cmds);
+ commands_free(cmds);
+
done = 1;
} else {
/* move to the next level window */
@@ -572,7 +624,6 @@
void
fn_select_packages(struct i_fn_args *a, struct aura_dict *packages, char *dir)
{
- struct dfui_field *fi;
struct dfui_form *f;
struct dfui_response *r;
struct dfui_dataset *ds;
@@ -596,7 +647,7 @@
"Install this Package", "",
"p", "control", "checkbox",
- "f", "package", "Package name",
+ "f", "package", "Package name ",
"The name of the Package to install", "",
"p", "editable", "false",
@@ -616,16 +667,22 @@
return;
}
+ /* loop through all sub-directories to the package dir */
while ((de = readdir(d)) != NULL) {
- /* I tried to use de->d_type == DT_DIR but d_type was always 0 */
+ /*
+ * I tried to check if (de->d_type == DT_DIR) here
+ * but d_type was always 0
+ */
struct stat sb;
char file[PATH_MAX];
- char *extension;
+ char *extension, *data;
+ int data_len;
if (de->d_name[0] == '.')
continue;
- snprintf(file, PATH_MAX, "/usr/packages/%s/%s", dir, de->d_name);
+ snprintf(file, PATH_MAX, "/usr/packages/%s/%s", dir,
+ de->d_name);
stat(file, &sb);
if (!S_ISREG(sb.st_mode))
@@ -636,7 +693,16 @@
extension[0] = '\0';
ds = dfui_dataset_new();
- dfui_dataset_celldata_add(ds, "install", "N");
+
+ aura_dict_fetch(packages, de->d_name, strlen(de->d_name),
+ (void*)&data, &data_len);
+
+ /* If the package is in the dictonary and is not deleted, mark it */
+ if (aura_dict_exists(packages, de->d_name,
+ strlen(de->d_name)) != 0 && strncmp("deleted", data, 8) != 0)
+ dfui_dataset_celldata_add(ds, "install", "Y");
+ else
+ dfui_dataset_celldata_add(ds, "install", "N");
dfui_dataset_celldata_add(ds, "package", de->d_name);
dfui_form_dataset_add(f, ds);
}
@@ -647,27 +713,186 @@
abort_backend();
if (strcmp(dfui_response_get_action_id(r), "ok") == 0) {
- /* Add the packages and dependencies to the dictonary */
- for (ds = dfui_response_dataset_get_first(r); ds != NULL;
- ds = dfui_dataset_get_next(ds)) {
- char install[2];
+ fn_add_remove_packages(a, packages, r);
+ }
+
+ dfui_response_free(r);
+ dfui_form_free(f);
+}
+
+/*
+ * "removes" the packages from the disctonary that are unselected
+ * Then adds the selected ones and dependencies
+ */
+void
+fn_add_remove_packages(struct i_fn_args *a, struct aura_dict *packages,
+ struct dfui_response *r)
+{
+ struct dfui_dataset *ds;
+
+ /* Remove unselected packages dictonary */
+ for (ds = dfui_response_dataset_get_first(r); ds != NULL;
+ ds = dfui_dataset_get_next(ds)) {
+ char install[2];
+ char *package;
+ int len;
- /* Copy the value of the install field to install */
- strncpy(install, dfui_dataset_get_value(ds, "install"), 2);
+ /* Copy the value of the install field to install */
+ strncpy(install, dfui_dataset_get_value(ds, "install"), 2);
- if (strncasecmp(install, "Y", 2) == 0) {
- /* Select this dist for installation */
- char *package;
- int len;
+ package = (char*)dfui_dataset_get_value
+ (ds, "package");
+ len = strlen(package);
- package = (char*)dfui_dataset_get_value(ds, "package");
- len = strlen(package);
+ if (strncasecmp(install, "N", 2) == 0) {
+ /*
+ * "remove" this package from the dictonary by
+ * changing it's value to "deleted".
+ */
+ if (aura_dict_exists(packages, package,
+ strlen(package)) != 0) {
aura_dict_store(packages, package, len,
- package, len);
+ "deleted", 8);
+ printf("Delete: %s\n", package);
}
}
}
- dfui_response_free(r);
- dfui_form_free(f);
+ /* Add selected packages and dependencies to the dictonary */
+ for (ds = dfui_response_dataset_get_first(r); ds != NULL;
+ ds = dfui_dataset_get_next(ds)) {
+ char install[2];
+ char *package;
+ int len;
+
+ /* Copy the value of the install field to install */
+ strncpy(install, dfui_dataset_get_value(ds, "install"), 2);
+
+ package = (char*)dfui_dataset_get_value
+ (ds, "package");
+ len = strlen(package);
+
+ if (strncasecmp(install, "Y", 2) == 0) {
+ /* Find all unmarked dependencies and mark them */
+ fn_package_mark_dependencies(packages, package);
+ }
+ }
+}
+
+void
+fn_package_mark_dependencies(struct aura_dict *packages, char *package)
+{
+ struct archive *a;
+ struct archive_entry *entry;
+ char *file;
+
+ /* If the package is in the dictonary don't check it's dependencies */
+ if (aura_dict_exists(packages, package, strlen(package)) != 0) {
+ char *data;
+ size_t data_len;
+ aura_dict_fetch(packages, package, strlen(package),
+ (void*)&data, &data_len);
+ if (strncmp("deleted", data, 8) != 0)
+ return;
+ }
+
+ /* Add this package to be installed */
+ aura_dict_store(packages, package, strlen(package), package, strlen(package));
+
+ a = archive_read_new();
+ archive_read_support_compression_all(a);
+ archive_read_support_format_all(a);
+
+ asprintf(&file, "/usr/packages/All/%s.tbz", package);
+ archive_read_open_file(a, file, 10240);
+ free(file);
+
+ if (archive_read_next_header(a, &entry) == ARCHIVE_OK) {
+ void *buffer;
+ char *b;
+ int64_t len = archive_entry_size(entry);
+
+ buffer = malloc(len + 1);
+ archive_read_data_into_buffer(a, buffer, len);
+ b = buffer;
+ b[len] = 0;
+
+ /* Find the dependencies from the buffer */
+ while ((b = strstr(b, "@pkgdep")) != NULL) {
+ char *eol = strchr(b, '\n');
+ eol[0] = '\0';
+ b+=8;
+ /* Recurse to the dependent package to install it */
+ fn_package_mark_dependencies(packages, b);
+ b = eol + 1;
+ }
+ free(buffer);
+ }
+
+ archive_read_finish(a);
+}
+
+/*
+ * Installs a package and it's dependencies
+ * XXX: This is a copy of the code above, it should be generalized
+ */
+void
+fn_package_install_dependencies(struct i_fn_args *ar, struct aura_dict *installed, char *package, struct commands *cmds)
+{
+ struct archive *a;
+ struct archive_entry *entry;
+ char *file;
+ size_t len = strlen(package);
+
+ /* If the package is installed return */
+ if (pkg_exists(ar, package))
+ return;
+
+ /* If the package is in the to-be-installed dictonary return */
+ if (aura_dict_exists(installed, package, len))
+ return;
+
+ aura_dict_store(installed, package, len, package, len);
+
+ a = archive_read_new();
+ archive_read_support_compression_all(a);
+ archive_read_support_format_all(a);
+
+ asprintf(&file, "/usr/packages/All/%s.tbz", package);
+ archive_read_open_file(a, file, 10240);
+ free(file);
+
+ /* Find the dependencies and install them */
+ if (archive_read_next_header(a, &entry) == ARCHIVE_OK) {
+ void *buffer;
+ char *b;
+ int64_t len = archive_entry_size(entry);
+
+ buffer = malloc(len + 1);
+ archive_read_data_into_buffer(a, buffer, len);
+ b = buffer;
+ b[len] = 0;
+
+ /* Find the dependencies from the buffer */
+ while ((b = strstr(b, "@pkgdep")) != NULL) {
+ char *eol = strchr(b, '\n');
+ eol[0] = '\0';
+ b+=8;
+ /* Recurse to the dependent package to install it */
+ fn_package_install_dependencies(ar, installed, b, cmds);
+ b = eol + 1;
+ }
+ free(buffer);
+ }
+
+ printf("Install %s\n", package);
+ command_add(cmds,
+ "cp /usr/packages/All/%s.tbz "
+ "/mnt/tmp", package);
+ command_add(cmds,
+ "pkg_add -C /mnt /tmp/%s.tbz", package);
+ command_add(cmds, "rm /mnt/tmp/%s.tbz", package);
+
+ archive_read_finish(a);
}
+
More information about the p4-projects
mailing list