Allow querying the game via --print-charset if encoding is "ask". (Adam Borowski <kilobyte@angband.pl>)

git-svn-id: svn://katsu.triplehelix.org/dgamelaunch/trunk@599 db0b04b0-f4d1-0310-9a6d-de3e77497b0e
This commit is contained in:
Pasi Kallinen 2011-10-03 15:31:15 +00:00
parent d497cb4529
commit eae0ddf649
1 changed files with 86 additions and 0 deletions

View File

@ -51,6 +51,7 @@
#include <sys/ioctl.h>
#include <sys/time.h>
#include <sys/wait.h>
#include <fcntl.h>
#include <termios.h>
#include <time.h>
@ -70,6 +71,7 @@
#ifndef XCASE
# define XCASE 0
#endif
static void query_encoding(int game, char *username);
int slave;
pid_t dgl_parent;
@ -155,6 +157,8 @@ ttyrec_main (int game, char *username, char *ttyrec_path, char* ttyrec_filename)
else
snprintf (dirname, 100, "%s/%s", ttyrec_path, ttyrec_filename);
ancient_encoding = myconfig[game]->encoding;
if (ancient_encoding == -1)
query_encoding(game, username);
atexit(&remove_ipfile);
if ((fscript = fopen (dirname, "w")) == NULL)
@ -596,3 +600,85 @@ int encoding_by_name(const char *enc)
return 1; // what to do with invalid chars?
return -1;
}
static void call_print_charset(char *exe, char **args)
{
char **args2, **a;
int nargs = 0;
for (args2 = args; *args2; args2++)
nargs++;
args2 = calloc(nargs + 1, sizeof(char*));
for (a = args2; *args; args++)
*a++ = *args;
*a++ = "--print-charset";
*a = 0;
execvp(exe, args2);
}
static void query_encoding(int game, char *username)
{
int son;
int p[2];
int null;
struct timeval tv;
fd_set se;
char buf[128];
if (pipe(p))
perror("pipe");
switch(son = fork())
{
case -1:
perror("fork");
fail();
case 0:
null = open("/dev/null", O_RDONLY);
if (null != -1)
dup2(null, 0), close(null);
else
{
fprintf(stderr, "Error: can't open /dev/null\n");
// non-fatal, but if the child opens some other file, it might
// get confused
close(0);
}
dup2(p[1], 1);
close(p[1]);
close(p[0]);
call_print_charset(myconfig[game]->game_path, myconfig[game]->bin_args);
exit(1);
}
close(p[1]);
FD_ZERO(&se);
FD_SET(p[0],&se);
tv.tv_sec = 60; // FIXME: a huge delay, in case there's a db rebuild
tv.tv_usec = 0;
if (select(p[0]+1,&se,NULL,NULL,&tv) != 1)
{
fprintf(stderr, "Error: can't obtain charset info.\nPress any key...\n");
read(0, buf, 1);
close(p[0]); // SIGPIPE
kill(son, SIGTERM); // and SIGTERM for a good measure
waitpid(son, 0, 0);
ancient_encoding = 0;
return;
}
// Sending _one_ short message over a pipe is atomic on all systems I know.
// Don't assume this on about any other file descriptor.
read(p[0], buf, sizeof(buf)-1);
buf[sizeof(buf)-1] = 0;
close(p[0]);
kill(son, SIGTERM);
waitpid(son, 0, 0);
if (strchr(buf, '\n'))
*strchr(buf, '\n') = 0;
ancient_encoding = encoding_by_name(buf);
if (ancient_encoding == -1)
{
fprintf(stderr, "Error: unknown encoding \"%s\"\nPress any key...\n", buf);
read(0, buf, 1);
}
}