1 // Copyright (C) 2017, 2020 Ben Asselstine
2 //
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 3 of the License, or
6 // (at your option) 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 Library General Public License for more details.
12 //
13 // You should have received a copy of the GNU General Public License
14 // along with this program; if not, write to the Free Software
15 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
16 // 02110-1301, USA.
17
18 #include "tarfile.h"
19 #include "tarhelper.h"
20
TarFile(Glib::ustring name,Glib::ustring ext)21 TarFile::TarFile(Glib::ustring name, Glib::ustring ext)
22 : d_dir(""), d_basename(name), d_extension(ext), d_tmp_filename("")
23 {
24 }
25
TarFile(const TarFile & s)26 TarFile::TarFile(const TarFile &s)
27 : d_dir(s.d_dir), d_basename(s.d_basename), d_extension(s.d_extension),
28 d_tmp_filename ("")
29 {
30 }
31
moved(Glib::ustring filename)32 void TarFile::moved(Glib::ustring filename)
33 {
34 created (filename);
35 }
36
created(Glib::ustring filename)37 void TarFile::created(Glib::ustring filename)
38 {
39 setDirectory(File::get_dirname(filename));
40 setBaseName(File::get_basename(filename, false));
41 setExtension(File::get_extension(filename));
42 }
43
getConfigurationFile(bool master) const44 Glib::ustring TarFile::getConfigurationFile(bool master) const
45 {
46 if (!master)
47 {
48 if (d_tmp_filename != "")
49 return d_tmp_filename;
50 }
51 return getDirectory() + getBaseName() + d_extension;
52 }
53
getFileFromConfigurationFile(Glib::ustring file)54 Glib::ustring TarFile::getFileFromConfigurationFile(Glib::ustring file)
55 {
56 if (getConfigurationFile () == "")
57 return "";
58 bool broken = false;
59 Tar_Helper t(getConfigurationFile(), std::ios::in, broken);
60 if (broken == false)
61 {
62 Glib::ustring filename = t.getFile(file, broken);
63 t.Close(false);
64
65 if (broken == false)
66 return filename;
67 }
68 return "";
69 }
70
removeFileInCfgFile(Glib::ustring file)71 bool TarFile::removeFileInCfgFile(Glib::ustring file)
72 {
73 bool broken = false;
74 Glib::ustring infile = d_tmp_filename;
75 if (infile == "")
76 infile = getConfigurationFile();
77 Tar_Helper t(infile, std::ios::in, broken);
78 if (broken == false)
79 {
80 broken = !t.replaceFile(file, "", "");
81 t.Close();
82 }
83 return !broken;
84 }
85
replaceFileInCfgFile(Glib::ustring file,Glib::ustring new_file,Glib::ustring & out)86 bool TarFile::replaceFileInCfgFile(Glib::ustring file, Glib::ustring new_file, Glib::ustring &out)
87 {
88 bool broken = false;
89 Glib::ustring infile = d_tmp_filename;
90 if (infile == "")
91 infile = getConfigurationFile();
92 Tar_Helper t(infile, std::ios::in, broken);
93 if (broken == false)
94 {
95 Glib::ustring bname = File::get_basename (new_file, true);
96 Glib::ustring outfile = t.makeNameUnique (bname);
97 Tar_Helper::reopen (&t);
98 if (bname != outfile && bname == file)
99 outfile = file;
100 broken = !t.replaceFile(file, new_file, outfile);
101 t.Close();
102 if (!broken)
103 out = outfile;
104 }
105 return !broken;
106 }
107
addFileInCfgFile(Glib::ustring new_file,Glib::ustring & out)108 bool TarFile::addFileInCfgFile(Glib::ustring new_file, Glib::ustring &out)
109 {
110 bool broken = false;
111 Glib::ustring infile = d_tmp_filename;
112 if (infile == "")
113 infile = getConfigurationFile();
114 Tar_Helper t(infile, std::ios::in, broken);
115 if (broken == false)
116 {
117 Glib::ustring bname = File::get_basename (new_file, true);
118 Glib::ustring outfile = t.makeNameUnique (bname);
119 Tar_Helper::reopen (&t);
120 broken = !t.replaceFile("", new_file, outfile);
121 t.Close();
122 if (!broken)
123 out = outfile;
124 }
125 return !broken;
126 }
127
clean_tmp_dir()128 void TarFile::clean_tmp_dir()
129 {
130 Tar_Helper::clean_tmp_dir(getConfigurationFile());
131 if (d_tmp_filename != "" && File::exists (d_tmp_filename))
132 {
133 File::erase (d_tmp_filename);
134 d_tmp_filename = "";
135 }
136 }
137
saveTar(Glib::ustring tmpfile,Glib::ustring tmptar,Glib::ustring dest,bool add_sets) const138 bool TarFile::saveTar(Glib::ustring tmpfile, Glib::ustring tmptar, Glib::ustring dest, bool add_sets) const
139 {
140 bool broken = false;
141 Tar_Helper t(tmptar, std::ios::out, broken);
142 if (broken == true)
143 return false;
144 t.saveFile(tmpfile, File::get_basename(dest, true));
145 //now the images, go get 'em from the tarball we were made from.
146 Glib::ustring infile = d_tmp_filename;
147 if (infile == "")
148 infile = getConfigurationFile ();
149 if (infile != "")
150 {
151 std::list<Glib::ustring> delfiles;
152 Tar_Helper orig(infile, std::ios::in, broken);
153 if (broken == false)
154 {
155 std::list<Glib::ustring> extensions;
156 extensions.push_back (".png");
157 extensions.push_back (".ogg");
158 if (add_sets)
159 {
160 extensions.push_back (ARMYSET_EXT);
161 extensions.push_back (TILESET_EXT);
162 extensions.push_back (SHIELDSET_EXT);
163 extensions.push_back (CITYSET_EXT);
164 }
165 for (auto ext : extensions)
166 {
167 std::list<Glib::ustring> files = orig.getFilenames(ext);
168 for (std::list<Glib::ustring>::iterator it = files.begin();
169 it != files.end(); it++)
170 {
171 Glib::ustring file = orig.getFile(*it, broken);
172 if (broken == false)
173 {
174 t.saveFile(file);
175 delfiles.push_back(file);
176 }
177 else
178 break;
179 }
180 if (broken)
181 break;
182 }
183 orig.Close();
184 for (std::list<Glib::ustring>::iterator it = delfiles.begin();
185 it != delfiles.end(); it++)
186 File::erase(*it);
187 }
188 else
189 {
190 FILE *fileptr = fopen (infile.c_str(), "r");
191 if (fileptr)
192 fclose (fileptr);
193 else
194 broken = false;
195 }
196 }
197 t.Close();
198 File::erase(tmpfile);
199 if (broken == false)
200 {
201 if (File::copy(tmptar, dest) == true)
202 File::erase(tmptar);
203 else
204 {
205 int save_errno = errno;
206 //all that work for nothing
207 File::erase(tmptar);
208 errno = save_errno;
209 broken = true;
210 }
211 }
212 return broken == false;
213 }
214
setNewTemporaryFile()215 void TarFile::setNewTemporaryFile ()
216 {
217 d_tmp_filename = File::get_tmp_file ();
218 bool broken = false;
219 Tar_Helper t(d_tmp_filename, std::ios::out, broken);
220 if (broken == true)
221 return;
222 t.Close ();
223 }
224
setLoadTemporaryFile()225 void TarFile::setLoadTemporaryFile ()
226 {
227 Glib::ustring f = File::get_tmp_file ();
228 File::copy (getConfigurationFile (), f);
229 d_tmp_filename = f;
230 }
231
isTemporaryFile() const232 bool TarFile::isTemporaryFile () const
233 {
234 return d_tmp_filename != "";
235 }
236