예제 #1
0
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);
        }
    }
}
예제 #2
0
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;
}
예제 #3
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;
}