Exemple #1
0
void ifparser_init (const char *eni_file, int quiet)
{
	FILE *inp = fopen (eni_file, "r");
	char line[255];
	int skip_to_block = 1;
	int skip_long_line = 0;
	int offs = 0;

	if (inp == NULL) {
		if (!quiet)
			g_warning ("Error: Can't open %s\n", eni_file);
		return;
	}

	first = last = NULL;
	while (!feof(inp))
	{
		char *token[128];	// 255 chars can only be split into 127 tokens
		char value[255];	// large enough to join previously split tokens
		char *safeptr;
		int toknum;
		int len = 0;

		char *ptr = fgets(line+offs, 255-offs, inp);
		if (ptr == NULL)
			break;

		len = strlen(line);
		// skip over-long lines
		if (!feof(inp) && len > 0 &&  line[len-1] != '\n') {
			if (!skip_long_line) {
				if (!quiet)
					g_message ("Error: Skipping over-long-line '%s...'\n", line);
			}
			skip_long_line = 1;
			continue;
		}

		// trailing '\n' found: remove it & reset offset to 0
		if (len > 0 && line[len-1] == '\n') {
			line[--len] = '\0';
			offs = 0;
		}

		// if we're in long_line_skip mode, terminate it for real next line
		if (skip_long_line) {
			if (len == 0 || line[len-1] != '\\')
				skip_long_line = 0;
			continue;
		}

		// unwrap wrapped lines
		if (len > 0 && line[len-1] == '\\') {
			offs = len - 1;
			continue;
		}

		//printf(">>%s<<\n", line);

#define SPACES	" \t"
		// tokenize input;
		for (toknum = 0, token[toknum] = strtok_r(line, SPACES, &safeptr);
		     token[toknum] != NULL;
		     toknum++, token[toknum] = strtok_r(NULL, SPACES, &safeptr))
			;

		// ignore comments and empty lines
		if (toknum == 0 || *token[0]=='#')
			continue;

		if (toknum < 2) {
			if (!quiet) {
				g_message ("Error: Can't parse interface line '%s'\n",
						join_values_with_spaces(value, token));
			}
			skip_to_block = 1;
			continue;
		}

		// There are four different stanzas:
		// iface, mapping, auto and allow-*. Create a block for each of them.

		// iface stanza takes at least 3 parameters
		if (strcmp(token[0], "iface") == 0) {
			if (toknum < 4) {
				if (!quiet) {
					g_message ("Error: Can't parse iface line '%s'\n",
							join_values_with_spaces(value, token));
				}
				continue;
			}
			add_block(token[0], token[1]);
			skip_to_block = 0;
			add_data(token[2], join_values_with_spaces(value, token + 3));
		}
		// auto and allow-auto stanzas are equivalent,
		// both can take multiple interfaces as parameters: add one block for each
		else if (strcmp(token[0], "auto") == 0 ||
			 strcmp(token[0], "allow-auto") == 0) {
			int i;
			for (i = 1; i < toknum; i++)
				add_block("auto", token[i]);
			skip_to_block = 0;
		}
		else if (strcmp(token[0], "mapping") == 0) {
			add_block(token[0], join_values_with_spaces(value, token + 1));
			skip_to_block = 0;
		}
		// allow-* can take multiple interfaces as parameters: add one block for each
		else if (strncmp(token[0],"allow-",6) == 0) {
			int i;
			for (i = 1; i < toknum; i++)
				add_block(token[0], token[i]);
			skip_to_block = 0;
		}
		else {
			if (skip_to_block) {
				if (!quiet) {
					g_message ("Error: ignoring out-of-block data '%s'\n",
							join_values_with_spaces(value, token));
				}
			} else
				add_data(token[0], join_values_with_spaces(value, token + 1));
		}
	}
	fclose(inp);
}
static void
_recursive_ifparser (const char *eni_file, int quiet)
{
	FILE *inp;
	char line[255];
	int skip_to_block = 1;
	int skip_long_line = 0;
	int offs = 0;

	// Check if interfaces file exists and open it
	if (!g_file_test (eni_file, G_FILE_TEST_EXISTS)) {
		if (!quiet)
			nm_log_warn (LOGD_SETTINGS, "interfaces file %s doesn't exist\n", eni_file);
		return;
	}
	inp = fopen (eni_file, "r");
	if (inp == NULL) {
		if (!quiet)
			nm_log_warn (LOGD_SETTINGS, "Can't open %s\n", eni_file);
		return;
	}
	if (!quiet)
		nm_log_info (LOGD_SETTINGS, "      interface-parser: parsing file %s\n", eni_file);


	while (!feof(inp))
	{
		char *token[128];	// 255 chars can only be split into 127 tokens
		char value[255];	// large enough to join previously split tokens
		char *safeptr;
		int toknum;
		int len = 0;

		char *ptr = fgets(line+offs, 255-offs, inp);
		if (ptr == NULL)
			break;

		len = strlen(line);
		// skip over-long lines
		if (!feof(inp) && len > 0 &&  line[len-1] != '\n') {
			if (!skip_long_line) {
				if (!quiet)
					nm_log_warn (LOGD_SETTINGS, "Skipping over-long-line '%s...'\n", line);
			}
			skip_long_line = 1;
			continue;
		}

		// trailing '\n' found: remove it & reset offset to 0
		if (len > 0 && line[len-1] == '\n') {
			line[--len] = '\0';
			offs = 0;
		}

		// if we're in long_line_skip mode, terminate it for real next line
		if (skip_long_line) {
			if (len == 0 || line[len-1] != '\\')
				skip_long_line = 0;
			continue;
		}

		// unwrap wrapped lines
		if (len > 0 && line[len-1] == '\\') {
			offs = len - 1;
			continue;
		}

		//printf(">>%s<<\n", line);

#define SPACES	" \t"
		// tokenize input;
		for (toknum = 0, token[toknum] = strtok_r(line, SPACES, &safeptr);
		     token[toknum] != NULL;
		     toknum++, token[toknum] = strtok_r(NULL, SPACES, &safeptr))
			;

		// ignore comments and empty lines
		if (toknum == 0 || *token[0]=='#')
			continue;

		if (toknum < 2) {
			if (!quiet) {
				nm_log_warn (LOGD_SETTINGS, "Can't parse interface line '%s'\n",
				             join_values_with_spaces(value, token));
			}
			skip_to_block = 1;
			continue;
		}

		// There are five different stanzas:
		// iface, mapping, auto, allow-* and source.
		// Create a block for each of them except source.

		// iface stanza takes at least 3 parameters
		if (strcmp(token[0], "iface") == 0) {
			if (toknum < 4) {
				if (!quiet) {
					nm_log_warn (LOGD_SETTINGS, "Can't parse iface line '%s'\n",
					             join_values_with_spaces(value, token));
				}
				continue;
			}
			add_block(token[0], token[1]);
			skip_to_block = 0;
			add_data(token[2], join_values_with_spaces(value, token + 3));
		}
		// auto and allow-auto stanzas are equivalent,
		// both can take multiple interfaces as parameters: add one block for each
		else if (strcmp(token[0], "auto") == 0 ||
			 strcmp(token[0], "allow-auto") == 0) {
			int i;
			for (i = 1; i < toknum; i++)
				add_block("auto", token[i]);
			skip_to_block = 0;
		}
		else if (strcmp(token[0], "mapping") == 0) {
			add_block(token[0], join_values_with_spaces(value, token + 1));
			skip_to_block = 0;
		}
		// allow-* can take multiple interfaces as parameters: add one block for each
		else if (strncmp(token[0],"allow-",6) == 0) {
			int i;
			for (i = 1; i < toknum; i++)
				add_block(token[0], token[i]);
			skip_to_block = 0;
		}
		// source stanza takes one or more filepaths as parameters
		else if (strcmp(token[0], "source") == 0) {
			int i;
			char *en_dir;

			skip_to_block = 0;

			if (toknum == 1) {
				if (!quiet)
					nm_log_warn (LOGD_SETTINGS, "Invalid source line without parameters\n");
				continue;
			}

			en_dir = g_path_get_dirname (eni_file);
			for (i = 1; i < toknum; ++i)
				_ifparser_source (token[i], en_dir, quiet);
			g_free (en_dir);
		}
		else {
			if (skip_to_block) {
				if (!quiet) {
					nm_log_warn (LOGD_SETTINGS, "ignoring out-of-block data '%s'\n",
					             join_values_with_spaces(value, token));
				}
			} else
				add_data(token[0], join_values_with_spaces(value, token + 1));
		}
	}
	fclose(inp);

	if (!quiet)
		nm_log_info (LOGD_SETTINGS, "      interface-parser: finished parsing file %s\n", eni_file);
}