diff --git a/src/sbbs3/sbbsexec.c b/src/sbbs3/sbbsexec.c index 4beeed2d605c387cdf4f48697f6f52ada16b7299..be1c3f51738914e144cd12f7050438c5b1395f17 100644 --- a/src/sbbs3/sbbsexec.c +++ b/src/sbbs3/sbbsexec.c @@ -39,22 +39,37 @@ #define READ_TIMEOUT (30 * 1000) // X00REF.DOC "the timeout value is set to 30 seconds" /* UART Parameters and virtual registers */ -WORD uart_io_base = UART_COM1_IO_BASE; /* COM1 */ -BYTE uart_irq = UART_COM1_IRQ; -BYTE uart_ier_reg = 0; -BYTE uart_lcr_reg = UART_LCR_8_DATA_BITS; -BYTE uart_mcr_reg = UART_MCR_DTR; -BYTE uart_lsr_reg = UART_LSR_EMPTY_DATA | UART_LSR_EMPTY_XMIT; -BYTE uart_msr_reg = UART_MSR_CTS | UART_MSR_DSR; -BYTE uart_scratch_reg = 0; -BYTE uart_divisor_latch_lsb = 0x03; /* 38400 */ -BYTE uart_divisor_latch_msb = 0x00; -BYTE uart_fifo_enabled = 0; +struct uart { + WORD io_base; + BYTE irq; + BYTE ier_reg; + BYTE lcr_reg; + BYTE mcr_reg; + BYTE lsr_reg; + BYTE msr_reg; + BYTE scratch_reg; + BYTE divisor_latch_lsb; + BYTE divisor_latch_msb; + BYTE fifo_enabled; + BOOL virtualize; +} default_uart = { + .io_base = UART_COM1_IO_BASE, /* COM1 */ + .irq = UART_COM1_IRQ, + .ier_reg = 0, + .lcr_reg = UART_LCR_8_DATA_BITS, + .mcr_reg = UART_MCR_DTR, + .lsr_reg = UART_LSR_EMPTY_DATA | UART_LSR_EMPTY_XMIT, + .msr_reg = UART_MSR_CTS | UART_MSR_DSR, + .scratch_reg = 0, + .divisor_latch_lsb = 0x03, /* 38400 */ + .divisor_latch_msb = 0x00, + .fifo_enabled = 0, + .virtualize = FALSE +}, uart; // Notice: re-initialize global variables in VDDInitialize for NTVDMx64 and pre-Vista versions of Windows int log_level = LOG_INFO; -BOOL virtualize_uart=FALSE; double yield_interval=1.0; BOOL dcd_changed = FALSE; BOOL hangup_supported=TRUE; @@ -125,27 +140,27 @@ void parse_ini(char* program) else SAFEPRINTF(section,"%s.UART",program); - virtualize_uart=iniGetBool(ini,section,"Virtualize",virtualize_uart); + uart.virtualize=iniGetBool(ini,section,"Virtualize",uart.virtualize); switch(iniGetInteger(ini,section,"ComPort",0)) { case 1: /* COM1 */ - uart_irq =UART_COM1_IRQ; - uart_io_base =UART_COM1_IO_BASE; + uart.irq =UART_COM1_IRQ; + uart.io_base =UART_COM1_IO_BASE; break; case 2: /* COM2 */ - uart_irq =UART_COM2_IRQ; - uart_io_base =UART_COM2_IO_BASE; + uart.irq =UART_COM2_IRQ; + uart.io_base =UART_COM2_IO_BASE; break; case 3: /* COM3 */ - uart_irq =UART_COM3_IRQ; - uart_io_base =UART_COM3_IO_BASE; + uart.irq =UART_COM3_IRQ; + uart.io_base =UART_COM3_IO_BASE; break; case 4: /* COM4 */ - uart_irq =UART_COM4_IRQ; - uart_io_base =UART_COM4_IO_BASE; + uart.irq =UART_COM4_IRQ; + uart.io_base =UART_COM4_IO_BASE; break; } - uart_irq=(BYTE)iniGetShortInt(ini,section,"IRQ",uart_irq); - uart_io_base=iniGetShortInt(ini,section,"Address",uart_io_base); + uart.irq=(BYTE)iniGetShortInt(ini,section,"IRQ",uart.irq); + uart.io_base=iniGetShortInt(ini,section,"Address",uart.io_base); lprintf(LOG_INFO,"Parsed %s section of %s" ,section @@ -163,9 +178,9 @@ void set_interrupt_pending(BYTE intr, BOOL assert) lprintf(LOG_DEBUG,"%sasserting interrupt %02X (pending: %02X, IER: %02X)" ,assert ? "" : "de-", intr ,pending_interrupts - ,uart_ier_reg); + ,uart.ier_reg); if(assert) { - if(uart_ier_reg&intr) { /* is interrupt enabled? */ + if(uart.ier_reg&intr) { /* is interrupt enabled? */ pending_interrupts |= intr; /* flag as pending */ SetEvent(interrupt_event); } @@ -180,15 +195,15 @@ void set_interrupt_pending(BYTE intr, BOOL assert) void data_waiting(BOOL waiting) { - if(waiting && (uart_mcr_reg & UART_MCR_RTS)) { + if(waiting && (uart.mcr_reg & UART_MCR_RTS)) { /* Set the "Data ready" bit in the LSR */ - uart_lsr_reg |= UART_LSR_DATA_READY; + uart.lsr_reg |= UART_LSR_DATA_READY; /* assert rx data interrupt */ assert_interrupt(UART_IER_RX_DATA); } else { /* Clear the data ready bit in the LSR */ - uart_lsr_reg &= ~UART_LSR_DATA_READY; + uart.lsr_reg &= ~UART_LSR_DATA_READY; /* Clear data ready interrupt identification in IIR */ deassert_interrupt(UART_IER_RX_DATA); @@ -211,17 +226,17 @@ void _cdecl interrupt_thread(void *arg) lprintf(LOG_NOTICE, "Waiting for interrupt returned %ld", result); break; } - if((uart_ier_reg&pending_interrupts) != 0) { + if((uart.ier_reg&pending_interrupts) != 0) { lprintf(LOG_DEBUG,"VDDSimulateInterrupt (pending: %02X) - IER: %02X" - ,pending_interrupts, uart_ier_reg); - VDDSimulateInterrupt(ICA_MASTER, uart_irq, /* count: */1); + ,pending_interrupts, uart.ier_reg); + VDDSimulateInterrupt(ICA_MASTER, uart.irq, /* count: */1); } #if 0 /* "Real 16550s should always reassert * this interrupt whenever the transmitter is idle and * the interrupt is enabled." */ - if(pending_interrupts==0 && uart_ier_reg&UART_IER_TX_EMPTY) + if(pending_interrupts==0 && uart.ier_reg&UART_IER_TX_EMPTY) assert_interrupt(UART_IER_TX_EMPTY); #endif } @@ -257,7 +272,7 @@ void _cdecl input_thread(void* arg) } RingBufWrite(&rdbuf,buf,count); - if(virtualize_uart) { + if(uart.virtualize) { data_waiting(TRUE); } } @@ -325,15 +340,15 @@ static char *chr(uchar ch) VOID uart_wrport(WORD port, BYTE data) { - int reg = port - uart_io_base; + int reg = port - uart.io_base; int retval; lprintf(LOG_DEBUG,"write of port: %x (%s) <- %02X", port, uart_reg_desc[reg], data); switch(reg) { case UART_BASE: - if(uart_lcr_reg&UART_LCR_DLAB) { - uart_divisor_latch_lsb = data; + if(uart.lcr_reg&UART_LCR_DLAB) { + uart.divisor_latch_lsb = data; lprintf(LOG_DEBUG,"set divisor latch low byte: %02X", data); } else { // Transmitter Holding Register if(log_level >= LOG_DEBUG) @@ -348,32 +363,32 @@ VOID uart_wrport(WORD port, BYTE data) } break; case UART_IER: - if(uart_lcr_reg&UART_LCR_DLAB) { - uart_divisor_latch_msb = data; + if(uart.lcr_reg&UART_LCR_DLAB) { + uart.divisor_latch_msb = data; lprintf(LOG_DEBUG,"set divisor latch high byte: %02X", data); } else { - uart_ier_reg = data; + uart.ier_reg = data; lprintf(LOG_DEBUG, "Set IER to %02X", data); } assert_interrupt(UART_IER_TX_EMPTY); /* should this be re-asserted for all writes? */ break; case UART_FCR: - uart_fifo_enabled = data & UART_FCR_ENABLE_FIFO; + uart.fifo_enabled = data & UART_FCR_ENABLE_FIFO; lprintf(LOG_INFO, "Set FCR to %02X", data); break; case UART_LCR: - uart_lcr_reg = data; + uart.lcr_reg = data; lprintf(LOG_INFO, "Set LCR to %02X", data); break; case UART_MCR: - uart_mcr_reg = data; - if((uart_mcr_reg&UART_MCR_DTR) == 0) /* Dropping DTR (i.e. "hangup") */ + uart.mcr_reg = data; + if((uart.mcr_reg&UART_MCR_DTR) == 0) /* Dropping DTR (i.e. "hangup") */ hangup(); data_waiting(RingBufFull(&rdbuf)); lprintf(LOG_INFO, "Set MCR to %02X", data); break; case UART_SCRATCH: - uart_scratch_reg = data; + uart.scratch_reg = data; lprintf(LOG_INFO, "Set scratch register to %02X", data); break; default: @@ -385,16 +400,16 @@ VOID uart_wrport(WORD port, BYTE data) VOID uart_rdport(WORD port, PBYTE data) { - int reg = port - uart_io_base; + int reg = port - uart.io_base; DWORD avail; lprintf(LOG_DEBUG,"read of port: %x (%s)", port, uart_reg_desc[reg]); switch(reg) { case UART_BASE: - if(uart_lcr_reg&UART_LCR_DLAB) { + if(uart.lcr_reg&UART_LCR_DLAB) { lputs(LOG_DEBUG,"reading divisor latch LSB"); - *data = uart_divisor_latch_lsb; + *data = uart.divisor_latch_lsb; break; } if((avail=RingBufFull(&rdbuf))!=0) { @@ -407,11 +422,11 @@ VOID uart_rdport(WORD port, PBYTE data) data_waiting(avail); break; case UART_IER: - if(uart_lcr_reg&UART_LCR_DLAB) { + if(uart.lcr_reg&UART_LCR_DLAB) { lputs(LOG_DEBUG,"reading divisor latch MSB"); - *data = uart_divisor_latch_msb; + *data = uart.divisor_latch_msb; } else - *data = uart_ier_reg; + *data = uart.ier_reg; break; case UART_IIR: { @@ -432,42 +447,42 @@ VOID uart_rdport(WORD port, PBYTE data) *data = UART_IIR_NONE; if(pending_interrupts) SetEvent(interrupt_event); - if(uart_fifo_enabled) + if(uart.fifo_enabled) *data |= UART_IIR_FIFO_ENABLED; lprintf(LOG_DEBUG, "IIR: %02X (pending: %02X)", *data, pending_interrupts); break; } case UART_LCR: - *data = uart_lcr_reg; - lprintf(LOG_INFO, "LCR: %02X", uart_lcr_reg); + *data = uart.lcr_reg; + lprintf(LOG_INFO, "LCR: %02X", uart.lcr_reg); break; case UART_MCR: - *data = uart_mcr_reg; - lprintf(LOG_INFO, "MCR: %02X", uart_mcr_reg); + *data = uart.mcr_reg; + lprintf(LOG_INFO, "MCR: %02X", uart.mcr_reg); break; case UART_LSR: - *data = uart_lsr_reg; + *data = uart.lsr_reg; /* Clear line status interrupt pending */ deassert_interrupt(UART_IER_LINE_STATUS); lprintf(LOG_DEBUG, "LSR: %02X", *data); break; case UART_MSR: if(WaitForSingleObject(hungup_event,0)==WAIT_OBJECT_0) - uart_msr_reg &= ~UART_MSR_DCD; + uart.msr_reg &= ~UART_MSR_DCD; else - uart_msr_reg |= UART_MSR_DCD; + uart.msr_reg |= UART_MSR_DCD; if(dcd_changed) - uart_msr_reg |= UART_MSR_DCD_CHANGE; + uart.msr_reg |= UART_MSR_DCD_CHANGE; else - uart_msr_reg &= ~UART_MSR_DCD_CHANGE; + uart.msr_reg &= ~UART_MSR_DCD_CHANGE; dcd_changed = FALSE; - *data = uart_msr_reg; + *data = uart.msr_reg; /* Clear modem status interrupt pending */ deassert_interrupt(UART_IER_MODEM_STATUS); lprintf(LOG_DEBUG, "MSR: %02X", *data); break; case UART_SCRATCH: - *data = uart_scratch_reg; + *data = uart.scratch_reg; break; default: lprintf(LOG_ERR,"UNSUPPORTED register: %u", reg); @@ -589,14 +604,14 @@ __declspec(dllexport) void __cdecl VDDDispatch(void) lprintf(LOG_INFO,"Yield interval: %f milliseconds", yield_interval); - if(virtualize_uart) { + if(uart.virtualize) { lprintf(LOG_INFO,"Virtualizing UART (0x%x, IRQ %u)" - ,uart_io_base, uart_irq); + ,uart.io_base, uart.irq); IOHandlers.inb_handler = uart_rdport; IOHandlers.outb_handler = uart_wrport; - PortRange.First=uart_io_base; - PortRange.Last=uart_io_base + UART_IO_RANGE; + PortRange.First=uart.io_base; + PortRange.Last=uart.io_base + UART_IO_RANGE; VDDInstallIOHook((HANDLE)getAX(), 1, &PortRange, &IOHandlers); @@ -626,7 +641,7 @@ __declspec(dllexport) void __cdecl VDDDispatch(void) lprintf(LOG_INFO," read=%u bytes (in %u calls)",bytes_read,reads); lprintf(LOG_INFO," wrote=%u bytes (in %u calls)",bytes_written,writes); - if(virtualize_uart) { + if(uart.virtualize) { lputs(LOG_INFO,"Uninstalling Virtualizaed UART IO Hook"); VDDDeInstallIOHook((HANDLE)getAX(), 1, &PortRange); DeleteCriticalSection(&interrupt_mutex); @@ -857,7 +872,8 @@ __declspec(dllexport) void __cdecl VDDDispatch(void) case VDD_LOAD_INI_SECTION: /* Parse (program-specific) sub-section of settings file */ count = getCX(); p = (BYTE*)GetVDMPointer((ULONG)((getES() << 16)|getDI()) - ,count,FALSE); + ,count,FALSE); + lprintf(LOG_INFO, "LOAD_INI_SECTION: %s", p); parse_ini(p); break; @@ -873,7 +889,7 @@ __declspec(dllexport) void __cdecl VDDDispatch(void) break; case VDD_VIRTUALIZE_UART: - virtualize_uart = TRUE; + uart.virtualize = TRUE; break; default: @@ -886,6 +902,7 @@ __declspec(dllexport) void __cdecl VDDDispatch(void) __declspec(dllexport) BOOL __cdecl VDDInitialize(IN PVOID hVDD, IN ULONG Reason, IN PCONTEXT Context OPTIONAL) { + memcpy(&uart, &default_uart, sizeof(uart)); log_level = LOG_INFO; lputs(LOG_INFO, __FUNCTION__); return TRUE; diff --git a/src/vdmodem/vdmodem.c b/src/vdmodem/vdmodem.c index 934905e5e4abb27d841e6b194d2721fe115cbb23..ea5f9b38d7daa3a96a410205268d422943b744c1 100644 --- a/src/vdmodem/vdmodem.c +++ b/src/vdmodem/vdmodem.c @@ -34,6 +34,7 @@ #include "sockwrap.h" #include "telnet.h" #include "ini_file.h" +#include "vdd_func.h" #include "git_branch.h" #include "git_hash.h" @@ -62,7 +63,7 @@ struct { uint cmdlen; uchar cmd[64]; } telnet; - +unsigned int sbbsexec_mode = SBBSEXEC_MODE_UNSPECIFIED; #define XTRN_IO_BUF_LEN 10000 #define RING_DELAY 6000 /* US standard is 6 seconds */ @@ -75,6 +76,7 @@ struct { ulong data_rate; bool server_echo; char busy_notice[INI_MAX_VALUE_LEN]; + char answer_banner[INI_MAX_VALUE_LEN]; enum { ADDRESS_FAMILY_UNSPEC ,ADDRESS_FAMILY_INET @@ -107,6 +109,7 @@ void usage(const char* progname) "\t-l[addr] Listen for incoming TCP connections\n" "\t [on optionally-specified network interface]\n" "\t-p<port> Specify default TCP port number (decimal)\n" + "\t-n<node> Specify node number\n" "\t-d Enable debug output\n" "\t-h<sock> Specify socket descriptor/handle to use (decimal)\n" "\t-r<cps> Specify maximum receive data rate (chars/second)\n" @@ -168,6 +171,8 @@ ulong count_esc(struct modem* modem, uint8_t* buf, size_t rd) for(size_t i = 0; i < rd; i++) { if(buf[i] == modem->esc) count++; + else + return 0; } return count; } @@ -214,9 +219,9 @@ char* response(struct modem* modem, enum modem_response code) if(modem->quiet) return ""; if(modem->numeric_mode) - sprintf(str, "%u%c", code, modem->cr); + safe_snprintf(str, sizeof(str), "%u%c", code, modem->cr); else - sprintf(str, "%c%c%s%c%c", modem->cr, modem->lf, response_str[code], modem->cr, modem->lf); + safe_snprintf(str, sizeof(str), "%c%c%s%c%c", modem->cr, modem->lf, response_str[code], modem->cr, modem->lf); return str; } @@ -353,13 +358,18 @@ const char* protocol(enum mode mode) return "Raw"; } -int address_family() +int address_family(BOOL for_listen) { switch(cfg.address_family) { case ADDRESS_FAMILY_INET: return PF_INET; case ADDRESS_FAMILY_INET6: return PF_INET6; } - return PF_UNSPEC; + return for_listen ? PF_INET : PF_UNSPEC; +} + +int listen_address_family() +{ + return address_family(true); } int putcom(char* buf, size_t len) @@ -574,24 +584,19 @@ char* dial(struct modem* modem, const char* number) char* p = strrchr(host, ':'); char* b = strrchr(host, ']'); if(p != NULL && p > b) { - port = (uint16_t)strtol(p, &p, 10); + port = (uint16_t)strtol(p + 1, NULL, 10); *p = 0; } dprintf("Connecting to port %hu at host '%s' via %s", port, host, protocol(mode)); memset(&hints, 0, sizeof(hints)); - hints.ai_flags=PF_UNSPEC; - hints.ai_family=address_family(); + hints.ai_family = address_family(/* for listen: */false); hints.ai_socktype=SOCK_STREAM; hints.ai_protocol=IPPROTO_TCP; - hints.ai_flags=AI_NUMERICSERV; -#ifdef AI_ADDRCONFIG - hints.ai_flags|=AI_ADDRCONFIG; -#endif dprintf("%s %d calling getaddrinfo", __FILE__, __LINE__); SAFEPRINTF(portnum, "%hu", port); int result = getaddrinfo(host, portnum, &hints, &res); if(result != 0) { - dprintf("getaddrinfo(%s, %s) returned %d", host, portnum, result); + dprintf("getaddrinfo(%s, %s) [family=%d] returned %d", host, portnum, hints.ai_family, result); return response(modem, NO_ANSWER); } @@ -699,6 +704,7 @@ char* answer(struct modem* modem) /* Will suppress Go Ahead */ request_telnet_opt(TELNET_WILL,TELNET_SUP_GA); } + putcom(cfg.answer_banner, strlen(cfg.answer_banner)); return connected(modem); } @@ -725,17 +731,18 @@ char* atmodem_exec(struct modem* modem) return error(modem); if(*p == '=') { p++; - if(strcmp(p, "L") == 0) + if(stricmp(p, "L") == 0) p = modem->last; SAFECOPY(modem->save[val], p); return write_save(modem, val) ? ok(modem) : error(modem); } - if(*p == '?' || strcmp(p, "L?") == 0) { - if(strcmp(p, "L?") == 0) + if(*p == '?' || stricmp(p, "L?") == 0) { + if(stricmp(p, "L?") == 0) p = modem->last; else p = modem->save[val]; - sprintf(respbuf, "%c%s%c%c%s", modem->lf, p, modem->cr, modem->lf, ok(modem)); + safe_snprintf(respbuf, sizeof(respbuf), "%c%s%c%c%s" + ,modem->lf, p, modem->cr, modem->lf, ok(modem)); return respbuf; } } @@ -854,7 +861,8 @@ char* atmodem_exec(struct modem* modem) val = 0; break; } - sprintf(respbuf, "%c%03lu%c%c%s", modem->lf, val, modem->cr, modem->lf, ok(modem)); + safe_snprintf(respbuf, sizeof(respbuf), "%c%03lu%c%c%s" + ,modem->lf, val, modem->cr, modem->lf, ok(modem)); return respbuf; } else return error(modem); @@ -928,7 +936,7 @@ BOOL vdd_write(HANDLE* slot, uint8_t* buf, size_t buflen) { if(*slot == INVALID_HANDLE_VALUE) { char path[MAX_PATH + 1]; - sprintf(path, "\\\\.\\mailslot\\sbbsexec\\wr%d", cfg.node_num); + SAFEPRINTF(path, "\\\\.\\mailslot\\sbbsexec\\wr%d", cfg.node_num); *slot = CreateFile(path ,GENERIC_WRITE ,FILE_SHARE_READ @@ -1000,6 +1008,9 @@ bool read_ini(const char* ini_fname) const char* p = iniGetString(ini, ROOT_SECTION, "BusyNotice", NULL, value); if(p != NULL) SAFECOPY(cfg.busy_notice, p); + p = iniGetString(ini, ROOT_SECTION, "AnswerBanner", NULL, value); + if(p != NULL) + SAFECOPY(cfg.answer_banner, p); return true; } @@ -1008,7 +1019,7 @@ int main(int argc, char** argv) int argn = 1; char tmp[256]; char path[MAX_PATH + 1]; - char fullmodemline[MAX_PATH + 1]; + char fullcmdline[MAX_PATH + 1]; uint8_t buf[XTRN_IO_BUF_LEN]; uint8_t telnet_buf[sizeof(buf) * 2]; size_t rx_buflen = sizeof(buf); @@ -1025,10 +1036,12 @@ int main(int argc, char** argv) } // Default configuration values + mode = TELNET; cfg.server_echo = TRUE; cfg.port = IPPORT_TELNET; - cfg.address_family = ADDRESS_FAMILY_INET; + cfg.address_family = ADDRESS_FAMILY_UNSPEC; SAFECOPY(cfg.busy_notice, "\r\nSorry, not available right now\r\n"); + SAFEPRINTF(cfg.answer_banner, "\r\n" TITLE " v" VERSION " Copyright %s Rob Swindell\r\n", &__DATE__[7]); ini = strListInit(); GetModuleFileName(NULL, ini_fname, sizeof(ini_fname) - 1); @@ -1045,11 +1058,11 @@ int main(int argc, char** argv) break; while(*arg == '-') arg++; - if(strcmp(arg, "telnet") == 0) { + if(stricmp(arg, "telnet") == 0) { mode = TELNET; continue; } - if(strcmp(arg, "raw") == 0) { + if(stricmp(arg, "raw") == 0) { mode = RAW; continue; } @@ -1064,13 +1077,16 @@ int main(int argc, char** argv) cfg.listen = true; arg++; if(*arg != '\0') { - listening_interface.addr.sa_family = address_family(); + listening_interface.addr.sa_family = listen_address_family(); if(inet_ptoaddr(arg, &listening_interface, sizeof(listening_interface)) == NULL) { fprintf(stderr, "!Error parsing network address: %s", arg); return EXIT_FAILURE; } } break; + case 'n': + cfg.node_num = atoi(arg + 1); + break; case 'p': cfg.port = atoi(arg + 1); break; @@ -1092,9 +1108,19 @@ int main(int argc, char** argv) break; case 'B': rx_buflen = min(strtoul(arg + 1, NULL, 10), sizeof(buf)); + break; case 'R': rx_delay = strtoul(arg + 1, NULL, 10); break; + case 'I': + sbbsexec_mode |= SBBSEXEC_MODE_DOS_IN; + break; + case 'O': + sbbsexec_mode |= SBBSEXEC_MODE_DOS_OUT; + break; + case 'M': + sbbsexec_mode = strtoul(arg + 1, NULL, 0); + break; case 'V': fprintf(stdout, "%s/%s\n", GIT_BRANCH, GIT_HASH); return EXIT_SUCCESS; @@ -1114,13 +1140,13 @@ int main(int argc, char** argv) if(sock != INVALID_SOCKET) listening_sock = sock; else { - listening_sock = socket(PF_INET, SOCK_STREAM, IPPROTO_IP); + listening_sock = socket(listen_address_family(), SOCK_STREAM, IPPROTO_IP); if(listening_sock == INVALID_SOCKET) { fprintf(stderr, "Error %ld creating socket\n", WSAGetLastError()); return EXIT_FAILURE; } } - listening_interface.addr.sa_family = address_family(); + listening_interface.addr.sa_family = listen_address_family(); inet_setaddrport(&listening_interface, cfg.port); result = bind(listening_sock, &listening_interface.addr, xp_sockaddr_len(&listening_interface)); if(result != 0) { @@ -1156,7 +1182,7 @@ int main(int argc, char** argv) fclose(fp); while(1) { - sprintf(path, "\\\\.\\mailslot\\sbbsexec\\rd%d", cfg.node_num); + SAFEPRINTF(path, "\\\\.\\mailslot\\sbbsexec\\rd%d", cfg.node_num); rdslot = CreateMailslot(path ,sizeof(buf)/2 // Maximum message size (0=unlimited) ,0 // Read time-out @@ -1170,7 +1196,7 @@ int main(int argc, char** argv) ++cfg.node_num; } - sprintf(path, "sbbsexec_carrier%d", cfg.node_num); + SAFEPRINTF(path, "sbbsexec_carrier%d", cfg.node_num); carrier_event = CreateEvent( NULL // pointer to security attributes ,FALSE // flag for manual-reset event @@ -1182,7 +1208,7 @@ int main(int argc, char** argv) return EXIT_FAILURE; } - sprintf(path, "sbbsexec_hangup%d", cfg.node_num); + SAFEPRINTF(path, "sbbsexec_hangup%d", cfg.node_num); hangup_event = CreateEvent( NULL // pointer to security attributes ,FALSE // flag for manual-reset event @@ -1194,7 +1220,7 @@ int main(int argc, char** argv) return EXIT_FAILURE; } - sprintf(path, "sbbsexec_hungup%d", cfg.node_num); + SAFEPRINTF(path, "sbbsexec_hungup%d", cfg.node_num); hungup_event = CreateEvent( NULL // pointer to security attributes ,TRUE // flag for manual-reset event @@ -1211,12 +1237,13 @@ int main(int argc, char** argv) BOOL x64 = FALSE; IsWow64Process(GetCurrentProcess(), &x64); - sprintf(fullmodemline, "dosxtrn.exe %s %s %u %s", dropfile, x64 ? "x64" : "NT", cfg.node_num, ini_fname); + safe_snprintf(fullcmdline, sizeof(fullcmdline), "dosxtrn.exe %s %s %u %u %s" + ,dropfile, x64 ? "x64" : "NT", cfg.node_num, sbbsexec_mode, ini_fname); PROCESS_INFORMATION process_info; if(!CreateProcess( NULL, // pointer to name of executable module - fullmodemline, // pointer to command line string + fullcmdline, // pointer to command line string NULL, // process security attributes NULL, // thread security attributes FALSE, // handle inheritance flag @@ -1226,10 +1253,10 @@ int main(int argc, char** argv) &startup_info, // pointer to STARTUPINFO &process_info // pointer to PROCESS_INFORMATION )) { - fprintf(stderr, "Error %ld executing '%s'", GetLastError(), fullmodemline); + fprintf(stderr, "Error %ld executing '%s'", GetLastError(), fullcmdline); return EXIT_FAILURE; } - printf("Executed '%s' successfully\n", fullmodemline); + printf("Executed '%s' successfully\n", fullcmdline); CloseHandle(process_info.hThread); @@ -1322,6 +1349,7 @@ int main(int argc, char** argv) if(rd) { if(modem.online) { if(modem.esc_count) { + dprintf("Esc count = %d", modem.esc_count); if(modem.esc_count >= 3) modem.esc_count = 0; else { @@ -1332,8 +1360,10 @@ int main(int argc, char** argv) modem.esc_count = 0; } } else { - if(now - lasttx > guard_time(&modem)) + if(now - lasttx > guard_time(&modem)) { modem.esc_count = count_esc(&modem, buf, rd); + dprintf("New esc count = %d", modem.esc_count); + } } size_t len = rd; uint8_t* p = buf;