Пример #1
0
static int
scan_keyword_assignment(struct misc_file_buffer* file, struct scan_token* token,
		       int line)
{
	int rc;

	rc = scan_keyword(file, &token->content.keyword.keyword, line);
	if (rc)
		return rc;
	skip_blanks(file);
	if (misc_get_char(file, 0) != '=') {
		error_reason("Line %d: unexpected characters after keyword",
			     line);
		return -1;
	}
	file->pos++;
	skip_blanks(file);
	rc = scan_value_string(file, &token->content.keyword.value, line);
	if (rc)
		return rc;
	if (skip_trailing_blanks(file)) {
		error_reason("Line %d: unexpected characters at end of line",
			     line);
		return -1;
	}
	token->id = scan_id_keyword_assignment;
	token->line = line;
	return 0;
}
Пример #2
0
static int
scan_number(struct misc_file_buffer* file, int* number, int line)
{
	int start_pos;
	int old_number;
	int new_number;

	old_number = 0;
	new_number = 0;
	start_pos = file->pos;
	for (; isdigit(misc_get_char(file, 0)); file->pos++) {
		new_number = old_number*10 + misc_get_char(file, 0) - '0';
		if (new_number < old_number) {
			error_reason("Line %d: number too large", line);
			return -1;
		}
		old_number = new_number;
	}
	if (file->pos == start_pos) {
		error_reason("Line %d: number expected", line);
		return -1;
	}
	*number = new_number;
	return 0;
}
Пример #3
0
static int
check_menu_keyword_data(char* keyword[], int* line, char* name,
			int section_line)
{
	int i;

	for (i = 0; i < SCAN_KEYWORD_NUM; i++) {
		switch (scan_menu_key_table[i]) {
		case inv:
			if (!keyword[i])
				break;
			error_reason("Line %d: keyword '%s' not allowed in "
				     "menu section '%s'", line[i],
				     scan_keyword_name(
					(enum scan_keyword_id) i), name);
				return -1;
			break;
		case req:
			if (keyword[i])
				break;
			error_reason("Line %d: missing keyword '%s' "
				     "in menu section '%s'", section_line,
				     scan_keyword_name(
					(enum scan_keyword_id) i), name);
			return -1;
		default:
			break;
		}
	}
	return 0;
}
Пример #4
0
static int
scan_get_defaultboot_type(char* keyword[], int line[], int section_line,
			  enum scan_section_type* type)
{
	int key1;
	int key2;

	if (keyword[(int) scan_keyword_defaultauto]) {
		if (keyword[(int) scan_keyword_defaultmenu]) {
			key1 = (int) scan_keyword_defaultauto;
			key2 = (int) scan_keyword_defaultmenu;
			goto err_too_much;
		}
		if (!keyword[(int) scan_keyword_target]) {
			goto err_no_target;
		}
		*type = section_default_auto;
	} else if (keyword[(int) scan_keyword_target]) {
		if (keyword[(int) scan_keyword_defaultmenu]) {
			key1 = (int) scan_keyword_target;
			key2 = (int) scan_keyword_defaultmenu;
			goto err_too_much_target;
		}
		*type = section_default_auto;
	} else if (keyword[(int) scan_keyword_defaultmenu]) {
		if (keyword[(int) scan_keyword_default]) {
			key1 = (int) scan_keyword_defaultmenu;
			key2 = (int) scan_keyword_default;
			goto err_too_much;
		}
		*type = section_default_menu;
	} else if (keyword[(int) scan_keyword_default]) {
		*type = section_default_section;
	} else {
		error_reason("Line %d: Section '%s' requires one of keywords "
			     "'default', 'defaultmenu', 'defaultauto' or "
			     "'target'", section_line, DEFAULTBOOT_SECTION);
		return -1;
	}
	return 0;

err_no_target:
	error_reason("Line %d: Keyword 'target' required in section '%s' when "
		     "specifying 'defaultauto'", section_line,
		     DEFAULTBOOT_SECTION);
	return -1;

err_too_much:
	error_reason("Line %d: Only one of keywords 'default', 'defaultmenu' "
		     "and 'defaultauto' allowed in section '%s'",
		     MAX(line[key1], line[key2]), DEFAULTBOOT_SECTION);
	return -1;

err_too_much_target:
	error_reason("Line %d: Only one of keywords 'default', 'defaultmenu' "
		     "and 'target' allowed in section '%s'",
		     MAX(line[key1], line[key2]), DEFAULTBOOT_SECTION);
	return -1;
}
Пример #5
0
/* Check scanned tokens for compliance with config file rules. Return zero
 * if config file complies, non-zero otherwise. Rules are:
 *
 * Global:
 *  1 - no keywords are allowed outside of a section
 *
 * Configuration sections:
 *  2 - may not contain number assignments
 *  3 - must contain certain keywords according to type (see keyword_table)
 *  4 - may not contain certain keywords according to type (see keyword_table)
 *  5 - keywords may be specified at most once
 *  6 - must contain at least one keyword assignment
 *  7 - section name must be unique in the configuration file
 *  8 - defaultboot:default must point to a valid section
 *
 * Menu sections:
 *  9  - must contain at least one number assignment
 *  10 - numbers in number assignment have to be unique in the section
 *  11 - referenced sections must be present
 *  12 - must contain certain keywords according to type (see keyword_table)
 *  13 - may not contain certain keywords according to type (see keyword_table)
 *  14 - keywords may be specified at most once
 *  15 - menu name must be unique in the configuration file
 *  16 - optional default position must be a valid position
 * */
