diff --git a/src/ftp.c b/src/ftp.c index 1aa262b..aa328b9 100644 --- a/src/ftp.c +++ b/src/ftp.c @@ -1039,7 +1039,6 @@ static void dproc_xfer(struct ftp *ftp, const char *buf, int sz, void *cls) } if(xfer->fp) { - ((char*)buf)[sz] = 0; fwrite(buf, 1, sz, xfer->fp); } else if(xfer->mem) { diff --git a/src/main.c b/src/main.c index 5ff626e..38cf061 100644 --- a/src/main.c +++ b/src/main.c @@ -64,8 +64,8 @@ static struct tui_widget *uilist[2]; static int focus; static unsigned int dirty; -static char *host = "localhost"; -static int port = 21; +static const char *opt_host = "localhost"; +static int opt_port = 21; static const char *opt_user, *opt_pass; static struct server *srvlist; @@ -111,7 +111,7 @@ int main(int argc, char **argv) return 1; } - if((srv = find_server(host)) && !opt_user && srv->user) { + if((srv = find_server(opt_host)) && !opt_user && srv->user) { opt_user = srv->user; opt_pass = srv->pass; } @@ -120,7 +120,7 @@ int main(int argc, char **argv) ftp_auth(ftp, opt_user, opt_pass ? opt_pass : "foobar"); } - if(ftp_connect(ftp, srv ? srv->host : host, port) == -1) { + if(ftp_connect(ftp, srv ? srv->host : opt_host, opt_port) == -1) { ftp_free(ftp); return 1; } @@ -215,7 +215,7 @@ static void updateui(void) tg_fgcolor(ftp->status ? TGFX_GREEN : TGFX_RED); tg_bgcolor(TGFX_BLACK); tg_rect(0, 0, 0, 40, 1, 0); - tg_text(0, 0, "Srv: %s", ftp->status ? host : "-"); + tg_text(0, 0, "Srv: %s", ftp->status ? opt_host : "-"); upd |= 0x8000; prev_status = ftp->status; } @@ -792,7 +792,7 @@ int parse_args(int argc, char **argv) break; case 1: - if((port = atoi(argv[i])) <= 0) { + if((opt_port = atoi(argv[i])) <= 0) { fprintf(stderr, "invalid port number: %s\n", argv[i]); return -1; } @@ -818,7 +818,7 @@ static int parse_host(const char *str) if((p = strchr(str, '@'))) { *p = 0; opt_user = str; - host = p + 1; + opt_host = p + 1; if((p = strchr(str, ':'))) { *p = 0; opt_pass = p + 1; @@ -826,6 +826,7 @@ static int parse_host(const char *str) opt_pass = 0; } } else { + opt_host = str; opt_user = opt_pass = 0; } diff --git a/src/util.c b/src/util.c index 7bc10eb..84dce4f 100644 --- a/src/util.c +++ b/src/util.c @@ -56,38 +56,89 @@ int match_prefix(const char *str, const char *prefix) static FILE *logfile; +#ifdef __DOS__ +static int setup_serial(void); +static void ser_putchar(int c); +static void ser_puts(const char *s); + +static int sdev = -1; + +#define LOG_OPEN (logfile || sdev >= 0) +#else +#define LOG_OPEN (logfile) +#endif + + static void closelog(void) { fclose(logfile); } -static void logmsg(const char *tag, const char *fmt, va_list ap) +static int loginit(void) { char *fname; + char *env = getenv("VISFTP_LOG"); + + if(env) { + fname = env; + } else { #ifdef __DOS__ - char *tmpdir = getenv("TEMP"); - if(!tmpdir) { - tmpdir = getenv("VISFTP"); + char *tmpdir = getenv("TEMP"); + if(!tmpdir) { + tmpdir = getenv("VISFTP"); + } + if(tmpdir) { + fname = alloca(strlen(tmpdir) + 16); + sprintf(fname, "%s\\visftp.log", tmpdir); + } else { + fname = "c:\\visftp.log"; + } +#else + fname = "/tmp/visftp.log"; +#endif } - if(tmpdir) { - fname = alloca(strlen(tmpdir) + 16); - sprintf(fname, "%s\\visftp.log", tmpdir); - } else { - fname = "c:\\visftp.log"; + +#ifdef __DOS__ + if(sscanf(fname, "COM%d", &sdev) == 1 || sscanf(fname, "com%d", &sdev) == 1) { + sdev--; + if(setup_serial() == -1) { + sdev = -1; + fprintf(stderr, "failed to setup serial port (%s)\n", fname); + return -1; + } + return 0; } -#else - fname = "/tmp/visftp.log"; #endif - if(!logfile) { - if(!(logfile = fopen(fname, "w"))) { + if(!(logfile = fopen(fname, "w"))) { + return -1; + } + setvbuf(logfile, 0, _IOLBF, 0); + atexit(closelog); + return 0; +} + +static void logmsg(const char *tag, const char *fmt, va_list ap) +{ + if(!LOG_OPEN) { + if(loginit() == -1) { return; } - setvbuf(logfile, 0, _IOLBF, 0); - atexit(closelog); } - fprintf(logfile, "%s: ", tag); - vfprintf(logfile, fmt, ap); + +#ifdef __DOS__ + if(sdev != -1) { + char buf[512]; + sprintf(buf, "%s: ", tag); + vsprintf(buf, fmt, ap); + ser_puts(buf); + } else { +#endif + fprintf(logfile, "%s: ", tag); + vfprintf(logfile, fmt, ap); +#ifdef __DOS__ + } +#endif } void errmsg(const char *fmt, ...) @@ -128,3 +179,77 @@ void infomsg(const char *fmt, ...) logmsg("info", fmt, ap); va_end(ap); } + +#ifdef __DOS__ +#include + +#define UART1_BASE 0x3f8 +#define UART2_BASE 0x2f8 + +#define UART_DATA 0 +#define UART_DIVLO 0 +#define UART_DIVHI 1 +#define UART_FIFO 2 +#define UART_LCTL 3 +#define UART_MCTL 4 +#define UART_LSTAT 5 + +#define DIV_9600 (115200 / 9600) +#define DIV_19200 (115200 / 19200) +#define DIV_38400 (115200 / 38400) +#define LCTL_8N1 0x03 +#define LCTL_DLAB 0x80 +#define FIFO_ENABLE_CLEAR 0x07 +#define MCTL_DTR_RTS_OUT2 0x0b +#define LST_TREG_EMPTY 0x20 + +static unsigned int iobase; + +static int setup_serial(void) +{ + switch(sdev) { + case 0: + iobase = UART1_BASE; + break; + case 1: + iobase = UART2_BASE; + break; + default: + sdev = -1; + return -1; + } + + /* set clock divisor */ + outp(iobase | UART_LCTL, LCTL_DLAB); + outp(iobase | UART_DIVLO, DIV_9600 & 0xff); + outp(iobase | UART_DIVHI, DIV_9600 >> 8); + /* set format 8n1 */ + outp(iobase | UART_LCTL, LCTL_8N1); + /* clear and enable fifo */ + outp(iobase | UART_FIFO, FIFO_ENABLE_CLEAR); + /* assert RTS and DTR */ + outp(iobase | UART_MCTL, MCTL_DTR_RTS_OUT2); + return 0; +} + +static void ser_putchar(int c) +{ + if(c == '\n') { + ser_putchar('\r'); + } + + while((inp(iobase | UART_LSTAT) & LST_TREG_EMPTY) == 0); + outp(iobase | UART_DATA, c); +} + +static void ser_puts(const char *s) +{ + while(*s) { + while((inp(iobase | UART_LSTAT) & LST_TREG_EMPTY) == 0); + if(*s == '\n') { + outp(iobase | UART_DATA, '\r'); + } + outp(iobase | UART_DATA, *s++); + } +} +#endif /* __DOS__ */