コード例 #1
0
/**
 * Parse a partition map from an XML file, storing it in the given label structure.
 */
int _xml_parse_partition_map(xmlTextReaderPtr reader, struct ltfs_label *label)
{
	declare_parser_vars("partitions");
	declare_tracking_arrays(2, 0);

	while (true) {
		get_next_tag();

		if (! strcmp(name, "index")) {
			check_required_tag(0);
			get_tag_text();
			if (_xml_parse_partition(value) < 0)
				return -1;
			label->partid_ip = value[0];
			check_tag_end("index");

		} else if (! strcmp(name, "data")) {
			check_required_tag(1);
			get_tag_text();
			if (_xml_parse_partition(value) < 0)
				return -1;
			label->partid_dp = value[0];
			check_tag_end("data");

		} else
			ignore_unrecognized_tag();
	}

	check_required_tags();
	return 0;
}
コード例 #2
0
bool class_source_parser::parse_tag(){
	while (!f_.eof()){
		std::string line;
		if (! getline(line) ) { return false; }
		if (check_valid(line)) {
			if (check_tag_begin(line)){
				parse_tag();
			}
			if (check_tag_end(line)){
				return true;
			}
			if (check_keys_begin(line)){
				parse_keys();
			}
			if (check_allow_link(line)){
				continue;
			}
			if (check_allow_global(line)){
				continue;
			}
			if (check_remove_key(line)){
			}
		}else{
			if (!current_.empty()){
				// adding error messages for each unclosed entity
				add_open_tag_error();
				close_opened_tags();
			}
			return true;
		}
	}
	return true;
}
コード例 #3
0
/**
 * Parse a partition location from a label.
 */
int _xml_parse_label_location(xmlTextReaderPtr reader, struct ltfs_label *label)
{
	declare_parser_vars("location");
	declare_tracking_arrays(1, 0);

	while (true) {
		get_next_tag();

		if (! strcmp(name, "partition")) {
			check_required_tag(0);
			get_tag_text();
			if (_xml_parse_partition(value) < 0)
				return -1;
			label->this_partition = value[0];
			check_tag_end("partition");

		} else
			ignore_unrecognized_tag();
	}

	check_required_tags();
	return 0;
}
コード例 #4
0
/**
 * Parse a directory tree from the given XML source into the given index data structure.
 * @param reader the XML source
 * @param parent Directory where the new subdirectory should be created, or NULL to populate the
 *               root dentry.
 * @param idx LTFS index data
 * @param vol LTFS volume to which the index belongs. May be NULL.
 * @return 0 on success or a negative value on error
 */
int _xml_parse_dirtree(xmlTextReaderPtr reader, struct dentry *parent,
	struct ltfs_index *idx, struct ltfs_volume *vol, struct name_list *dirname)
{
	int ret;
	unsigned long long value_int;
	struct dentry *dir;
	declare_parser_vars("directory");
	declare_tracking_arrays(9, 1);

	if (! parent && idx->root) {
		dir = idx->root;
		dir->vol = vol;
	} else {
		dir = fs_allocate_dentry(parent, NULL, NULL, true, false, false, idx);
		if (! dir) {
			ltfsmsg(LTFS_ERR, "10001E", __FUNCTION__);
			return -LTFS_NO_MEMORY;
		}
		if (! parent) {
			idx->root = dir;
			dir->vol = vol;
			++dir->link_count;
		}
	}

