From edf108a2299a1504adc7fa5a070d116439512fa1 Mon Sep 17 00:00:00 2001 From: Marko Lindqvist Date: Sun, 17 Sep 2023 09:51:08 +0300 Subject: [PATCH 28/28] fcmp: Add support for multiple files_ sections Each such section have their own baseURL. See osdn #48613 Signed-off-by: Marko Lindqvist --- doc/README.modpack_installer | 30 +++-- tools/fcmp/download.c | 224 +++++++++++++++++++---------------- tools/fcmp/download.h | 2 +- 3 files changed, 148 insertions(+), 108 deletions(-) diff --git a/doc/README.modpack_installer b/doc/README.modpack_installer index b9fc889cb8..228eff2321 100644 --- a/doc/README.modpack_installer +++ b/doc/README.modpack_installer @@ -236,8 +236,7 @@ of the general syntax. Its filename must end in ".mpdl". Here is an example of a .mpdl file: [info] -options = "+Freeciv-mpdl-Devel-3.2-2022.Jul.14" -baseURL = "./ancients-6f88ee23de" +options = "+Freeciv-mpdl-Devel-3.2-2023.Sep.17" name = "Ancients" type = "Modpack" version = "3.1-0" @@ -248,7 +247,9 @@ list = "Ancients-tiles", "./ancients-tiles.mpdl", "Tileset", "3.1-0" } -[files] +[files_1] +baseURL = "./ancients-6f88ee23de" + list = { "src", "dest" "ancients/ancients.serv", "ancients.serv" @@ -256,6 +257,17 @@ list = ; ... } +[files_2] +baseURL = "https://ancients.org/docs/" + +list = +{ "src" + "ancients/ChangeLog" + "ancients/Usage" + ; ... +} + + The [info] section has overall control information: - "options": must be exactly as shown in the example. - "name": @@ -279,16 +291,20 @@ The [info] section has overall control information: than one of the above kinds of material - "Group": contains no files but only depends on other modpacks At the moment, only "Scenario" causes special behavior. + +The [files_*] sections lists the individual files comprising your modpack. +(They must list every file individually; any files in the same directory +on the webserver that are not listed will not be downloaded.) +The "files_" part is mandatory. It can be followed by any identifier as long +as each such section has a distinct name. + - "baseURL": URL to prepend to the "src" filenames in the [files] section. May be relative to the .mpdl file (starting with "./"), or absolute (in which case the files can be on some web server different to where the .mpdl file lives). -The [files] section lists the individual files comprising your modpack. -(It must list every file individually; any files in the same directory -on the webserver that are not listed will not be downloaded.) -After the header, each line can contain two strings: +For entries in the list, each line can contain two strings: - "src" Mandatory. Path of file on webserver, relative to "baseURL", and also by default installation path. diff --git a/tools/fcmp/download.c b/tools/fcmp/download.c index 965f4305e4..cc1e13a95a 100644 --- a/tools/fcmp/download.c +++ b/tools/fcmp/download.c @@ -83,21 +83,18 @@ static const char *download_modpack_recursive(const char *URL, char local_dir[2048]; char local_name[2048]; int start_idx; - int filenbr, total_files; + int total_files; struct section_file *control; const char *control_capstr; - const char *baseURLpart; enum modpack_type type; const char *typestr; const char *mpname; const char *mpver; - char baseURL[2048]; - char fileURL[2048]; const char *src_name; bool partial_failure = FALSE; int dep; const char *dep_name; - int URL_len; + struct section_list *sec; if (recursion > 5) { return _("Recursive dependencies too deep"); @@ -182,25 +179,6 @@ static const char *download_modpack_recursive(const char *URL, "%s" DIR_SEPARATOR DATASUBDIR, fcmp->inst_prefix); } - baseURLpart = secfile_lookup_str(control, "info.baseURL"); - - if (baseURLpart[0] == '.') { - char URLstart[start_idx]; - - strncpy(URLstart, URL, start_idx - 1); - URLstart[start_idx - 1] = '\0'; - fc_snprintf(baseURL, sizeof(baseURL), "%s%s", - URLstart, baseURLpart + 1); - } else { - sz_strlcpy(baseURL, baseURLpart); - } - - /* Remove potential ending '/' as one will get added later. */ - URL_len = strlen(baseURL); - if (baseURL[URL_len - 1] == '/') { - baseURL[URL_len - 1] = '\0'; - } - dep = 0; do { dep_name = secfile_lookup_str_default(control, NULL, @@ -273,117 +251,163 @@ static const char *download_modpack_recursive(const char *URL, total_files = 0; - do { - src_name = secfile_lookup_str_default(control, NULL, - "files.list%d.src", total_files); + sec = secfile_sections_by_name_prefix(control, "files_"); + + if (sec != NULL) { + size_t sec_count = section_list_size(sec); + size_t i; + int filenbr = 0; + + for (i = 0; i < sec_count; i++) { + const char *sec_name = section_name(section_list_get(sec, i)); - if (src_name != NULL) { - total_files++; + do { + src_name = secfile_lookup_str_default(control, NULL, + "%s.list%d.src", + sec_name, total_files); + + if (src_name != NULL) { + total_files++; + } + } while (src_name != NULL); } - } while (src_name != NULL); - if (pbcb != NULL) { - /* Control file already downloaded */ - pbcb(1, total_files + 1); - } + if (pbcb != NULL) { + /* Control file already downloaded */ + pbcb(1, total_files + 1); + } - for (filenbr = 0; filenbr < total_files; filenbr++) { - const char *dest_name; + for (i = 0; i < sec_count; i++) { + const char *sec_name = section_name(section_list_get(sec, i)); + const char *baseURLpart; + int URL_len; + char baseURL[2048]; + int j; + + baseURLpart = secfile_lookup_str(control, "%s.baseURL", sec_name); + + if (baseURLpart[0] == '.') { + char URLstart[start_idx]; + + strncpy(URLstart, URL, start_idx - 1); + URLstart[start_idx - 1] = '\0'; + fc_snprintf(baseURL, sizeof(baseURL), "%s%s", + URLstart, baseURLpart + 1); + } else { + sz_strlcpy(baseURL, baseURLpart); + } + + /* Remove potential ending '/' as one will get added later. */ + URL_len = strlen(baseURL); + if (baseURL[URL_len - 1] == '/') { + baseURL[URL_len - 1] = '\0'; + } + + for (j = 0; + (src_name = secfile_lookup_str_default(control, NULL, + "%s.list%d.src", sec_name, j)) != NULL; + j++) { + const char *dest_name; #ifndef DIR_SEPARATOR_IS_DEFAULT - char *dest_name_copy; + char *dest_name_copy; #else /* DIR_SEPARATOR_IS_DEFAULT */ #define dest_name_copy dest_name #endif /* DIR_SEPARATOR_IS_DEFAULT */ - int i; - bool illegal_filename = FALSE; - - src_name = secfile_lookup_str_default(control, NULL, - "files.list%d.src", filenbr); + int k; + bool illegal_filename = FALSE; - dest_name = secfile_lookup_str_default(control, NULL, - "files.list%d.dest", filenbr); + dest_name = secfile_lookup_str_default(control, NULL, + "%s.list%d.dest", sec_name, j); - if (dest_name == NULL || dest_name[0] == '\0') { - /* Missing dest name is ok, we just default to src_name */ - dest_name = src_name; - } + if (dest_name == NULL || dest_name[0] == '\0') { + /* Missing dest name is ok, we just default to src_name */ + dest_name = src_name; + } #ifndef DIR_SEPARATOR_IS_DEFAULT - dest_name_copy = fc_malloc(strlen(dest_name) + 1); + dest_name_copy = fc_malloc(strlen(dest_name) + 1); #endif /* DIR_SEPARATOR_IS_DEFAULT */ - for (i = 0; dest_name[i] != '\0'; i++) { - if (dest_name[i] == '.' && dest_name[i + 1] == '.') { - if (mcb != NULL) { - char buf[2048]; + for (k = 0; dest_name[k] != '\0'; k++) { + if (dest_name[k] == '.' && dest_name[k + 1] == '.') { + if (mcb != NULL) { + char buf[2048]; - fc_snprintf(buf, sizeof(buf), _("Illegal path for %s"), - dest_name); - mcb(buf); - } - partial_failure = TRUE; - illegal_filename = TRUE; - } + fc_snprintf(buf, sizeof(buf), _("Illegal path for %s"), + dest_name); + mcb(buf); + } + partial_failure = TRUE; + illegal_filename = TRUE; + } #ifndef DIR_SEPARATOR_IS_DEFAULT - if (dest_name[i] == '/') { - dest_name_copy[i] = DIR_SEPARATOR_CHAR; - } else { - dest_name_copy[i] = dest_name[i]; - } + if (dest_name[k] == '/') { + dest_name_copy[k] = DIR_SEPARATOR_CHAR; + } else { + dest_name_copy[k] = dest_name[k]; + } #endif /* DIR_SEPARATOR_IS_DEFAULT */ - } + } #ifndef DIR_SEPARATOR_IS_DEFAULT - dest_name_copy[i] = '\0'; + dest_name_copy[k] = '\0'; #endif /* DIR_SEPARATOR_IS_DEFAULT */ - if (!illegal_filename) { - fc_snprintf(local_name, sizeof(local_name), - "%s" DIR_SEPARATOR "%s", local_dir, dest_name_copy); + if (!illegal_filename) { + char fileURL[2048]; + + fc_snprintf(local_name, sizeof(local_name), + "%s" DIR_SEPARATOR "%s", local_dir, dest_name_copy); #ifndef DIR_SEPARATOR_IS_DEFAULT - free(dest_name_copy); + free(dest_name_copy); #endif /* DIR_SEPARATOR_IS_DEFAULT */ - if (!make_dir_for_file(local_name)) { - secfile_destroy(control); - return _("Cannot create required directories"); - } - - if (mcb != NULL) { - char buf[2048]; - - fc_snprintf(buf, sizeof(buf), _("Downloading %s"), src_name); - mcb(buf); - } + if (!make_dir_for_file(local_name)) { + secfile_destroy(control); + return _("Cannot create required directories"); + } + + if (mcb != NULL) { + char buf[2048]; + + fc_snprintf(buf, sizeof(buf), _("Downloading %s"), src_name); + mcb(buf); + } + + fc_snprintf(fileURL, sizeof(fileURL), "%s/%s", baseURL, src_name); + log_debug("Download \"%s\" as \"%s\".", fileURL, local_name); + if (!netfile_download_file(fileURL, local_name, nf_cb, mcb)) { + if (mcb != NULL) { + char buf[2048]; + + fc_snprintf(buf, sizeof(buf), _("Failed to download %s"), + src_name); + mcb(buf); + } + partial_failure = TRUE; + } + } else { +#ifndef DIR_SEPARATOR_IS_DEFAULT + free(dest_name_copy); +#endif /* DIR_SEPARATOR_IS_DEFAULT */ + } - fc_snprintf(fileURL, sizeof(fileURL), "%s/%s", baseURL, src_name); - log_debug("Download \"%s\" as \"%s\".", fileURL, local_name); - if (!netfile_download_file(fileURL, local_name, nf_cb, mcb)) { - if (mcb != NULL) { - char buf[2048]; + filenbr++; - fc_snprintf(buf, sizeof(buf), _("Failed to download %s"), - src_name); - mcb(buf); + if (pbcb != NULL) { + /* Count download of control file also */ + pbcb(filenbr + 1, total_files + 1); } - partial_failure = TRUE; } - } else { -#ifndef DIR_SEPARATOR_IS_DEFAULT - free(dest_name_copy); -#endif /* DIR_SEPARATOR_IS_DEFAULT */ - } - - if (pbcb != NULL) { - /* Count download of control file also */ - pbcb(filenbr + 2, total_files + 1); } } + section_list_destroy(sec); + if (partial_failure) { secfile_destroy(control); diff --git a/tools/fcmp/download.h b/tools/fcmp/download.h index c5fdcea124..973e281cf4 100644 --- a/tools/fcmp/download.h +++ b/tools/fcmp/download.h @@ -22,7 +22,7 @@ extern "C" { #define MODPACKDL_SUFFIX ".mpdl" -#define MODPACK_CAPSTR "+Freeciv-mpdl-Devel-3.2-2022.Jul.14" +#define MODPACK_CAPSTR "+Freeciv-mpdl-Devel-3.2-2023.Sep.17" #define MODLIST_CAPSTR "+Freeciv-modlist-Devel-3.2-2022.Jul.14" #define FCMP_CONTROLD ".control" -- 2.40.1