]> git.pond.sub.org Git - empserver/blobdiff - src/client/servcmd.c
Rewrite much of client's playing phase code:
[empserver] / src / client / servcmd.c
index 24bae60844c9e544e249c268d191df91048f8b9c..f4129b138a6be605eee05ce3ab4282587f00c74b 100644 (file)
 
 #include <config.h>
 
+#include <assert.h>
 #include <ctype.h>
 #include <errno.h>
 #include <fcntl.h>
 #include <stdio.h>
-#include <stdlib.h>
 #include <string.h>
-#ifdef _WIN32
-#include <io.h>
-#else
-#include <unistd.h>
-#endif
-
-#include "ioqueue.h"
 #include "misc.h"
 #include "proto.h"
-#include "tags.h"
+#include "secure.h"
+
+int eight_bit_clean;
+FILE *auxfp;
 
-static char num_teles[64];
-static char the_prompt[1024];
-static int mode;
-static int nbtu;
-static int nmin;
 static FILE *redir_fp;
 static FILE *pipe_fp;
 
-static void prompt(FILE *auxfi);
+static void prompt(int, char *, char *);
 static void doredir(char *p);
 static void dopipe(char *p);
-static void doexecute(char *p, FILE *auxfi);
-static void output(int code, char *buf, FILE *auxfi);
-static void screen(char *buf);
+static void doexecute(char *p);
 
 void