	while (true) {
		get_next_tag();

		if (!strcmp(name, "name")) {
			check_required_tag(0);

			if (parent) {
				get_tag_text();
				if (xml_parse_filename(&dir->name, value) < 0)
					return -1;
				dirname->name = dir->name;
				dirname->d = dir;
				check_tag_end("name");
			} else {
				/* this is the root directory, so set the volume name */
				check_empty();
				if (empty > 0) {
					value = NULL;
				} else {
					if (xml_scan_text(reader, &value) < 0)
						return -1;
				}

				if (value && strlen(value) > 0) {
					if (xml_parse_filename(&idx->volume_name, value) < 0)
						return -1;
					/* if the value is the empty string, then xml_scan_text consumed the "name"
					 * element end */
					check_tag_end("name");
				} else
					idx->volume_name = NULL;
			}

		} else if (!strcmp(name, "readonly")) {
			check_required_tag(1);
			get_tag_text();
			if (xml_parse_bool(&dir->readonly, value) < 0)
				return -1;
			check_tag_end("readonly");

		} else if (!strcmp(name, "modifytime")) {
			check_required_tag(2);
			get_tag_text();
			ret = xml_parse_time(true, value, &dir->modify_time);
			if (ret < 0)
				return -1;
			else if (ret == LTFS_TIME_OUT_OF_RANGE)
				ltfsmsg(LTFS_WARN, "17220W", "updatetime", dir->name, dir->uid, value);

			check_tag_end("modifytime");

		} else if (!strcmp(name, "creationtime")) {
			check_required_tag(3);
			get_tag_text();
			ret = xml_parse_time(true, value, &dir->creation_time);
			if (ret < 0)
				return -1;
			else if (ret == LTFS_TIME_OUT_OF_RANGE)
				ltfsmsg(LTFS_WARN, "17220W", "creationtime", dir->name, dir->uid, value);

			check_tag_end("creationtime");

		} else if (!strcmp(name, "accesstime")) {
			check_required_tag(4);
			get_tag_text();
			ret = xml_parse_time(true, value, &dir->access_time);
			if (ret < 0)
				return -1;
			else if (ret == LTFS_TIME_OUT_OF_RANGE)
				ltfsmsg(LTFS_WARN, "17220W", "accesstime", dir->name, dir->uid, value);

			check_tag_end("accesstime");

		} else if (!strcmp(name, "changetime")) {
			check_required_tag(5);
			get_tag_text();
			ret = xml_parse_time(true, value, &dir->change_time);
			if (ret < 0)
				return -1;
			else if (ret == LTFS_TIME_OUT_OF_RANGE)
				ltfsmsg(LTFS_WARN, "17220W", "changetime", dir->name, dir->uid, value);

			check_tag_end("changetime");

		} else if (! strcmp(name, "contents")) {
			check_required_tag(6);
			check_empty();
			if (empty == 0 && (ret = _xml_parse_dir_contents(reader, dir, idx)) < 0) {
				if (ret == -LTFS_NO_MEMORY)
					return ret;
				else
					return -1;
			}

		} else if (!strcmp(name, "extendedattributes")) {
			check_optional_tag(0);
			check_empty();
			if (empty == 0 && _xml_parse_xattrs(reader, dir) < 0)
					return -1;

		} else if (idx->version >= IDX_VERSION_UID && ! strcmp(name, UID_TAGNAME)) {
			check_required_tag(7);
			get_tag_text();
			if (xml_parse_ull(&value_int, value) < 0)
				return -1;
			dir->uid = value_int;
			if (dir->uid > idx->uid_number)
				idx->uid_number = dir->uid;
			if (parent) {
				dirname->uid  = dir->uid;
			}
			check_tag_end(UID_TAGNAME);
		} else if (! strcmp(name, UID_TAGNAME)) {
			ignore_unrecognized_tag();

		} else if (idx->version >= IDX_VERSION_BACKUPTIME && ! strcmp(name, BACKUPTIME_TAGNAME)) {
			check_required_tag(8);
			get_tag_text();
			ret = xml_parse_time(true, value, &dir->backup_time);
			if (ret < 0)
				return -1;
			else if (ret == LTFS_TIME_OUT_OF_RANGE)
				ltfsmsg(LTFS_WARN, "17220W", "backuptime", dir->name, dir->uid, value);

			check_tag_end(BACKUPTIME_TAGNAME);
		} else if (! strcmp(name, BACKUPTIME_TAGNAME)) {
			ignore_unrecognized_tag();

		} else
			preserve_unrecognized_tag(dir);
	}

