#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;
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);
}
}
static void
doredir(char *p)
{
- char *tag;
int mode;
int fd;
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;
} 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) {
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));
}
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);
}