int
scan_check(struct scan_token* scan)
{
	int i;
	int rc;

	i = 0;
	while (scan[i].id != scan_id_empty) {
		switch (scan[i].id) {
		case scan_id_section_heading:
			rc = check_section(scan, &i);
			if (rc)
				return rc;
			break;
		case scan_id_menu_heading:
			rc = check_menu(scan, &i);
			if (rc)
				return rc;
			break;
		default:
			/* Rule 1 */
			error_reason("Line %d: %s not allowed outside of "
				     "section", scan[i].line,
				     scan_id_name(scan[i].id));
			return -1;
		}
	}
	return 0;
}
Пример #6
0
static int
scan_section_heading(struct misc_file_buffer* file, struct scan_token* token,
		     int line)
{
	int start_pos;
	int end_pos;
	int current;
	char* name;

	for (start_pos=file->pos; misc_get_char(file, 0) != ']'; file->pos++) {
		current = misc_get_char(file, 0);
		switch (current) {
		case EOF:
		case '\n':
			error_reason("Line %d: unterminated section heading",
				     line);
			return -1;
		default:
			if (!(isalnum(current) || ispunct(current))) {
				error_reason("Line %d: invalid character in "
					     "section name", line);
				return -1;
			}
		}
	}
	end_pos = file->pos;
	if (end_pos == start_pos) {
		error_reason("Line %d: empty section name", line);
		return -1;
	}
	file->pos++;
	if (skip_trailing_blanks(file)) {
		error_reason("Line %d: unexpected characters after section "
			     "name", line);
		return -1;
	}
	name = (char *) misc_malloc(end_pos - start_pos + 1);
	if (name == NULL)
		return -1;
	memcpy(name, &file->buffer[start_pos], end_pos - start_pos);
	name[end_pos - start_pos] = 0;
	token->id = scan_id_section_heading;
	token->line = line;
	token->content.section.name = name;
	return 0;
}
Пример #7
0
static int
scan_menu_heading(struct misc_file_buffer* file, struct scan_token* token,
		  int line)
{
	int start_pos;
	int end_pos;
	int current;
	char* name;

	for (start_pos=file->pos; ; file->pos++) {
		current = misc_get_char(file, 0);
		if ((current == EOF) || (current == '\n'))
			break;
		else if (isblank(current))
			break;
		else if (!isalnum(current)) {
			error_reason("Line %d: invalid character in menu name ",
				     line);
			return -1;
		}
	}
	end_pos = file->pos;
	if (skip_trailing_blanks(file)) {
		error_reason("Line %d: blanks not allowed in menu name",
			     line);
		return -1;
	}
	if (end_pos == start_pos) {
		error_reason("Line %d: empty menu name", line);
		return -1;
	}
	name = (char *) misc_malloc(end_pos - start_pos + 1);
	if (name == NULL)
		return -1;
	memcpy(name, &file->buffer[start_pos], end_pos - start_pos);
	name[end_pos - start_pos] = 0;
	token->id = scan_id_menu_heading;
	token->line = line;
	token->content.menu.name = name;
	return 0;
}
Пример #8
0
static int
scan_keyword(struct misc_file_buffer* file, enum scan_keyword_id* id, int line)
{
	unsigned int i;

	for (i=0; i < ARRAY_SIZE(keyword_list); i++)
		if (match_keyword(file, keyword_list[i].keyword) == 0) {
			file->pos += strlen(keyword_list[i].keyword);
			*id = keyword_list[i].id;
			return 0;
		}
	error_reason("Line %d: unknown keyword", line);
	return -1;
}
Пример #9
0
static int
scan_value_string(struct misc_file_buffer* file, char** value, int line)
{
	int quote;
	int start_pos;
	int end_pos;
	int last_nonspace;
	int current;
	char* string;

	current = misc_get_char(file, 0);
	if (current == '\"') {
		quote = '\"';
		file->pos++;
	} else if (current == '\'') {
		quote = '\'';
		file->pos++;
	} else quote = 0;
	last_nonspace = -1;
	for (start_pos=file->pos;; file->pos++) {
		current = misc_get_char(file, 0);
		if ((current == EOF) || (current == '\n')) {
			break;
		} else if (quote) {
			if (current == quote)
				break;
		} else if (!isblank(current))
			last_nonspace = file->pos;
	}
	end_pos = file->pos;
	if (quote) {
		if (current != quote) {
			error_reason("Line %d: unterminated quotes", line);
			return -1;
		}
	} else if (last_nonspace >= 0)
		end_pos = last_nonspace + 1;
	string = (char *) misc_malloc(end_pos - start_pos + 1);
	if (string == NULL)
		return -1;
	if (end_pos > start_pos)
		memcpy(string, &file->buffer[start_pos], end_pos - start_pos);
	string[end_pos - start_pos] = 0;
	*value = string;
	if (quote)
		file->pos++;
	return 0;
}
Пример #10
0
static int
scan_keyword_only_statement(struct misc_file_buffer* file,
			    struct scan_token* token, int line)
{
	int rc;