	/* For old index versions, allocate a UID */
	if (idx->version < IDX_VERSION_UID) {
		check_required_tag(7);
		if (parent) {
			dir->uid = fs_allocate_uid(idx);
			if (dir->uid > idx->uid_number)
				idx->uid_number = dir->uid;
			dirname->uid  = dir->uid;
		}
		/* root directory already got assigned UID 1 by fs_allocate_dentry */
	}

	/* For old index versions, set backup time equal to creation time */
	if (idx->version < IDX_VERSION_BACKUPTIME) {
		check_required_tag(8);
		dir->backup_time = dir->creation_time;
	}

	check_required_tags();

	/* Validate UID: root directory must have uid==1, other dentries must have nonzero UID */
	/* TODO: would be nice to verify that there are no UID conflicts */
	if (parent && dir->uid == 1) {
		ltfsmsg(LTFS_ERR, "17101E");
		return -1;
	} else if (! parent && dir->uid != 1) {
		ltfsmsg(LTFS_ERR, "17100E");
		return -1;
	} else if (dir->uid == 0) {
		ltfsmsg(LTFS_ERR, "17106E");
		return -1;
	}

	return 0;
}
コード例 #5
0
/**
 * Parse index partition criteria.
 */
int _xml_parse_ip_criteria(xmlTextReaderPtr reader, struct ltfs_index *idx)
{
	int ret;
	unsigned long long value_int;
	char *glob_norm;
	int num_patterns = 0;
	declare_parser_vars("indexpartitioncriteria");
	declare_tracking_arrays(1, 0);

	/* clear the glob pattern list first */
	index_criteria_free(&idx->original_criteria);
	index_criteria_free(&idx->index_criteria);

	/* We have a policy. */
	idx->original_criteria.have_criteria = true;

	while (true) {
		get_next_tag();

		if (! strcmp(name, "size")) {
			check_required_tag(0);
			get_tag_text();
			if (xml_parse_ull(&value_int, value) < 0) {
				ltfsmsg(LTFS_ERR, "17024E", value);
				return -1;
			}
			idx->original_criteria.max_filesize_criteria = value_int;
			check_tag_end("size");

		} else if (! strcmp(name, "name")) {
			get_tag_text();

			if (pathname_validate_file(value) < 0) {
				ltfsmsg(LTFS_ERR, "17098E", value);
				return -1;
			}

			++num_patterns;
			/* quite inefficient, but the number of patterns should be small. */
			idx->original_criteria.glob_patterns = realloc(idx->original_criteria.glob_patterns,
				(num_patterns + 1) * sizeof(char *));
			if (! idx->original_criteria.glob_patterns) {
				ltfsmsg(LTFS_ERR, "10001E", __FUNCTION__);
				return -1;
			}
			idx->original_criteria.glob_patterns[num_patterns] = NULL;

			ret = pathname_normalize(value, &glob_norm);
			if (ret < 0) {
				ltfsmsg(LTFS_ERR, "17025E", ret);
				return ret;
			}
			idx->original_criteria.glob_patterns[num_patterns - 1] = glob_norm;

			check_tag_end("name");

		} else
			ignore_unrecognized_tag();
	}

	/* Make an active copy of these index criteria. The caller can override idx->index_criteria
	 * later without affecting the criteria stored in future indexes (idx->original_criteria). */
	if (index_criteria_dup_rules(&idx->index_criteria, &idx->original_criteria) < 0) {
		/* Could not duplicate index criteria rules */
		ltfsmsg(LTFS_ERR, "11301E");
		return -1;
	}

	check_required_tags();
	return 0;
}
コード例 #6
0
/**
 * Parse an index file from the given source and populate the priv->root virtual dentry tree.
 * with the nodes found during the scanning.
 * @param reader Source of XML data
 * @param idx LTFS index
 * @param vol LTFS volume to which the index belongs. May be NULL.
 * @return 0 on success or a negative value on error.
 */
