diff --git a/man/emp_client.6 b/man/emp_client.6 index 1dcc5cce..ed5519f8 100644 --- a/man/emp_client.6 +++ b/man/emp_client.6 @@ -7,6 +7,9 @@ empire \- Empire client .BI \-k ] [ +.BI \-u +] +[ .BI \-2 " outfile" ] [ @@ -37,6 +40,12 @@ the password for your country in the game .BI \-k if someone else is connected to your country, kill their connection .TP +.BI \-u +use UTF-8 rather than ASCII character set +.IP +This requires server version 4.2.21 or later, and a terminal that +understands UTF-8. +.TP .BI \-2 " outfile" redirect output to .I outfile diff --git a/src/client/expect.c b/src/client/expect.c index 6a82a8da..c65523d9 100644 --- a/src/client/expect.c +++ b/src/client/expect.c @@ -45,7 +45,7 @@ #endif int -expect(int s, int match, char *buf) +recvline(int s, char *buf) { int size; char *p; @@ -62,7 +62,6 @@ expect(int s, int match, char *buf) ptr = buf; n = recv(s, ptr, size, MSG_PEEK); if (n <= 0) { - fprintf(stderr, "Expecting code %d\n", match); #ifdef _WIN32 errno = WSAGetLastError(); #endif @@ -91,7 +90,10 @@ expect(int s, int match, char *buf) } ptr += n; if ((n = recv(s, ptr, size, MSG_PEEK)) <= 0) { - fprintf(stderr, "Expecting %d, got %s\n", match, buf); +#ifdef _WIN32 + errno = WSAGetLastError(); +#endif + perror("recv"); return 0; } size -= n; @@ -123,7 +125,7 @@ expect(int s, int match, char *buf) (void)alarm(0); #endif if (!isxdigit(*buf)) { - fprintf(stderr, "Expecting %d, got %s\n", match, buf); + fprintf(stderr, "Malformed line %s\n", buf); return 0; } if (isdigit(*buf)) @@ -133,9 +135,14 @@ expect(int s, int match, char *buf) *buf = tolower(*buf); code = 10 + *buf - 'a'; } - if (code == match) - return 1; - return 0; + return code; +} + +int +expect(int s, int match, char *buf) +{ + int code = recvline(s, buf); + return code == match; } void diff --git a/src/client/login.c b/src/client/login.c index f888e06a..869eb1de 100644 --- a/src/client/login.c +++ b/src/client/login.c @@ -44,19 +44,31 @@ #endif int -login(int s, char *uname, char *cname, char *cpass, int kill_proc) +login(int s, char *uname, char *cname, char *cpass, int kill_proc, int utf8) { char tmp[128]; char buf[1024]; char *ptr; char *p; - int len; + int len, code; if (!expect(s, C_INIT, buf)) return 0; (void)sendcmd(s, "user", uname); if (!expect(s, C_CMDOK, buf)) return 0; + if (utf8) { + sendcmd(s, "options", "utf-8"); + for (;;) { + code = recvline(s, buf); + if (code == C_CMDOK) + break; + if (code != C_DATA) { + fprintf(stderr, "Server doesn't support UTF-8\n"); + return 0; + } + } + } if (cname == NULL) { (void)printf("Country name? "); cname = fgets(tmp, sizeof(tmp), stdin); diff --git a/src/client/main.c b/src/client/main.c index 7cd3317b..f56bd44f 100644 --- a/src/client/main.c +++ b/src/client/main.c @@ -70,6 +70,7 @@ HANDLE hStdIn; #define RETRY 3 +int eight_bit_clean; int interrupt; int sock; @@ -105,6 +106,7 @@ main(int ac, char **av) char *pname; char *uname; int send_kill = 0; + int utf8 = 0; #ifdef _WIN32 err = WSAStartup(0x0101, &WsaData); @@ -133,6 +135,9 @@ main(int ac, char **av) } else if (strcmp(ptr, "-k") == 0) { send_kill = 1; continue; + } else if (strcmp(ptr, "-u") == 0) { + utf8 = eight_bit_clean = 1; + continue; } argv[j] = argv[i]; ++j; @@ -184,7 +189,7 @@ main(int ac, char **av) uname = "nobody"; #endif } - if (!login(sock, uname, cname, pname, send_kill)) { + if (!login(sock, uname, cname, pname, send_kill, utf8)) { close(sock); exit(1); } diff --git a/src/client/misc.h b/src/client/misc.h index c908e559..be2faa03 100644 --- a/src/client/misc.h +++ b/src/client/misc.h @@ -50,6 +50,7 @@ struct ioqueue; extern char empirehost[]; extern char empireport[]; +extern int eight_bit_clean; extern int interrupt; extern char num_teles[]; extern int sock; @@ -61,12 +62,13 @@ HANDLE hStdIn; #endif void getsose(void); +int recvline(int s, char *buf); int expect(int s, int match, char *buf); int handleintr(int); int hostaddr(char *name, struct sockaddr_in *addr); int hostconnect(struct sockaddr_in *addr); int hostport(char *name, struct sockaddr_in *addr); -int login(int s, char *uname, char *cname, char *cpass, int kill_proc); +int login(int s, char *uname, char *cname, char *cpass, int kill_proc, int); void saveargv(int ac, char **src, char **dst); void sendcmd(int s, char *cmd, char *arg); int sendeof(int sock); diff --git a/src/client/servcmd.c b/src/client/servcmd.c index 073cf573..df37c787 100644 --- a/src/client/servcmd.c +++ b/src/client/servcmd.c @@ -344,11 +344,15 @@ screen(char *buf) char c; while ((c = *buf++)) { - if (c & 0x80) { - for (sop = SO; putc(*sop, stdout); sop++) ; - (void)putc(c & 0x7f, stdout); - for (sop = SE; putc(*sop, stdout); sop++) ; + if (eight_bit_clean) { + if (c == 14) fputs(SO, stdout); + else if (c == 15) fputs(SE, stdout); + else putchar(c); + } else if (c & 0x80) { + fputs(SO, stdout); + putchar(c & 0x7f); + fputs(SE, stdout); } else - (void)putc(c, stdout); + putchar(c); } }