/** * 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; }
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; }
/** * 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; }
/** * 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; }
/** * 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; }
/** * 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; }
/** * 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; }