From 23670b82cf5003ca5ab95e56c8557dd196993055 Mon Sep 17 00:00:00 2001
From: Marko Lindqvist <cazfi74@gmail.com>
Date: Sat, 10 Dec 2022 13:54:34 +0200
Subject: [PATCH 49/49] Rulesave: Save description file when needed

If description file lives under the ruleset directory itself,
save it to the new ruleset directory being created.

See osdn #46242

Signed-off-by: Marko Lindqvist <cazfi74@gmail.com>
---
 tools/fcmp/download.c     | 10 ++-----
 tools/ruleutil/rulesave.c | 55 +++++++++++++++++++++++++++++----------
 utility/shared.c          | 23 ++++++++++++++++
 utility/shared.h          |  2 ++
 4 files changed, 68 insertions(+), 22 deletions(-)

diff --git a/tools/fcmp/download.c b/tools/fcmp/download.c
index 0d2baa307c..965f4305e4 100644
--- a/tools/fcmp/download.c
+++ b/tools/fcmp/download.c
@@ -315,7 +315,7 @@ static const char *download_modpack_recursive(const char *URL,
 #endif /* DIR_SEPARATOR_IS_DEFAULT */
 
     for (i = 0; dest_name[i] != '\0'; i++) {
-      if (dest_name[i] == '.' && dest_name[i+1] == '.') {
+      if (dest_name[i] == '.' && dest_name[i + 1] == '.') {
         if (mcb != NULL) {
           char buf[2048];
 
@@ -348,16 +348,10 @@ static const char *download_modpack_recursive(const char *URL,
       free(dest_name_copy);
 #endif /* DIR_SEPARATOR_IS_DEFAULT */
 
-      for (i = strlen(local_name) - 1 ; local_name[i] != DIR_SEPARATOR_CHAR ; i--) {
-        /* Nothing */
-      }
-      local_name[i] = '\0';
-      log_debug("Create directory \"%s\"", local_name);
-      if (!make_dir(local_name)) {
+      if (!make_dir_for_file(local_name)) {
         secfile_destroy(control);
         return _("Cannot create required directories");
       }
-      local_name[i] = DIR_SEPARATOR_CHAR;
 
       if (mcb != NULL) {
         char buf[2048];
diff --git a/tools/ruleutil/rulesave.c b/tools/ruleutil/rulesave.c
index 7a7b221e0d..c5526984e1 100644
--- a/tools/ruleutil/rulesave.c
+++ b/tools/ruleutil/rulesave.c
@@ -3231,22 +3231,33 @@ static bool save_units_ruleset(const char *filename, const char *name)
 /**********************************************************************//**
   Save script.lua
 **************************************************************************/
-static bool save_script_lua(const char *filename, const char *name,
-                            const char *buffer)
+static bool copy_ruleset_file(const char *filename, const char *name,
+                              const char *buffer)
 {
   if (buffer != NULL) {
-    FILE *ffile = fc_fopen(filename, "w");
-    int full_len = strlen(buffer);
-    int len;
+    char *local_name = fc_strdup(filename);
+    bool success;
 
-    if (ffile != NULL) {
-      len = fwrite(buffer, 1, full_len, ffile);
+    success = make_dir_for_file(local_name);
 
-      if (len != full_len) {
+    free(local_name);
+
+    if (success) {
+      FILE *ffile = fc_fopen(filename, "w");
+      int full_len = strlen(buffer);
+      int len;
+
+      if (ffile != NULL) {
+        len = fwrite(buffer, 1, full_len, ffile);
+
+        if (len != full_len) {
+          return FALSE;
+        }
+
+        fclose(ffile);
+      } else {
         return FALSE;
       }
-
-      fclose(ffile);
     } else {
       return FALSE;
     }
@@ -3305,7 +3316,7 @@ bool save_ruleset(const char *path, const char *name, struct rule_data *data)
       fc_snprintf(filename, sizeof(filename), "%s/governments.ruleset", path);
       success = save_governments_ruleset(filename, name);
     }
-    
+
     if (success) {
       fc_snprintf(filename, sizeof(filename), "%s/nations.ruleset", path);
       success = save_nations_ruleset(filename, name, data);
@@ -3327,18 +3338,18 @@ bool save_ruleset(const char *path, const char *name, struct rule_data *data)
     }
 
     if (success) {
-      fc_snprintf(filename,sizeof(filename), "%s/actions.ruleset",path);
+      fc_snprintf(filename, sizeof(filename), "%s/actions.ruleset", path);
       success = save_actions_ruleset(filename, name);
     }
 
     if (success) {
       fc_snprintf(filename, sizeof(filename), "%s/script.lua", path);
-      success = save_script_lua(filename, name, get_script_buffer());
+      success = copy_ruleset_file(filename, name, get_script_buffer());
     }
 
     if (success) {
       fc_snprintf(filename, sizeof(filename), "%s/parser.lua", path);
-      success = save_script_lua(filename, name, get_parser_buffer());
+      success = copy_ruleset_file(filename, name, get_parser_buffer());
     }
 
     if (success) {
@@ -3346,6 +3357,22 @@ bool save_ruleset(const char *path, const char *name, struct rule_data *data)
       success = save_luadata(filename);
     }
 
+    if (success
+        && game.ruleset_description != NULL
+        && game.server.ruledit.description_file != NULL) {
+      size_t rsdir_name_len = strlen(game.server.rulesetdir);
+
+      if (!strncmp(game.server.ruledit.description_file, game.server.rulesetdir,
+                   rsdir_name_len)
+          && game.server.ruledit.description_file[rsdir_name_len] == '/') {
+        /* Description file lives under old rulesetdir.
+         * Write it also to the new rulesetdir. */
+        fc_snprintf(filename, sizeof(filename), "%s/%s", path,
+                    game.server.ruledit.description_file + rsdir_name_len + 1);
+        success = copy_ruleset_file(filename, name, game.ruleset_description);
+      }
+    }
+
     return success;
   } else {
     log_error(_("Failed to create directory %s"), path);
diff --git a/utility/shared.c b/utility/shared.c
index 303b65eea9..e6075ce6af 100644
--- a/utility/shared.c
+++ b/utility/shared.c
@@ -1815,6 +1815,29 @@ bool make_dir(const char *pathname)
   return TRUE;
 }
 
+/************************************************************************//**
+  If the directory part of the "filename" does not exist, recursively create
+  all directories until it does.
+****************************************************************************/
+bool make_dir_for_file(char *filename)
+{
+  int i;
+
+  for (i = strlen(filename) - 1 ; filename[i] != DIR_SEPARATOR_CHAR ; i--) {
+    /* Nothing */
+  }
+
+  filename[i] = '\0';
+  log_debug("Create directory \"%s\"", filename);
+
+  if (!make_dir(filename)) {
+    return FALSE;
+  }
+  filename[i] = DIR_SEPARATOR_CHAR;
+
+  return TRUE;
+}
+
 /************************************************************************//**
   Returns TRUE if the filename's path is absolute.
 ****************************************************************************/
diff --git a/utility/shared.h b/utility/shared.h
index a1a2a0ee3a..ad49c7a753 100644
--- a/utility/shared.h
+++ b/utility/shared.h
@@ -255,6 +255,8 @@ char *skip_to_basename(char *filepath);
 
 bool make_dir(const char *pathname)
        fc__attribute((nonnull (1)));
+bool make_dir_for_file(char *filename)
+       fc__attribute((nonnull (1)));
 
 bool path_is_absolute(const char *filename);
 
-- 
2.35.1