	rc = scan_keyword_only(file, &token->content.keyword.keyword, line);
	if (rc)
		return rc;
	if (skip_trailing_blanks(file)) {
		error_reason("Line %d: unexpected characters at end of line",
			     line);
		return -1;
	}
	token->id = scan_id_keyword_only;
	token->line = line;
	return 0;
}
Пример #11
0
static int
disk_determine_dasd_type(struct disk_info *data,
                         struct dasd_information dasd_info)
{
    if (strncmp(dasd_info.type, "FBA ",4) == 0)
        data->type = disk_type_fba;
    else if (strncmp(dasd_info.type, "DIAG",4) == 0)
        data->type = disk_type_diag;
    else if (strncmp(dasd_info.type, "ECKD",4) == 0) {
        if (dasd_info.FBA_layout)
            data->type = disk_type_eckd_ldl;
        else
            data->type = disk_type_eckd_cdl;
    } else {
        error_reason("Unknown DASD type");
        return -1;
    }
    return 0;
}
Пример #12
0
/* Check section at INDEX for compliance with config file rules. Upon success,
 * return zero and advance INDEX to point to the end of the section. Return
 * non-zero otherwise. */
static int
check_section(struct scan_token* scan, int* index)
{
	char* name;
	char* keyword[SCAN_KEYWORD_NUM];
	int keyword_line[SCAN_KEYWORD_NUM];
	enum scan_section_type type;
	int line;
	int rc;
	
	name = scan[*index].content.section.name;
	/* Ensure unique section names */
	line = scan_find_section(scan, name, scan_id_section_heading, *index+1);
	if (line >= 0) {
		error_reason("Line %d: section name '%s' already specified",
			     scan[line].line, name);
		return -1;
	}
	line = scan[*index].line;
	/* Get keyword data and advance index to end of section */
	rc = scan_get_section_keywords(scan, index, name, keyword, keyword_line,
				       NULL, NULL);
	if (rc)
		return rc;
	/* Check already done in scan_check_defaultboot */
	if (strcmp(name, DEFAULTBOOT_SECTION) == 0)
		return 0;
	else
		type = section_invalid;
	/* Check section data */
	rc = scan_check_section_data(keyword, keyword_line, name, line, &type);
	if (rc)
		return rc;
	/* Check target data */
	rc = scan_check_target_data(keyword, keyword_line);
	if (rc)
		return rc;
	return 0;
}
void EmacsPythonCommand::runPythonStringInsideTryExcept( const EmacsString &_command )
{
    EmacsString command( _command );

    //_dbg_msg( FormatString( "runPythonStringInsideTryExcept: Command: %s" ) << command );

    int pos=0;
    for(;;)
    {
        pos = command.index( '\n', pos );
        if( pos < 0 )
            break;
        command.insert( pos+1, '\t' );
        pos = pos + 2;
    }


    EmacsString wrapped_command( FormatString( python_try_command_except_structure ) << command );

    PyRun_SimpleString( wrapped_command.sdataHack() );

    try
    {
        Py::Module module( "__main__" );
        Py::Dict dict( module.getDict() );

        Py::Object error_reason( dict[ "__bemacs_error" ] );
        if( error_reason.isString() )
        {
            std::string reason_1 = Py::String( error_reason );
            commandFailed( EmacsString( EmacsString::copy, reason_1.c_str() ) );
        }
    }
    catch( Py::Exception &e )
    {
        //_dbg_msg( "runPythonStringInsideTryExcept: catch()" );
        e.clear();
    }
}
Пример #14
0
/*
 * Copy data from scan array to keyword/number assignment array. Return 0
 * on success, non-zero otherwise.
 *
 * If keyword X is specified in the section, keyword[X] contains the value of
 * that keyword and keyword_line[x] the line in which the keyword was defined.
 * Otherwise keyword[X] contains NULL.
 * If number assignment X is specified in the section, num[X - 1] contains
 * the value of that assignment and num_line the line in which the assignment
 * was found. Otherwise num[X - 1] contains NULL. If num is NULL, an error
 * is reported if a number assignment is found.
 */