int _xml_parse_schema(xmlTextReaderPtr reader, struct ltfs_index *idx, struct ltfs_volume *vol)
{
	int ret;
	unsigned long long value_int;
	declare_parser_vars("ltfsindex");
	declare_tracking_arrays(8, 3);

	/* start the parser: find top-level "index" tag, check version and encoding */
	ret = _xml_parser_init(reader, parent_tag, &idx->version,
						   LTFS_INDEX_VERSION_MIN, LTFS_INDEX_VERSION_MAX);
	if (ret < 0)
		return ret;

	if (idx->version < LTFS_INDEX_VERSION)
		ltfsmsg(LTFS_WARN, "17095W",
				LTFS_INDEX_VERSION_STR,
				LTFS_FORMAT_MAJOR(idx->version),
				LTFS_FORMAT_MINOR(idx->version),
				LTFS_FORMAT_REVISION(idx->version));
	else if (idx->version / 100 > LTFS_INDEX_VERSION / 100)
		ltfsmsg(LTFS_WARN, "17096W",
				LTFS_INDEX_VERSION_STR,
				LTFS_FORMAT_MAJOR(idx->version),
				LTFS_FORMAT_MINOR(idx->version),
				LTFS_FORMAT_REVISION(idx->version));
	else if (idx->version > LTFS_INDEX_VERSION)
		ltfsmsg(LTFS_WARN, "17234W",
				LTFS_INDEX_VERSION_STR,
				LTFS_FORMAT_MAJOR(idx->version),
				LTFS_FORMAT_MINOR(idx->version),
				LTFS_FORMAT_REVISION(idx->version));

	if (idx->commit_message) {
		free(idx->commit_message);
		idx->commit_message = NULL;
	}

	/* parse index file contents */
	while (true) {
		get_next_tag();

		if (! strcmp(name, "creator")) {
			check_required_tag(0);
			get_tag_text();
			if (idx->creator)
				free(idx->creator);
			idx->creator = strdup(value);
			if (! idx->creator) {
				ltfsmsg(LTFS_ERR, "10001E", name);
				return -1;
			}
			check_tag_end("creator");

		} else if (! strcmp(name, "volumeuuid")) {
			check_required_tag(1);
			get_tag_text();
			if (xml_parse_uuid(idx->vol_uuid, value) < 0)
				return -1;
			check_tag_end("volumeuuid");

		} else if (! strcmp(name, "generationnumber")) {
			check_required_tag(2);
			get_tag_text();
			if (xml_parse_ull(&value_int, value) < 0) {
				ltfsmsg(LTFS_ERR, "17023E", value);
				return -1;
			}
			idx->generation = value_int;
			check_tag_end("generationnumber");

		} else if (! strcmp(name, "updatetime")) {
			check_required_tag(3);
			get_tag_text();
			ret = xml_parse_time(true, value, &idx->mod_time);
			if (ret < 0)
				return -1;
			else if (ret == LTFS_TIME_OUT_OF_RANGE)
				ltfsmsg(LTFS_WARN, "17219W", "updatetime", value);

			check_tag_end("updatetime");

		} else if (! strcmp(name, "location")) {
			check_required_tag(4);
			assert_not_empty();
			if (_xml_scan_tapepos(reader, "location", &idx->selfptr) < 0)
				return -1;

		} else if (! strcmp(name, "allowpolicyupdate")) {
			check_required_tag(5);
			get_tag_text();
			if (xml_parse_bool(&idx->criteria_allow_update, value) < 0)
				return -1;
			check_tag_end("allowpolicyupdate");

		} else if (! strcmp(name, "directory")) {
			check_required_tag(6);
			assert_not_empty();
			if ((ret = _xml_parse_dirtree(reader, NULL, idx, vol, NULL)) < 0) {
				if (ret == -LTFS_NO_MEMORY)
					return -LTFS_NO_MEMORY;
				else
					return -1;
			}

		} else if (! strcmp(name, "previousgenerationlocation")) {
			check_optional_tag(0);
			assert_not_empty();
			if (_xml_scan_tapepos(reader, "previousgenerationlocation", &idx->backptr) < 0)
				return -1;

		} else if (! strcmp(name, "dataplacementpolicy")) {
			check_optional_tag(1);
			assert_not_empty();
			if (_xml_parse_policy(reader, idx) < 0)
				return -1;

		} else if (! strcmp(name, "comment")) {
			check_optional_tag(2);
			get_tag_text();
			if (strlen(value) > INDEX_MAX_COMMENT_LEN) {
				ltfsmsg(LTFS_ERR, "17094E");
				return -1;
			}
			idx->commit_message = strdup(value);
			if (! idx->commit_message) {
				ltfsmsg(LTFS_ERR, "10001E", "_xml_parse_schema: index comment");
				return -1;
			}
			check_tag_end("comment");

		} else if (idx->version >= IDX_VERSION_UID && ! strcmp(name, NEXTUID_TAGNAME)) {
			check_required_tag(7);
			get_tag_text();
			if (xml_parse_ull(&value_int, value) < 0)
				return -1;
			if (value_int > idx->uid_number)
				idx->uid_number = value_int;
			check_tag_end(NEXTUID_TAGNAME);
		} else if (! strcmp(name, NEXTUID_TAGNAME)) {
			ignore_unrecognized_tag();

		} else
			preserve_unrecognized_tag(idx);
	}

	/* For older index versions, assume we handle UIDs correctly.
	 * The idx->uid_number field is automatically initialized to 1, so it will be set correctly
	 * once all files and directories are parsed. */
	if (idx->version < IDX_VERSION_UID)
		check_required_tag(7);

	check_required_tags();

	if ( idx->symerr_count != 0 ) {
		return -LTFS_SYMLINK_CONFLICT;
	}


	return 0;
}
コード例 #7
0
/**
 * Parse an XML label, populating the given label data structure.
 */
