/*
	Add an address to the buffer.
	
	Parameter
		result
			Result structure to write to
		data
			Incoming address data buffer
			Must be 'int' aligned
		len
			Length of data buffer (in bytes)
			Must match data alignment
	
	Result
		Pointer to start of newly written data,
		or NULL on error.
		If address already exists in buffer, returns pointer to that instead.
 */
static void *
add_address_to_buffer (result_map_t * result, const void * data, int len)
{
	int new_addr;
	void * start;
	void * temp;
	
	if ((temp = contains_address (result, data, len)))
	{
		return temp;
	}
	
	if (result->addrs_count >= k_addrs_max)
	{
		// Not enough addr slots
		set_err_internal_resource_full (result);
		LOG(PHIDGET_LOG_ERROR,
			"mdns: Internal address buffer full; increase size"
		);
		return NULL;
	}
	
	// Idiot check
	if (len != result->hostent->h_length)
	{
		LOG(PHIDGET_LOG_WARNING,
			"mdns: Unexpected rdata length for address.  Expected %d, got %d",
			result->hostent->h_length,
			len
		);
		// XXX And continue for now.
	}

	new_addr = result->addr_idx + len;
	
	if (new_addr > result->alias_idx)
	{
		// Not enough room
		set_err_buf_too_small (result);
		LOG(PHIDGET_LOG_DEBUG,
			"mdns: Ran out of buffer when adding address %d",
			result->addrs_count + 1
		);
		return NULL;
	}

	start = result->buffer + result->addr_idx;
	memcpy (start, data, len);
	result->addr_idx = new_addr;
	result->header->addrs [result->addrs_count] = start;
	result->addrs_count ++;
	result->header->addrs [result->addrs_count] = NULL;

	return start;
}
Example #2
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;
}