static int
scan_get_section_keywords(struct scan_token* scan, int* index, char* name,
			  char* keyword[], int keyword_line[], char** num,
			  int* num_line)
{
	int i;
	int id;
	int key;
	int line;
	int number;
	char* value;

	/* Initialize array data. */
	for (i = 0; i < SCAN_KEYWORD_NUM; i++) {
		keyword[i] = NULL;
		keyword_line[i] = 0;
	}
	if (num) {
		for (i = 0; i < BOOT_MENU_ENTRIES; i++) {
			num[i] = NULL;
			num_line[i] = 0;
		}
	}
	/* Extract data for keyword and number assignments. */
	for (i = *index + 1; !scan_is_delimiter(scan[i].id); i++) {
		id = (int) scan[i].id;
		line = scan[i].line;
		/* Handle number assignments first. */
		if (id == scan_id_number_assignment) {
			number = scan[i].content.number.number;
			/* Check if number assignments are expected. */
			if (!num) {
				error_reason("Line %d: number assignment not "
					     "allowed in section '%s'",
					     line, name);
				return -1;
			}
			/* Check for valid numbers. */
			if (number <= 0) {
				error_reason("Line %d: position must be "
					     "greater than zero",
					     line);
                                return -1;

			}
			if (number > BOOT_MENU_ENTRIES) {
				error_reason("Line %d: position must not "
					     "exceed %d", line,
					     BOOT_MENU_ENTRIES);
                                return -1;
			}
			/* Rule 10 */
			if (num[number - 1]) {
				error_reason("Line %d: position %d already "
					     "specified", line, number);
				return -1;
			}
			num[number - 1] = scan[i].content.number.value;
			num_line[number - 1] = line;
			continue;
		}
		/* Handle keyword assignments. */
		if (id == scan_id_keyword_assignment) {
			key = scan[i].content.keyword.keyword;
			value = scan[i].content.keyword.value;
		} else if (id == scan_id_keyword_only) {
			key = scan[i].content.keyword_only.keyword;
			/* Define a dummy value. */
			value = "";
		} else {
			continue;
		}
		if (keyword[key]) {
			/* Rule 5 */
			error_reason("Line %d: keyword '%s' already specified",
				     line, scan_keyword_name(key));
			return -1;
		}
		keyword[key] = value;
		keyword_line[key] = line;
	}
	*index = i;

	return 0;
}
Пример #15
0
/* Check menu section at INDEX for compliance with config file rules. Upon
 * success, return zero and advance INDEX to point to the end of the section.
 * Return non-zero otherwise. */