-servercmd(struct ioqueue *ioq, FILE *auxfi)
+servercmd(int code, char *arg, int len)
 {
-    char buf[1024];
-    char *p;
-    static int code = -1;
-    int eol;
+    static int nmin, nbtu;
+    static char the_prompt[1024];
+    static char teles[64];
 
-    while (ioq_gets(ioq, buf, sizeof(buf), &eol)) {
-       p = buf;
-       if (code == -1) {
-           if (isalpha(*buf))
-               code = 10 + (*buf - 'a');
-           else
-               code = *buf - '0';
-           while (*p && !isspace(*p))
-               p++;
-           *p++ = 0;
+    switch (code) {
+    case C_PROMPT:
+       if (sscanf(arg, "%d %d", &nmin, &nbtu) != 2) {
+           fprintf(stderr, "prompt: bad server prompt %s\n", arg);
        }
-       /*
-        * FIXME
-        * C_REDIR, C_PIPE, and C_EXECUTE will not
-        * work with filename longer than one buffer
-        */
-       switch (code) {
-       case C_PROMPT:
-           if (sscanf(p, "%d %d", &nmin, &nbtu) != 2) {
-               fprintf(stderr, "prompt: bad server prompt %s\n", p);
+       snprintf(the_prompt, sizeof(the_prompt), "[%d:%d] Command : ",
+                nmin, nbtu);
+       prompt(code, the_prompt, teles);
+       break;
+    case C_FLUSH:
+       snprintf(the_prompt, sizeof(the_prompt), "%.*s", len - 1, arg);
+       prompt(code, the_prompt, teles);
+       break;
+    case C_EXECUTE:
+       doexecute(arg);
+       break;
+    case C_EXIT:
+       printf("Exit: %s", arg);
+       if (auxfp)
+           fprintf(auxfp, "Exit: %s", arg);
+       break;
+    case C_FLASH:
+       printf("\n%s", arg);
+       if (auxfp)
+           fprintf(auxfp, "\n%s", arg);
+       break;
+    case C_INFORM:
+       if (*arg) {
+           snprintf(teles, sizeof(teles), "(%.*s )", len -1, arg);
+           if (!redir_fp && !pipe_fp) {
+               putchar('\07');
+               prompt(code, the_prompt, teles);
            }
-           mode = code;
-           sprintf(the_prompt, "[%d:%d] Command : ", nmin, nbtu);
-           prompt(auxfi);
-           break;
-       case C_REDIR:
-           if (eol)
-               p[strlen(p) - 1] = '\0';
-           doredir(p);
-           break;
-       case C_PIPE:
-           if (eol)
-               p[strlen(p) - 1] = '\0';
-           dopipe(p);
-           break;
-       case C_FLUSH:
-           mode = code;
-           if (eol)
-               p[strlen(p) - 1] = '\0';
-           sprintf(the_prompt, "%s", p);
-           prompt(auxfi);
-           break;
-       case C_EXECUTE:
-           if (eol)
-               p[strlen(p) - 1] = '\0';
-           doexecute(p, auxfi);
-           break;
-       case C_INFORM:
-           if (eol)
-               p[strlen(p) - 1] = '\0';
-           if (*p) {
-               p[strlen(p) - 1] = '\0';
-               sprintf(num_teles, "(%s) ", p + 1);
-               if (!redir_fp && !pipe_fp) {
-                   putchar('\07');
-                   prompt(NULL);
-               }
-           } else
-               *num_teles = '\0';
-           break;
-       default:
-           output(code, p, auxfi);
-           break;
-       }
-       if (eol)
-           code = -1;
+       } else
+           teles[0] = 0;
+       break;
+    case C_PIPE:
+       dopipe(arg);
+       break;
+    case C_REDIR:
+       doredir(arg);
+       break;
+    default:
+       assert(0);
+       break;
     }
 }
 
 static void
-prompt(FILE *auxfi)
+prompt(int code, char *prompt, char *teles)
 {
-    if (mode == C_PROMPT) {
+    char *nl;
+
+    if (code == C_PROMPT) {
        if (redir_fp) {
            (void)fclose(redir_fp);
            redir_fp = NULL;
@@ -156,13 +125,12 @@ prompt(FILE *auxfi)
            pipe_fp = NULL;
        }
     }
-    if (mode == C_PROMPT)
-       printf("\n");
-    printf("%s%s", num_teles, the_prompt);
-    (void)fflush(stdout);
-    if (auxfi) {
-       fprintf(auxfi, "\n%s%s", num_teles, the_prompt);
-       (void)fflush(auxfi);
+    nl = code == C_PROMPT || code == C_INFORM ? "\n" : "";
+    printf("%s%s%s", nl, teles, prompt);
+    fflush(stdout);
+    if (auxfp) {
+       fprintf(auxfp, "%s%s%s", nl, teles, prompt);
+       fflush(auxfp);
     }
 }
 
@@ -183,7 +151,6 @@ fname(char *s)
 static void
 doredir(char *p)
 {
-    char *tag;
     int mode;
     int fd;
 
@@ -192,6 +159,12 @@ doredir(char *p)
        redir_fp = NULL;
     }
 
+    if (!seen_input(p)) {
+       fprintf(stderr, "WARNING!  Server attempted to redirect %s\n",
+               p);
+       return;
+    }
+
     if (*p++ != '>') {
        fprintf(stderr, "WARNING!  Weird redirection %s", p);
        return;
@@ -207,19 +180,12 @@ doredir(char *p)
     } else
        mode |= O_EXCL;
 
-    tag = gettag(p);
     p = fname(p);
-    if (tag == NULL) {
-       fprintf(stderr, "WARNING!  Server redirected output to file %s\n",
-               p);
-       return;
-    }
-    free(tag);
-
     if (*p == 0) {
        fprintf(stderr, "Redirection lacks a file name\n");
        return;
     }
+
     fd = open(p, mode, 0600);
     redir_fp = fd < 0 ? NULL : fdopen(fd, "w");
     if (!redir_fp) {
@@ -234,25 +200,22 @@ doredir(char *p)
 static void
 dopipe(char *p)
 {
-    char *tag;
-
-    if (*p++ != '|') {
-       fprintf(stderr, "WARNING!  Weird pipe %s", p);
+    if (!seen_input(p)) {
+       fprintf(stderr, "WARNING!  Server attempted to pipe %s", p);
        return;
     }
 
-    tag = gettag(p);
-    if (tag == NULL) {
-       fprintf(stderr, "WARNING!  Server attempted to run: %s\n", p);
+    if (*p++ != '|') {
+       fprintf(stderr, "WARNING!  Weird pipe %s", p);
        return;
     }
-    free(tag);
 
     for (; *p && isspace(*p); p++) ;
     if (*p == 0) {
        fprintf(stderr, "Redirection lacks a command\n");
        return;
     }
+
     if ((pipe_fp = popen(p, "w")) == NULL) {
        fprintf(stderr, "Can't redirect to pipe %s: %s\n",
                p, strerror(errno));
@@ -260,103 +223,48 @@ dopipe(char *p)
 }
 
 static void
-doexecute(char *p, FILE *auxfi)
+doexecute(char *p)
 {
-    int fd;
-    char *tag;
-
-    tag = gettag(p);
-    if (tag == NULL) {
+    if (!seen_input(p)) {
        fprintf(stderr,
-               "WARNING!  Server attempted unauthorized read of file %s\n",
+               "WARNING!  Server attempted to read file %s",
                p);
        return;
     }
-    free(tag);
 
     p = fname(p);
     if (*p == 0) {
        fprintf(stderr, "Need a file to execute\n");
        return;
     }
-    if ((fd = open(p, O_RDONLY, 0)) < 0) {
+
+    if ((input_fd = open(p, O_RDONLY)) < 0) {
        fprintf(stderr, "Can't open execute file %s: %s\n",
                p, strerror(errno));
        return;
     }
-    /* copies 4k at a time to the socket */
-    while (termio(fd, sock, auxfi))    /*do copy */
-       ;
-    /*
-     * Some platforms don't send the eof (cntl-D) at the end of
-     * copying a file.  If emp_client hangs at the end of an
-     * execute, include the following line and notify wolfpack
-     * of the platform you are using.
-     * sendeof(sock);
-     */
-    close(fd);
 }
 
-static void
-output(int code, char *buf, FILE *auxfi)
+void
+outch(char c)
 {
-    switch (code) {
-    case C_NOECHO:
-       /* not implemented; server doesn't send it */
-       break;
-    case C_ABORT:
-       printf("Aborted\n");
-       if (auxfi)
-           fprintf(auxfi, "Aborted\n");
-       break;
-    case C_CMDERR:
-    case C_BADCMD:
-       printf("Error; ");
-       if (auxfi)
-           fprintf(auxfi, "Error; ");
-       break;
-    case C_EXIT:
-       printf("Exit: ");
-       if (auxfi)
-           fprintf(auxfi, "Exit: ");
-       break;
-    case C_FLASH:
-       printf("\n");
-       break;
-    default:
-       break;
-    }
-    if (auxfi) {
-       fprintf(auxfi, "%s", buf);
-    }
-
+    if (auxfp)
+       putc(c, auxfp);
     if (redir_fp)
-       fprintf(redir_fp, "%s", buf);
+       putc(c, redir_fp);
     else if (pipe_fp)
-       fprintf(pipe_fp, "%s", buf);
-    else {
-       screen(buf);
-    }
-}
-
-static void
-screen(char *buf)
-{
-    char c;
-
-    while ((c = *buf++)) {
-       if (eight_bit_clean) {
-           if (c == 14)
-               putso();
-           else if (c == 15)
-               putse();
-           else
-               putchar(c);
-       } else if (c & 0x80) {
+       putc(c, pipe_fp);
+    else if (eight_bit_clean) {
+       if (c == 14)
            putso();
-           putchar(c & 0x7f);
+       else if (c == 15)
            putse();
-       else
+       else
            putchar(c);
-    }
+    } else if (c & 0x80) {
+       putso();
+       putchar(c & 0x7f);
+       putse();
+    } else
+       putchar(c);
 }