1 /***********************************************************************
2  Freeciv - Copyright (C) 1996 - A Kjeldberg, L Gregersen, P Unold
3    This program is free software; you can redistribute it and/or modify
4    it under the terms of the GNU General Public License as published by
5    the Free Software Foundation; either version 2, or (at your option)
6    any later version.
7 
8    This program is distributed in the hope that it will be useful,
9    but WITHOUT ANY WARRANTY; without even the implied warranty of
10    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11    GNU General Public License for more details.
12 ***********************************************************************/
13 
14 #ifdef HAVE_CONFIG_H
15 #include <fc_config.h>
16 #endif
17 
18 #include "fc_prehdrs.h"
19 
20 /* utility */
21 #include "fciconv.h"
22 #include "fcintl.h"
23 #include "log.h"
24 #include "mem.h"
25 #include "net_types.h"
26 #include "rand.h"
27 #include "registry.h"
28 
29 /* common */
30 #include "fc_interface.h"
31 
32 /* modinst */
33 #include "mpdb.h"
34 
35 #include "modinst.h"
36 
37 static struct install_info_list *main_ii_list;
38 static bool main_list_changed = FALSE;
39 static struct install_info_list *scenario_ii_list;
40 static bool scenario_list_changed = FALSE;
41 
42 static char main_ii_filename[500];
43 static char scenario_ii_filename[500];
44 
45 /**************************************************************************
46   Load all required install info lists.
47 **************************************************************************/
load_install_info_lists(struct fcmp_params * fcmp)48 void load_install_info_lists(struct fcmp_params *fcmp)
49 {
50   main_ii_list = install_info_list_new();
51   scenario_ii_list = install_info_list_new();
52 
53   fc_snprintf(main_ii_filename, sizeof(main_ii_filename),
54               "%s" DIR_SEPARATOR DATASUBDIR DIR_SEPARATOR FCMP_CONTROLD DIR_SEPARATOR "modpacks.db",
55               fcmp->inst_prefix);
56   fc_snprintf(scenario_ii_filename, sizeof(scenario_ii_filename),
57               "%s" DIR_SEPARATOR "scenarios" DIR_SEPARATOR FCMP_CONTROLD DIR_SEPARATOR "modpacks.db",
58               fcmp->inst_prefix);
59 
60   load_install_info_list(main_ii_filename, main_ii_list);
61   load_install_info_list(scenario_ii_filename, scenario_ii_list);
62 }
63 
64 /**************************************************************************
65   Save all changed install info lists.
66 **************************************************************************/
save_install_info_lists(struct fcmp_params * fcmp)67 void save_install_info_lists(struct fcmp_params *fcmp)
68 {
69   if (main_list_changed) {
70     char controld[500];
71 
72     fc_snprintf(controld, sizeof(controld),
73                 "%s" DIR_SEPARATOR DATASUBDIR DIR_SEPARATOR FCMP_CONTROLD,
74                 fcmp->inst_prefix);
75 
76     if (make_dir(controld)) {
77       save_install_info_list(main_ii_filename, main_ii_list);
78     } else {
79       log_error(_("Failed to create control directory \"%s\""),
80                 controld);
81     }
82   }
83 
84   if (scenario_list_changed) {
85     char controld[500];
86 
87     fc_snprintf(controld, sizeof(controld),
88                 "%s" DIR_SEPARATOR "scenarios" DIR_SEPARATOR FCMP_CONTROLD,
89                 fcmp->inst_prefix);
90 
91     if (make_dir(controld)) {
92       save_install_info_list(scenario_ii_filename, scenario_ii_list);
93     } else {
94       log_error(_("Failed to create control directory \"%s\""),
95                 controld);
96     }
97   }
98 
99   install_info_list_iterate(scenario_ii_list, ii) {
100     FC_FREE(ii);
101   } install_info_list_iterate_end;
102 
103   install_info_list_iterate(main_ii_list, ii) {
104     FC_FREE(ii);
105   } install_info_list_iterate_end;
106 
107   install_info_list_destroy(scenario_ii_list);
108   install_info_list_destroy(main_ii_list);
109 }
110 
111 /**************************************************************************
112   Modpack successfully installed. Store information to appropriate list.
113 **************************************************************************/
update_install_info_lists(const char * name,enum modpack_type type,const char * version)114 void update_install_info_lists(const char *name,
115                                enum modpack_type type,
116                                const char *version)
117 {
118   struct install_info *new_ii;
119   struct install_info_list *ii_list;
120 
121   if (type == MPT_SCENARIO) {
122     ii_list = scenario_ii_list;
123     scenario_list_changed = TRUE;
124   } else {
125     ii_list = main_ii_list;
126     main_list_changed = TRUE;
127   }
128 
129   install_info_list_iterate(ii_list, ii) {
130     if (!fc_strcasecmp(name, ii->name)) {
131       if (type != ii->type) {
132         /* TRANS: ... Ubermod ... Ruleset, not Scenario */
133         log_normal(_("Earlier installation of %s found, but it seems to be %s, not %s"),
134                     name, _(modpack_type_name(ii->type)), _(modpack_type_name(type)));
135       } else {
136         log_debug("Earlier installation of %s found", name);
137       }
138 
139       ii->type = type;
140       sz_strlcpy(ii->version, version);
141 
142       return;
143     }
144   } install_info_list_iterate_end;
145 
146   /* No existing entry with that name found, creating new one */
147   new_ii = fc_malloc(sizeof(*new_ii));
148 
149   sz_strlcpy(new_ii->name, name);
150   new_ii->type = type;
151   sz_strlcpy(new_ii->version, version);
152 
153   install_info_list_append(ii_list, new_ii);
154 }
155 
156 /**************************************************************************
157   Get version number string of currently installed version, or NULL if not
158   installed.
159 **************************************************************************/
get_installed_version(const char * name,enum modpack_type type)160 const char *get_installed_version(const char *name, enum modpack_type type)
161 {
162   struct install_info_list *ii_list;
163 
164   if (type == MPT_SCENARIO) {
165     ii_list = scenario_ii_list;
166   } else {
167     ii_list = main_ii_list;
168   }
169 
170   install_info_list_iterate(ii_list, ii) {
171     if (!fc_strcasecmp(name, ii->name)) {
172       return ii->version;
173     }
174   } install_info_list_iterate_end;
175 
176   return NULL;
177 }
178 
179 /**************************************************************************
180   Initialize modpack installer
181 **************************************************************************/
fcmp_init(void)182 void fcmp_init(void)
183 {
184   init_nls();
185   init_character_encodings(FC_DEFAULT_DATA_ENCODING, FALSE);
186   registry_module_init();
187 
188   fc_init_network();
189 
190   fc_srand(time(NULL)); /* Needed at least for Windows version of netfile_get_section_file() */
191 }
192 
193 /**************************************************************************
194   Deinitialize modpack installer
195 **************************************************************************/
fcmp_deinit(void)196 void fcmp_deinit(void)
197 {
198   registry_module_close();
199   fc_shutdown_network();
200   /* log_init() was not done by fcmp_init(); we assume the caller called
201    * fcmp_parse_cmdline() (which sets up logging) in between */
202   log_close();
203   free_libfreeciv();
204   free_nls();
205 }
206