static int
check_menu(struct scan_token* scan, int* index)
{
	char* keyword[SCAN_KEYWORD_NUM];
	int keyword_line[SCAN_KEYWORD_NUM];
	char* num[BOOT_MENU_ENTRIES];
	int num_line[BOOT_MENU_ENTRIES];
	char* menu_name;
	int menu_line;
	char dummy;
	int i;
	int rc;
	int number;
	int num_configs;

	menu_name = scan[*index].content.menu.name;
	menu_line = scan[*index].line;
	/* Rule 15 */
	i = scan_find_section(scan, menu_name, scan_id_menu_heading,
			      *index + 1);
	if (i >= 0) {
		error_reason("Line %d: menu name '%s' already specified",
			     scan[i].line, menu_name);
		return -1;
	}
	/* Get keyword and number assignment data */
	rc = scan_get_section_keywords(scan, index, menu_name, keyword,
				       keyword_line, num, num_line);
	if (rc)
		return rc;
	/* Check for required and invalid keywords */
	rc = check_menu_keyword_data(keyword, keyword_line, menu_name,
				     menu_line);
	if (rc)
		return rc;
	/* Check default value */
	i = (int) scan_keyword_default;
	if (keyword[i]) {
		if (sscanf(keyword[i], "%d %c", &number, &dummy) != 1) {
			error_reason("Line %d: default position must be a "
				     "number", keyword_line[i]);
			return -1;
		}
		if (number < 1) {
			error_reason("Line %d: default position must be "
				     "greater than zero", keyword_line[i]);
			return -1;
		}
		if (number > BOOT_MENU_ENTRIES) {
			error_reason("Line %d: default position too large",
				     keyword_line[i]);
			return -1;
		}
		if (!num[number - 1]) {
			error_reason("Line %d: menu position %d not defined",
				     keyword_line[i], number);
			return -1;
		}
	}
	/* Check prompt value */
	i = (int) scan_keyword_prompt;
	if (keyword[i]) {
		if (sscanf(keyword[i], "%d %c", &number, &dummy) != 1) {
			error_reason("Line %d: prompt value must be a number",
				     keyword_line[i]);
			return -1;
		}
		if (number != 0 && number != 1) {
			error_reason("Line %d: prompt value is out of range "
				     "(must be 0 or 1)", keyword_line[i]);
			return -1;
		}
	}
	/* Check timeout value */
	i = (int) scan_keyword_timeout;
	if (keyword[i]) {
		if (sscanf(keyword[i], "%d %c", &number, &dummy) != 1) {
			error_reason("Line %d: timeout value must be a number",
				     keyword_line[i]);
			return -1;
		}
		if (number < 0) {
			error_reason("Line %d: timeout value is out of range",
				     keyword_line[i]);
			return -1;
		}
	}
	/* Check number assignments */
	num_configs = 0;
	for (i = 0; i < BOOT_MENU_ENTRIES; i++) {
		if (!num[i])
			continue;
		if (scan_find_section(scan, num[i], scan_id_section_heading,
				      0) < 0) {
			error_reason("Line %d: section '%s' not found",
				     num_line[i], num[i]);
			return -1;
		}
		num_configs++;
	}
	/* Check for boot configurations */
	if (num_configs == 0) {
		error_reason("Line %d: no boot configuration specified in "
			     "menu '%s'", menu_line, menu_name);
		return -1;
	}
	/* Check target data */
	rc = scan_check_target_data(keyword, keyword_line);
	if (rc)
		return rc;

	return 0;
}
Пример #16
0
int
scan_check_target_data(char* keyword[], int* line)
{
	int cylinders, heads, sectors;
	char dummy;
	int number;
	enum scan_keyword_id errid;

	if (keyword[(int) scan_keyword_targetbase] == 0) {
		if (keyword[(int) scan_keyword_targettype] != 0)
			errid = scan_keyword_targettype;
		else if ((keyword[(int) scan_keyword_targetgeometry] != 0))
			errid = scan_keyword_targetgeometry;
		else if ((keyword[(int) scan_keyword_targetblocksize] != 0))
			errid = scan_keyword_targetblocksize;
		else if ((keyword[(int) scan_keyword_targetoffset] != 0))
			errid = scan_keyword_targetoffset;
		else
			return 0;
		if (line != NULL)
			error_reason("Line %d: keyword 'targetbase' required "
				"when specifying '%s'",
				line[(int) errid], scan_keyword_name(errid));
		else
			error_reason("Option 'targetbase' required when "
				"specifying '%s'",
				scan_keyword_name(errid));
		return -1;
	}
	if (keyword[(int) scan_keyword_targettype] == 0) {
		if (line != NULL)
			error_reason("Line %d: keyword 'targettype' "
				"required when specifying 'targetbase'",
				line[(int) scan_keyword_targetbase]);
		else
			error_reason("Option 'targettype' required "
				     "when specifying 'targetbase'");
		return -1;
	}
	switch (scan_get_target_type(keyword[(int) scan_keyword_targettype])) {
	case target_type_cdl:
	case target_type_ldl:
		if ((keyword[(int) scan_keyword_targetgeometry] != 0))
			break;
		if (line != NULL)
			error_reason("Line %d: keyword 'targetgeometry' "
				"required when specifying 'targettype' %s",
				line[(int) scan_keyword_targettype],
				keyword[(int) scan_keyword_targettype]);
		else
			error_reason("Option 'targetgeometry' required when "
				"specifying 'targettype' %s",
				keyword[(int) scan_keyword_targettype]);
		return -1;
	case target_type_scsi:
	case target_type_fba:
		if ((keyword[(int) scan_keyword_targetgeometry] == 0))
			break;
		if (line != NULL)
			error_reason("Line %d: keyword "
				"'targetgeometry' not allowed for "
				"'targettype' %s",
				line[(int) scan_keyword_targetgeometry],
				keyword[(int) scan_keyword_targettype]);
		else
			error_reason("Keyword 'targetgeometry' not "
				"allowed for 'targettype' %s",
				keyword[(int) scan_keyword_targettype]);
		return -1;
	case target_type_invalid:
		if (line != NULL)
			error_reason("Line %d: Unrecognized 'targettype' value "
				"'%s'",
				line[(int) scan_keyword_targettype],
				keyword[(int) scan_keyword_targettype]);
		else
			error_reason("Unrecognized 'targettype' value '%s'",
				keyword[(int) scan_keyword_targettype]);
		return -1;
	}
	if (keyword[(int) scan_keyword_targetgeometry] != 0) {
		if ((sscanf(keyword[(int) scan_keyword_targetgeometry],
		    "%d,%d,%d %c", &cylinders, &heads, &sectors, &dummy)
		    != 3) || (cylinders <= 0) || (heads <= 0) ||
		    (sectors <= 0)) {
			if (line != NULL)
				error_reason("Line %d: Invalid target geometry "
					"'%s'", line[
					(int) scan_keyword_targetgeometry],
					keyword[
					(int) scan_keyword_targetgeometry]);
			else
				error_reason("Invalid target geometry '%s'",
					keyword[
					(int) scan_keyword_targetgeometry]);
			return -1;
		}
	}
	if (keyword[(int) scan_keyword_targetblocksize] == 0) {
		if (line != NULL)
			error_reason("Line %d: Keyword 'targetblocksize' "
				"required when specifying 'targetbase'",
				line[(int) scan_keyword_targetbase]);
		else
			error_reason("Option 'targetblocksize' required when "
				"specifying 'targetbase'");
		return -1;
	}
	if ((sscanf(keyword[(int) scan_keyword_targetblocksize], "%d %c",
	    &number, &dummy) != 1) || check_blocksize(number)) {
		if (line != NULL)
			error_reason("Line %d: Invalid target blocksize '%s'",
				line[(int) scan_keyword_targetblocksize],
				keyword[(int) scan_keyword_targetblocksize]);
		else
			error_reason("Invalid target blocksize '%s'",
				keyword[(int) scan_keyword_targetblocksize]);
		return -1;
	}
	if (keyword[(int) scan_keyword_targetoffset] == 0) {
		if (line != NULL)
			error_reason("Line %d: Keyword 'targetoffset' "
				"required when specifying 'targetbase'",
				line[(int) scan_keyword_targetbase]);
		else
			error_reason("Option 'targetoffset' required when "
				"specifying 'targetbase'");
		return -1;
	}
	if (sscanf(keyword[(int) scan_keyword_targetoffset], "%d %c",
	    &number, &dummy) != 1) {
		if (line != NULL)
			error_reason("Line %d: Invalid target offset '%s'",
				line[(int) scan_keyword_targetoffset],
				keyword[(int) scan_keyword_targetoffset]);
		else
			error_reason("Invalid target offset '%s'",
				keyword[(int) scan_keyword_targetoffset]);
		return -1;
	}
	return 0;
}
Пример #17
0
/* Check section data for correctness. KEYWORD[keyword_id] defines whether
 * a keyword is present, LINE[keyword_id] specifies in which line a keyword
 * was found or NULL when specified on command line, NAME specifies the
 * section name or NULL when specified on command line. */