int _xml_parse_label(xmlTextReaderPtr reader, struct ltfs_label *label)
{
	int ret;
	unsigned long long value_int;
	declare_parser_vars("ltfslabel");
	declare_tracking_arrays(7, 0);

	/* start the parser: find top-level "label" tag, check version and encoding */
	if (_xml_parser_init(reader, parent_tag, &label->version,
		LTFS_LABEL_VERSION_MIN, LTFS_LABEL_VERSION_MAX) < 0)
		return -1;

	/* parse label contents */
	while (true) {
		get_next_tag();

		if (! strcmp(name, "creator")) {
			check_required_tag(0);
			get_tag_text();
			if (label->creator) {
				free(label->creator); 
				label->creator = NULL;
			}
			label->creator = strdup(value);
			if (! label->creator) {
				ltfsmsg(LTFS_ERR, "10001E", name);
				return -1;
			}
			check_tag_end("creator");

		} else if (! strcmp(name, "formattime")) {
			check_required_tag(1);
			get_tag_text();
			ret = xml_parse_time(true, value, &label->format_time);
			if (ret < 0)
				return -1;
			else if (ret == LTFS_TIME_OUT_OF_RANGE)
				ltfsmsg(LTFS_WARN, "17218W", "formattime", value);
			check_tag_end("formattime");

		} else if (! strcmp(name, "volumeuuid")) {
			check_required_tag(2);
			get_tag_text();
			if (xml_parse_uuid(label->vol_uuid, value) < 0)
				return -1;
			check_tag_end("volumeuuid");

		} else if (! strcmp(name, "location")) {
			check_required_tag(3);
			assert_not_empty();
			if (_xml_parse_label_location(reader, label) < 0)
				return -1;

		} else if (! strcmp(name, "partitions")) {
			check_required_tag(4);
			assert_not_empty();
			if (_xml_parse_partition_map(reader, label) < 0)
				return -1;

		} else if (! strcmp(name, "blocksize")) {
			check_required_tag(5);
			get_tag_text();
			if (xml_parse_ull(&value_int, value) < 0 || value_int == 0) {
				ltfsmsg(LTFS_ERR, "17022E", value);
				return -1;
			}
			label->blocksize = value_int;
			check_tag_end("blocksize");

		} else if (! strcmp(name, "compression")) {
			check_required_tag(6);
			get_tag_text();
			if (xml_parse_bool(&label->enable_compression, value) < 0)
				return -1;
			check_tag_end("compression");

		} else
			ignore_unrecognized_tag();
	}

	check_required_tags();
	return 0;
}