Date: Wed, 31 Aug 2005 09:25:07 GMT From: soc-andrew <soc-andrew@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 82892 for review Message-ID: <200508310925.j7V9P7Fg073927@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=82892 Change 82892 by soc-andrew@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); } +
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200508310925.j7V9P7Fg073927>