int
scan_check_section_data(char* keyword[], int* line, char* name,
			int section_line, enum scan_section_type* type)
{
	char* main_keyword;
	int i;

	main_keyword = "";
	/* Find out what type this section is */
	if (*type == section_invalid) {
		if (keyword[(int) scan_keyword_tape]) {
			*type = section_ipl_tape;
			main_keyword = scan_keyword_name(scan_keyword_tape);
		} else if (keyword[(int) scan_keyword_image]) {
			*type = section_ipl;
			main_keyword = scan_keyword_name(scan_keyword_image);
		} else if (keyword[(int) scan_keyword_segment]) {
			*type = section_segment;
			main_keyword = scan_keyword_name(scan_keyword_segment);
		} else if (keyword[(int) scan_keyword_dumpto]) {
			*type = section_dump;
			main_keyword = scan_keyword_name(scan_keyword_dumpto);
		} else if (keyword[(int) scan_keyword_dumptofs]) {
			error_reason("Option dumptofs is deprecated, "
				     "use dumpto instead");
			return -1;
		} else if (keyword[(int) scan_keyword_mvdump]) {
			*type = section_mvdump;
			main_keyword = scan_keyword_name(scan_keyword_mvdump);
		} else {
			error_reason("Line %d: section '%s' must contain "
				     "either one of keywords 'image', "
				     "'segment', 'dumpto', 'dumptofs', "
				     "'mvdump' or 'tape'", section_line, name);
			return -1;
		}
	}
	/* Check keywords */
	for (i=0; i < SCAN_KEYWORD_NUM; i++) {
		switch (scan_key_table[(int) *type][i]) {
		case req:
			/* Check for missing data */
			if ((keyword[i] == 0) && (line != NULL)) {
				/* Missing keyword in config file section */
				error_reason("Line %d: missing keyword '%s' "
					     "in section '%s'", section_line,
					     scan_keyword_name(
						     (enum scan_keyword_id) i),
					     name);
				return -1;
			} else if ((keyword[i] == 0) && (line == NULL)) {
				/* Missing keyword on command line */
				error_reason("Option '%s' required when "
					     "specifying '%s'",
					     scan_keyword_name(
						     (enum scan_keyword_id) i),
					     main_keyword);

				return -1;
			}
			break;
		case inv:
			/* Check for invalid data */
			if ((keyword[i] != 0) && (line != NULL)) {
				/* Invalid keyword in config file section */
				error_reason("Line %d: keyword '%s' not "
					     "allowed in section '%s'",
					     line[i],
					     scan_keyword_name(
						     (enum scan_keyword_id) i),
					     name);
				return -1;
			} else if ((keyword[i] != 0) && (line == NULL)) {
				/* Invalid keyword on command line */
				error_reason("Only one of options '%s' and "
					     "'%s' allowed", main_keyword,
					     scan_keyword_name(
						     (enum scan_keyword_id) i));
				return -1;
			}
			break;
		case opt:
			break;
		}
	}
	/* Additional check needed for segment */
	i = (int) scan_keyword_segment;
	if (keyword[i] != NULL) {
		if (!contains_address(keyword[i])) {
			if (line != NULL) {
				error_reason("Line %d: keyword 'segment' "
					     "requires "
					     "load address", line[i]);
			} else {
				error_reason("Option 'segment' requires "
					     "load address");
			}
			return -1;
		}
	}
	return 0;
}
Пример #18
0
/* scan_check_defaultboot checks the defaultboot section of the configuration
 * file. It returns
 *    0   on successful check, NO automenu is to be built
 *    1   on successful check, the automenu must be built
 *   -1   on error
 */
