Index: CHANGES =================================================================== RCS file: /cvs/cvsroot/loki_setup/CHANGES,v retrieving revision 1.86 diff -u -r1.86 CHANGES --- CHANGES 2003/09/24 04:02:47 1.86 +++ CHANGES 2003/10/24 18:12:36 @@ -25,6 +25,10 @@ Stephane Peter (Codehost) - Tue Feb 11 20:33:32 PST 2003 * Added the 'environment' tag to store the values of environment variables. +TTimo (qeradiant.com) - Mon Feb 10 12:17:08 CET 2003 + * Added SETUP_COMPONENT_PATH env to run scripts +TTimo (qeradiant.com) - Sun Jan 26 23:36:06 CET 2003 + * Ported over our subcomponent code Ryan C. Gordon (icculus.org) - Tue Jan 14 23:46:31 EST 2003 * Committed initial MacOS X patches to CVS on behalf of Jon C. Stephane Peter (Codehost) - Fri Dec 6 16:31:27 PST 2002 Index: Makefile.in =================================================================== RCS file: /cvs/cvsroot/loki_setup/Makefile.in,v retrieving revision 1.25 diff -u -r1.25 Makefile.in --- Makefile.in 2003/05/02 22:54:49 1.25 +++ Makefile.in 2003/10/24 18:12:36 @@ -134,19 +134,19 @@ endif @if [ -d image/setup.data/bin/$(os)/$(arch)/$(libc) ]; then \ cp setup image/setup.data/bin/$(os)/$(arch); \ - strip image/setup.data/bin/$(os)/$(arch)/setup; \ + strip -r image/setup.data/bin/$(os)/$(arch)/setup; \ $(BRANDELF) -t $(os) image/setup.data/bin/$(os)/$(arch)/setup; \ cp uninstall image/setup.data/bin/$(os)/$(arch); \ - strip image/setup.data/bin/$(os)/$(arch)/uninstall; \ + strip -r image/setup.data/bin/$(os)/$(arch)/uninstall; \ $(BRANDELF) -t $(os) image/setup.data/bin/$(os)/$(arch)/uninstall; \ cp xsu image/setup.data/bin/$(os)/$(arch)/$(libc); \ - strip image/setup.data/bin/$(os)/$(arch)/$(libc)/xsu; \ + strip -r image/setup.data/bin/$(os)/$(arch)/$(libc)/xsu; \ $(BRANDELF) -t $(os) image/setup.data/bin/$(os)/$(arch)/$(libc)/xsu; \ cp setup.gtk image/setup.data/bin/$(os)/$(arch)/$(libc); \ - strip image/setup.data/bin/$(os)/$(arch)/$(libc)/setup.gtk; \ + strip -r image/setup.data/bin/$(os)/$(arch)/$(libc)/setup.gtk; \ $(BRANDELF) -t $(os) image/setup.data/bin/$(os)/$(arch)/$(libc)/setup.gtk; \ else \ - echo No directory to copy the binary files to.; \ + echo image/setup.data/bin/$(os)/$(arch)/$(libc): No directory to copy the binary files to.; \ fi install-image: all @@ -171,7 +171,7 @@ cp setup.gtk $(IMAGE)/setup.data/bin/$(os)/$(arch)/$(libc); \ strip $(IMAGE)/setup.data/bin/$(os)/$(arch)/$(libc)/setup.gtk; \ else \ - echo No directory to copy the binary files to.; \ + echo $(IMAGE)/setup.data/bin/$(os)/$(arch)/$(libc): No directory to copy the binary files to.; \ fi # Pretty LPP-specific @@ -181,7 +181,7 @@ strip $(IMAGE)/bin/$(os)/$(arch)/check; \ cp check.glade $(IMAGE)/misc/; \ else \ - echo No directory to copy the binary files to.; \ + echo $(IMAGE)/bin/$(os)/$(arch): No directory to copy the binary files to.; \ fi # Copy loki_uninstall and the required files @@ -196,7 +196,7 @@ cp $$file $$path; \ done; \ else \ - echo No directory to copy the binary files to.; \ + echo $(IMAGE)/bin/$(os)/$(arch): No directory to copy the binary files to.; \ fi install-loki_uninstall: loki_uninstall @@ -211,7 +211,7 @@ cp $$file $$path; \ done; \ else \ - echo No directory to copy the binary files to.; \ + echo $(IMAGE)/loki_uninstall/bin/$(arch)/$(libc): No directory to copy the binary files to.; \ fi @if [ -d $(UPDATES) ]; then \ rm -rf $(UPDATES)/bin-$(arch)-$(UNINSTALL_VERSION)/; \ Index: configure.in =================================================================== RCS file: /cvs/cvsroot/loki_setup/configure.in,v retrieving revision 1.41 diff -u -r1.41 configure.in --- configure.in 2003/08/13 21:48:29 1.41 +++ configure.in 2003/10/24 18:12:36 @@ -161,7 +161,7 @@ LIBDL="" ARCH=`uname -p` ;; powerpc-apple-darwin*) - STATIC="-static" + STATIC="" RDYNAMIC="-Wl,-Sn" BSTATIC="" BDYNAMIC="" @@ -242,16 +242,6 @@ CARBONLIBS="$CARBON_LIBS $LIBINTL" fi ) - -case "$target" in - powerpc-apple-darwin*) - if test -f /sw/lib/libintl.a; then - LIBINTL="/sw/lib/libintl.a /sw/lib/libiconv.a" - LIBS="$LIBS $LIBINTL" - GUILIBS="$GUI_LIBS $LIBINTL" - CARBONLIBS="$CARBON_LIBS $LIBINTL" - fi -esac AC_CHECK_LIB(gpm, Gpm_Open, USE_GPM=yes) Index: copy.c =================================================================== RCS file: /cvs/cvsroot/loki_setup/copy.c,v retrieving revision 1.69 diff -u -r1.69 copy.c --- copy.c 2003/09/04 02:29:03 1.69 +++ copy.c 2003/10/24 18:12:37 @@ -347,7 +347,7 @@ *slash = '\0'; } push_curdir(dir); - if ( run_script(info, buf, 0, 1) == 0 ) { + if ( run_script(info, buf, NULL, 0, 1) == 0 ) { const char *target = xmlGetProp(node, "target"); if ( target ) { char targetpath[PATH_MAX]; @@ -719,7 +719,7 @@ if ( ! update(info, _("Running script"), 0, 0, current_option_txt) ) return 0; } - return(run_script(info, script, -1, 1)); + return(run_script(info, script, dest, -1, 1)); } ssize_t copy_node(install_info *info, xmlNodePtr node, const char *dest, @@ -808,6 +808,7 @@ { ssize_t size, copied; char tmppath[PATH_MAX]; + const char *component_dest; size = 0; while ( node ) { @@ -894,6 +895,58 @@ } current_component = NULL; /* Out of the component */ } + } + /* Parse subcomponents */ + else if (!strcmp(node->name, "subcomponent")) { + const char *name, *version; + xmlNodePtr child; + name = xmlGetProp(node, "name"); + if (!name) + log_fatal(_("SubComponent element must have a name")); + version = xmlGetProp(node, "version"); + if (!version) + { + log_warning(_("SubComponent doesn't have a version")); + version = strdup("noversion"); + } + child = node->childs; + while(child) + { + if(!strcmp(child->name, "option")) + { + /* only run if it has been actually selected for install */ + const char *install; + install = xmlGetProp(child, "install"); + if (install && !strcmp(install,"true")) + { + /* add this subcomponent as a standard component */ + current_component = add_component_entry(info, name, version, + (strcmp(xmlGetProp(child, "install"), "true") != 0) ? 0 : 1, NULL, NULL ); + if(xmlGetProp(child, "path")) + { + /* if the path's been changed, use the path it was changed to */ + component_dest = xmlGetProp(child, "path"); + } + else + { + /* if the path hasn't been changed, install to the default path */ + component_dest = xmlGetProp(child, "default_path"); + } + // TODO: verify the install location ? + copied = copy_node(info, child, component_dest, update); + if ( copied > 0 ) + { + size += copied; + } + copied = copy_tree(info, child->childs, component_dest, update); + if(copied > 0) + { + size += copied; + } + } + } + child = child->next; + } } else if ( ! strcmp(node->name, "environment") ) { const char *prop = xmlGetProp(node, "var"); if ( prop ) { Index: gtk_ui.c =================================================================== RCS file: /cvs/cvsroot/loki_setup/gtk_ui.c,v retrieving revision 1.87 diff -u -r1.87 gtk_ui.c --- gtk_ui.c 2003/10/15 00:08:11 1.87 +++ gtk_ui.c 2003/10/24 18:12:37 @@ -143,6 +143,7 @@ static GladeXML *setup_glade = NULL; static GladeXML *setup_glade_readme = NULL; static GladeXML *setup_glade_license = NULL; +static GladeXML *setup_glade_subcomponent = NULL; static int cur_state; static install_info *cur_info; static int diskspace; @@ -159,6 +160,7 @@ void setup_destroy_view_readme_slot(GtkWidget*, gpointer); static yesno_answer gtkui_prompt(const char*, yesno_answer); static void gtkui_abort(install_info *info); +static int gtkui_dir_prompt (install_info *info, const char *message, char *path); static int iterate_for_state(void) { @@ -1216,6 +1218,189 @@ } } +/*************** subcomponent *********************/ + +void setup_button_subcomponent_browse(GtkWidget *widget, gpointer func_data) +{ + GtkWidget *entry = (GtkWidget *)func_data; + xmlNodePtr node = gtk_object_get_data(GTK_OBJECT(widget), "node"); + char *widget_data = gtk_object_get_data(GTK_OBJECT(widget), "data"); + char path[PATH_MAX]; + strncpy(path, gtk_entry_get_text(GTK_ENTRY(entry)), PATH_MAX); + + gtkui_dir_prompt(cur_info, widget_data, path); + + if(path[strlen(path)-1] != '/') + strcat(path, "/"); + + gtk_entry_set_text(GTK_ENTRY(entry), path); + + xmlSetProp(node, "path", path); +} + +void setup_subcomponent_toggle(GtkWidget *widget, gpointer func_data) +{ + int state = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)); + GtkWidget *entry = gtk_object_get_data(GTK_OBJECT(widget), "entry"); + GtkWidget *button = gtk_object_get_data(GTK_OBJECT(widget), "button"); + xmlNodePtr node = gtk_object_get_data(GTK_OBJECT(widget), "node"); + + if(state) + { + gtk_widget_set_sensitive(GTK_WIDGET(entry), TRUE); + gtk_widget_set_sensitive(GTK_WIDGET(button), TRUE); + xmlSetProp(node, "install", "true"); + xmlSetProp(node, "path", gtk_entry_get_text(GTK_ENTRY(entry))); + } + else + { + gtk_widget_set_sensitive(GTK_WIDGET(entry), FALSE); + gtk_widget_set_sensitive(GTK_WIDGET(button), FALSE); + xmlSetProp(node, "install", "false"); + xmlSetProp(node, "path", ""); + } +} + +void subcomponent_update_entry(GtkWidget *widget, gpointer func_data) +{ + xmlNodePtr node = gtk_object_get_data(GTK_OBJECT(widget), "node"); + char *path = malloc(strlen(gtk_entry_get_text(GTK_ENTRY(widget)))+2); + strcpy(path, gtk_entry_get_text(GTK_ENTRY(widget))); + + if (path[strlen(path)-1] != '/') + strcat(path, "/"); + + if(path) + xmlSetProp(node, "path", path); +} + +void setup_button_subcomponent(GtkWidget *widget, gpointer func_data) +{ + xmlNodePtr node; + xmlNodePtr child; + GtkWidget *window, *frame, *w, *vbox, *hbox, + *check, *entry, *button, *sep; + const char *text; + char name[256]; + int count=0; + int install=0; + + install_info *info = (install_info *)func_data; + + setup_glade_subcomponent = glade_xml_new(SETUP_GLADE, "subcomponent_dialog"); + glade_xml_signal_autoconnect(setup_glade_subcomponent); + window = glade_xml_get_widget(setup_glade_subcomponent, "subcomponent_dialog"); + frame = glade_xml_get_widget(setup_glade_subcomponent, "subcomponent_frame"); + + w = glade_xml_get_widget(setup_glade_subcomponent, "subcomponent_button_cancel"); + gtk_widget_hide(w); + + gtk_widget_realize(window); + gtk_widget_realize(frame); + gtk_container_foreach(GTK_CONTAINER(frame), empty_container, frame); + + w = gtk_vbox_new(TRUE, 2); + gtk_container_add(GTK_CONTAINER(frame), w); + gtk_widget_show(w); + + gtk_object_set_data(GTK_OBJECT(window), "data", w); + + node = info->config->root->childs; + while(node != NULL && strcmp(node->name, "subcomponent")) + node = node->next; + if (!node) + log_fatal(_("subcomponent element not found")); + child = node->childs; + // subcomponent options + while(child != NULL) + { + if(!strcmp(child->name, "option")) + { + if(!strcmp(xmlGetProp(child, "install"), "true")) + install=1; + else + install=0; + + vbox = gtk_vbox_new(FALSE, 2); + gtk_box_pack_start(GTK_BOX(w), vbox, TRUE, FALSE, 0); + gtk_container_set_border_width(GTK_CONTAINER(vbox), 5); + gtk_widget_show(vbox); + + if(count) + { + sep = gtk_hseparator_new(); + gtk_box_pack_start(GTK_BOX(vbox), sep, FALSE, FALSE, 0); + gtk_widget_show(sep); + } + + text = xmlNodeListGetString(info->config, child->childs, 1); + parse_line(&text, name, sizeof(name)); + + check = gtk_check_button_new_with_label(name); + gtk_box_pack_start(GTK_BOX(vbox), check, FALSE, FALSE, 0); + if(install) + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check), TRUE); + gtk_signal_connect(GTK_OBJECT(check), "toggled", GTK_SIGNAL_FUNC(setup_subcomponent_toggle), NULL); + gtk_object_set_data(GTK_OBJECT(check), "name", name); + gtk_object_set_data(GTK_OBJECT(check), "node", child); + gtk_widget_show(check); + + hbox = gtk_hbox_new(FALSE, 2); + gtk_box_pack_start(GTK_BOX(vbox), hbox, TRUE, FALSE, 0); + gtk_widget_show(hbox); + + entry = gtk_entry_new(); + //gtk_box_pack_start(GTK_BOX(hbox), entry, TRUE, FALSE, 0); + gtk_container_add(GTK_CONTAINER(hbox), entry); + if(!install) + gtk_widget_set_sensitive(GTK_WIDGET(entry), FALSE); + gtk_signal_connect(GTK_OBJECT(entry), "focus_out_event", GTK_SIGNAL_FUNC(subcomponent_update_entry), NULL); + gtk_object_set_data(GTK_OBJECT(entry), "name", name); + gtk_object_set_data(GTK_OBJECT(entry), "node", child); + gtk_widget_show(entry); + + if(xmlGetProp(child, "path")) + { + gtk_entry_set_text(GTK_ENTRY(entry), xmlGetProp(child, "path")); + } + else if (xmlGetProp(child, "default_path")) + { + gtk_entry_set_text(GTK_ENTRY(entry), xmlGetProp(child, "default_path")); + } + + + button = gtk_button_new_with_label("..."); + gtk_box_pack_end(GTK_BOX(hbox), button, FALSE, FALSE, 0); + gtk_object_set_data(GTK_OBJECT(button), "data", gtk_entry_get_text(GTK_ENTRY(entry))); + gtk_object_set_data(GTK_OBJECT(button), "node", child); + gtk_signal_connect(GTK_OBJECT(button), "clicked", GTK_SIGNAL_FUNC(setup_button_subcomponent_browse), entry); + if(!install) + gtk_widget_set_sensitive(GTK_WIDGET(button), FALSE); + gtk_widget_show(button); + + gtk_object_set_data(GTK_OBJECT(check), "entry", entry); + gtk_object_set_data(GTK_OBJECT(check), "button", button); + + count++; + } + child = child->next; + } + gtk_widget_show(window); + //gtk_window_set_modal(GTK_WINDOW(window), TRUE); +} + +void setup_button_subcomponent_cancel(GtkWidget *widget, gpointer func_data) +{ + GtkWidget *window = glade_xml_get_widget(setup_glade_subcomponent, "subcomponent_dialog"); + gtk_widget_hide(window); +} + +void setup_button_subcomponent_ok(GtkWidget *widget, gpointer func_data) +{ + GtkWidget *window = glade_xml_get_widget(setup_glade_subcomponent, "subcomponent_dialog"); + gtk_widget_hide(window); +} + /********** UI functions *************/ static install_state gtkui_init(install_info *info, int argc, char **argv, int noninteractive) @@ -1533,6 +1718,12 @@ } } } + } else if ( ! strcmp(node->name, "subcomponent") ) { + GtkWidget *widget = gtk_button_new_with_label(xmlGetProp(node, "name")); + gtk_box_pack_start(GTK_BOX(options), GTK_WIDGET(widget), FALSE, FALSE, 5); + gtk_object_set_data(GTK_OBJECT(widget), "data", (gpointer)xmlGetProp(node, "name")); + gtk_signal_connect(GTK_OBJECT(widget), "clicked", GTK_SIGNAL_FUNC(setup_button_subcomponent), (gpointer)info); + gtk_widget_show(widget); } node = node->next; } @@ -1719,6 +1910,63 @@ gtkui_idle(info); } +static int dirname_loop; +static int prompt_ret; + +void store_dirname_slot(GtkFileSelection *selector, gpointer user_data) { + char *aux; + char *selected_dirname = (char *)user_data; + GtkWidget *parent; + + parent = gtk_widget_get_toplevel (GTK_WIDGET(selector)); + aux = gtk_file_selection_get_filename (GTK_FILE_SELECTION (parent)); + if (strlen(aux)) + strcpy(selected_dirname, aux); + + dirname_loop = 0; +} + +void abort_slot(GtkFileSelection *selector, gpointer user_data) { + dirname_loop = 0; + prompt_ret = 0; +} + +static int gtkui_dir_prompt (install_info *info, const char *message, char *path) +{ + GtkWidget *selector; + char *aux; + + /* Create the selector */ + selector = gtk_file_selection_new(message); + + gtk_file_selection_set_filename(GTK_FILE_SELECTION(selector), path); + gtk_file_selection_hide_fileop_buttons (GTK_FILE_SELECTION(selector)); + + gtk_signal_connect (GTK_OBJECT (GTK_FILE_SELECTION(selector)->ok_button), + "clicked", GTK_SIGNAL_FUNC (store_dirname_slot), path); + + gtk_signal_connect (GTK_OBJECT (GTK_FILE_SELECTION(selector)->cancel_button), + "clicked", GTK_SIGNAL_FUNC (abort_slot), path); + + /* Display that dialog */ + + gtk_grab_add(selector); + gtk_widget_show (selector); + gtk_grab_remove(selector); + + dirname_loop = 1; + prompt_ret = 1; + + while (dirname_loop==1) + gtk_main_iteration(); + + aux = gtk_file_selection_get_filename (GTK_FILE_SELECTION(selector)); + + gtk_widget_destroy(selector); + + return prompt_ret; +} + int gtkui_okay(Install_UI *UI, int *argc, char ***argv) { extern int force_console; @@ -1769,7 +2017,3 @@ #endif #endif - - - - Index: install.c =================================================================== RCS file: /cvs/cvsroot/loki_setup/install.c,v retrieving revision 1.124 diff -u -r1.124 install.c --- install.c 2003/09/27 01:52:38 1.124 +++ install.c 2003/10/24 18:12:38 @@ -429,7 +429,7 @@ } prop = xmlGetProp(node, "command"); if ( prop ) { /* Run the command */ - if ( run_script(info, prop, 0, 1) != 0 ) /* Failed, skip */ + if ( run_script(info, prop, NULL, 0, 1) != 0 ) /* Failed, skip */ continue; } prop = xmlGetProp(node, "lang"); @@ -1084,7 +1084,7 @@ log_fatal(_("XML: 'require' tag doesn't have a mandatory 'command' attribute")); } else { /* Launch the command */ - if ( run_script(info, prop, 0, 0) != 0 ) { + if ( run_script(info, prop, NULL, 0, 0) != 0 ) { /* We failed: print out error message */ text = xmlNodeListGetString(info->config, node->childs, 1); if(text) { @@ -1224,7 +1224,7 @@ return 0; /* Launch the command */ - return run_script(info, txt, 0, 0) == 0; + return run_script(info, txt, NULL, 0, 0) == 0; } } return 1; @@ -1431,7 +1431,7 @@ if (GetPreUnInstall(info) && info->installed_bytes>0) { snprintf(path, sizeof(path), "sh %s", GetPreUnInstall(info)); - run_script(info, path, 0, 1); + run_script(info, path, NULL, 0, 1); } if ( file_exists(info->install_path) ) { @@ -1448,7 +1448,7 @@ /* Do not run scripts if nothing was installed */ if ( info->installed_bytes>0 ) { for ( selem = opt->pre_script_list; selem; selem = selem->next ) { /* RPM pre-uninstall */ - run_script(info, selem->script, 0, 1); + run_script(info, selem->script, NULL, 0, 1); } } @@ -1465,7 +1465,7 @@ } if ( info->installed_bytes>0 ) { for ( selem = opt->post_script_list; selem; selem = selem->next ) { /* RPM post-uninstall */ - run_script(info, selem->script, 0, 1); + run_script(info, selem->script, NULL, 0, 1); } } @@ -1483,7 +1483,7 @@ } if (GetPostUnInstall(info) && info->installed_bytes>0) { snprintf(path, sizeof(path), "sh %s", GetPostUnInstall(info)); - run_script(info, path, 0, 1); + run_script(info, path, NULL, 0, 1); } if ( uninstall_generated ) { @@ -1896,7 +1896,7 @@ if ( ! restoring_corrupt() ) { script = GetPreInstall(info); if ( script ) { - exitval = run_script(info, script, -1, 1); + exitval = run_script(info, script, NULL, -1, 1); } } return exitval; @@ -1909,7 +1909,7 @@ if ( ! restoring_corrupt() ) { script = GetPostInstall(info); if ( script ) { - exitval = run_script(info, script, -1, 1); + exitval = run_script(info, script, NULL, -1, 1); } } return exitval; @@ -1930,7 +1930,7 @@ /* Run the command and set it to "true" if the return value is ok */ str = xmlGetProp(child, "command"); if ( str ) { - cmd = run_script(info, str, 0, 0); + cmd = run_script(info, str, NULL, 0, 0); xmlSetProp(child, "install", cmd ? "false" : "true"); log_debug("Script run: '%s' returned %d\n", str, cmd); } else { @@ -2370,13 +2370,16 @@ } /* Run some shell script commands */ -int run_script(install_info *info, const char *script, int arg, int include_tags) +int run_script(install_info *info, const char *script, const char *dest, int arg, int include_tags) { char script_file[PATH_MAX]; int fd; int exitval; char working_dir[PATH_MAX]; + if (!dest) + dest = ""; + /* We need to append the working directory onto the script name so it can always be found. Do this only if the script file exists (to avoid problems with 'sh script.sh') @@ -2412,13 +2415,16 @@ "SETUP_CDROMPATH=\"%s\"\n" "SETUP_DISTRO=\"%s\"\n" "SETUP_REINSTALL=\"%s\"\n" - "export SETUP_PRODUCTNAME SETUP_PRODUCTVER SETUP_INSTALLPATH SETUP_SYMLINKSPATH SETUP_CDROMPATH SETUP_DISTRO SETUP_REINSTALL\n", + "SETUP_COMPONENT_PATH=\"%s\"\n" + "export SETUP_PRODUCTNAME SETUP_PRODUCTVER SETUP_INSTALLPATH SETUP_SYMLINKSPATH SETUP_CDROMPATH SETUP_DISTRO SETUP_REINSTALL SETUP_OPTIONTAGS SETUP_COMPONENT_PATH\n", info->name, info->version, info->install_path, info->symlinks_path, info->cdroms_list ? info->cdroms_list->mounted : "", info->distro ? distribution_symbol[info->distro] : "", - info->options.reinstalling ? "1" : "0"); + info->options.reinstalling ? "1" : "0", + dest + ); if ( include_tags ) fprintf(fp, Index: install.h =================================================================== RCS file: /cvs/cvsroot/loki_setup/install.h,v retrieving revision 1.73 diff -u -r1.73 install.h --- install.h 2003/09/24 04:02:48 1.73 +++ install.h 2003/10/24 18:12:38 @@ -369,7 +369,7 @@ otherwise the install path is passed as a command line argument. 'include_tags' indicates if the SETUP_OPTIONTAGS should be set in the script header. */ -extern int run_script(install_info *info, const char *script, int arg, int include_tags); +extern int run_script(install_info *info, const char *script, const char *dest, int arg, int include_tags); /* returns true if any deviant paths are not writable */ char check_deviant_paths(xmlNodePtr node, install_info *info); @@ -399,4 +399,3 @@ #endif /* _install_h */ -