static void parse_option(install_info *info, const char *component, xmlNodePtr node, OptionsBox *box, int level, OptionsButton *parent, int exclusive, RadioGroup **radio) { xmlNodePtr child; char text[1024] = ""; const char *help; const char *wanted; char *name; int i; OptionsButton *button = NULL; /* See if this node matches the current architecture */ wanted = xmlGetProp(node, "arch"); if ( ! match_arch(info, wanted) ) { return; } wanted = xmlGetProp(node, "libc"); if ( ! match_libc(info, wanted) ) { return; } wanted = xmlGetProp(node, "distro"); if ( ! match_distro(info, wanted) ) { return; } if ( ! get_option_displayed(info, node) ) { return; } /* See if the user wants this option */ if ( node->type == XML_TEXT_NODE ) { //name = g_strdup(node->content); name = strdup(node->content); //!!!TODO - Strip name //g_strstrip(name); if( *name ) { //button = gtk_label_new(name); //gtk_widget_show(button); //gtk_box_pack_start(GTK_BOX(box), GTK_WIDGET(button), FALSE, FALSE, 0); button = carbon_OptionsNewLabel(box, name); } //!!!TODO - Free name //g_free(name); return; } else { name = get_option_name(info, node, NULL, 0); for(i=0; i < (level*5); i++) text[i] = ' '; text[i] = '\0'; strncat(text, name, sizeof(text)-strlen(text)); } if ( GetProductIsMeta(info) ) { //button = gtk_radio_button_new_with_label(radio_list, text); //radio_list = gtk_radio_button_group(GTK_RADIO_BUTTON(button)); button = carbon_OptionsNewRadioButton(box, text, &radio_list); } else if ( exclusive ) { //button = gtk_radio_button_new_with_label(*radio, text); //*radio = gtk_radio_button_group(GTK_RADIO_BUTTON(button)); button = carbon_OptionsNewRadioButton(box, text, radio); } else { //button = gtk_check_button_new_with_label(text); button = carbon_OptionsNewCheckButton(box, text); } /* Add tooltip help, if available */ help = get_option_help(info, node); if ( help ) { //GtkTooltipsData* group; //group = gtk_tooltips_data_get(window); //if ( group ) { //gtk_tooltips_set_tip( group->tooltips, button, help, 0); //} else { //gtk_tooltips_set_tip( gtk_tooltips_new(), button, help, 0); //} carbon_OptionsSetTooltip(button, help); } /* Set the data associated with the button */ if ( button ) { //gtk_object_set_data(GTK_OBJECT(button), "data", (gpointer)node); button->Data = (void *)node; /* Register the button in the window's private data */ //window = glade_xml_get_widget(setup_glade, "setup_window"); //gtk_object_set_data(GTK_OBJECT(window), name, (gpointer)button); if(strlen(name) >= MAX_BUTTON_NAME) carbon_debug("parse_option() - Button name exceeeded length! This will cause problems with selecting options!\n"); else strcpy(button->Name, name); } /* Check for required option */ if ( xmlGetProp(node, "required") ) { xmlSetProp(node, "install", "true"); //gtk_widget_set_sensitive(GTK_WIDGET(button), FALSE); DisableControl(button->Control); } /* If this is a sub-option and parent is not active, then disable option */ wanted = xmlGetProp(node, "install"); //if( level>0 && GTK_IS_TOGGLE_BUTTON(parent) && !gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(parent)) ) { if( level>0 && parent->Type == ButtonType_Radio && !carbon_OptionsGetValue(parent)) { wanted = "false"; //gtk_widget_set_sensitive(GTK_WIDGET(button), FALSE); DisableControl(button->Control); } //***This functionality is implemented automatically when creating no option*** // buttons and labels //if ( button ) { // gtk_box_pack_start(GTK_BOX(box), GTK_WIDGET(button), FALSE, FALSE, 0); // gtk_signal_connect(GTK_OBJECT(button), "toggled", // GTK_SIGNAL_FUNC(setup_checkbox_option_slot), (gpointer)node); // gtk_widget_show(button); //} if ( wanted && (strcmp(wanted, "true") == 0) ) { //gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), TRUE); carbon_OptionsSetValue(button, true); } else { /* Unmark this option for installation */ mark_option(info, node, "false", 1); } /* Recurse down any other options */ child = node->childs; while ( child ) { if ( !strcmp(child->name, "option") ) { //parse_option(info, component, child, window, box, level+1, button, 0, NULL); parse_option(info, component, child, box, level+1, button, 0, NULL); } else if ( !strcmp(child->name, "exclusive") ) { xmlNodePtr exchild; //GSList *list = NULL; RadioGroup *list = NULL; for ( exchild = child->childs; exchild; exchild = exchild->next) { //parse_option(info, component, exchild, window, box, level+1, button, 1, &list); parse_option(info, component, exchild, box, level+1, button, 1, &list); } } child = child->next; } /* Disable any options that are already installed */ if ( info->product && ! GetProductReinstall(info) ) { product_component_t *comp; if ( component ) { comp = loki_find_component(info->product, component); } else { comp = loki_getdefault_component(info->product); } if ( comp && loki_find_option(comp, name) ) { /* Unmark this option for installation */ //gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), FALSE); //gtk_widget_set_sensitive(button, FALSE); carbon_OptionsSetValue(button, FALSE); DisableControl(button->Control); mark_option(info, node, "false", 1); } } }
int main(int argc, char **argv) { /* * VARIABLES */ /* simple counter */ int i = 1; /* getopt_long-options */ static struct option long_options[] = { {"dist", required_argument, 0, 'd'}, {"in", required_argument, 0, 'i'}, {"out", required_argument, 0, 'o'}, {0, 0, 0, 0} }; /* Filepointers to in and outfile */ FILE *in; FILE *out = NULL; /* a string containing the name of the distro we are working on */ const char *distro = NULL; /* filenames, of in and outfiles */ const char *infile = NULL; const char *outfile = NULL; /* temporary data storage */ const char *data; /* space to get the line we are parsing */ char line[LINE_LEN]; /* if parsing an #exec, fill this string with #exec data */ char exec_buffer[EXEC_BUFFER_LEN]; /* The maximum exec_buffer lengt we have left to fill */ int exec_buffer_free = EXEC_BUFFER_LEN - 1; /* Current line number in input */ int lineno = 0; /* Stack - please use the macros defined below, if possible */ struct { enum_block block_type; int process_elses; int print_out; int lineno; } stack[16]; int stack_top = 0; #define POP_STACK --stack_top #define PUSH_STACK(type) ( stack[stack_top].process_elses = BLOCK_PRINTS_OUT, \ stack[stack_top].print_out = BLOCK_PRINTS_OUT, \ stack[stack_top].lineno = lineno, \ stack[stack_top++].block_type = type) #define BLOCK_PRINTS_OUT ( stack_top ? stack[stack_top-1].print_out : 1 ) #define STACK_EMPTY ( stack_top == 0 ) #define STACK_TOP ( stack[stack_top-1] ) #define IN_BLOCK ( stack_top ? stack[stack_top-1].block_type : 0 ) /* * CODE */ /* parse and fill path struct */ path = str_split(getenv("PATH"), ':'); if (!path) { fprintf(stderr, " **\tERROR: could not get $PATH\n"); exit(1); } /* Parse initial arguments */ while (-1 != (i = getopt_long(argc, argv, "hi:o:d:", long_options, NULL))) { switch (i) { /* set the distro manually */ case 'd': distro = optarg; break; /* set the file to parse */ case 'i': infile = optarg; break; /* set the outfile manually */ case 'o': outfile = optarg; break; default: fprintf(stdout, "Ups, what's that? <0%o>\n", i); } } /* if not set, probe it */ if (!distro) distro = probe_distribution(); if (!distro) { fprintf(stderr, " **\tUnknown DISTRIBUTION\n"); exit(1); } fprintf(stderr, " **\tDistribution set: \"%s\"\n", distro); /* load the overlay */ { int j; char file[200]; /* reset the ovelay */ for (j = 0; j < 1000; j++) { overlay[j].opt = NULL; overlay[j].value = NULL; } /* and distro dependent overlay, found in workdir */ sprintf(file, "%s.overlay", distro); load_overlay_file(file); /* a standard path for overlay */ strcpy(file, INITNG_ROOT); strcat(file, "/initng.overlay"); load_overlay_file(file); /*printf("Overlays found:\n"); for(j=0;j<1000 && overlay[j].opt;j++) { printf(" \"%s\" == \"%s\"\n", overlay[j].opt, overlay[j].value); } */ } /* open input for writing */ if (!infile) { fprintf(stderr, " **\tYou have to set input file with -i\n"); exit(1); } if (!(in = fopen(infile, "r"))) { fprintf(stderr, " **\tcould not open input file!\n"); exit(1); } /* make sure input is service.s */ if (!strstr(infile, ".s")) { printf("install_service_file only handles *.s files!\n"); exit(1); } /* open output for writing */ if (!outfile) { if (strstr(infile, ".s")) { outfile = strndup(infile, strlen(infile) - 2); } else { fprintf(stderr, " **\tout with -o not set, " "defaulting to stdout.\n"); out = stdout; } } if (!out && !(out = fopen(outfile, "w"))) { fprintf(stderr, " **\tcould not open output file!\n"); exit(1); } /* Print header */ fprintf(out, "#!/sbin/runiscript\n" "# This is an init script file, used by initng.\n\n"); /* Okay, go parse every line */ while (fgets(line, LINE_LEN, in)) { lineno++; /* * This is an internal set, to force an standard default path, * please us an direct @/usr/sbin/gdm@ instead. */ if (match("#atdefpath", line)) { D_("found #atdefpath. updating at default path\n"); /* get the data after #atdefpath data */ data = skip_spaces(line + LEN("#atdefpath")); /* free previous fore path */ if (at_default_path) free(at_default_path); /* allocate an new one */ at_default_path = malloc(strlen(data) + 1); /* copy the data */ i = 0; while (data[i] && data[i] != ' ' && data[i] != '\t' && data[i] != '\n') { at_default_path[i] = data[i]; i++; } at_default_path[i] = '\0'; D_("at_default_path updated to %s\n", at_default_path); /* explain */ at_default_paths = str_split(at_default_path, ':'); continue; } /* If this is an ordinary line, not starting with an # */ if (STACK_EMPTY && line[0] != '#') { /* youst print it to outfile */ print_it(out, line); continue; /* read next line */ } /* either in_block != 0 or line started with '#' */ if (IN_BLOCK == EXEC_BLOCK) { /* in_block == EXEC_BLOCK */ if (match("#endexec", line)) { D_("found #endexec, line %i\n", lineno); /* Do the exec shit */ if (BLOCK_PRINTS_OUT) { data = do_exec(exec_buffer, strlen(exec_buffer)); if (data) { print_it(out, data); free((void *)data); } } POP_STACK; continue; } else { strncat(exec_buffer, line, exec_buffer_free); exec_buffer_free -= strlen(line); continue; } } else { /* #exec is an internal run, and output will be * outputed to outfile */ if (match("#exec", line)) { D_("found #exec, line %i\n", lineno); exec_buffer[0] = '\0'; exec_buffer_free = EXEC_BUFFER_LEN - 1; PUSH_STACK(EXEC_BLOCK); continue; } else if (match("#endexec", line)) { fprintf(stderr, "ERROR: #endexec without " "#exec, line %i\n", lineno); fclose(out); if (outfile) unlink(outfile); exit(1); } /* #ifd debian, meens utput this to outfile if * distro == debian */ else if (match("#ifd", line)) { D_("found #ifd, line %i\n", lineno); PUSH_STACK(IF_BLOCK); STACK_TOP.print_out = 0; if (STACK_TOP.process_elses && match_distro(line, distro)) { D_("actual distro %s matches line " "%i: %s\n", distro, lineno, line); STACK_TOP.print_out = 1; STACK_TOP.process_elses = 0; } continue; } else if (match("#elsed", line)) { if (IN_BLOCK != IF_BLOCK) { fprintf(stderr, "ERROR: unexpected " "#elsed, line %i\n", lineno); fclose(out); if (outfile) unlink(outfile); exit(1); } if (STACK_TOP.process_elses) { if (empty_elsed(line) || match_distro(line, distro)) { STACK_TOP.print_out = 1; STACK_TOP.process_elses = 0; } } else { STACK_TOP.print_out = 0; } } else if (match("#endd", line)) { if (IN_BLOCK != IF_BLOCK) { fprintf(stderr, "ERROR: unexpected " "#endd, line %i\n", lineno); fclose(out); if (outfile) unlink(outfile); exit(1); } POP_STACK; } else { /* it's just an ordinary line */ if (BLOCK_PRINTS_OUT) print_it(out, line); continue; /* read next line */ } } } if (!STACK_EMPTY) { while (!STACK_EMPTY) { if (IN_BLOCK == EXEC_BLOCK) fprintf(stderr, "ERROR: missing #endexec for " "#exec on line %i\n", STACK_TOP.lineno); else fprintf(stderr, "ERROR: missing #endd for " "#ifd on line %i\n", STACK_TOP.lineno); POP_STACK; } fclose(out); if (outfile) unlink(outfile); exit(1); } #if 0 /* We don't really need to free anything, 'coz we will exit soon */ /* free the overlay table */ for (i = 0; i < 1000 && overlay[i].opt; i++) { free((char *)overlay[i].opt); /* const-cast */ overlay[i].opt = NULL; if (overlay[i].value) { free((char *)overlay[i].value); /* const-cast */ overlay[i].value = NULL; } } #endif /* close bouth input and output file */ fclose(in); fclose(out); if (outfile) { chmod(outfile, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH); } return 0; }
static install_state carbonui_setup(install_info *info) { //GtkWidget *window; //GtkWidget *options; OptionsBox *options; xmlNodePtr node; carbon_debug("***carbonui_setup()\n"); // These are required before displaying the CDKey. I'm not sure why this // is true, but they show up blank later on...even when making a call to // these functions later in this function. init_install_path(); init_binary_path(); update_size(); update_space(); // If CDKEY attribute was specified, show the CDKEY screen if(GetProductCDKey(cur_info)) { // Show CDKey entry page and wait for user to hit cancel or continue carbon_SetProperWindowSize(MyRes, NULL); carbon_ShowInstallScreen(MyRes, CDKEY_PAGE); CDKeyOK = false; carbon_IterateForState(MyRes, &CDKeyOK); // Go back to the option page as normal for this function if(!express_setup) carbon_ShowInstallScreen(MyRes, OPTION_PAGE); } // If express setup, go right to copy page if(express_setup) { carbon_ShowInstallScreen(MyRes, COPY_PAGE); cur_state = SETUP_INSTALL; return cur_state; } // User could've canceled installation during the CDKey if(cur_state != SETUP_EXIT) { // Else, let the user select appropriate options //options = glade_xml_get_widget(setup_glade, "option_vbox"); //gtk_container_foreach(GTK_CONTAINER(options), empty_container, options); options = carbon_OptionsNewBox(MyRes, true, OnOptionClickEvent); info->install_size = 0; node = info->config->root->childs; radio_list = NULL; in_setup = TRUE; while ( node ) { if ( ! strcmp(node->name, "option") ) { parse_option(info, NULL, node, options, 0, NULL, 0, NULL); } else if ( ! strcmp(node->name, "exclusive") ) { xmlNodePtr child; RadioGroup *list = NULL; for ( child = node->childs; child; child = child->next) { parse_option(info, NULL, child, options, 0, NULL, 1, &list); } } else if ( ! strcmp(node->name, "component") ) { if ( match_arch(info, xmlGetProp(node, "arch")) && match_libc(info, xmlGetProp(node, "libc")) && match_distro(info, xmlGetProp(node, "distro")) ) { xmlNodePtr child; if ( xmlGetProp(node, "showname") ) { //GtkWidget *widget = gtk_hseparator_new(); //gtk_box_pack_start(GTK_BOX(options), GTK_WIDGET(widget), FALSE, FALSE, 0); //gtk_widget_show(widget); carbon_OptionsNewSeparator(options); //widget = gtk_label_new(xmlGetProp(node, "name")); //gtk_box_pack_start(GTK_BOX(options), GTK_WIDGET(widget), FALSE, FALSE, 10); //gtk_widget_show(widget); carbon_OptionsNewLabel(options, xmlGetProp(node, "name")); } for ( child = node->childs; child; child = child->next) { if ( ! strcmp(child->name, "option") ) { //parse_option(info, xmlGetProp(node, "name"), child, window, options, 0, NULL, 0, NULL); parse_option(info, xmlGetProp(node, "name"), child, options, 0, NULL, 0, NULL); } else if ( ! strcmp(child->name, "exclusive") ) { xmlNodePtr child2; RadioGroup *list = NULL; for ( child2 = child->childs; child2; child2 = child2->next) { //parse_option(info, xmlGetProp(node, "name"), child2, window, options, 0, NULL, 1, &list); parse_option(info, xmlGetProp(node, "name"), child2, options, 0, NULL, 1, &list); } } } } } node = node->next; } // Render and display options in window carbon_OptionsShowBox(options); // Refresh the enable/disable status of buttons carbon_RefreshOptions(options); // Resize the window if there are too many options to fit carbon_SetProperWindowSize(MyRes, options); init_install_path(); init_binary_path(); update_size(); update_space(); init_menuitems_option(info); in_setup = FALSE; int TempState = carbon_IterateForState(MyRes, &cur_state); // Return the window back to default size, if necessary except // if we're exiting (so we don't redisplay the window after it // has been hidden if(cur_state != SETUP_EXIT) carbon_SetProperWindowSize(MyRes, NULL); // Return the next state as appopriate return TempState; } // Return the current state if it's SETUP_EXIT return cur_state; }