int
scan_check_defaultboot(struct scan_token* scan)
{
	int i;
	int j;
	char* keyword[SCAN_KEYWORD_NUM];
	int keyword_line[SCAN_KEYWORD_NUM];
	enum scan_section_type type;
	int defaultboot_line;
	int rc;

	/* Check if defaultboot is defined */
	i = scan_find_section(scan, DEFAULTBOOT_SECTION,
			      scan_id_section_heading, 0);
	if (i < 0) {
		error_reason("No '%s' section found and no section specified "
			     "on command line", DEFAULTBOOT_SECTION);
		return -1;
	}
	/* Ensure unique section names */
	j = scan_find_section(scan, DEFAULTBOOT_SECTION,
			      scan_id_section_heading, i + 1);
	if (j >= 0) {
		error_reason("Line %d: section name '%s' already specified",
			     scan[j].line, DEFAULTBOOT_SECTION);
		return -1;
	}
	defaultboot_line = scan[i].line;
	/* Get keyword data */
	rc = scan_get_section_keywords(scan, &i, DEFAULTBOOT_SECTION, keyword,
				       keyword_line, NULL, NULL);
	if (rc)
		return rc;
	/* Check default keyword value */
	i = (int) scan_keyword_default;
	if (keyword[i] && scan_find_section(scan, keyword[i],
					    scan_id_section_heading, 0) < 0) {
		error_reason("Line %d: no such section '%s'", keyword_line[i],
			     keyword[i]);
		return -1;
	}
	/* Determine default boot type */
	rc = scan_get_defaultboot_type(keyword, keyword_line, defaultboot_line,
				       &type);
	if (rc)
		return rc;
	/* Check target keywords */
	if (type == section_default_auto &&
	    scan_count_target_keywords(keyword) > 0) {
		rc = scan_check_target_data(keyword, keyword_line);
		if (rc)
			return rc;
	}
	/* Check remaining section data */
	rc = scan_check_section_data(keyword, keyword_line, DEFAULTBOOT_SECTION,
				     defaultboot_line, &type);
	if (rc)
		return rc;
	if (type == section_default_auto)
		return 1;
	else
		return 0;
}
Пример #19
0
struct scan_token *
scan_build_automenu(struct scan_token* scan)
{
	char* entry[BOOT_MENU_ENTRIES];
	int num_entries;
	int default_entry;
	char* db_keyword[SCAN_KEYWORD_NUM];
	int db_line[SCAN_KEYWORD_NUM];
	char* sec_keyword[SCAN_KEYWORD_NUM];
	int sec_line[SCAN_KEYWORD_NUM];
	int num_targets;
	int num_sections;
	size_t size;
	struct scan_token* new_scan;
	int i;
	int i_new;
	char* name;
	char* default_name;
	int pos;

	/* Find defaultboot */
	i = scan_find_section(scan, DEFAULTBOOT_SECTION,
			      scan_id_section_heading, 0);
	/* Get defaultboot data */
	if (scan_get_section_keywords(scan, &i, DEFAULTBOOT_SECTION, db_keyword,
				      db_line, NULL, NULL))
		return NULL;
	default_name = db_keyword[(int) scan_keyword_default];
	num_targets = scan_count_target_keywords(db_keyword);
	/* Get size of scan array and number of sections */
	num_sections = 0;
	for (i = 0; scan[i].id != scan_id_empty; i++) {
		if (scan[i].id == scan_id_section_heading)
			num_sections++;
	}
	size = /* old scan array + delimiter */     i + 1 +
	       /* defaultboot heading  */           1 +
	       /* defaultmenu */                    1 +
	       /* menu heading  */                  1 +
	       /* keyword default,prompt,timeout */ 3 +
	       /* target keywords*/                 num_targets +
	       /* missing target definitions */     num_sections * num_targets +
	       /* number assigment  */              num_sections;
	size *= sizeof(struct scan_token);
	new_scan = misc_malloc(size);
	if (!new_scan)
		return NULL;
	memset(new_scan, 0, size);
	/* Fill new array */
	i = 0;
	i_new = 0;
	num_entries = 0;
	default_entry = -1;
	memset(entry, 0, sizeof(entry));
	while (scan[i].id != scan_id_empty) {
		switch (scan[i].id) {
		case scan_id_menu_heading:
			name = scan[i].content.menu.name;
			/* Abort if automenu name is already in use */
			if (strcmp(name, SCAN_AUTOMENU_NAME) == 0) {
				error_reason("Cannot build automenu: menu name "
					     "'%s' already used",
					     SCAN_AUTOMENU_NAME);
				goto err;
			}
			/* Menu sections are copied without changes */
			if (scan_copy_section(scan, new_scan, &i, &i_new))
				goto err;
			break;
		case scan_id_section_heading:
			name = scan[i].content.section.name;
			/* Do not copy old defaultboot section */
			if (strcmp(name, DEFAULTBOOT_SECTION) == 0) {
				scan_skip_section(scan, &i);
				break;
			}
			/* Get section data but do not advance index */
			pos = i;
			if (scan_get_section_keywords(scan, &pos, name,
						      sec_keyword, sec_line,
						      NULL, NULL))
				goto err;
			/* Copy section contents and advance index */
			if (scan_copy_section(scan, new_scan, &i, &i_new))
				goto err;
			/* Stop here for non-IPL sections. */
			if (scan_get_section_type(sec_keyword) != section_ipl)
				break;
			/* Is there enough room for another section? */
			if (num_entries == BOOT_MENU_ENTRIES) {
				error_reason("Cannot build automenu: too many "
					     "IPL sections defined (max %d)",
					     BOOT_MENU_ENTRIES);
				goto err;
			}
			/* Determine if this is the default entry */
			if (default_name && strcmp(default_name, name) == 0)
				default_entry = num_entries;
			entry[num_entries++] = name;
			/* Add missing target parameters if necessary */
			if (scan_count_target_keywords(sec_keyword) > 0)
				break;
			if (scan_append_target_keywords(new_scan, &i_new,
							db_keyword))
				goto err;
			break;
		default:
			/* Rule 1 */
			error_reason("Line %d: %s not allowed outside of "
				     "section", scan[i].line,
				     scan_id_name(scan[i].id));
			goto err;
		}
	}
	if (num_entries == 0) {
		error_reason("Cannot build automenu: no IPL entries available");
		goto err;
	}

	/* Append new defaultboot and automenu sections */
	/* [defaultboot] */
	if (scan_append_section_heading(new_scan, &i_new, DEFAULTBOOT_SECTION))
		goto err;
	/* defaultmenu=zipl-automatic-menu */
	if (scan_append_keyword_assignment(new_scan, &i_new,
				scan_keyword_defaultmenu, SCAN_AUTOMENU_NAME))
		goto err;
	/* :zipl-automatic-menu */
	if (scan_append_menu_heading(new_scan, &i_new, SCAN_AUTOMENU_NAME))
		goto err;
	/* default= */
	if (default_entry >= 0) {
		char str[20];

		snprintf(str, sizeof(str), "%d", default_entry + 1);
		if (scan_append_keyword_assignment(new_scan, &i_new,
						   scan_keyword_default, str))
			goto err;
	}
	/* prompt= */
	i = (int) scan_keyword_prompt;
	if (db_keyword[i]) {
		if (scan_append_keyword_assignment(new_scan, &i_new,
						   scan_keyword_prompt,
						   db_keyword[i]))
			goto err;
	}
	/* timeout= */
	i = (int) scan_keyword_timeout;
	if (db_keyword[i]) {
		if (scan_append_keyword_assignment(new_scan, &i_new,
						   scan_keyword_timeout,
						   db_keyword[i]))
			goto err;
	}
	/* target= */
	/* targetbase= */
	/* targetgeometry= */
	/* targetblocksize= */
	/* targetoffset= */
	if (scan_append_target_keywords(new_scan, &i_new, db_keyword))
		goto err;
	/* <num>=<section name>*/
	for (i = 0; i < num_entries; i++) {
		if (scan_append_number_assignment(new_scan, &i_new, i + 1,
						  entry[i]))
			goto err;
	}

	return new_scan;

err:
	scan_free(new_scan);
	return NULL;
}