]> git.pond.sub.org Git - empserver/blob - src/util/empdump.c
Make empdump call ef_close() regardless of -n
[empserver] / src / util / empdump.c
1 /*
2  *  Empire - A multi-player, client/server Internet based war game.
3  *  Copyright (C) 1986-2009, Dave Pare, Jeff Bailey, Thomas Ruschak,
4  *                           Ken Stevens, Steve McClure
5  *
6  *  This program is free software; you can redistribute it and/or modify
7  *  it under the terms of the GNU General Public License as published by
8  *  the Free Software Foundation; either version 2 of the License, or
9  *  (at your option) any later version.
10  *
11  *  This program is distributed in the hope that it will be useful,
12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *  GNU General Public License for more details.
15  *
16  *  You should have received a copy of the GNU General Public License
17  *  along with this program; if not, write to the Free Software
18  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  *
20  *  ---
21  *
22  *  See files README, COPYING and CREDITS in the root of the source
23  *  tree for related information and legal notices.  It is expected
24  *  that future projects/authors will amend these files as needed.
25  *
26  *  ---
27  *
28  *  empdump.c: Export/import Empire game state
29  *
30  *  Known contributors to this file:
31  *     Markus Armbruster, 2008
32  */
33
34 #include <config.h>
35
36 #include <errno.h>
37 #include <stdarg.h>
38 #include <stdio.h>
39 #include <stdlib.h>
40 #include <unistd.h>
41 #include "file.h"
42 #include "optlist.h"
43 #include "nat.h"
44 #include "prototypes.h"
45 #include "version.h"
46 #include "xdump.h"
47
48 static void exit_bad_arg(char *, ...)
49     ATTRIBUTE((noreturn, format (printf, 1, 2)));
50 static void dump_table(int, int);
51
52 int
53 main(int argc, char *argv[])
54 {
55     char *config_file = NULL;
56     char *import = NULL;
57     int export = 0;
58     int private = 0;
59     int human = 1;
60     int opt, i, lineno, type;
61     FILE *impf = NULL;
62     int dirty[EF_MAX];
63
64     while ((opt = getopt(argc, argv, "e:i:mnxhv")) != EOF) {
65         switch (opt) {
66         case 'e':
67             config_file = optarg;
68             break;
69         case 'i':
70             import = optarg;
71             break;
72         case 'm':
73             human = 0;
74             break;
75         case 'n':
76             private = EFF_PRIVATE;
77             break;
78         case 'x':
79             export = 1;
80             break;
81         case 'h':
82             printf("Usage: %s [OPTION]...\n"
83                    "  -e CONFIG-FILE  configuration file\n"
84                    "                  (default %s)\n"
85                    "  -i DUMP-FILE    import from DUMP-FILE\n"
86                    "  -m              use machine-readable format\n"
87                    "  -n              dry run, don't update game state\n"
88                    "  -x              export to standard output\n"
89                    "  -h              display this help and exit\n"
90                    "  -v              display version information and exit\n",
91                    argv[0], dflt_econfig);
92             exit(0);
93         case 'v':
94             printf("%s\n\n%s", version, legal);
95             exit(0);
96         default:
97             exit_bad_arg(NULL);
98         }
99     }
100
101     if (argv[optind])
102         exit_bad_arg("%s: extra operand %s\n", argv[0], argv[optind]);
103
104     if (!import && !export)
105         exit_bad_arg("%s: nothing to do!\n", argv[0]);
106
107     if (import) {
108         impf = fopen(import, "r");
109         if (!impf) {
110             fprintf(stderr, "%s: Can't open %s for reading (%s)\n",
111                     argv[0], import, strerror(errno));
112             exit(1);
113         }
114     } else
115         private = EFF_PRIVATE;
116
117     /* read configuration & initialize */
118     empfile_init();
119     if (emp_config(config_file) < 0)
120         exit(1);
121     empfile_fixup();
122     nsc_init();
123     if (read_builtin_tables() < 0)
124         exit(1);
125     if (read_custom_tables() < 0)
126         exit(1);
127     if (chdir(gamedir)) {
128         fprintf(stderr, "%s: Can't chdir to %s (%s)\n",
129                 argv[0], gamedir, strerror(errno));
130         exit(1);
131     }
132     global_init();
133
134     for (i = 0; i < EF_MAX; i++) {
135         if (!EF_IS_GAME_STATE(i))
136             continue;
137         if (!ef_open(i, EFF_MEM | private, -1))
138             exit(1);
139     }
140
141     /* import from IMPORT */
142     memset(dirty, 0, sizeof(dirty));
143     if (import) {
144         lineno = 1;
145         while ((type = xundump(impf, import, &lineno, EF_BAD)) >= 0)
146             dirty[type] = 1;
147         if (type == EF_BAD)
148             exit(1);
149     }
150
151     if (ef_verify() < 0)
152         exit(1);
153
154     /* export to stdout */
155     if (export) {
156         for (i = 0; i < EF_MAX; i++) {
157             if (!EF_IS_GAME_STATE(i))
158                 continue;
159             dump_table(i, human);
160         }
161         if (fclose(stdout) != 0) {
162             fprintf(stderr, "%s: error writing export (%s)\n",
163                     argv[0], strerror(errno));
164             exit(1);
165         }
166     }
167
168     /* write out imported data */
169     for (i = 0; i < EF_MAX; i++) {
170         if (!EF_IS_GAME_STATE(i))
171             continue;
172         if (dirty[i]) {
173             if (!ef_close(i))
174                 exit(1);
175         }
176     }
177
178     return 0;
179 }
180
181 static void
182 exit_bad_arg(char *complaint, ...)
183 {
184     va_list ap;
185
186     if (complaint) {
187         va_start(ap, complaint);
188         vfprintf(stderr, complaint, ap);
189         va_end(ap);
190     }
191     fprintf(stderr, "Try -h for help.\n");
192     exit(1);
193 }
194
195 static void
196 printf_wrapper(char *fmt, ...)
197 {
198     va_list ap;
199
200     va_start(ap, fmt);
201     vprintf(fmt, ap);
202     va_end(ap);
203 }
204
205 static void
206 dump_table(int type, int human)
207 {
208     struct xdstr xd;
209     struct castr *ca;
210     int i;
211     void *p;
212
213     ca = ef_cadef(type);
214     if (!ca)
215         return;
216
217     xdinit(&xd, NATID_BAD, human, printf_wrapper);
218     xdhdr(&xd, ef_nameof(type), 0);
219     xdcolhdr(&xd, ca);
220     for (i = 0; (p = ef_ptr(type, i)); i++) {
221         xdflds(&xd, ca, p);
222         printf("\n");
223     }
224     xdftr(&xd, i);
225 }