67
71
static pid_t server_pid = - 1;
70
char leader_name[MAX_LEN_NAME];
72
74
static char challenge_fullname[MAX_LEN_PATH];
73
75
static bool client_has_hack = FALSE;
75
77
int internal_server_port;
77
const char *skill_level_names[NUM_SKILL_LEVELS] = {
85
79
/**************************************************************************
86
80
The general chain of events:
203
197
char cmdline3[512];
204
198
char logcmdline[512];
205
199
char scriptcmdline[512];
200
char savescmdline[512];
201
# endif /* WIN32_NATIVE */
208
203
/* only one server (forked from this client) shall be running at a time */
209
204
/* This also resets client_has_hack. */
210
205
client_kill_server(TRUE);
212
append_output_window(_("Starting server..."));
207
output_window_append(ftc_client, _("Starting server..."));
214
209
/* find a free port */
215
210
internal_server_port = find_next_free_port(DEFAULT_SOCK_PORT);
227
222
/* Set up the command-line parameters. */
228
223
my_snprintf(port_buf, sizeof(port_buf), "%d", internal_server_port);
229
argv[argc++] = "civserver";
224
argv[argc++] = "freeciv-server";
230
225
argv[argc++] = "-p";
231
226
argv[argc++] = port_buf;
232
227
argv[argc++] = "-q";
267
264
/* If it's still attatched to our terminal, things get messed up,
268
but civserver needs *something* */
265
but freeciv-server needs *something* */
270
267
fd = open("/dev/null", O_RDONLY);
275
272
/* these won't return on success */
276
273
execvp("./ser", argv);
277
execvp("./server/civserver", argv);
278
execvp("civserver", argv);
274
execvp("./server/freeciv-server", argv);
275
execvp("freeciv-server", argv);
280
/* This line is only reached if civserver cannot be started,
277
/* This line is only reached if freeciv-server cannot be started,
281
278
* so we kill the forked process.
282
279
* Calling exit here is dangerous due to X11 problems (async replies) */
282
# else /* HAVE_WORKING_FORK */
286
283
# ifdef WIN32_NATIVE
288
285
loghandle = CreateFile(logfile, GENERIC_WRITE,
302
299
logcmdline[0] = 0;
303
300
scriptcmdline[0] = 0;
302
/* the server expects command line arguments to be in local encoding */
304
char *logfile_in_local_encoding = internal_to_local_string_malloc(logfile);
306
305
my_snprintf(logcmdline, sizeof(logcmdline), " --debug 3 --log %s",
306
logfile_in_local_encoding);
307
free(logfile_in_local_encoding);
309
309
if (scriptfile) {
310
char *scriptfile_in_local_encoding = internal_to_local_string_malloc(scriptfile);
310
311
my_snprintf(scriptcmdline, sizeof(scriptcmdline), " --read %s",
312
scriptfile_in_local_encoding);
313
free(scriptfile_in_local_encoding);
314
316
interpret_tilde(savesdir, sizeof(savesdir), "~/.freeciv/saves");
317
internal_to_local_string_buffer(savesdir, savescmdline, sizeof(savescmdline));
316
319
my_snprintf(options, sizeof(options), "-p %d -q 1 -e%s%s --saves \"%s\"",
317
internal_server_port, logcmdline, scriptcmdline, savesdir);
320
internal_server_port, logcmdline, scriptcmdline, savescmdline);
318
321
my_snprintf(cmdline1, sizeof(cmdline1), "./ser %s", options);
319
my_snprintf(cmdline2, sizeof(cmdline2), "./server/civserver %s", options);
320
my_snprintf(cmdline3, sizeof(cmdline3), "civserver %s", options);
322
my_snprintf(cmdline2, sizeof(cmdline2),
323
"./server/freeciv-server %s", options);
324
my_snprintf(cmdline3, sizeof(cmdline3),
325
"freeciv-server %s", options);
322
327
if (!CreateProcess(NULL, cmdline1, NULL, NULL, TRUE,
323
328
DETACHED_PROCESS | NORMAL_PRIORITY_CLASS,
328
333
&& !CreateProcess(NULL, cmdline3, NULL, NULL, TRUE,
329
334
DETACHED_PROCESS | NORMAL_PRIORITY_CLASS,
330
335
NULL, NULL, &si, &pi)) {
331
append_output_window(_("Couldn't start the server."));
332
append_output_window(_("You'll have to " "start one manually. Sorry..."));
336
output_window_append(ftc_client, _("Couldn't start the server."));
337
output_window_append(ftc_client,
338
_("You'll have to start one manually. Sorry..."));
336
342
server_process = pi.hProcess;
344
# endif /* WIN32_NATIVE */
345
# endif /* HAVE_WORKING_FORK */
341
347
/* a reasonable number of tries */
342
348
while (connect_to_server(user_name, "localhost", internal_server_port,
357
363
/* weird, but could happen, if server doesn't support new startup stuff
358
364
* capabilities won't help us here... */
359
if (!aconnection.used) {
365
if (!client.conn.used) {
360
366
/* possible that server is still running. kill it */
361
367
client_kill_server(TRUE);
363
append_output_window(_("Couldn't connect to the server."));
364
append_output_window(_("We probably couldn't start it from here."));
365
append_output_window(_("You'll have to start one manually. Sorry..."));
369
output_window_append(ftc_client, _("Couldn't connect to the server."));
370
output_window_append(ftc_client,
371
_("We probably couldn't start it from here."));
372
output_window_append(ftc_client,
373
_("You'll have to start one manually. Sorry..."));
381
389
* Setting the option here is a bit of a hack, but so long as the client
382
390
* has sufficient permissions to do so (it doesn't have HACK access yet) it
383
391
* is safe enough. Note that if you load a savegame the topology will be
384
* set but then overwritten during the load. */
385
my_snprintf(buf, sizeof(buf), "/set topology %d",
387
| ((tileset_is_isometric(tileset)
388
&& tileset_hex_height(tileset) == 0) ? TF_ISO : 0)
389
| ((tileset_hex_width(tileset) != 0
390
|| tileset_hex_height(tileset) != 0) ? TF_HEX : 0)));
392
* set but then overwritten during the load.
394
* Don't send it now, it will be sent to the server when receiving the
395
* server setting infos. */
399
my_snprintf(buf, sizeof(buf), "%d",
401
| ((tileset_is_isometric(tileset)
402
&& tileset_hex_height(tileset) == 0) ? TF_ISO : 0)
403
| ((tileset_hex_width(tileset) != 0
404
|| tileset_hex_height(tileset) != 0) ? TF_HEX : 0)));
405
desired_settable_option_update("topology", buf, FALSE);
409
#endif /* HAVE_WORKING_FORK || WIN32_NATIVE */
412
/*************************************************************************
413
generate a random string.
414
*************************************************************************/
415
static void randomize_string(char *str, size_t n)
418
"0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
421
for (i = 0; i < n - 1; i++) {
422
str[i] = chars[myrand(sizeof(chars) - 1)];
397
427
/*************************************************************************
436
466
sz_strlcat(challenge_fullname, filename);
438
468
/* generate an authentication token */
439
randomize_base64url_string(req.token, sizeof(req.token));
469
randomize_string(req.token, sizeof(req.token));
441
471
section_file_init(&file);
442
472
secfile_insert_str(&file, req.token, "challenge.token");
443
if (!section_file_save(&file, challenge_fullname, 0)) {
473
if (!section_file_save(&file, challenge_fullname, 0, FZ_PLAIN)) {
444
474
freelog(LOG_ERROR, "Couldn't write token to temporary file: %s",
445
475
challenge_fullname);
447
477
section_file_free(&file);
449
479
/* tell the server what we put into the file */
450
send_packet_single_want_hack_req(&aconnection, &req);
480
send_packet_single_want_hack_req(&client.conn, &req);
454
484
/****************************************************************
455
client has hack (or not).
485
handle response (by the server) if the client has got hack or not.
456
486
*****************************************************************/
457
487
void handle_single_want_hack_reply(bool you_have_hack)
459
489
/* remove challenge file */
460
490
if (challenge_fullname[0] != '\0') {
461
if (remove(challenge_fullname) == -1) {
491
if (fc_remove(challenge_fullname) == -1) {
462
492
freelog(LOG_ERROR, "Couldn't remove temporary file: %s",
463
493
challenge_fullname);
468
498
if (you_have_hack) {
469
append_output_window(_("Established control over the server. "
499
output_window_append(ftc_client,
500
_("Established control over the server. "
470
501
"You have command access level 'hack'."));
471
502
client_has_hack = TRUE;
472
503
} else if (is_server_running()) {
473
504
/* only output this if we started the server and we NEED hack */
474
append_output_window(_("Failed to obtain the required access "
505
output_window_append(ftc_client,
506
_("Failed to obtain the required access "
475
507
"level to take control of the server. "
476
508
"The server will now be shutdown."));
477
509
client_kill_server(TRUE);
481
513
/****************************************************************
482
send server commands to start a saved game.
483
*****************************************************************/
484
void send_start_saved_game(void)
486
char buf[MAX_LEN_MSG];
488
send_chat("/set timeout 0");
489
my_snprintf(buf, sizeof(buf), "/take \"%s\" \"%s\"",
490
user_name, leader_name);
495
/****************************************************************
496
514
send server command to save game.
497
515
*****************************************************************/
498
516
void send_save_game(char *filename)
500
char message[MAX_LEN_MSG];
503
my_snprintf(message, MAX_LEN_MSG, "/save %s", filename);
519
send_chat_printf("/save %s", filename);
505
my_snprintf(message, MAX_LEN_MSG, "/save");
511
525
/**************************************************************************