home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
PsL Monthly 1994 February
/
psl_9403.zip
/
psl_9403
/
DOS
/
COMMUNIC
/
COMM.ZIP
/
COMM.C
< prev
next >
Wrap
C/C++ Source or Header
|
1991-07-25
|
195KB
|
6,783 lines
/* COMM.C */
/* background communications program */
/* Copyright (c) 1989, 1991 Barry R. Nance */
#pragma inline
#include <stdio.h>
#include <dos.h>
#include <dir.h>
#include <mem.h>
#include <io.h>
#include <conio.h>
#include <bios.h>
#include <stdlib.h>
#include <string.h>
#include <stddef.h>
#include <stdarg.h>
#include <ctype.h>
#include "comm.h"
/* ------------------------------------------- */
char compliments[] = "BYTE Magazine--Software Corner Telecomm Pgm";
unsigned paragraphs;
unsigned temp1, temp2;
char crit_err_occurred = FALSE;
char critical_error = FALSE;
int i, j, k;
int c = 0;
int xc = 0;
char ch = 0;
struct date today;
unsigned old_ss, old_sp, our_ss, our_sp;
unsigned char kbd_code;
unsigned char prev_kbd_code;
unsigned char alt_menu = FALSE;
unsigned char use_alt = TRUE;
unsigned char function_id;
long far *sk_ptr1;
unsigned far *sk_ptr2;
char far *ourdta_ptr;
char far *olddta_ptr;
char far *our_mcb;
unsigned far *our_mcb_size;
char far *next_mcb;
unsigned far *next_mcb_owner;
unsigned ourpsp;
unsigned oldpsp;
int break_state;
void interrupt (*oldint08)(void);
void interrupt (*oldint09)(void);
void interrupt (*oldint10)(void);
void interrupt (*oldint13)(void);
void interrupt (*oldint16)(void);
void interrupt (*oldint1b)(void);
void interrupt (*oldint1c)(void);
void interrupt (*oldint21)(void);
void interrupt (*oldint23)(void);
void interrupt (*oldint24)(void);
void interrupt (*oldint28)(void);
void interrupt (*oldint0b)(void);
void interrupt (*oldint0c)(void);
void interrupt (*vectsave)(void);
void interrupt (*vecthold)(void);
char far *kbd_flag_ptr;
unsigned char far *prtsc_flag_ptr;
unsigned char far *indos_ptr;
unsigned char far *indos2_ptr;
volatile unsigned char in_int08 = FALSE;
volatile unsigned char in_int09 = FALSE;
volatile unsigned char in_int10 = FALSE;
volatile unsigned char in_int13 = FALSE;
volatile unsigned char in_int16 = FALSE;
volatile unsigned char in_int21 = FALSE;
volatile unsigned char in_int28 = FALSE;
volatile unsigned char in_popup = FALSE;
volatile unsigned char in_background = FALSE;
volatile unsigned char pass_through = FALSE;
volatile unsigned char hot_flag = FALSE;
volatile unsigned char leave_flag = FALSE;
volatile unsigned char de_install = FALSE;
unsigned char first_time = TRUE;
unsigned char first_menu_appearance = TRUE;
unsigned char call_in_progress= FALSE;
unsigned char use_carrier = TRUE;
volatile long tick_counter = 0l;
volatile long next_fg_slice = 0l;
volatile long next_bg_slice = 0l;
volatile long timeout_ticks = 0l;
volatile long timeout_value = 0l;
volatile long commit_ticks = 0l;
unsigned int xtimeout = 2;
long xticks = 0;
unsigned int foreground_ticks = 8;
unsigned int background_ticks = 3;
unsigned int dial_wait_secs = 30;
unsigned int break_milliseconds = 250;
int handle = 0;
int io_len = 0;
unsigned int fbufndx = 2000;
unsigned int fbufbytes = 0;
int config_error = 0;
int dial_error = 0;
char *config_msg[18] = {
"file not found",
"reg. fg. color",
"reg. bg. color",
"msg. fg. color",
"msg. bg. color",
"comm. port #",
"baud rate",
"data bits",
"parity",
"stop bits",
"echo toggle",
"break ticks",
"foreg ticks",
"backg ticks",
"dial wait",
"init menu",
"xmodem timeout",
"macro def."
};
char *dial_msg[10] = {
"parms",
"name",
"number",
"baudrate",
"data bits",
"parity",
"stop bits",
"echo flag",
"flow ctrl",
"add lf"
};
char string1[LINE_LENGTH];
char string2[LINE_LENGTH];
char string3[LINE_LENGTH];
char holdstr[LINE_LENGTH];
char kbd_macro1[LINE_LENGTH];
char kbd_macro2[LINE_LENGTH];
char kbd_macro3[LINE_LENGTH];
char kbd_macro4[LINE_LENGTH];
char kbd_macro5[LINE_LENGTH];
char kbd_macro6[LINE_LENGTH];
char kbd_macro7[LINE_LENGTH];
char kbd_macro8[LINE_LENGTH];
char kbd_macro9[LINE_LENGTH];
char *kbd_macro_list[9] = {
kbd_macro1,
kbd_macro2,
kbd_macro3,
kbd_macro4,
kbd_macro5,
kbd_macro6,
kbd_macro7,
kbd_macro8,
kbd_macro9
};
char *line_ptrs[MAX_LINES];
int line_sub = 0;
int curr_line = 0;
int disp_line = 0;
unsigned char reg_fg = WHITE;
unsigned char reg_bg = BLUE;
unsigned char msg_fg = BLACK;
unsigned char msg_bg = CYAN;
unsigned int our_port = 1;
unsigned int our_speed = 1200;
int our_par = EV_PAR;
int our_bits = 7;
int our_stop = 1;
unsigned char term_type = 1;
unsigned char term_type_save = 1;
int top_chat_x = 1;
int top_chat_y = 1;
int bottom_chat_x = 1;
int bottom_chat_y = 1;
int bottom_line = 25;
unsigned char screen_is_clear = TRUE;
unsigned char switch_to_chat = FALSE;
unsigned char switch_from_chat= FALSE;
unsigned char auto_answer = FALSE;
unsigned char set_answer = FALSE;
char phone_number[30] = "";
int dial_count = 0;
char phone_num1 [81] = " ";
char phone_num2 [81] = " ";
char phone_num3 [81] = " ";
char phone_num4 [81] = " ";
char phone_num5 [81] = " ";
char phone_num6 [81] = " ";
char phone_num7 [81] = " ";
char phone_num8 [81] = " ";
char phone_num9 [81] = " ";
char phone_num10[81] = " ";
char *phone_list[10] = {
phone_num1,
phone_num2,
phone_num3,
phone_num4,
phone_num5,
phone_num6,
phone_num7,
phone_num8,
phone_num9,
phone_num10
};
char no_carrier_msg [21] = "NO CARRIER";
char phone_busy [21] = "BUSY";
char dial_cmd [21] = "ATD";
char modem_init [51] = "";
char modem_ok [21] = "OK";
char modem_error[21] = "ERROR";
char hangup [51] = "~+++~~ATH~|";
char connect_msg[21] = "CONNECT";
char answer_on [21] = "~ATS0=1~|";
char answer_off [21] = "~ATS0=0~|";
int sticky_menu = 1;
int curr_item, old_item;
unsigned char dont_redraw = FALSE;
int item_recall[6] = {0, 0, 0, 0, 0, 0};
char *dial_menu [13] = {
" Phone Number 1 ",
" Phone Number 2 ",
" Phone Number 3 ",
" Phone Number 4 ",
" Phone Number 5 ",
" Phone Number 6 ",
" Phone Number 7 ",
" Phone Number 8 ",
" Phone Number 9 ",
" Phone Number 10 ",
" Manual Dial ",
" Load Phone Directory ",
" Hang Up "
};
char *file_menu [9] = {
" XModem Receive ",
" YModem Receive ",
" Kermit Receive ",
" Ascii Receive ",
" XModem Send ",
" YModem Send ",
" Kermit Send ",
" Ascii Send ",
" Capture xxx "
};
char *term_menu [2] = {
" Normal ",
" Split (Chat) "
};
char *modem_menu [9] = {
" Comm. Port x ",
" Baud Rate xxxxx ",
" Data Bits x ",
" Parity xxxx ",
" Stop Bits x ",
" Local Echo xxx ",
" XON/XOFF xxx ",
" Add LineFeeds xxx ",
" Auto Answer xxx "
};
char *exit_menu[2] = {
" Stay Ready ",
" Unload "
};
char *help_menu [7] = {
" General ",
" Dialing ",
" Sending Files ",
" Receiving ",
" Configuration ",
" Modem Control ",
" Scrolling "
};
char *xfr_box [3] = {
"┌───────────────────────────────────────┐",
"│ │",
"└───────────────────────────────────────┘"
};
char *ascii_box [3] = {
"┌──────────────────────────────────────────────────────────────────────────────┐",
"│ │",
"└──────────────────────────────────────────────────────────────────────────────┘"
};
int oldx, oldy, did_ascii_xfr;
unsigned char key_char;
unsigned char extended_char;
unsigned char curr_row, curr_col;
unsigned char capturing = FALSE;
int capture_handle = -1;
int last_char = 0;
volatile unsigned char transferring_file = FALSE;
volatile unsigned char stats_in_progress = FALSE;
volatile unsigned char transfer_init = FALSE;
volatile unsigned char transfer_type = NO_TRANSFER;
unsigned char break_flag = FALSE;
char bs_str[4] = {BS, ' ', BS, 0};
char spaces[5] = " ";
volatile int tail = 0;
volatile int head = 0;
volatile int out_head = 0;
volatile int out_tail = 0;
volatile unsigned char output_queue_empty = TRUE;
unsigned char iir_val = 0;
int gap1 = 0;
int gap2 = 0;
int gap3 = 0;
unsigned char flow_control = FALSE;
unsigned char busy = FALSE;
long timeout = 0l;
int port_base= 0;
int port_id = 0;
unsigned int speedsave;
int paritysave, bitssave, stop_bitsave;
int old_parity, old_bits, old_stop;
unsigned char re_open_flag= FALSE;
unsigned char flag_save = FALSE;
unsigned char echo_flag = FALSE;
unsigned char crlf_for_cr = FALSE;
unsigned char send_crlf = FALSE;
unsigned int char_delay = 0;
unsigned int line_delay = 0;
int THR = 0;
int IER = 0;
int IIR = 0;
int LCR = 0;
int MCR = 0;
int LSR = 0;
int MSR = 0;
int DLAB_LO = 0;
int DLAB_HI = 0;
int app_cursor_save;
int app_cursor_type;
int our_cursor_save;
int our_cursor_type;
unsigned vidmode;
unsigned char curr_vid_mode;
char app_screen [4000];
char our_screen [4000];
int transfer_handle;
char filename[50] = "";
unsigned int x_index;
int eot_processed;
char nak_char;
char soh_char;
char prev_char;
unsigned char chksum;
unsigned int crc;
unsigned int xfr_size;
volatile unsigned char xfr_abort = FALSE;
volatile unsigned char user_abort = FALSE;
unsigned char EOF_flag = FALSE;
unsigned char waiting_for_1st_nak = FALSE;
volatile unsigned blocks_to_send;
volatile unsigned errors_this_block;
volatile unsigned error_count;
volatile unsigned block_count;
volatile unsigned long byte_count;
volatile unsigned long file_bytes;
unsigned short crctab[256] = {
0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7,
0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef,
0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6,
0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de,
0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485,
0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d,
0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4,
0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc,
0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823,
0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b,
0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12,
0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a,
0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41,
0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49,
0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70,
0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78,
0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f,
0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067,
0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e,
0x02b1, 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256,
0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d,
0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c,
0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634,
0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab,
0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3,
0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a,
0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92,
0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9,
0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1,
0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8,
0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0
};
#define updcrc(crc,ch) (crctab[((crc >> 8) & 0xFF)] ^ (crc << 8) ^ ch)
char xmodem_area[1024+1+2+2];
char modem_buff[SBUFSIZ];
char outbuff[OBUFSIZ];
unsigned *our_stack;
/* -------------------------------------------------- */
/*
*
* Kermit stuff
*
*/
/* Symbol Definitions */
#define MAXPACKSIZ 94 /* Maximum packet size */
#define SP 32 /* ASCII space */
#define DEL 127 /* Delete (rubout) */
#define ESCCHR '^' /* Default escape character for CONNECT */
#define MAXTRY 10 /* Times to retry a packet */
#define MYQUOTE '#' /* Quote character I will use */
#define MYPAD 0 /* Number of padding characters I will need */
#define MYPCHAR 0 /* Padding character I need (NULL) */
#define MYEOL '\n' /* End-Of-Line character I need */
#define MYTIME 10 /* Seconds after which I should be timed out */
#define MAXTIM 60 /* Maximum timeout interval */
#define MINTIM 2 /* Minumum timeout interval */
/* Macro Definitions */
/*
* tochar: converts a control character to a printable one by adding a space.
*
* unchar: undoes tochar.
*
* ctl: converts between control characters and printable characters by
* toggling the control bit (ie. ^A becomes A and A becomes ^A).
*/
#define tochar(ch) ((ch) + ' ')
#define unchar(ch) ((ch) - ' ')
#define ctl(ch) ((ch) ^ 64 )
int _sizedata, /* Size of present data */
_spsiz, /* Maximum send packet size */
_pad, /* How much padding to send */
_packnum, /* Packet number */
_oldtry, /* Times previous packet retried */
_times_up, /* Timeout signal to 'rpack()' */
_remote, /* -1 means we're a _remote kermit */
_image, /* -1 means 8-bit mode */
_timint, /* Timeout for foreign host on sends */
_filnamcnv, /* -1 means do file name case conversions */
_filecount, /* Number of files left to send */
rpack_done; /* True if 'rpack()' did a complete packet */
char _state, /* Present state of the automaton */
_padchar, /* Padding character to send */
_eol, /* End-Of-Line character to send */
_escchr, /* Connect command escape character */
_quote, /* Quote character in incoming data */
**_filelist, /* List of files to be sent */
kermit_path[80], /* drive:\directory\ for receive */
_recpkt[101], /* Receive packet buffer */
_packet[101]; /* Packet buffer */
char *name_area;
char *name_ptrs[25];
/* mouse stuff */
unsigned char mouse_exists = FALSE;
unsigned char mouse_shared = FALSE;
int num_buttons = 0;
int mouse_menu_x = 0;
unsigned mouse_status = 0;
unsigned mouse_column = 0;
unsigned mouse_row = 0;
unsigned left_button_x = 0;
unsigned left_button_y = 0;
unsigned mouse_x_save = 39;
unsigned mouse_y_save = 12;
/* -------------------------------- */
int DosCancel(void)
{
critical_error = FALSE;
if (!in_popup)
return TRUE;
beep();
delay(100);
beep();
ask_yn("I/O error! Cancel the file activity?");
if (key_char == 'y')
return TRUE;
return FALSE;
}
int DosOpen(char *name, unsigned char mode)
{
retry_open:
crit_err_occurred = FALSE;
_DX = (unsigned) name;
_AL = mode;
_AH = 0x3D;
geninterrupt(0x21);
temp1 = _AX;
asm pushf
asm pop temp2
if (critical_error)
{
if (!DosCancel()) goto retry_open;
crit_err_occurred = TRUE;
return -1;
}
if ( (temp2 & 0x0001) == 0x0001 )
return -1;
return temp1;
}
int DosRead(int handle, char *buffer, unsigned count)
{
retry_read:
_DX = (unsigned) buffer;
_CX = count;
_BX = handle;
_AH = 0x3F;
geninterrupt(0x21);
temp1 = _AX;
asm pushf
asm pop temp2
if (critical_error)
{
if (!DosCancel()) goto retry_read;
return -1;
}
if ( (temp2 & 0x0001) == 0x0001 )
return -1;
return temp1;
}
int DosWrite(int handle, char *buffer, unsigned count)
{
retry_write:
_DX = (unsigned) buffer;
_CX = count;
_BX = handle;
_AH = 0x40;
geninterrupt(0x21);
temp1 = _AX;
asm pushf
asm pop temp2
if (critical_error)
{
if (!DosCancel()) goto retry_write;
return -1;
}
if ( (temp2 & 0x0001) == 0x0001
|| temp1 != count )
return -1;
return temp1;
}
int DosCreate(char *name)
{
retry_create:
crit_err_occurred = FALSE;
_DX = (unsigned) name;
_CX = 0;
_AH = 0x3C;
geninterrupt(0x21);
temp1 = _AX;
asm pushf
asm pop temp2
if (critical_error)
{
if (!DosCancel()) goto retry_create;
crit_err_occurred = TRUE;
return -1;
}
if ( (temp2 & 0x0001) == 0x0001)
return -1;
return temp1;
}
int DosClose(int handle)
{
_BX = handle;
_AH = 0x3E;
geninterrupt(0x21);
critical_error = FALSE;
return 0;
}
void DosSeekEOF(unsigned handle)
{
_CX = 0;
_DX = 0;
_BX = handle;
_AX = 0x4202;
geninterrupt(0x21);
}
void DosSeekBackOne(unsigned handle)
{
_CX = 0;
_DX = 0;
_BX = handle;
_AX = 0x4202;
geninterrupt(0x21);
_CX = _DX;
_DX = _AX - 1;
_BX = handle;
_AX = 0x4200;
geninterrupt(0x21);
}
/* ------------------------------------ */
void mouse_init(void)
{
void far * far *iv;
iv = MK_FP(0x0000, 0x00CC);
if (FP_SEG(*iv) == 0x0000)
{
mouse_exists = 0;
num_buttons = 0;
}
else
{
_AX = 0;
geninterrupt(0x33);
mouse_exists = _AX;
num_buttons = _BX;
}
}
void show_mouse (void)
{
_AX = 1;
geninterrupt(0x33);
}
void hide_mouse (void)
{
_AX = 2;
geninterrupt(0x33);
}
void get_mouse (void)
{
unsigned b, c, d;
_AX = 3;
geninterrupt(0x33);
b = _BX;
c = _CX;
d = _DX;
mouse_status = b;
mouse_column = (c / 8) + 1;
mouse_row = (d / 8) + 1;
}
void move_mouse (int new_col, int new_row)
{
unsigned a, c, d;
a = 4;
c = (new_col - 1) * 8;
d = (new_row - 1) * 8;
_AX = a;
_CX = c;
_DX = d;
geninterrupt(0x33);
}
int left_button_down(void)
{
unsigned b, c, d;
_AX = 3;
geninterrupt(0x33);
b = _BX; c = _CX; d = _DX;
left_button_x = (c / 8) + 1;
left_button_y = (d / 8) + 1;
if ( (b & 0x01) == 0x01) return TRUE;
return FALSE;
}
int left_button_up(void)
{
unsigned b, c, d;
_AX = 6;
_BX = 0;
geninterrupt(0x33);
b = _BX; c = _CX; d = _DX;
left_button_x = (c / 8) + 1;
left_button_y = (d / 8) + 1;
if (b > 0) return TRUE;
return FALSE;
}
int right_button_up(void)
{
unsigned b;
_AX = 6;
_BX = 1;
geninterrupt(0x33);
b = _BX;
if (b > 0) return TRUE;
return FALSE;
}
/* -------------------------------------------------- */
void interrupt com_int (void)
{
enable();
_DX = inportb (LSR); /* clear error conditions */
get_int_id:
iir_val = inportb (IIR);
/*******************************************
* if ( (iir_val & 0x01) == 0x01 )
* goto do_eoi;
******************************************/
if ( (iir_val & 0x04) == 0x04 )
goto handle_rdr;
if ( (iir_val & 0x02) == 0x02 )
goto handle_thre;
goto do_eoi;
handle_thre:
disable();
if (out_head == out_tail)
{
output_queue_empty = TRUE;
enable();
goto get_int_id;
}
outportb(THR, outbuff[out_tail]);
if (++out_tail == OBUFSIZ)
out_tail = 0;
enable();
goto get_int_id;
handle_rdr:
modem_buff[head] = inportb (THR);
if (++head == SBUFSIZ)
head = 0;
modem_buff[head] = 0;
if (!flow_control || busy || transfer_type > 10)
goto get_int_id;
gap1 = (head<tail) ? (SBUFSIZ-tail)+head : head-tail;
if (gap1 < HWM)
goto get_int_id;
busy = TRUE;
timeout = 0x000fffffl;
while ( (inportb(LSR) & 0x20) == 0 && --timeout > 0l )
;
disable ();
outportb(THR, XOFF);
enable ();
goto get_int_id;
do_eoi:
outportb (ICR, EOI);
}
/* -------------------------------- */
int get_modem(void)
{
int res, x;
if (transfer_type > 10)
{
if (tail == head) return (-1);
res = (int) modem_buff[tail];
if (++tail == SBUFSIZ) tail = 0;
return(res);
}
if (crlf_for_cr && last_char == CR)
{
res = LINEFEED;
}
else
{
if (tail == head) return (-1);
res = (int) modem_buff[tail];
if (++tail == SBUFSIZ) tail = 0;
}
if (capturing)
{
ch = (unsigned char) res;
if (ch >= 32
|| ch == LINEFEED || ch == FORMFEED || ch == CR)
io_len = DosWrite(capture_handle, &ch, 1);
else
if (ch == TAB)
io_len = DosWrite(capture_handle, spaces, 4);
else
if (ch == BS)
DosSeekBackOne(capture_handle);
else
goto save_last_char;
if (io_len == -1)
{
capturing = FALSE;
}
}
save_last_char:
last_char = res;
if ( res == LINEFEED
|| (wherex() == 79 && res != CR && res != BS) )
{
line_ptrs[line_sub] = &modem_buff[tail];
if (tail > SBUFSIZ - 100 || line_sub == MAX_LINES - 2)
{
for (x=0; x<MAX_LINES; x++)
line_ptrs[x] = line_ptrs[x+1];
--line_sub;
}
curr_line = disp_line = line_sub;
line_ptrs[++line_sub] = NULL;
}
if (strlen(holdstr) < LINE_LENGTH - 1)
holdstr[strlen(holdstr)] = (char) res;
else
{
for (i=0; i<LINE_LENGTH; i++)
holdstr[i] = holdstr[i+1];
holdstr[LINE_LENGTH - 1] = (char) res;
}
if (!busy) goto get_modem_exit;
gap2 = (head<tail) ? (SBUFSIZ-tail)+head : head-tail;
if (gap2 > LWM)
goto get_modem_exit;
timeout = 0x000fffffl;
while ( (inportb(LSR) & 0x20) == 0 && --timeout > 0l )
;
disable ();
outportb(THR, XON);
enable ();
busy = FALSE;
get_modem_exit:
return (res);
}
void purge_buffer(void)
{
delay(1000);
while ( (get_modem()) != -1 )
;
}
void send_break(void)
{
c = inportb(LCR);
outportb(LCR, (c | 0x40));
delay(break_milliseconds);
outportb(LCR, c);
break_flag = FALSE;
}
void com_enable (void)
{
switch (port_id)
{
case 1 :
{
setvect(0x0c, com_int);
vectsave = getvect(0x0c);
c = inportb(IMR) & IRQ4;
break;
}
case 2 :
{
setvect(0x0b, com_int);
vectsave = getvect(0x0b);
c = inportb(IMR) & IRQ3;
break;
}
case 3 :
{
setvect(0x0c, com_int);
vectsave = getvect(0x0c);
c = inportb(IMR) & IRQ4;
break;
}
case 4 :
{
setvect(0x0b, com_int);
vectsave = getvect(0x0b);
c = inportb(IMR) & IRQ3;
break;
}
default : break;
}
disable();
outportb(IER, RX_INT);
outportb(MCR, RTS | DTR | OUT2);
outportb(IMR, c);
enable();
}
void drop_dtr(void)
{
outportb(MCR, 0);
delay(250);
outportb(MCR, RTS | DTR | OUT2);
}
void close_port(void)
{
disable();
c = inportb(IMR);
outportb(MCR, 0);
outportb(IER, 0);
switch (port_id)
{
case 1 : c |= ~IRQ4; setvect(0x0c, oldint0c); break;
case 2 : c |= ~IRQ3; setvect(0x0b, oldint0b); break;
case 3 : c |= ~IRQ4; setvect(0x0c, oldint0c); break;
case 4 : c |= ~IRQ3; setvect(0x0b, oldint0b); break;
default: break;
}
outportb(IMR, c);
enable();
vectsave = NULL;
port_id = 0;
}
void send_char (char x)
{
do
gap3 = (out_head<out_tail)?
(OBUFSIZ-out_tail)+out_head : out_head-out_tail;
while (gap3 > (OBUFSIZ / 4) * 3);
if (echo_flag && transfer_type < 10 && x != XON && x != XOFF)
{
disable();
modem_buff[head] = x;
if (++head == SBUFSIZ)
head = 0;
modem_buff[head] = 0;
enable();
}
disable();
if (output_queue_empty)
{
outportb(THR, x);
output_queue_empty = FALSE;
enable();
return;
}
outbuff [out_head] = x;
if (++out_head == OBUFSIZ)
out_head = 0;
enable ();
}
void send_string (char *s)
{
while (*s)
{
if (*s == '~')
delay(950);
else
if (*s == '|')
send_char(CR);
else
send_char(*s);
delay(10);
s++;
}
}
int carrier(void)
{
if (!use_carrier) return call_in_progress;
inportb(MSR);
return ( (int) ( (inportb(MSR) >> 7) & 0x01) );
}
int set_port (int port)
{
int far *RS232_addr;
switch (port)
{
case 1 : RS232_addr=MK_FP(0x0040, 0);
port_base = *RS232_addr;
break;
case 2 : RS232_addr=MK_FP(0x0040, 2);
port_base = *RS232_addr;
break;
case 3 : port_base = 0x03E8;
break;
case 4 : port_base = 0x02E8;
break;
default : return (-1);
}
if (port < 3 && *RS232_addr == 0)
return (-1);
port_id = port;
THR = port_base;
IER = port_base + 1;
IIR = port_base + 2;
LCR = port_base + 3;
MCR = port_base + 4;
LSR = port_base + 5;
MSR = port_base + 6;
DLAB_HI = port_base + 1;
DLAB_LO = port_base;
inportb(THR);
inportb(LSR);
return (0);
}
int set_speed (unsigned int speed)
{
char c;
unsigned divisor;
if (speed < 1 || speed > MAX_BAUD) return (-1);
divisor = (unsigned) (115200l/speed);
disable ();
c=inportb (LCR);
outportb (LCR, (c | 0x80));
outportb (DLAB_LO, (divisor & 0x00ff));
outportb (DLAB_HI, ((divisor>>8) & 0x00ff));
outportb (LCR, c);
enable();
speedsave = speed;
return (0);
}
int set_parms (int parity, int bits, int stop_bit)
{
int temp;
if ((parity < NO_PAR) || (parity > OD_PAR)) return (-1);
if ((bits < 5) || (bits > 8)) return (-1);
if ((stop_bit < 1) || (stop_bit > 2)) return (-1);
temp = bits - 5;
temp|= ((stop_bit == 1) ? 0x00 : 0x04);
switch (parity)
{
case NO_PAR : temp |= 0x00; break;
case OD_PAR : temp |= 0x08; break;
case EV_PAR : temp |= 0x18; break;
}
disable();
outportb (LCR, temp);
enable();
paritysave = parity;
bitssave = bits;
stop_bitsave = stop_bit;
return (0);
}
int open_port(int port,unsigned speed,int parity,int bits,int stop_bit)
{
if (set_port(port) == -1) return(-1);
if (set_speed(speed) == -1) return(-1);
if (set_parms(parity, bits, stop_bit) == -1) return (-1);
com_enable();
return (0);
}
/* -------------------------------------------------- */
int sk_loaded(void)
{
asm mov ax, 0
asm mov es, ax
asm mov bx, 0020h
asm mov dx, word ptr es:[bx]
asm mov cx, word ptr es:[bx+2]
asm sub dx, 4
sk_ptr1 = MK_FP(_CX, _DX);
if (*sk_ptr1 == 0x49424b53l) return TRUE;
asm mov ax, 0
asm mov es, ax
asm mov bx, 0020h
asm mov dx, word ptr es:[bx]
asm mov cx, word ptr es:[bx+2]
asm sub dx, 2
sk_ptr2 = MK_FP(_CX, _DX);
if (*sk_ptr2 == 0x4b53) return TRUE;
return FALSE;
}
void interrupt int08(void)
{
in_int08 = TRUE;
oldint08();
tick_counter++;
enable();
if (!hot_flag && !de_install && !transferring_file)
goto exit08;
if (in_int09 || in_int10 || in_int13 || in_int16 || in_int28)
goto exit08;
if (*indos_ptr != 0)
goto exit08;
if (*indos2_ptr != 0)
goto exit08;
if (*prtsc_flag_ptr == 1)
goto exit08;
outportb(0x20, 0x0b);
if (inportb(0x20)) goto exit08;
if ( (hot_flag || de_install) && !in_popup && !in_background)
{
in_popup = TRUE;
do_popup();
in_popup = FALSE;
}
else
if (transferring_file && !in_background && !in_popup)
{
in_background = TRUE;
do_transfer();
in_background = FALSE;
}
exit08:
in_int08 = FALSE;
}
void interrupt int09 (void)
{
in_int09 = TRUE;
kbd_code = inportb(0x60);
oldint09();
enable();
if (use_alt)
if (kbd_code == (ALT | 0x80))
if (prev_kbd_code == ALT)
if (in_popup)
alt_menu = TRUE;
if (kbd_code != 0 && kbd_code != 0xE0)
prev_kbd_code = kbd_code;
if ( (*kbd_flag_ptr & 0x09) == 0x09 )
{
de_install = FALSE;
hot_flag = TRUE;
goto int09_exit;
}
int09_exit:
in_int09 = FALSE;
}
void interrupt int10(unsigned bp,
unsigned di,
unsigned si,
unsigned ds,
unsigned es,
unsigned dx,
unsigned cx,
unsigned bx,
unsigned ax,
unsigned ip,
unsigned cs,
unsigned flags)
{
in_int10 = TRUE;
enable();
asm push ds
_DS = ds;
_AX = ax;
asm push bp
asm pushf
asm cli
asm call dword ptr cs:[0004h]
asm pop bp
asm pushf
asm pop flags
ax = _AX;
bx = _BX;
cx = _CX;
dx = _DX;
si = _SI;
di = _DI;
es = _ES;
ds = _DS;
asm pop ds
in_int10 = FALSE;
}
void interrupt int13(unsigned bp,
unsigned di,
unsigned si,
unsigned ds,
unsigned es,
unsigned dx,
unsigned cx,
unsigned bx,
unsigned ax,
unsigned ip,
unsigned cs,
unsigned flags)
{
in_int13 = TRUE;
enable();
asm push ds
_DS = ds;
_AX = ax;
asm push bp
asm pushf
asm cli
asm call dword ptr cs:[0008h]
asm pop bp
asm pushf
asm pop flags
ax = _AX;
bx = _BX;
cx = _CX;
dx = _DX;
si = _SI;
di = _DI;
es = _ES;
ds = _DS;
asm pop ds
in_int13 = FALSE;
}
void interrupt int16(unsigned bp,
unsigned di,
unsigned si,
unsigned ds,
unsigned es,
unsigned dx,
unsigned cx,
unsigned bx,
unsigned ax,
unsigned ip,
unsigned cs,
unsigned flags)
{
unsigned temp_ax;
unsigned char temp_ah;
in_int16 = TRUE;
enable();
temp_ax = _AX;
temp_ah = _AH;
if (temp_ax == 'SN')
{
ax = 'sn';
goto int16_exit;
}
if (in_popup)
goto do_old16;
if (temp_ah != 0)
goto do_old16;
wait_for_key:
_AH = 1;
oldint16();
asm jz popup_16
goto do_old16;
popup_16:
if (!hot_flag && !de_install && !transferring_file)
goto wait_for_key;
if (in_int09 || in_int10 || in_int13 || in_int08 || in_int28)
goto wait_for_key;
if (*indos_ptr != 0)
goto wait_for_key;
if (*indos2_ptr != 0)
goto wait_for_key;
if (*prtsc_flag_ptr == 1)
goto wait_for_key;
outportb(0x20, 0x0b);
if (inportb(0x20)) goto wait_for_key;
if ( (hot_flag || de_install) && !in_popup && !in_background)
{
in_popup = TRUE;
do_popup();
in_popup = FALSE;
}
else
if (transferring_file && !in_background && !in_popup)
{
in_background = TRUE;
do_transfer();
in_background = FALSE;
}
goto wait_for_key;
do_old16:
_AX = temp_ax;
oldint16();
asm pushf
asm pop flags
ax = _AX;
bx = _BX;
cx = _CX;
dx = _DX;
int16_exit:
in_int16 = FALSE;
}
void interrupt int1b (void)
{
enable();
break_flag = TRUE;
}
void interrupt int1c (void)
{
enable();
}
void interrupt int21(unsigned bp,
unsigned di,
unsigned si,
unsigned ds,
unsigned es,
unsigned dx,
unsigned cx,
unsigned bx,
unsigned ax,
unsigned ip,
unsigned cs,
unsigned flags)
{
enable();
function_id = _AH;
if ( function_id != 0x00
&& function_id != 0x31
&& function_id != 0x4b
&& function_id != 0x4c
&& function_id != 0x44
&& function_id != 0x2f
&& function_id != 0x1a)
goto carry_on;
skip_out:
asm mov sp, bp
asm pop bp
asm pop di
asm pop si
asm pop ds
asm pop es
asm pop dx
asm pop cx
asm pop bx
asm pop ax
/* jmp dword ptr cs:[0] */
asm db 02eh,0ffh,02eh,0000h,000h
carry_on:
if (!sk_loaded() || *indos2_ptr == 0)
goto skip_out;
if (*indos_ptr == 0)
in_int21 = FALSE;
if (in_popup || in_int21)
{
pass_through = TRUE;
goto do_the_call;
}
in_int21 = TRUE;
invoke_dos:
if ( function_id != 0x01
&& function_id != 0x07
&& function_id != 0x08
&& function_id != 0x0a
&& function_id != 0x0c)
goto do_the_call;
wait_for_dos_key:
_AH = 0x0b;
asm pushf
asm cli
asm call dword ptr cs:[0000]
if (_AL == 0)
goto check_flags;
do_the_call:
asm push ds
_AX = ax;
_BX = bx;
_CX = cx;
_DX = dx;
_SI = si;
_DI = di;
_ES = es;
_DS = ds;
asm pushf
asm cli
asm call dword ptr cs:[0000]
asm pushf
asm pop flags
ax = _AX;
bx = _BX;
cx = _CX;
dx = _DX;
si = _SI;
di = _DI;
es = _ES;
ds = _DS;
asm pop ds
if (pass_through)
{
pass_through = FALSE;
goto int21out;
}
if ( function_id == 0x01
|| function_id == 0x07
|| function_id == 0x08
|| function_id == 0x0c)
{
in_int21 = FALSE;
goto int21out;
}
check_flags:
if (!hot_flag && !transferring_file && !de_install)
goto int21exit;
if (*indos_ptr != 0)
goto int21exit;
if (*indos2_ptr != 0)
goto int21exit;
if (*prtsc_flag_ptr == 1)
goto int21exit;
outportb(0x20, 0x0b);
if (inportb(0x20)) goto int21exit;
if ( (hot_flag || de_install) && !in_popup && !in_background)
{
in_popup = TRUE;
do_popup();
in_popup = FALSE;
}
else
if (transferring_file && !in_background && !in_popup)
{
in_background = TRUE;
do_transfer();
in_background = FALSE;
}
int21exit:
if ( function_id == 0x01
|| function_id == 0x07
|| function_id == 0x08
|| function_id == 0x0a
|| function_id == 0x0c)
goto wait_for_dos_key;
in_int21 = FALSE;
int21out:
;
}
void interrupt int23 (void)
{
enable();
}
void interrupt int24(unsigned bp,
unsigned di,
unsigned si,
unsigned ds,
unsigned es,
unsigned dx,
unsigned cx,
unsigned bx,
unsigned ax,
unsigned ip,
unsigned cs,
unsigned flags)
{
temp1 = _AX;
critical_error = TRUE;
if (_osmajor < 3)
ax = (temp1 & 0xFF00);
else
ax = (temp1 & 0xFF00) | 0x03;
}
void interrupt int28(void)
{
in_int28 = TRUE;
oldint28();
enable();
if (!hot_flag && !de_install && !transferring_file)
goto exit28;
if (in_int09 || in_int10 || in_int13 || in_int16 || in_int08)
goto exit28;
if (*indos_ptr > 1)
goto exit28;
if (*indos2_ptr != 0)
goto exit28;
if (*prtsc_flag_ptr == 1)
goto exit28;
outportb(0x20, 0x0b);
if (inportb(0x20)) goto exit28;
if ( (hot_flag || de_install) && !in_popup && !in_background)
{
in_popup = TRUE;
do_popup();
in_popup = FALSE;
}
else
if (transferring_file && !in_background && !in_popup)
{
in_background = TRUE;
do_transfer();
in_background = FALSE;
}
exit28:
in_int28 = FALSE;
}
/* ------------------------------------------- */
void beep(void)
{
sound(880);
delay(100);
nosound();
}
void cls(void)
{
if (mouse_exists) hide_mouse();
if (term_type == CHAT)
{
window(1, 1, 80, 16);
textcolor(reg_fg);
textbackground(reg_bg);
clrscr();
window(1, 1, 80, 25);
}
else
{
clrscr();
}
gotoxy(1, 1);
if (mouse_exists) show_mouse();
screen_is_clear = TRUE;
}
void cls_bottom(void)
{
window(1, 17, 80, 25);
textcolor(msg_fg);
textbackground(msg_bg);
clrscr();
textcolor(reg_fg);
textbackground(reg_bg);
bottom_chat_x = bottom_chat_y = 1;
gotoxy(1, 1);
window(1, 1, 80, 25);
}
void save_screen(unsigned left, unsigned top,
unsigned right, unsigned bottom, char *buf,
int *curpos, int *curtype)
{
gettext(left, top, right, bottom, buf);
_AH = 3;
_BH = 0;
geninterrupt(0x10);
*curpos = _DX;
*curtype = _CX;
}
void restore_screen(unsigned left, unsigned top,
unsigned right, unsigned bottom, char *buf,
int *curpos, int *curtype)
{
puttext(left, top, right, bottom, buf);
_DX = *curpos;
curr_row = _DH + 1;
curr_col = _DL + 1;
_DX = *curpos;
_AH = 2;
_BH = 0;
geninterrupt(0x10);
_CX = *curtype;
_AH = 1;
geninterrupt(0x10);
}
void getkey(void)
{
int k;
if (!mouse_exists || break_flag) goto get_kbd_char;
kbd_mouse_loop:
if (bioskey(1)) goto get_kbd_char;
if ( left_button_up() )
{
key_char = CR;
extended_char = 0;
return;
}
if ( right_button_up() )
{
key_char = ESC;
extended_char = 0;
return;
}
goto kbd_mouse_loop;
get_kbd_char:
k = bioskey(0);
key_char = k & 0x00FF;
extended_char = (k & 0xFF00) >> 8;
}
int kbdstring(char buff[], int max_chars)
{
int i, j, insert_mode, ctype, res;
unsigned char row, col, trow, tcol;
unsigned int cblock;
if (mouse_exists) hide_mouse();
i = j = insert_mode = 0;
if (get_vid_mode() == 7)
cblock = 0x000D;
else
cblock = 0x0007;
_AH = 3;
_BH = 0;
geninterrupt(0x10);
ctype = _CX;
col = wherex();
row = wherey();
textcolor(msg_fg);
textbackground(msg_bg);
cprintf("%-*s", max_chars-1, buff);
gotoxy(col, row);
ks1: getkey();
tcol = wherex();
trow = wherey();
if (key_char == ESC)
{
buff[0] = '\0';
res = 0;
goto kbdstring_exit;
}
if (key_char == 0)
{
if (extended_char == INSKEY)
{
if (insert_mode)
{
insert_mode = FALSE;
_CX = ctype;
_AH = 1;
geninterrupt(0x10);
}
else
{
insert_mode = TRUE;
_CX = cblock;
_AH = 1;
geninterrupt(0x10);
}
}
else
if (extended_char == HOMEKEY)
{
i = 0;
gotoxy(col, row);
}
else
if (extended_char == ENDKEY)
{
i = strlen(buff);
gotoxy(col+strlen(buff), row);
}
else
if (extended_char == DELKEY)
{
for (j = i; j < strlen(buff); j++)
buff[j] = buff[j+1];
gotoxy(col, row);
textcolor(msg_fg);
textbackground(msg_bg);
cprintf("%-*s", max_chars-1, buff);
gotoxy(tcol, trow);
}
else
if (extended_char == RIGHTKEY)
{
if (i < strlen(buff))
{
i++;
gotoxy(tcol+1, trow);
}
}
else
if (extended_char == LEFTKEY)
{
if (i > 0)
{
i--;
gotoxy(tcol-1, trow);
}
}
}
if (key_char == 0)
goto ks1;
if (key_char == BS)
{
if (i > 0)
{
i--;
gotoxy(tcol-1, trow);
}
}
if (key_char == CR)
{
res = 0;
goto kbdstring_exit;
}
if (key_char < 32)
goto ks1;
if (i == max_chars-1)
goto ks1;
if (insert_mode)
{
for (j = strlen(buff)-1; j >= i; j--)
if (j < max_chars-2)
buff[j+1] = buff[j];
buff[i++] = key_char;
_CX = ctype;
_AH = 1;
geninterrupt(0x10);
gotoxy(col, row);
textcolor(msg_fg);
textbackground(msg_bg);
cprintf("%-*s", max_chars-1, buff);
gotoxy(++tcol, trow);
_CX = cblock;
_AH = 1;
geninterrupt(0x10);
}
else
{
buff[i++] = key_char;
textcolor(msg_fg);
textbackground(msg_bg);
cprintf("%c", key_char);
}
goto ks1;
kbdstring_exit:
_CX = ctype;
_AH = 1;
geninterrupt(0x10);
if (mouse_exists) show_mouse();
return(res);
}
/************************************/
int fgetbuf(int fh)
{
fgetbuf01:
if (fbufndx < fbufbytes)
return( (int) xmodem_area[fbufndx++]);
io_len = DosRead(fh, xmodem_area, 1024);
if (io_len == -1)
{
fbufndx = 2000;
return(-1);
}
fbufbytes = io_len;
if (fbufbytes == 0)
{
fbufndx = 2000;
return(-1);
}
fbufndx = 0;
goto fgetbuf01;
}
/************************************/
int fgetstring(int fh, char buff[], int max_chars)
{
int i, c;
setmem(buff, max_chars, 0);
i = 0;
fgs1: if (i == max_chars - 1)
{
buff[i] = '\0';
return(0);
}
if ( (c = fgetbuf(fh)) == -1 )
{
buff[i] = '\0';
return(-1);
}
if (c == CR || c == CTRLZ)
goto fgs1;
if (c == LINEFEED)
{
buff[i] = '\0';
return(0);
}
buff[i++] = (char) c;
goto fgs1;
}
void ask_yn(char *s)
{
char linsav[160];
int cpos, ctype;
int mx, my;
if (mouse_exists) hide_mouse();
save_screen(1,25,80,25, linsav, &cpos, &ctype);
textcolor(msg_fg);
textbackground(msg_bg);
gotoxy(1, 25);
cprintf("%-79.79s", " ");
gotoxy(1, 25);
cprintf("%s", s);
if (mouse_exists) show_mouse();
if (mouse_exists)
{
mx = wherex(); my = wherey();
cprintf(" < YES > < NO >");
}
else
{
cprintf(" (y/n) ");
}
ask10: if (!mouse_exists) goto ayn_kbd;
if ( left_button_up() )
{
if (left_button_y != my) goto ask10;
if (left_button_x >= mx+1 && left_button_x <= mx+7)
{
key_char = 'y';
goto ayn_exit;
}
if (left_button_x >= mx+11 && left_button_x <= mx+17)
{
key_char = 'n';
goto ayn_exit;
}
goto ask10;
}
if (!bioskey(1)) goto ask10;
ayn_kbd:
getkey();
if ( key_char != 'y' && key_char != 'Y'
&& key_char != 'n' && key_char != 'N' )
goto ask10;
ayn_exit:
key_char |= 0x20;
if (mouse_exists) hide_mouse();
restore_screen(1,25,80,25, linsav, &cpos, &ctype);
if (mouse_exists) show_mouse();
textcolor(reg_fg);
textbackground(reg_bg);
}
void message(char *s)
{
char linsav[160];
int cpos, ctype;
if (mouse_exists) hide_mouse();
save_screen(1,25,80,25, linsav, &cpos, &ctype);
textcolor(msg_fg);
textbackground(msg_bg);
gotoxy(1, 25);
if (mouse_exists)
cprintf("%-54.54s<Press a key or button.> ", s);
else
cprintf("%-64.64s<Press a key.> ", s);
if (mouse_exists) show_mouse();
getkey();
if (mouse_exists) hide_mouse();
restore_screen(1,25,80,25, linsav, &cpos, &ctype);
if (mouse_exists) show_mouse();
textcolor(reg_fg);
textbackground(reg_bg);
}
int okay_to_unload(void)
{
next_mcb = MK_FP( (ourpsp) + *our_mcb_size, 0);
next_mcb_owner = MK_FP( ourpsp + *our_mcb_size, 1);
if ( *next_mcb_owner == 0x0000
|| *next_mcb_owner == 0xffff
|| *next_mcb_owner < ourpsp )
if (!carrier())
return TRUE;
return FALSE;
}
void show_help(int context)
{
int help_handle, row, j;
char *p;
char str80[81];
char itemid[4];
char pageid[4];
if ( (p = searchpath("comm.hlp")) == NULL || critical_error )
{
critical_error = FALSE;
beep();
message("ERROR. 'COMM.HLP' not found.");
return;
}
term_type_save = term_type;
term_type = NORMAL;
strcpy(str80, p);
help_handle = DosOpen(str80, 0);
if (help_handle < 1)
{
beep();
message("ERROR. 'COMM.HLP' not found.");
return;
}
fbufndx = 2000;
fbufbytes = 0;
sprintf(itemid, "%1d", context);
strcpy(pageid, "pg");
strcat(pageid, itemid);
i = fgetstring(help_handle, str80, 80);
while (strcmp(str80, pageid) NE && i != -1)
i = fgetstring(help_handle, str80, 80);
another_one:
i = fgetstring(help_handle, str80, 80);
row = 0;
textcolor(msg_fg);
textbackground(msg_bg);
cls();
while (strchr(str80, FORMFEED) == NULL && i != -1 && row < 24)
{
gotoxy(1, ++row);
for (j=0; j<strlen(str80); j++)
{
if (str80[j] == 01)
{
textcolor(msg_bg);
textbackground(msg_fg);
}
else
if (str80[j] == 02)
{
textcolor(msg_fg);
textbackground(msg_bg);
}
else
cprintf("%c", str80[j]);
}
i = fgetstring(help_handle, str80, 80);
}
if (i != -1)
{
message(" ESC to leave Help; any other key to see more Help. ");
if (key_char != ESC)
{
i = fgetstring(help_handle, str80, 80);
goto another_one;
}
}
else
message(" ");
DosClose(help_handle);
term_type = term_type_save;
}
void scroll_up(void)
{
_BH = (reg_bg << 4) | reg_fg;
_AX = 0x0601;
_CX = 0x0000;
_DX = 0x184F;
geninterrupt(0x10);
}
void scroll_up_top(void)
{
_BH = (reg_bg << 4) | reg_fg;
_AX = 0x0601;
_CX = 0x0000;
_DX = 0x0F4F;
geninterrupt(0x10);
}
void scroll_down(void)
{
_BH = (reg_bg << 4) | reg_fg;
_AX = 0x0701;
_CX = 0x0000;
_DX = 0x184F;
geninterrupt(0x10);
}
void scroll_down_top(void)
{
_BH = (reg_bg << 4) | reg_fg;
_AX = 0x0701;
_CX = 0x0000;
_DX = 0x0F4F;
geninterrupt(0x10);
}
void scroll_up_bottom(void)
{
_BH = (msg_bg << 4) | msg_fg;
_AX = 0x0601;
_CX = 0x1000;
_DX = 0x184F;
geninterrupt(0x10);
}
void display_chat_bottom(char ch)
{
int x;
if (ch == LINEFEED || ch == CTRLS || ch == CTRLQ) return;
if (ch == CR)
{
if (wherey() == 9)
{
if (mouse_exists) hide_mouse();
scroll_up_bottom();
gotoxy(1, 9);
if (mouse_exists) show_mouse();
}
else
{
gotoxy(1, bottom_chat_y+1);
}
return;
}
if (mouse_exists) hide_mouse();
if (ch == BS)
cprintf("%s", bs_str);
else
if (ch == TAB)
{
x = wherex();
x = 8 - ((x + 7) % 8);
cprintf("%*.*s", x, x, " ");
}
else
cprintf("%c", ch);
if (mouse_exists) show_mouse();
}
void display_char(char ch)
{
int x;
int last_line;
screen_is_clear = FALSE;
if (term_type == CHAT)
last_line = 16;
else
last_line = 25;
if (wherex() == 80 && ch != LINEFEED && ch != CR && ch != BS)
{
if (mouse_exists) hide_mouse();
cprintf("%c%c", CR, LINEFEED);
if (mouse_exists) show_mouse();
}
if (wherey() == last_line && ch == LINEFEED)
{
if (mouse_exists) hide_mouse();
x = wherex();
if (term_type == CHAT)
scroll_up_top();
else
scroll_up();
gotoxy(x, last_line - 1);
if (mouse_exists) show_mouse();
}
if (mouse_exists) hide_mouse();
if (ch == BS)
cprintf("%s", bs_str);
else
if (ch == TAB)
{
x = wherex();
x = 8 - ((x + 7) % 8);
cprintf("%*.*s", x, x, " ");
}
else
cprintf("%c", ch);
if (mouse_exists) show_mouse();
if (term_type == CHAT)
{
top_chat_x = wherex();
top_chat_y = wherey();
}
}
void display_line(int i)
{
char *p1, *p2;
p1 = line_ptrs[i];
if (p1 == NULL) return;
if (++i == MAX_LINES) i = 0;
p2 = line_ptrs[i];
if (p2 == NULL) p2 = &modem_buff[tail];
while (p1 != p2 && *p1 != LINEFEED)
{
display_char(*p1);
if (++p1 == &modem_buff[SBUFSIZ]) p1 = &modem_buff[0];
}
}
void do_up_motion(int x, int y)
{
if (disp_line == 0) return;
if (y > 1)
{
while (y != 1 && disp_line != 0)
{
disp_line--;
y--;
gotoxy(x, y);
}
return;
}
if (term_type == CHAT)
scroll_down_top();
else
scroll_down();
gotoxy(1, 1);
if (!screen_is_clear)
disp_line--;
display_line(disp_line);
screen_is_clear = FALSE;
gotoxy(x, 1);
}
void do_down_motion(int x, int y)
{
if (disp_line == curr_line) return;
if (screen_is_clear) return;
if (y < bottom_line)
{
while (y != bottom_line && disp_line != curr_line)
{
disp_line++;
y++;
gotoxy(x, y);
}
return;
}
if (term_type == CHAT)
scroll_up_top();
else
scroll_up();
gotoxy(1, bottom_line);
disp_line++;
display_line(disp_line);
gotoxy(x, bottom_line);
}
void show_screenfull(void)
{
int y;
cls();
for (y=1; y<=bottom_line; y++, disp_line++)
{
gotoxy(1, y);
display_line(disp_line);
if (disp_line == curr_line) return;
}
disp_line--;
}
void scroll_buffer(void)
{
int r, x, y;
x = wherex(); y = wherey();
bottom_line = 25;
if (mouse_exists) hide_mouse();
if (term_type == CHAT)
{
window(1, 1, 80, 16);
gotoxy(top_chat_x, top_chat_y);
x = top_chat_x;
y = top_chat_y;
bottom_line = 16;
}
scr_buf_action:
if (extended_char == UPKEY)
{
do_up_motion(x, y);
}
else
if (extended_char == DOWNKEY)
{
do_down_motion(x, y);
}
else
if (extended_char == HOMEKEY)
{
disp_line = 0;
show_screenfull();
}
else
if (extended_char == ENDKEY)
{
if (disp_line == curr_line) goto scrbuf_exit;
disp_line = max(curr_line-bottom_line+2, 0);
show_screenfull();
}
else
if (extended_char == PGUPKEY)
{
if (disp_line < bottom_line)
{
extended_char = HOMEKEY;
goto scr_buf_action;
}
r = disp_line + 2 - (bottom_line + y);
disp_line = max(r, 0);
show_screenfull();
}
else
if (extended_char == PGDNKEY)
{
r = disp_line + bottom_line - y;
disp_line = min(r, curr_line);
if (disp_line > curr_line - bottom_line)
{
extended_char = ENDKEY;
goto scr_buf_action;
}
show_screenfull();
}
scrbuf_exit:
if (term_type == CHAT)
{
top_chat_y = wherey();
window(1, 1, 80, 25);
}
if (mouse_exists) show_mouse();
}
void init_line_pointers(void)
{
int a;
for (a=0; a<MAX_LINES; a++)
line_ptrs[a] = NULL;
disp_line = curr_line = 0;
line_ptrs[0] = &modem_buff[tail];
line_sub = 1;
}
int chk_abort_requested(void)
{
if (key_char == ESC || break_flag)
{
break_flag = FALSE;
if (mouse_exists) show_mouse();
ask_yn("Sure you want to end the transfer?");
if (mouse_exists) hide_mouse();
textcolor(msg_fg);
textbackground(msg_bg);
if (key_char == 'y')
{
user_abort = TRUE;
return TRUE;
}
}
return FALSE;
}
int get_filename(void)
{
char linsav[160];
int cpos, ctype, h;
file_bytes = 0l;
blocks_to_send = 0;
setmem(filename, sizeof(filename)-1, 0);
if (mouse_exists) hide_mouse();
save_screen(1,25,80,25, linsav, &cpos, &ctype);
textcolor(msg_fg);
textbackground(msg_bg);
gotoxy(1, 25);
cprintf("Filename? ");
kbdstring(filename, 45);
restore_screen(1,25,80,25, linsav, &cpos, &ctype);
if (mouse_exists) show_mouse();
if (strlen(filename) == 0)
return 0;
h = DosOpen(filename, 0);
if (h == -1)
{
if (crit_err_occurred)
{
crit_err_occurred = FALSE;
return 0;
}
return -1;
}
file_bytes = filelength(h);
if (transfer_type == XMODEM_SEND)
blocks_to_send = (unsigned) ((filelength(h) +127l) / 128l);
else
if (transfer_type == YMODEM_SEND)
blocks_to_send = (unsigned) ((filelength(h) +1023l) / 1024l);
DosClose(h);
return 1;
}
void init_for_transfer(void)
{
name_ptrs[0] = NULL;
name_ptrs[1] = NULL;
critical_error = FALSE;
old_parity = paritysave;
old_bits = bitssave;
old_stop = stop_bitsave;
open_port(port_id, speedsave, NO_PAR, 8, 1);
timeout_value = 11l * 18l;
timeout_ticks = tick_counter + timeout_value;
x_index = 0;
block_count = 0;
error_count = 0;
errors_this_block = 0;
EOF_flag = FALSE;
xfr_abort = FALSE;
user_abort = FALSE;
eot_processed = FALSE;
transferring_file = TRUE;
}
void title_the_box(void)
{
gotoxy(20, 8);
switch (transfer_type)
{
case XMODEM_RECV:
cprintf("[XModem Receive]");
break;
case YMODEM_RECV:
cprintf("[YModem Receive]");
break;
case XMODEM_SEND:
cprintf("[XModem Send]");
break;
case YMODEM_SEND:
cprintf("[YModem Send]");
break;
case KERMIT_RECV:
cprintf("[Kermit Receive]");
break;
case KERMIT_SEND:
cprintf("[Kermit Send]");
break;
default : break;
}
}
void draw_transfer_box(void)
{
if (mouse_exists) hide_mouse();
textcolor(msg_fg);
textbackground(msg_bg);
gotoxy(16, 8);
cprintf("%s", xfr_box[0]);
for (i=0; i<6; i++)
{
gotoxy(16, i+9);
cprintf("%s", xfr_box[1]);
}
gotoxy(16, 15);
cprintf("%s", xfr_box[2]);
title_the_box();
gotoxy(17, 9);
strupr(filename);
cprintf("%-39.39s", filename);
gotoxy(18, 15);
cprintf("[ESC-Abort Alt/X-foreground task]");
if (transfer_type == XMODEM_SEND
|| transfer_type == YMODEM_SEND)
{
gotoxy(17, 11);
cprintf("Total blocks: %5u", blocks_to_send);
}
gotoxy(17, 12);
cprintf(" Good blocks: %5u", block_count);
gotoxy(17, 13);
cprintf("Error blocks: %5u", error_count);
if (mouse_exists) show_mouse();
}
void fg_transfer_processing(void)
{
if (mouse_exists) hide_mouse();
while (transferring_file)
{
do_transfer();
if (hot_flag)
{
leave_flag = TRUE;
goto fg_tp_exit;
}
if (block_count != j || error_count != k)
{
if (transfer_type == XMODEM_SEND
|| transfer_type == YMODEM_SEND)
{
gotoxy(31, 11);
cprintf("%5u", blocks_to_send);
}
gotoxy(31, 12);
cprintf("%5u", block_count);
if (error_count < 0)
error_count = 0;
gotoxy(31, 13);
cprintf("%5u", error_count);
j = block_count;
k = error_count;
}
if (bioskey(1) || break_flag)
{
getkey();
if (key_char == 0 && extended_char == ALTX)
{
leave_flag = TRUE;
goto fg_tp_exit;
}
chk_abort_requested();
}
}
fg_tp_exit:
if (mouse_exists) show_mouse();
textcolor(reg_fg);
textbackground(reg_bg);
}
void show_final_stats(void)
{
open_port(port_id, speedsave, old_parity, old_bits, old_stop);
if (mouse_exists) hide_mouse();
textcolor(msg_fg);
textbackground(msg_bg);
gotoxy(16, 8);
cprintf("%s", xfr_box[0]);
for (i=0; i<6; i++)
{
gotoxy(16, i+9);
cprintf("%s", xfr_box[1]);
}
gotoxy(16, 15);
cprintf("%s", xfr_box[2]);
title_the_box();
gotoxy(17, 9);
strupr(filename);
cprintf("%-39.39s", filename);
if (transfer_type == XMODEM_SEND || transfer_type == YMODEM_SEND)
{
gotoxy(17, 11);
cprintf("Total blocks: %5u", blocks_to_send);
}
gotoxy(17, 12);
cprintf(" Good blocks: %5u", block_count);
gotoxy(17, 13);
cprintf("Error blocks: %5u", error_count);
gotoxy(17, 14);
if (xfr_abort)
cprintf("Transfer aborted. Press a key.");
else
cprintf("Transfer complete. Press a key.");
if (mouse_exists) show_mouse();
getkey();
stats_in_progress = FALSE;
transfer_type = NO_TRANSFER;
init_line_pointers();
textcolor(reg_fg);
textbackground(reg_bg);
}
void receive_xymodem(void)
{
j = k = 0;
if (stats_in_progress) goto show_recv_stats;
get_name:
j = get_filename();
if (j == 0) return;
if (j == 1)
{
beep();
ask_yn("File exists already. Replace it?");
if (key_char == 'n')
goto get_name;
}
j = 0;
init_for_transfer();
show_recv_stats:
stats_in_progress = TRUE;
draw_transfer_box();
fg_transfer_processing();
if (leave_flag) return;
show_final_stats();
}
void send_xymodem(void)
{
j = k = 0;
if (stats_in_progress) goto show_send_stats;
get_name:
j = get_filename();
if (j == 0) return;
if (j == -1)
{
beep();
message("File not found.");
goto get_name;
}
j = 0;
init_for_transfer();
show_send_stats:
stats_in_progress = TRUE;
draw_transfer_box();
fg_transfer_processing();
if (leave_flag) return;
show_final_stats();
}
void receive_kermit(void)
{
char linsav[160];
int cpos, ctype;
char a;
j = k = 0;
if (stats_in_progress) goto show_recv_stats;
save_screen(1,25,80,25, linsav, &cpos, &ctype);
setmem(kermit_path, sizeof(kermit_path)-1, 0);
textcolor(msg_fg);
textbackground(msg_bg);
get_directory:
gotoxy(1, 25);
cprintf("Drive:\\Path (─┘ for current) ");
kbdstring(kermit_path, 39);
if (strlen(kermit_path) != 0)
{
a = kermit_path[strlen(kermit_path)-1];
if (a != '\\' && a != ':')
strcat(kermit_path, "\\");
strcpy(string1, kermit_path);
strcat(string1, "kertemp.$$$");
if ( (j = DosCreate(string1)) == -1)
{
beep();
goto get_directory;
}
DosClose(j);
unlink(string1);
}
restore_screen(1,25,80,25, linsav, &cpos, &ctype);
init_for_transfer();
setmem(filename, sizeof(filename)-1, 0);
show_recv_stats:
stats_in_progress = TRUE;
draw_transfer_box();
fg_transfer_processing();
if (leave_flag) return;
show_final_stats();
}
void send_kermit(void)
{
int res, w;
struct ffblk ff;
j = k = 0;
if (stats_in_progress) goto show_send_stats;
get_name:
if (get_filename() == 0) return;
res=findfirst(filename, &ff, 0);
if (res != 0 || critical_error)
{
critical_error = FALSE;
goto get_name;
}
init_for_transfer();
_filecount = w = 0;
name_area = xmodem_area;
_filelist = name_ptrs;
while (res == 0 && !critical_error)
{
if (_filecount > 24 || w > 1000) break;
strcpy(&name_area[w], ff.ff_name);
name_ptrs[_filecount] = &name_area[w];
w += strlen(ff.ff_name) + 1;
_filecount++;
res = findnext(&ff);
}
show_send_stats:
stats_in_progress = TRUE;
draw_transfer_box();
fg_transfer_processing();
if (leave_flag) return;
show_final_stats();
}
void receive_ascii(void)
{
char linsav[160];
int h;
unsigned long j;
j = 0l;
if (stats_in_progress) goto show_recv_stats;
get_name:
h = get_filename();
if (h == 0) return;
if (h == 1)
{
beep();
ask_yn("File exists already. Replace it?");
if (key_char == 'n')
goto get_name;
}
setmem(holdstr, 81, 0);
timeout_value = 11l * 18l;
timeout_ticks = tick_counter + timeout_value;
EOF_flag = FALSE;
xfr_abort = FALSE;
user_abort = FALSE;
transferring_file = TRUE;
term_type_save = term_type;
term_type = NORMAL;
show_recv_stats:
stats_in_progress = TRUE;
if (mouse_exists) hide_mouse();
textcolor(msg_fg);
textbackground(msg_bg);
gotoxy(1, 16);
cprintf("%s", ascii_box[0]);
for (i=0; i<7; i++)
{
gotoxy(1, i+17);
cprintf("%s", ascii_box[1]);
}
gotoxy(1, 24);
cprintf("%s", ascii_box[2]);
gettext(1, 24, 80, 24, linsav);
puttext(1, 25, 80, 25, linsav);
gotoxy(1, 24);
cprintf("%s", ascii_box[1]);
gotoxy(10, 16);
cprintf("[ASCII Receive -- %s]", filename);
gotoxy(10, 25);
cprintf("[ESC when done Received: %7lu]", byte_count);
oldx = oldy = 1;
while (transferring_file)
{
do_transfer();
if (hot_flag)
{
leave_flag = TRUE;
if (mouse_exists) show_mouse();
textcolor(reg_fg);
textbackground(reg_bg);
return;
}
if (j != byte_count)
{
gotoxy(37, 25);
cprintf("%7lu", byte_count);
j = byte_count;
}
if (bioskey(1) || break_flag)
{
getkey();
chk_abort_requested();
if (key_char == 0 && extended_char == ALTX)
{
leave_flag = TRUE;
if (mouse_exists) show_mouse();
textcolor(reg_fg);
textbackground(reg_bg);
return;
}
if (!user_abort && key_char != 0)
{
send_char(key_char);
}
}
}
gotoxy(10, 25);
cprintf("[Transfer complete <press a key>. Received: %7lu]",
byte_count);
if (mouse_exists) show_mouse();
getkey();
stats_in_progress = FALSE;
transfer_type = NO_TRANSFER;
did_ascii_xfr = TRUE;
textcolor(reg_fg);
textbackground(reg_bg);
}
void send_ascii(void)
{
char linsav[160];
int h;
unsigned long j;
j = 0l;
if (stats_in_progress) goto show_send_stats;
get_name:
h = get_filename();
if (h == 0) return;
if (h == -1)
{
beep();
message("File not found.");
goto get_name;
}
setmem(holdstr, 81, 0);
timeout_value = 11l * 18l;
timeout_ticks = tick_counter + timeout_value;
EOF_flag = FALSE;
xfr_abort = FALSE;
user_abort = FALSE;
transferring_file = TRUE;
term_type_save = term_type;
term_type = NORMAL;
show_send_stats:
stats_in_progress = TRUE;
if (mouse_exists) hide_mouse();
textcolor(msg_fg);
textbackground(msg_bg);
gotoxy(1, 16);
cprintf("%s", ascii_box[0]);
for (i=0; i<7; i++)
{
gotoxy(1, i+17);
cprintf("%s", ascii_box[1]);
}
gotoxy(1, 24);
cprintf("%s", ascii_box[2]);
gettext(1, 24, 80, 24, linsav);
puttext(1, 25, 80, 25, linsav);
gotoxy(1, 24);
cprintf("%s", ascii_box[1]);
gotoxy(10, 16);
cprintf("[ASCII Send -- %s]", filename);
gotoxy(10, 25);
cprintf("[ESC to interrupt File size: %7lu Sent: %7lu]",
file_bytes, byte_count);
oldx = oldy = 1;
while (transferring_file)
{
do_transfer();
if (hot_flag)
{
leave_flag = TRUE;
if (mouse_exists) show_mouse();
textcolor(reg_fg);
textbackground(reg_bg);
return;
}
if (j != byte_count)
{
gotoxy(55, 25);
cprintf("%7lu", byte_count);
j = byte_count;
}
if (bioskey(1) || break_flag)
{
getkey();
if (key_char == 0 && extended_char == ALTX)
{
leave_flag = TRUE;
if (mouse_exists) show_mouse();
textcolor(reg_fg);
textbackground(reg_bg);
return;
}
chk_abort_requested();
}
}
gotoxy(10, 25);
cprintf("[Done <press a key>. File size: %7lu Sent: %7lu]",
file_bytes, byte_count);
window(2, 17, 79, 24);
gotoxy(oldx, oldy);
textcolor(msg_fg);
textbackground(msg_bg);
while ( !bioskey(1) )
if ( (i = get_modem()) != -1 )
display_char( (char) i);
if (mouse_exists) show_mouse();
getkey();
oldx = wherex();
oldy = wherey();
window(1, 1, 80, 25);
stats_in_progress = FALSE;
transfer_type = NO_TRANSFER;
did_ascii_xfr = TRUE;
textcolor(reg_fg);
textbackground(reg_bg);
}
void capture_file(void)
{
int h;
if (capturing)
{
DosClose(capture_handle);
capturing = FALSE;
transferring_file = FALSE;
return;
}
get_name:
h = get_filename();
if (h == 0) return;
strlwr(filename);
if ( (filename[0] == 'l' && filename[1] == 'p' && filename[2] == 't')
||
(filename[0] == 'p' && filename[1] == 'r' && filename[2] == 'n') )
{
if ( (capture_handle = DosOpen(filename, 2)) == -1)
{
beep();
return;
}
capturing = TRUE;
transferring_file = TRUE;
return;
}
if (h == 1)
{
beep();
ask_yn("File exists already. Append to it?");
if (key_char == 'y')
{
if ( (capture_handle = DosOpen(filename, 2)) == -1)
{
beep();
return;
}
DosSeekEOF(capture_handle);
capturing = TRUE;
transferring_file = TRUE;
return;
}
ask_yn("Replace it?");
if (key_char == 'n')
goto get_name;
}
if ( (capture_handle = DosCreate(filename)) == -1)
{
beep();
return;
}
capturing = TRUE;
transferring_file = TRUE;
}
void set_term(int tt)
{
if (term_type == tt) return;
if (tt == CHAT)
switch_to_chat = TRUE;
else
if (term_type == CHAT)
switch_from_chat = TRUE;
term_type = tt;
}
void change_port(void)
{
switch (our_port)
{
case 1 : {our_port = 2; break;}
case 2 : {our_port = 3; break;}
case 3 : {our_port = 4; break;}
case 4 : {our_port = 1; break;}
default: {our_port = 1; break;}
}
re_open_flag = TRUE;
}
void change_baud(void)
{
switch (our_speed)
{
case 110 : {our_speed = 150; break;}
case 150 : {our_speed = 300; break;}
case 300 : {our_speed = 600; break;}
case 600 : {our_speed = 1200; break;}
case 1200 : {our_speed = 2400; break;}
case 2400 : {our_speed = 4800; break;}
case 4800 : {our_speed = 9600; break;}
case 9600 : {our_speed =19200; break;}
case 19200 : {our_speed =38400l; break;}
case 38400l: {our_speed = 110; break;}
default : {our_speed = 1200; break;}
}
re_open_flag = TRUE;
}
void change_data(void)
{
switch (our_bits)
{
case 5 : {our_bits = 6; break;}
case 6 : {our_bits = 7; break;}
case 7 : {our_bits = 8; break;}
case 8 : {our_bits = 5; break;}
default: {our_bits = 7; break;}
}
re_open_flag = TRUE;
}
void change_parity(void)
{
switch (our_par)
{
case EV_PAR : {our_par = NO_PAR; break;}
case NO_PAR : {our_par = OD_PAR; break;}
case OD_PAR : {our_par = EV_PAR; break;}
default : {our_par = EV_PAR; break;}
}
re_open_flag = TRUE;
}
void change_stop(void)
{
our_stop = our_stop == 2? 1 : 2;
re_open_flag = TRUE;
}
void change_echo(void)
{
echo_flag = echo_flag? FALSE : TRUE;
}
void change_xon(void)
{
flow_control = flow_control? FALSE : TRUE;
}
void change_add_lf(void)
{
crlf_for_cr = crlf_for_cr? FALSE : TRUE;
}
void change_auto_answer(void)
{
if (carrier()) return;
auto_answer = auto_answer? FALSE : TRUE;
if (auto_answer)
send_string(answer_on);
else
send_string(answer_off);
}
int parse_phone_entry(int sel)
{
char *token;
setmem(string1, LINE_LENGTH, 0);
strncpy(string1, phone_list[sel], LINE_LENGTH);
token = strtok(string1, ";");
if (token == NULL) {dial_error = 1; return -1;}
if (strncmp(token, " ", 10) == 0)
{dial_error = 1; return -1;}
token = strtok(NULL, ";");
if (token == NULL) {dial_error = 2; return -1;}
if (strlen(token) > 28) {dial_error = 2; return -1;}
strcpy(phone_number, token);
token = strtok(NULL, ";");
if (token == NULL) {dial_error = 3; return -1;}
speedsave = (unsigned) atol(token);
if ( speedsave < 1
|| speedsave > MAX_BAUD) {dial_error = 3; return -1;}
our_speed = speedsave;
token = strtok(NULL, ";");
if (token == NULL) {dial_error = 0; return -1;}
strcpy(string2, token);
token = strtok(NULL, ";");
if (token == NULL) {dial_error = 7; return -1;}
strcpy(string3, token);
strcat(string3, " ");
strlwr(string3);
if (strstr(string3, "noecho") != NULL)
echo_flag = FALSE;
else
if (strstr(string3, "echo") != NULL)
echo_flag = TRUE;
else
{dial_error = 7; return -1;}
token = strtok(NULL, ";");
if (token == NULL) {dial_error = 8; return -1;}
strcpy(string3, token);
strcat(string3, " ");
strlwr(string3);
if (strstr(string3, "noflow") != NULL)
flow_control = FALSE;
else
if (strstr(string3, "flow") != NULL)
flow_control = TRUE;
else
{dial_error = 8; return -1;}
token = strtok(NULL, ";");
if (token == NULL) {dial_error = 9; return -1;}
strcpy(string3, token);
strcat(string3, " ");
strlwr(string3);
if (strstr(string3, "yes") != NULL)
crlf_for_cr = TRUE;
else
if (strstr(string3, "no") != NULL)
crlf_for_cr = FALSE;
else
{dial_error = 9; return -1;}
token = strtok(string2, "-");
if (token == NULL) {dial_error = 4; return -1;}
if (atoi(token) < 5 || atoi(token) > 8)
{dial_error = 4; return -1;}
our_bits = atoi(token);
token = strtok(NULL, "-");
if (token == NULL) {dial_error = 5; return -1;}
strcpy(string3, token);
strlwr(string3);
if (string3[0] == 'e')
our_par = EV_PAR;
else
if (string3[0] == 'o')
our_par = OD_PAR;
else
if (string3[0] == 'n')
our_par = NO_PAR;
else
{dial_error = 5; return -1;}
token = strtok(NULL, " -");
if (token == NULL) {dial_error = 6; return -1;}
if (atoi(token) < 1 || atoi(token) > 2)
{dial_error = 6; return -1;}
our_stop = atoi(token);
return 0;
}
int make_the_call(void)
{
int dialing_period;
call_in_progress = FALSE;
setmem(holdstr, 81, 0);
flag_save = echo_flag;
echo_flag = FALSE;
send_string(dial_cmd);
send_string(phone_number);
send_char(CR);
echo_flag = flag_save;
dialing_period = 1;
while (dialing_period <= dial_wait_secs)
{
if (strlen(no_carrier_msg) > 0
&& strstr(holdstr, no_carrier_msg) != NULL)
return 0;
if (strlen(phone_busy) > 0
&& strstr(holdstr, phone_busy) != NULL)
return 0;
if (strlen(connect_msg) > 0)
{
if (strstr(holdstr, connect_msg) != NULL)
{
call_in_progress = TRUE;
return 1;
}
}
if (use_carrier && carrier())
{
call_in_progress = TRUE;
return 1;
}
else
if (!use_carrier)
{
call_in_progress = TRUE;
return 1;
}
if (in_popup)
{
gotoxy(1, 25);
textcolor(msg_fg);
textbackground(msg_bg);
cprintf("[%2d secs.] ", dialing_period);
}
purge_buffer();
dialing_period++;
if ( mouse_exists && right_button_up() )
{
if (!carrier())
send_char(CR);
return -1;
}
if (bioskey(1))
{
getkey();
if (key_char == ESC)
{
if (!carrier())
send_char(CR);
return -1;
}
}
}
return 0;
}
void tell_modem_to_dial(void)
{
char linsav[160];
int cpos, ctype;
int r;
if (mouse_exists) hide_mouse();
save_screen(1,25,80,25, linsav, &cpos, &ctype);
textcolor(msg_fg);
textbackground(msg_bg);
gotoxy(1, 25);
cprintf(
" Dialing %-23.23s (ESC to interrupt) ",
phone_number);
r = make_the_call();
restore_screen(1,25,80,25, linsav, &cpos, &ctype);
textcolor(msg_fg);
textbackground(msg_bg);
gotoxy(69, 1);
if (carrier())
cprintf("[Online ]");
else
cprintf("[Offline]");
textcolor(reg_fg);
textbackground(reg_bg);
if (mouse_exists) show_mouse();
if (r == -1)
{
message("Dialing interrupted. ");
goto tmtd_exit;
}
if (r == 0)
{
beep();
message(" The call was unsuccessful. ");
goto tmtd_exit;
}
message(" The other computer has answered the phone. ");
tmtd_exit:
;
}
void dial_manually(void)
{
char linsav[160];
int cpos, ctype;
if (carrier())
{
beep();
return;
}
if (mouse_exists) hide_mouse();
save_screen(1,25,80,25, linsav, &cpos, &ctype);
setmem(phone_number, sizeof(phone_number)-1, 0);
textcolor(msg_fg);
textbackground(msg_bg);
gotoxy(1, 25);
cprintf("Phone number? ");
kbdstring(phone_number, 29);
restore_screen(1,25,80,25, linsav, &cpos, &ctype);
if (mouse_exists) show_mouse();
if (strlen(phone_number) == 0)
return;
tell_modem_to_dial();
}
void dial_phone(int sel)
{
if (carrier())
{
beep();
return;
}
if (parse_phone_entry(sel) == -1)
{
beep();
sprintf(string1, "%s missing or invalid.", dial_msg[dial_error]);
message(string1);
return;
}
close_port();
open_port(our_port,our_speed,our_par,our_bits,our_stop);
tell_modem_to_dial();
}
/************************************/
int hangup_phone(void)
{
int retry_cnt;
char linsav[160];
int cpos, ctype;
if (!carrier() || strlen(hangup) == 0)
{
beep();
return(-1);
}
ask_yn("Sure you want to hang up?");
if (key_char == 'n')
return(-1);
if (mouse_exists) hide_mouse();
save_screen(1,25,80,25, linsav, &cpos, &ctype);
textcolor(msg_fg);
textbackground(msg_bg);
gotoxy(1, 25);
cprintf(
" Ok. Hanging up the phone. (please wait...) ");
setmem(holdstr, 81, 0);
drop_dtr();
if (!carrier())
goto hup_exit;
flag_save = echo_flag;
echo_flag = FALSE;
retry_cnt = 0;
retry:
send_string(hangup);
delay(100);
if (carrier() && retry_cnt < 2)
{
retry_cnt++;
goto retry;
}
echo_flag = flag_save;
hup_exit:
call_in_progress = FALSE;
restore_screen(1,25,80,25, linsav, &cpos, &ctype);
textcolor(msg_fg);
textbackground(msg_bg);
gotoxy(69, 1);
if (carrier())
cprintf("[Online ]");
else
cprintf("[Offline]");
textcolor(reg_fg);
textbackground(reg_bg);
if (mouse_exists) show_mouse();
return(0);
}
unsigned int get_color(char *s1)
{
if (strstr(s1, "darkgray") != NULL)
return(DARKGRAY);
if (strstr(s1, "lightblue") != NULL)
return(LIGHTBLUE);
if (strstr(s1, "lightgreen") != NULL)
return(LIGHTGREEN);
if (strstr(s1, "lightcyan") != NULL)
return(LIGHTCYAN);
if (strstr(s1, "lightred") != NULL)
return(LIGHTRED);
if (strstr(s1, "lightmagenta") != NULL)
return(LIGHTMAGENTA);
if (strstr(s1, "yellow") != NULL)
return(YELLOW);
if (strstr(s1, "brightwhite") != NULL)
return(BRIGHTWHITE);
if (strstr(s1, "black") != NULL)
return(BLACK);
if (strstr(s1, "blue") != NULL)
return(BLUE);
if (strstr(s1, "green") != NULL)
return(GREEN);
if (strstr(s1, "cyan") != NULL)
return(CYAN);
if (strstr(s1, "red") != NULL)
return(RED);
if (strstr(s1, "magenta") != NULL)
return(MAGENTA);
if (strstr(s1, "brown") != NULL)
return(BROWN);
if (strstr(s1, "white") != NULL)
return(WHITE);
if (strstr(s1, "highintensity") != NULL)
return(HIGHINTENSITY);
if (strstr(s1, "underline") != NULL)
return(UNDERLINE);
return(-1);
}
/************************************/
void get_parms(void)
{
int i1;
char *t1;
strtok(string2, "=");
i1 = atoi(strtok(NULL, "-/ \n"));
if (i1 < 5 || i1 > 8) {config_error = 7; return;}
our_bits = i1;
t1 = strtok(NULL, "-/ \n");
if (strcmp(t1, "e") EQ)
our_par = EV_PAR;
else
if (strcmp(t1, "n") EQ)
our_par = NO_PAR;
else
if (strcmp(t1, "o") EQ)
our_par = OD_PAR;
else
{config_error = 8; return;};
i1 = atoi(strtok(NULL, "-/ \n"));
if (i1 < 1 || i1 > 2) {config_error = 9; return;}
our_stop = i1;
}
void get_string_token(char *id, char *t, int toklen)
{
if (strstr(string2, id) != NULL)
if (strtok(string1, "=") != NULL)
strncpy(t, strtok(NULL, "\n"), toklen);
}
void get_int_token(char *id, unsigned int *t)
{
if (strstr(string2, id) != NULL)
if (strtok(string1, "=") != NULL)
*t = (unsigned) atol(strtok(NULL, "\n"));
}
void get_boolean_token(char *id, unsigned char *t)
{
char *p;
if (strstr(string2, id) != NULL)
if (strtok(string2, "=") != NULL)
{
p = strtok(NULL, "\n");
if (strstr(p, "yes") != NULL || strstr(p, "on") != NULL)
*t = TRUE;
else
if (strstr(p, "no") != NULL || strstr(p, "off") != NULL)
*t = FALSE;
}
}
/************************************/
int get_config(char *config_name)
{
char *p;
char spath[81];
int i1;
config_error = -1;
strcpy(spath, config_name);
find_the_file:
if ( (p = searchpath(spath)) == NULL || critical_error )
{
if (strchr(spath, '.') == NULL && !critical_error)
{
strcat(spath, ".CFG");
goto find_the_file;
}
critical_error = FALSE;
config_error = 0;
return(-1);
}
strcpy(string1, p);
handle = DosOpen(string1, 0);
if (handle < 1)
{
config_error = 0;
return(-1);
}
fbufndx = 2000;
fbufbytes = 0;
while ((fgetstring(handle, string1, 80)) != -1)
{
if (string1[0] == ';' || string1[0] == '*')
continue;
strcat(string1, "\n");
strcpy(string2, string1);
strlwr(string2);
if (strstr(string2, "phone dir") != NULL)
{
for (i1 = 0; i1 < 10; i1++)
{
strcpy(phone_list[i1], " ");
strcpy(dial_menu[i1], " ");
}
dial_count = 0;
while ((fgetstring(handle, string1, 80)) != -1)
{
if (string1[0] == ';' || string1[0] == '*')
continue;
strcat(string1, ";");
while ( (p = strchr(string1, TAB)) != NULL )
*p = ' ';
strcpy(string2, string1);
strlwr(string2);
if (dial_count > 9)
break;
if (strlen(string1) < 7)
break;
if (strstr(string2, "modem string") != NULL)
break;
strcpy(phone_list[dial_count], string1);
strtok(string1, ";");
for (i1=strlen(string1); i1<25; i1++)
string1[i1] = ' ';
string1[24] = '\0';
strcpy(dial_menu[dial_count], " ");
strcat(dial_menu[dial_count], string1);
dial_count++;
}
}
else
if (strstr(string2, "regular foreground") != NULL)
{
if ((i1 = get_color(string2)) == -1)
config_error = 1;
else
reg_fg = (unsigned char) i1;
}
else
if (strstr(string2, "regular background") != NULL)
{
if ((i1 = get_color(string2)) == -1)
config_error = 2;
else
reg_bg = (unsigned char) i1;
}
else
if (strstr(string2, "message foreground") != NULL)
{
if ((i1 = get_color(string2)) == -1)
config_error = 3;
else
msg_fg = (unsigned char) i1;
}
else
if (strstr(string2, "message background") != NULL)
{
if ((i1 = get_color(string2)) == -1)
config_error = 4;
else
msg_bg = (unsigned char) i1;
}
else
if (strstr(string2, "parms") != NULL)
get_parms();
else
{
get_string_token("phone busy", phone_busy, 20);
get_string_token("no carrier", no_carrier_msg, 20);
get_string_token("dial command", dial_cmd, 20);
get_string_token("modem init", modem_init, 50);
get_string_token("answer on", answer_on, 20);
get_string_token("answer off", answer_off, 20);
get_string_token("modem ok", modem_ok, 20);
get_string_token("modem error", modem_error, 20);
get_string_token("hang", hangup, 50);
get_string_token("connect", connect_msg, 20);
get_int_token("break ms", &break_milliseconds);
get_int_token("foreground ticks", &foreground_ticks);
get_int_token("background ticks", &background_ticks);
get_int_token("xmodem timeout", &xtimeout);
get_int_token("dial wait", &dial_wait_secs);
get_int_token("char send delay", &char_delay);
get_int_token("line send delay", &line_delay);
get_int_token("com port", &our_port);
get_int_token("baud rate", &our_speed);
get_boolean_token("send lf with cr", &send_crlf);
get_boolean_token("use alt", &use_alt);
get_boolean_token("use carrier", &use_carrier);
get_boolean_token("auto answer", &auto_answer);
get_boolean_token("echo", &echo_flag);
get_boolean_token("mouse", &mouse_exists);
}
if (strstr(string2, "macro") != NULL)
if (strtok(string1, " ") != NULL)
{
p = strtok(NULL, "=\n");
if (p != NULL)
{
i1 = atoi(p);
if (i1 < 1 || i1 > 9)
config_error = 17;
else
strncpy(kbd_macro_list[i1-1], strtok(NULL, "\n"), 80);
}
}
if (strstr(string2, "auto answer") != NULL)
set_answer = TRUE;
}
DosClose(handle);
if (our_port < 1 || our_port > 4)
config_error = 5;
if (our_speed < 1 || our_speed > MAX_BAUD)
config_error = 6;
if (break_milliseconds < 1 || break_milliseconds > 2000)
config_error = 11;
if (foreground_ticks < 2 || foreground_ticks > 20)
config_error = 12;
if (background_ticks < 2 || background_ticks > 20)
config_error = 13;
if (xtimeout < 1 || xtimeout > 30)
config_error = 16;
if (dial_wait_secs < 1 || dial_wait_secs > 800)
config_error = 14;
if (config_error != -1)
return(-1);
xticks = (long) (xtimeout * 18) + 2;
return(0);
}
int pulldown(int x, int y,
int mx1, int mx2,
int fg, int bg,
int count, int start,
char *items[])
{
char *tline =
"┬────────────────────────────────────────────────────────────────────────────┬";
char *mline =
"│ │";
char *bline =
"└────────────────────────────────────────────────────────────────────────────┘";
int i, len, sx, res;
char *menu_chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
len = strlen(items[0]) + 5;
sx = x + 3;
if (x < mx1) mx1 = x;
if (mouse_exists)
{
left_button_up();
right_button_up();
}
if (dont_redraw)
{
dont_redraw = FALSE;
goto highlight_current;
}
if (mouse_exists) hide_mouse();
textcolor(fg);
textbackground(bg);
gotoxy(x, y);
cprintf("%*.*s", len, len, tline);
cprintf("%c", tline[strlen(tline)-1]);
for (i=0; i<count; i++)
{
gotoxy(x, y+i+1);
cprintf("%*.*s", len, len, mline);
cprintf("%c", mline[strlen(mline)-1]);
}
gotoxy(x, y+count+1);
cprintf("%*.*s", len, len, bline);
cprintf("%c", bline[strlen(bline)-1]);
textcolor(fg);
textbackground(bg);
for (i=0; i<count; i++)
{
gotoxy(sx, y+i+1);
cprintf("%s", items[i]);
}
curr_item = old_item = start;
goto highlight_current;
de_highlight_old:
if (mouse_exists) hide_mouse();
textcolor(fg);
textbackground(bg);
gotoxy(sx, y+old_item+1);
cprintf("%s", items[old_item]);
old_item = curr_item;
highlight_current:
textcolor(bg);
textbackground(fg);
gotoxy(sx, y+curr_item+1);
cprintf("%s", items[curr_item]);
if (mouse_exists) show_mouse();
if (stats_in_progress)
{
res = start + 1;
goto pulldown_exit;
}
operate_menu:
if (mouse_exists)
{
if ( right_button_up() )
{
res = 0;
goto pulldown_exit;
}
if ( left_button_down() )
{
if (left_button_y <= y)
{
if (left_button_x < mx1
|| left_button_x > mx2)
{
mouse_menu_x = left_button_x;
return -4;
}
goto operate_menu;
}
if (left_button_y > y + count) goto operate_menu;
if (left_button_x < mx1
|| left_button_x > x + len + 1)
{
mouse_menu_x = left_button_x;
return -4;
}
if (curr_item == (left_button_y - y) - 1) goto operate_menu;
curr_item = (left_button_y - y) - 1;
while (strncmp(items[curr_item], " ", 10) == 0)
{
if (old_item < curr_item)
{
curr_item++;
move_mouse(left_button_x, ++left_button_y);
}
else
{
curr_item--;
move_mouse(left_button_x, --left_button_y);
}
}
goto de_highlight_old;
}
if ( left_button_up() )
{
if (left_button_y <= y)
{
if (left_button_x >= mx1 && left_button_x < x + len)
goto operate_menu;
mouse_menu_x = left_button_x;
return -4;
}
if (left_button_x <= mx1
|| left_button_x >= x + len - 1
|| left_button_y > y + count)
goto operate_menu;
if (left_button_y == y + curr_item + 1)
{
res = curr_item + 1;
goto pulldown_exit;
}
curr_item = (left_button_y - y) - 1;
goto de_highlight_old;
}
}
if (!bioskey(1)) goto operate_menu;
getkey();
move_lightbar:
if (key_char == 0)
switch (extended_char)
{
case ALTX : {res = -3; goto pulldown_exit;}
case LEFTKEY : {res = -2; goto pulldown_exit;}
case RIGHTKEY: {res = -1; goto pulldown_exit;}
case ALTD : {
res = -4;
mouse_menu_x = 10;
goto pulldown_exit;
}
case ALTS : {
res = -4;
mouse_menu_x = 25;
goto pulldown_exit;
}
case ALTF : {
res = -4;
mouse_menu_x = 25;
goto pulldown_exit;
}
case ALTT : {
res = -4;
mouse_menu_x = 35;
goto pulldown_exit;
}
case ALTM : {
res = -4;
mouse_menu_x = 50;
goto pulldown_exit;
}
case ALTE : {
res = -4;
mouse_menu_x = 60;
goto pulldown_exit;
}
case ALTH : {
res = -4;
mouse_menu_x = 75;
goto pulldown_exit;
}
case UPKEY : {
if (curr_item == 0)
curr_item = count - 1;
else
--curr_item;
if (strncmp(items[curr_item], " ", 10)
== 0)
goto move_lightbar;
goto de_highlight_old;
}
case DOWNKEY : {
if (curr_item == count - 1)
curr_item = 0;
else
++curr_item;
if (strncmp(items[curr_item], " ", 10)
== 0)
goto move_lightbar;
goto de_highlight_old;
}
case HOMEKEY : {
curr_item = 0;
goto de_highlight_old;
}
case ENDKEY : {
curr_item = count - 1;
goto de_highlight_old;
}
case BACKTAB : {
if (curr_item == 0)
curr_item = count - 1;
else
--curr_item;
if (strncmp(items[curr_item], " ", 10)
== 0)
goto move_lightbar;
goto de_highlight_old;
}
default : {
goto operate_menu;
}
}
/* not an extended code; handle regular keypress */
if (key_char >= 'A' && key_char <= 'z')
{
key_char = toupper(key_char);
i = curr_item;
do {
i = i == count - 1? 0 : i + 1;
if (*strpbrk(items[i], menu_chars) == key_char)
{
curr_item = i;
goto de_highlight_old;
}
}
while (i != curr_item);
goto operate_menu;
}
if (key_char == ESC) /* ESC */
{
res = 0;
goto pulldown_exit;
}
if (key_char == CR) /* <return> */
{
res = curr_item + 1;
goto pulldown_exit;
}
if (key_char == ' ') /* space bar */
{
if (curr_item == count - 1)
curr_item = 0;
else
++curr_item;
if (strncmp(items[curr_item], " ", 10) == 0)
goto move_lightbar;
goto de_highlight_old;
}
if (key_char == TAB) /* tab key */
{
if (curr_item == count - 1)
curr_item = 0;
else
++curr_item;
if (strncmp(items[curr_item], " ", 10) == 0)
goto move_lightbar;
goto de_highlight_old;
}
goto operate_menu;
pulldown_exit:
if (mouse_exists)
{
left_button_up();
right_button_up();
}
return res;
}
void put_parms_in_menu(void)
{
char s[10];
sprintf(&modem_menu[0] [17], "%1d", our_port);
sprintf(&modem_menu[1] [13], "%5u", our_speed);
sprintf(&modem_menu[2] [17], "%1d", our_bits);
if (our_par == EV_PAR) strcpy(s, "EVEN");
else if (our_par == OD_PAR) strcpy(s, "ODD ");
else strcpy(s, "NONE");
sprintf(&modem_menu[3] [14], "%4.4s", s);
sprintf(&modem_menu[4] [17], "%1d", our_stop);
if (echo_flag) strcpy(s, "ON "); else strcpy(s, "OFF");
sprintf(&modem_menu[5] [15], "%3.3s", s);
if (flow_control) strcpy(s, "ON "); else strcpy(s, "OFF");
sprintf(&modem_menu[6] [15], "%3.3s", s);
if (crlf_for_cr) strcpy(s, "ON "); else strcpy(s, "OFF");
sprintf(&modem_menu[7] [15], "%3.3s", s);
if (auto_answer) strcpy(s, "ON "); else strcpy(s, "OFF");
sprintf(&modem_menu[8] [15], "%3.3s", s);
if (capturing) strcpy(s, "ON "); else strcpy(s, "OFF");
sprintf(&file_menu[8] [15], "%3.3s", s);
}
int main_menu(int menu_id)
{
int r, sx1, sx2, sy1, sy2, cnt, cpos, ctyp, mx1, mx2;
char **plist;
if (mouse_exists) hide_mouse();
save_screen(1, 1, 80, 3, &our_screen[0], &cpos, &ctyp);
if (menu_id < 1) menu_id = 1;
textcolor(msg_fg);
textbackground(msg_bg);
gotoxy(1, 1);
cprintf(
"┌──────────────────────────────────────────────────────────────────────────────┐");
gotoxy(1, 2);
cprintf(
"│ │");
gotoxy(1, 3);
cprintf(
"└──────────────────────────────────────────────────────────────────────────────┘");
gotoxy(5, 1);
cprintf("%s", compliments);
gotoxy(69, 1);
if (carrier())
cprintf("[Online ]");
else
cprintf("[Offline]");
if (mouse_exists) show_mouse();
step4:
if (mouse_exists) hide_mouse();
textcolor(msg_fg);
textbackground(msg_bg);
gotoxy(1, 2);
cprintf(
"│ Dialing File Terminal Modem Control Exit Help │");
/* 3 15 30 42 59 69 */
switch (menu_id)
{
case 1 :{sx1=2; sx2=34; sy1=3; sy2=18;
mx1=0; mx2=13;
cnt=13; plist=dial_menu;
gotoxy(2, 2);
textcolor(msg_bg);
textbackground(msg_fg);
cprintf(" Dialing ");
break;
}
case 2 :{sx1=14; sx2=65; sy1=3; sy2=18;
mx1=13; mx2=28;
cnt=9; plist=file_menu;
gotoxy(14, 2);
textcolor(msg_bg);
textbackground(msg_fg);
cprintf(" File ");
break;
}
case 3 :{sx1=29; sx2=61; sy1=3; sy2=18;
mx1=28; mx2=40;
cnt= 2; plist=term_menu;
gotoxy(29, 2);
textcolor(msg_bg);
textbackground(msg_fg);
cprintf(" Terminal ");
break;
}
case 4 :{sx1=41; sx2=73; sy1=3; sy2=18;
mx1=40; mx2=57;
cnt= 9; plist=modem_menu;
gotoxy(41, 2);
textcolor(msg_bg);
textbackground(msg_fg);
cprintf(" Modem Control ");
break;
}
case 5 :{sx1=58; sx2=79; sy1=3; sy2=18;
mx1=57; mx2=67;
cnt= 2; plist=exit_menu;
gotoxy(58, 2);
textcolor(msg_bg);
textbackground(msg_fg);
cprintf(" Exit ");
break;
}
case 6 :{sx1=59; sx2=79; sy1=3; sy2=18;
mx1=67; mx2=80;
cnt= 7; plist=help_menu;
gotoxy(68, 2);
textcolor(msg_bg);
textbackground(msg_fg);
cprintf(" Help ");
break;
}
}
textcolor(msg_fg);
textbackground(msg_bg);
put_parms_in_menu();
gettext(sx1, sy1, sx2, sy2, &our_screen[500]);
if (mouse_exists) show_mouse();
do_pulldown:
r = pulldown(sx1, sy1,
mx1, mx2,
msg_fg, msg_bg,
cnt, item_recall[menu_id-1],
plist);
item_recall[menu_id-1] = curr_item;
if (r < 1)
{
if (mouse_exists) hide_mouse();
puttext(sx1, sy1, sx2, sy2, &our_screen[500]);
if (mouse_exists) show_mouse();
}
if (r == 0 || r == -3) /* ESC; ALTX */
goto step99;
if (r == -4) /* mouse menu selection */
{
if (mouse_menu_x < 13) menu_id = 1;
else
if (mouse_menu_x < 28) menu_id = 2;
else
if (mouse_menu_x < 40) menu_id = 3;
else
if (mouse_menu_x < 57) menu_id = 4;
else
if (mouse_menu_x < 67) menu_id = 5;
else
menu_id = 6;
goto step4;
}
if (r == -1) /* RIGHT */
{
if (++menu_id == 7)
menu_id = 1;
goto step4;
}
if (r == -2) /* LEFT */
{
if (--menu_id == 0)
menu_id = 6;
goto step4;
}
if (menu_id == 1)
{
if (r < 11)
{
dial_phone(r-1);
if (!carrier())
goto do_pulldown;
}
else
if (r == 11)
{
dial_manually();
if (!carrier())
goto do_pulldown;
}
else
if (r == 13)
{
hangup_phone();
goto do_pulldown;
}
else
if (r == 12)
{
if (get_filename() != 0)
{
if (get_config(filename) != 0)
{
beep();
sprintf(string1, "Error with '%s': %s.",
filename,
config_msg[config_error]);
message(string1);
}
else
{
message("Phone Directory file loaded.");
}
goto do_pulldown;
}
}
if (mouse_exists) hide_mouse();
puttext(sx1, sy1, sx2, sy2, &our_screen[500]);
if (mouse_exists) show_mouse();
goto step99;
}
else
if (menu_id == 2)
{
if (r == 1)
{
if (!stats_in_progress)
{
transfer_type = XMODEM_RECV;
transfer_init = TRUE;
soh_char = SOH;
nak_char = NAK;
xfr_size = 132;
}
receive_xymodem();
}
else
if (r == 2)
{
if (!stats_in_progress)
{
transfer_type = YMODEM_RECV;
transfer_init = TRUE;
soh_char = STX;
nak_char = 'C';
xfr_size = 1029;
}
receive_xymodem();
}
else
if (r == 3)
{
if (!stats_in_progress)
{
transfer_type = KERMIT_RECV;
transfer_init = TRUE;
_eol = CR; /* EOL for outgoing packets */
_quote = '#'; /* Standard control-quote char "#" */
_pad = 0; /* No padding */
_padchar = 0; /* Use null if any padding wanted */
_image = TRUE; /* Default to no processing for */
_filnamcnv = FALSE; /* non-UNIX systems */
_escchr = ESCCHR; /* Default escape character */
}
receive_kermit();
}
else
if (r == 4)
{
if (!stats_in_progress)
{
transfer_type = ASCII_RECV;
transfer_init = TRUE;
byte_count = 0;
}
receive_ascii();
}
else
if (r == 5)
{
if (!stats_in_progress)
{
transfer_type = XMODEM_SEND;
transfer_init = TRUE;
soh_char = SOH;
nak_char = NAK;
xfr_size = 132;
}
send_xymodem();
}
else
if (r == 6)
{
if (!stats_in_progress)
{
transfer_type = YMODEM_SEND;
transfer_init = TRUE;
soh_char = STX;
nak_char = 'C';
xfr_size = 1029;
}
send_xymodem();
}
else
if (r == 7)
{
if (!stats_in_progress)
{
transfer_type = KERMIT_SEND;
transfer_init = TRUE;
_eol = CR; /* EOL for outgoing packets */
_quote = '#'; /* Standard control-quote char "#" */
_pad = 0; /* No padding */
_padchar = 0; /* Use null if any padding wanted */
_image = TRUE; /* Default to no processing for */
_filnamcnv = FALSE; /* non-UNIX systems */
_escchr = ESCCHR; /* Default escape character */
}
send_kermit();
}
else
if (r == 8)
{
if (!stats_in_progress)
{
transfer_type = ASCII_SEND;
transfer_init = TRUE;
byte_count = 0;
}
send_ascii();
}
else
if (r == 9)
{
capture_file();
}
if (mouse_exists) hide_mouse();
puttext(sx1, sy1, sx2, sy2, &our_screen[500]);
if (mouse_exists) show_mouse();
goto step99;
}
else
if (menu_id == 3)
{
set_term(r);
if (mouse_exists) hide_mouse();
puttext(sx1, sy1, sx2, sy2, &our_screen[500]);
if (mouse_exists) show_mouse();
goto step99;
}
else
if (menu_id == 4)
{
switch (r)
{
case 1 : {change_port(); break;}
case 2 : {change_baud(); break;}
case 3 : {change_data(); break;}
case 4 : {change_parity(); break;}
case 5 : {change_stop(); break;}
case 6 : {change_echo(); break;}
case 7 : {change_xon(); break;}
case 8 : {change_add_lf(); break;}
case 9 : {
gotoxy(44, 12);
textcolor(msg_bg);
textbackground(msg_fg);
cprintf(" (please wait...) ");
textcolor(reg_bg);
textbackground(reg_fg);
change_auto_answer();
break;
}
}
put_parms_in_menu();
if (re_open_flag)
{
re_open_flag = FALSE;
close_port();
i = open_port(our_port,our_speed,our_par,our_bits,our_stop);
}
dont_redraw = TRUE;
goto do_pulldown;
}
else
if (menu_id == 5)
{
leave_flag = TRUE;
if (r == 2)
{
de_install = TRUE;
if (!okay_to_unload())
message(
"Okay; will do it when offline & other programs gone.");
}
if (mouse_exists) hide_mouse();
puttext(sx1, sy1, sx2, sy2, &our_screen[500]);
if (mouse_exists) show_mouse();
goto step99;
}
else
if (menu_id == 6)
{
if (mouse_exists) hide_mouse();
puttext(sx1, sy1, sx2, sy2, &our_screen[500]);
restore_screen(1, 1, 80, 3, &our_screen[0], &cpos, &ctyp);
save_screen(1, 1, 80, 25, our_screen, &cpos, &ctyp);
show_help(r);
restore_screen(1, 1, 80, 25, our_screen, &cpos, &ctyp);
if (mouse_exists) show_mouse();
textcolor(reg_fg);
textbackground(reg_bg);
return r;
}
if (mouse_exists) hide_mouse();
puttext(sx1, sy1, sx2, sy2, &our_screen[500]);
if (mouse_exists) show_mouse();
goto step4;
step99:
sticky_menu = menu_id;
if (mouse_exists) hide_mouse();
if (first_menu_appearance)
{
first_menu_appearance = FALSE;
restore_screen(1, 1, 80, 3, &our_screen[0], &cpos, &ctyp);
textcolor(msg_fg);
textbackground(msg_bg);
gotoxy(1, 1);
cprintf(
" REMINDER: Alt-X to Exit. F2 for Menu. F1 for Help. ");
gotoxy(1, 2);
if (mouse_exists)
{
cprintf(
" Left Button for Menu. Right Button to Exit. ");
gotoxy(1, 3);
}
cprintf(
" (Press ─┘ to continue) ");
textcolor(reg_fg);
textbackground(reg_bg);
gotoxy(1, 1);
getkey();
}
restore_screen(1, 1, 80, 3, &our_screen[0], &cpos, &ctyp);
if (mouse_exists) show_mouse();
if (did_ascii_xfr)
{
did_ascii_xfr = FALSE;
term_type = term_type_save;
if (term_type == CHAT)
cls_bottom();
cls();
top_chat_x = top_chat_y = 1;
disp_line = curr_line;
extended_char = PGUPKEY;
scroll_buffer();
extended_char = ENDKEY;
scroll_buffer();
}
if (switch_to_chat)
{
switch_to_chat = FALSE;
cls();
top_chat_x = top_chat_y = 1;
disp_line = curr_line;
cls_bottom();
}
if (switch_from_chat)
{
switch_from_chat = FALSE;
window(1, 1, 80, 25);
textcolor(reg_fg);
textbackground(reg_bg);
cls();
top_chat_x = top_chat_y = 1;
disp_line = curr_line;
}
if (mouse_exists) hide_mouse();
save_screen(1, 1, 80, 25, our_screen, &cpos, &ctyp);
if (mouse_exists) show_mouse();
textcolor(reg_fg);
textbackground(reg_bg);
alt_menu = FALSE;
return r;
}
void actual_popup(void)
{
de_install = FALSE;
hot_flag = FALSE;
leave_flag = FALSE;
textcolor(reg_fg);
textbackground(reg_bg);
if (first_time)
{
first_time = FALSE;
cls();
gotoxy(1, 1);
save_screen(1,1,80,25, our_screen,
&our_cursor_save, &our_cursor_type);
}
if (!carrier() && set_answer)
{
set_answer = FALSE;
gotoxy(1, 25);
textcolor(msg_fg);
textbackground(msg_bg);
cprintf("Setting auto-answer (please wait)...");
if (auto_answer)
send_string(answer_on);
else
send_string(answer_off);
textcolor(reg_fg);
textbackground(reg_bg);
}
restore_screen(1,1,80,25, our_screen,
&our_cursor_save, &our_cursor_type);
if (mouse_exists && !mouse_shared)
show_mouse();
if (mouse_exists)
{
move_mouse(mouse_x_save, mouse_y_save);
}
if (stats_in_progress)
{
main_menu(2);
if (leave_flag)
goto exit_popup;
}
else
if (capturing)
{
cls();
top_chat_x = top_chat_y = 1;
disp_line = curr_line;
extended_char = PGUPKEY;
scroll_buffer();
extended_char = ENDKEY;
scroll_buffer();
}
if (!carrier())
{
main_menu(1);
if (leave_flag)
goto exit_popup;
}
each_char:
if (term_type == CHAT)
{
if (curr_line == disp_line)
gotoxy(bottom_chat_x, bottom_chat_y+16);
else
gotoxy(top_chat_x, top_chat_y);
}
if (hot_flag)
goto exit_popup;
if (break_flag)
{
getkey();
textcolor(msg_fg);
textbackground(msg_bg);
cprintf("*BREAK*");
send_break();
textcolor(reg_fg);
textbackground(reg_bg);
}
if (mouse_exists)
{
if (left_button_up())
{
if (carrier())
main_menu(sticky_menu);
else
main_menu(1);
}
else
if (right_button_up())
{
goto exit_popup;
}
}
if (alt_menu)
{
alt_menu = FALSE;
if (carrier())
main_menu(sticky_menu);
else
main_menu(1);
}
if (bioskey(1))
{
getkey();
if (key_char != 0)
{
send_char(key_char);
if (term_type == CHAT)
{
window(1, 17, 80, 25);
textcolor(msg_fg);
textbackground(msg_bg);
gotoxy(bottom_chat_x, bottom_chat_y);
display_chat_bottom(key_char);
bottom_chat_x = wherex();
bottom_chat_y = wherey();
textcolor(reg_fg);
textbackground(reg_bg);
window(1, 1, 80, 25);
}
}
else
if (extended_char == ALTC)
{
cls();
top_chat_x = top_chat_y = 1;
disp_line = curr_line;
}
else
if (extended_char == ALTX)
goto exit_popup;
else
if (extended_char == ALTH || extended_char == F1)
main_menu(6);
else
if (extended_char == F2)
{
if (!carrier()) sticky_menu = 1;
main_menu(sticky_menu);
}
else
if (extended_char == ALTD || extended_char == F3)
main_menu(1);
else
if (extended_char == ALTF || extended_char == F4)
main_menu(2);
else
if (extended_char == ALTT || extended_char == F5)
main_menu(3);
else
if (extended_char == ALTM || extended_char == F6)
main_menu(4);
else
if (extended_char == ALTE || extended_char == F7)
main_menu(5);
else
if (extended_char >= ALT1 && extended_char <= ALT9)
{
i = (int) extended_char;
i -= ALT1;
if (strlen(kbd_macro_list[i]) > 0)
send_string(kbd_macro_list[i]);
}
else
if ( extended_char == UPKEY
|| extended_char == DOWNKEY
|| extended_char == PGUPKEY
|| extended_char == PGDNKEY
|| extended_char == HOMEKEY
|| extended_char == ENDKEY)
scroll_buffer();
}
if (leave_flag)
goto exit_popup;
read_from_modem:
if (disp_line != curr_line)
goto each_char;
if ((c = get_modem()) != -1)
{
if (term_type == CHAT)
{
window(1, 1, 80, 16);
gotoxy(top_chat_x, top_chat_y);
bottom_line = 16;
}
display_char((char) c);
if (term_type == CHAT)
{
if (top_chat_x == 80)
{
display_char(CR);
display_char(LINEFEED);
}
window(1, 1, 80, 25);
}
}
goto each_char;
exit_popup:
hot_flag = FALSE;
leave_flag = FALSE;
if (mouse_exists)
{
get_mouse();
mouse_x_save = mouse_column;
mouse_y_save = mouse_row;
if (!mouse_shared)
hide_mouse();
}
if (transferring_file)
{
if (capturing)
DosClose(dup(capture_handle));
if (transfer_type != NO_TRANSFER)
DosClose(dup(transfer_handle));
}
save_screen(1,1,80,25, our_screen,
&our_cursor_save, &our_cursor_type);
}
int get_vid_mode(void)
{
_AH = 15;
geninterrupt(0x10);
_AH = 0;
temp1 = _AX;
return temp1;
}
void abort_transfer(void)
{
xfr_abort = TRUE;
transferring_file = FALSE;
beep();
delay(100);
beep();
DosClose(transfer_handle);
send_char(CTRLX);
send_char(CTRLX);
purge_buffer();
if (transfer_type == XMODEM_RECV || transfer_type == YMODEM_RECV)
unlink(filename);
}
void process_xymodem_char(void)
{
char this_block, prev_block;
int i;
if (x_index == 0 && xc == EOT)
{
eot_processed = TRUE;
DosClose(transfer_handle);
send_char(ACK);
transferring_file = FALSE;
beep();
return;
}
if (x_index == 0)
{
timeout_value = xticks;
crc = 0;
if (xc == SOH)
xfr_size = 132;
else
if (xc == STX)
xfr_size = 1029;
else
return;
}
xmodem_area[x_index++] = (char) xc;
nak_char = NAK;
if (xmodem_area[0] == STX && x_index > 3)
crc = updcrc(crc, xc);
if (x_index < xfr_size)
return;
x_index = 0;
this_block = (char) (int) (block_count + 1) % 256;
prev_block = (char) (int) (block_count) % 256;
if ( xmodem_area[1] != this_block
&& xmodem_area[1] != prev_block)
goto error_in_block;
if (xmodem_area[1] == prev_block)
{
send_char(ACK);
return;
}
if (xmodem_area[0] == SOH)
{
chksum = 0;
for (i=3; i<131; i++)
chksum+= xmodem_area[i];
if (chksum != xmodem_area[131])
goto error_in_block;
}
else
{
if (crc != 0)
goto error_in_block;
}
send_char(ACK);
errors_this_block = 0;
if (xmodem_area[0] == SOH)
io_len = DosWrite(transfer_handle, &xmodem_area[3], 128);
else
io_len = DosWrite(transfer_handle, &xmodem_area[3], 1024);
if (io_len == -1)
{
errors_this_block = 10;
goto error_in_block;
}
block_count++;
return;
error_in_block:
error_count++;
if (++errors_this_block >= 10)
abort_transfer();
else
{
purge_buffer();
send_char(NAK);
}
}
/************************************/
void build_xmodem_blk(void)
{
int blksize;
if (transfer_type == XMODEM_SEND)
blksize = 128;
else
blksize = 1024;
setmem(xmodem_area, xfr_size, 0);
io_len = DosRead(transfer_handle, &xmodem_area[3], blksize);
if (io_len == -1)
{
DosClose(transfer_handle);
return;
}
if (io_len == 0)
{
DosClose(transfer_handle);
xmodem_area[0] = EOT;
xfr_size = 1;
EOF_flag = TRUE;
return;
}
if (transfer_type == XMODEM_SEND)
xmodem_area[0] = SOH;
else
xmodem_area[0] = STX;
xmodem_area[1] = ( (unsigned char) ( (block_count+1) % 256 ) );
xmodem_area[2] = ~( (unsigned char) ( (block_count+1) % 256 ) );
if (transfer_type == YMODEM_SEND)
{
crc = 0;
for (i=3; i<1027; i++)
crc = updcrc(crc, xmodem_area[i]);
crc = updcrc(crc, '\0');
crc = updcrc(crc, '\0');
_DX = crc;
xmodem_area[1027] = _DH;
xmodem_area[1028] = _DL;
}
else
{
chksum = 0;
for (i=3; i<131; i++)
chksum+= xmodem_area[i];
xmodem_area[131] = chksum;
}
}
void background_xy_recv(void)
{
if (transfer_init)
{
transfer_init = FALSE;
transfer_handle = DosCreate(filename);
if (transfer_handle == -1)
{
transferring_file = FALSE;
xfr_abort = TRUE;
return;
}
purge_buffer();
send_char(nak_char);
}
if (user_abort)
{
abort_transfer();
return;
}
if ((xc = get_modem()) != -1)
{
process_xymodem_char();
timeout_ticks = tick_counter + timeout_value;
}
else
if (tick_counter > timeout_ticks)
{
error_count++;
timeout_ticks = tick_counter + timeout_value;
if (++errors_this_block >= 10)
abort_transfer();
else
send_char(nak_char);
}
}
void background_xy_send(void)
{
if (transfer_init)
{
transfer_init = FALSE;
transfer_handle = DosOpen(filename, 0);
if (transfer_handle == -1)
{
transferring_file = FALSE;
xfr_abort = TRUE;
return;
}
waiting_for_1st_nak = TRUE;
return;
}
if (user_abort)
{
abort_transfer();
return;
}
if (!output_queue_empty)
{
timeout_ticks = tick_counter + timeout_value;
next_fg_slice = tick_counter;
return;
}
if ((xc = get_modem()) == -1)
{
if (tick_counter > timeout_ticks)
{
error_count++;
timeout_ticks = tick_counter + timeout_value;
if (++errors_this_block >= 10)
abort_transfer();
}
return;
}
ch = (char) xc;
if (waiting_for_1st_nak)
{
timeout_value = xticks;
if (ch == NAK)
{
transfer_type = XMODEM_SEND;
xfr_size = 132;
nak_char = NAK;
soh_char = SOH;
}
else
if (ch == 'C')
{
transfer_type = YMODEM_SEND;
xfr_size = 1029;
nak_char = 'C';
soh_char = STX;
}
}
if (ch == ACK)
{
if (EOF_flag)
{
eot_processed = TRUE;
transferring_file = FALSE;
beep();
}
else
{
block_count++;
errors_this_block = 0;
prev_char = 0;
build_xmodem_blk();
for (x_index=0; x_index<xfr_size; x_index++)
send_char(xmodem_area[x_index]);
timeout_ticks = tick_counter + timeout_value;
}
return;
}
if (ch == nak_char)
{
prev_char = 0;
if (!waiting_for_1st_nak)
{
error_count++;
purge_buffer();
if ((++errors_this_block) >= 10)
{
abort_transfer();
return;
}
}
else
{
waiting_for_1st_nak = FALSE;
nak_char = NAK;
purge_buffer();
build_xmodem_blk();
}
for (x_index=0; x_index<xfr_size; x_index++)
send_char(xmodem_area[x_index]);
timeout_ticks = tick_counter + timeout_value;
return;
}
if (ch == CTRLX && prev_char == CTRLX)
{
abort_transfer();
return;
}
prev_char = ch;
}
void write_tty(buffer, nbytes)
char *buffer;
int nbytes;
{
int i;
for (i=0; i<nbytes; i++)
{
send_char(*buffer);
buffer++;
}
}
/*
* s e n d s w
*
* Sendsw is the state table switcher for sending files.
*
*/
void sendsw(void)
{
switch(_state)
{
case 'S': _state = sinit(); return; /* Send-Init */
case 'F': _state = sfile(); return; /* Send-File */
case 'D': _state = sdata(); return; /* Send-Data */
case 'Z': _state = seof(); return; /* Send-End-of-File */
case 'B': _state = sbreak(); return; /* Send-Break */
case 'C': transferring_file=FALSE; /* Complete */
beep();
return;
case 'A': transferring_file=FALSE; /* "Abort" */
beep();
xfr_abort = TRUE;
return;
default: transferring_file=FALSE; /* Unknown, fail */
beep();
xfr_abort = TRUE;
return;
}
}
/*
* s i n i t
*
* Send Initiate: send this host's parameters and get other side's back.
*/
char sinit()
{
static int num; /* Packet number */
static int len; /* length */
if (!rpack_done) goto rpack_continue;
num = len = 0;
if (error_count++ > MAXTRY) return('A'); /* If too many tries, give up */
spar(_packet); /* Fill up init info packet */
purge_buffer(); /* Flush pending input */
spack((char)'S',_packnum,10,_packet); /* Send an S packet */
rpack_continue:
switch(rpack(&len,&num,_recpkt)) /* What was the reply? */
{
case 'I': return(_state); /* Incomplete */
case 'N': return(_state); /* NAK, try it again */
case 'Y': /* ACK */
if (_packnum != num) /* If wrong ACK, stay in S state */
return(_state); /* and try again */
rpar(_recpkt); /* Get other side's init info */
if (_eol == 0) _eol = '\n'; /* Check and set defaults */
if (_quote == 0) _quote = '#';
error_count = 0; /* Reset try counter */
_packnum = (_packnum+1)%64; /* Bump packet count */
block_count++;
return('F'); /* OK, switch state to F */
case 'E': /* Error packet received */
return('A'); /* abort */
case FALSE: return(_state); /* Receive failure, try again */
default: return('A'); /* Anything else, just "abort" */
}
}
/*
* s f i l e
*
* Send File Header.
*/
char sfile()
{
static int num; /* Packet number */
static int len; /* length */
static char *new_filnam; /* Pointer to file name to send */
static char *cp; /* char pointer */
if (!rpack_done) goto rpack_continue;
num = len = 0;
if (error_count++ > MAXTRY) return('A'); /* If too many tries, give up */
transfer_handle = DosOpen(filename, 0); /* open the file to be sent */
if (transfer_handle == -1)
{
spack((char)'E',_packnum,15,"file open error"); /* Send error packet */
return('A');
}
new_filnam = cp = filename;
while (*cp != '\0') /* Strip off all leading directory */
if (*cp++ == '\\') /* names (ie. up to the last /). */
new_filnam = cp;
len = cp - new_filnam; /* Compute length of new filename */
spack((char)'F',_packnum,len,new_filnam); /* Send an F packet */
rpack_continue:
switch(rpack(&len,&num,_recpkt)) /* What was the reply? */
{
case 'I': return(_state); /* Incomplete */
case 'N': /* NAK, just stay in this state, */
num = (--num<0 ? 63:num); /* unless it's NAK for next packet */
if (_packnum != num) /* which is just like an ACK for */
return(_state); /* this packet so fall thru to... */
case 'Y': /* ACK */
if (_packnum != num) return(_state); /* If wrong ACK, stay in F state */
error_count = 0; /* Reset try counter */
_packnum = (_packnum+1)%64; /* Bump packet count */
block_count++;
if ((_sizedata = bufill(_packet)) == -1) /* Get data from file */
{
if (io_len == -1) return('A');
return('Z'); /* If EOF set state to that */
}
return('D'); /* Switch state to D */
case 'E': /* Error packet received */
return('A'); /* abort */
case FALSE: return(_state); /* Receive failure, stay in F state */
default: return('A'); /* Something else, just "abort" */
}
}
/*
* s d a t a
*
* Send File Data
*/
char sdata()
{
static int num; /* Packet number */
static int len; /* length */
if (!rpack_done) goto rpack_continue;
num = len = 0;
if (error_count++ > MAXTRY) return('A'); /* If too many tries, give up */
spack((char)'D',_packnum,_sizedata,_packet); /* Send a D packet */
rpack_continue:
switch(rpack(&len,&num,_recpkt)) /* What was the reply? */
{
case 'I': return(_state); /* Incomplete */
case 'N': /* NAK, just stay in this state, */
num = (--num<0 ? 63:num); /* unless it's NAK for next packet */
if (_packnum != num) /* which is just like an ACK for */
return(_state); /* this packet so fall thru to... */
case 'Y': /* ACK */
if (_packnum != num) return(_state); /* If wrong ACK, fail */
error_count = 0; /* Reset try counter */
_packnum = (_packnum+1)%64; /* Bump packet count */
block_count++;
if ((_sizedata = bufill(_packet)) == -1) /* Get data from file */
{
if (io_len == -1) return('A');
return('Z'); /* If EOF set state to that */
}
return('D'); /* Got data, stay in state D */
case 'E': /* Error packet received */
return('A'); /* abort */
case FALSE: return(_state); /* Receive failure, stay in D */
default: return('A'); /* Anything else, "abort" */
}
}
/*
* s e o f
*
* Send End-Of-File.
*/
char seof()
{
static int num; /* Packet number */
static int len; /* length */
if (!rpack_done) goto rpack_continue;
num = len = 0;
if (error_count++ > MAXTRY) return('A'); /* If too many tries, "abort" */
spack((char)'Z',_packnum,0,_packet); /* Send a 'Z' packet */
rpack_continue:
switch(rpack(&len,&num,_recpkt)) /* What was the reply? */
{
case 'I': return(_state); /* Incomplete */
case 'N': /* NAK, just stay in this state, */
num = (--num<0 ? 63:num); /* unless it's NAK for next packet, */
if (_packnum != num) /* which is just like an ACK for */
return(_state); /* this packet so fall thru to... */
case 'Y': /* ACK */
if (_packnum != num) return(_state); /* If wrong ACK, hold out */
error_count = 0; /* Reset try counter */
_packnum = (_packnum+1)%64; /* and bump packet count */
block_count++;
DosClose(transfer_handle); /* Close the input file */
if (gnxtfl() == FALSE) /* No more files go? */
return('B'); /* if not, break, EOT, all done */
return('F'); /* More files, switch state to F */
case 'E': /* Error packet received */
return('A'); /* abort */
case FALSE: return(_state); /* Receive failure, stay in Z */
default: return('A'); /* Something else, "abort" */
}
}
/*
* s b r e a k
*
* Send Break (EOT)
*/
char sbreak()
{
static int num; /* Packet number */
static int len; /* length */
if (!rpack_done) goto rpack_continue;
num = len = 0;
if (error_count++ > MAXTRY) return('A'); /* If too many tries "abort" */
spack((char)'B',_packnum,0,_packet); /* Send a B packet */
rpack_continue:
switch (rpack(&len,&num,_recpkt)) /* What was the reply? */
{
case 'I': return(_state); /* Incomplete */
case 'N': /* NAK, just stay in this state, */
num = (--num<0 ? 63:num); /* unless NAK for previous packet, */
if (_packnum != num) /* which is just like an ACK for */
return(_state); /* this packet so fall thru to... */
case 'Y': /* ACK */
if (_packnum != num) return(_state); /* If wrong ACK, fail */
error_count = 0; /* Reset try counter */
_packnum = (_packnum+1)%64; /* and bump packet count */
block_count++;
return('C'); /* Switch state to Complete */
case 'E': /* Error packet received */
return('A'); /* abort */
case FALSE: return(_state); /* Receive failure, stay in B */
default: return ('A'); /* Other, "abort" */
}
}
/*
* r e c s w
*
* This is the _state table switcher for receiving files.
*/
void recsw(void)
{
switch(_state)
{
case 'R': _state = rinit(); return; /* Receive-Init */
case 'F': _state = rfile(); return; /* Receive-File */
case 'D': _state = rdata(); return; /* Receive-Data */
case 'C': transferring_file=FALSE; /* Complete state */
beep();
return;
case 'A': transferring_file=FALSE; /* "Abort" state */
beep();
xfr_abort = TRUE;
return;
default: transferring_file=FALSE; /* Unknown, fail */
beep();
xfr_abort = TRUE;
return;
}
}
/*
* r i n i t
*
* Receive Initialization
*/
char rinit()
{
static int num; /* Packet number */
static int len; /* length */
if (!rpack_done) goto rpack_continue;
num = len = 0;
if (error_count++ > MAXTRY) return('A'); /* If too many tries, "abort" */
rpack_continue:
switch(rpack(&len,&num,_packet)) /* Get a packet */
{
case 'I': return(_state); /* Incomplete */
case 'S': /* Send-Init */
rpar(_packet); /* Get the other side's init data */
spar(_packet); /* Fill up packet with my init info */
spack((char)'Y',_packnum,10,_packet);/* ACK with my parameters */
_oldtry = error_count; /* Save old try count */
error_count = 0; /* Start a new counter */
_packnum = (_packnum+1)%64; /* Bump packet number, mod 64 */
block_count++;
return('F'); /* Enter File-Receive state */
case 'E': /* Error packet received */
return('A'); /* abort */
case FALSE: /* Didn't get packet */
spack((char)'N',_packnum,0,NULL); /* Return a NAK */
return(_state); /* Keep trying */
default: return('A'); /* Some other packet type, "abort" */
}
}
/*
* r f i l e
*
* Receive File Header
*/
char rfile()
{
static int num; /* Packet number */
static int len; /* length */
static int fch_cnt; /* filename char count */
if (!rpack_done) goto rpack_continue;
num = len = fch_cnt = 0;
if (error_count++ > MAXTRY) return('A'); /* "abort" if too many tries */
rpack_continue:
switch(rpack(&len,&num,_packet)) /* Get a packet */
{
case 'I': return(_state); /* Incomplete */
case 'S': /* Send-Init, maybe our ACK lost */
if (_oldtry++ > MAXTRY) return('A'); /* If too many tries "abort" */
if (num == ((_packnum==0) ? 63:_packnum-1)) /* Previous packet, mod 64? */
{ /* Yes, ACK it again with */
spar(_packet); /* our Send-Init parameters */
spack((char)'Y',num,10,_packet);
error_count = 0; /* Reset try counter */
return(_state); /* Stay in this state */
}
else return('A'); /* Not previous packet, "abort" */
case 'Z': /* End-Of-File */
if (_oldtry++ > MAXTRY) return('A');
if (num == ((_packnum==0) ? 63:_packnum-1)) /* Previous packet, mod 64? */
{ /* Yes, ACK it again. */
spack((char)'Y',num,0,NULL);
error_count = 0;
return(_state); /* Stay in this state */
}
else return('A'); /* Not previous packet, "abort" */
case 'F': /* File Header (just what we want) */
if (num != _packnum) return('A'); /* The packet number must be right */
_packet[12] = '\0';
setmem(filename, 80, 0);
while (_packet[fch_cnt] && fch_cnt < 8 && _packet[fch_cnt] != '.')
{
filename[fch_cnt] = _packet[fch_cnt];
fch_cnt++;
}
if (_packet[fch_cnt] == '.')
while (_packet[fch_cnt] && fch_cnt < 12)
{
filename[fch_cnt] = _packet[fch_cnt];
fch_cnt++;
}
strcpy(string2, filename);
strcpy(filename, kermit_path);
strcat(filename, string2);
if ((transfer_handle=DosCreate(filename))==-1) /* open new file */
{
spack((char)'E',_packnum,17,"file create error"); /* Send error packet */
return('A');
}
spack((char)'Y',_packnum,0,NULL); /* Acknowledge the file header */
_oldtry = error_count; /* Reset try counters */
error_count = 0; /* ... */
_packnum = (_packnum+1)%64; /* Bump packet number, mod 64 */
block_count++;
return('D'); /* Switch to Data state */
case 'B': /* Break transmission (EOT) */
if (num != _packnum) return ('A'); /* Need right packet number here */
spack((char)'Y',_packnum,0,NULL); /* Say OK */
return('C'); /* Go to complete state */
case 'E': /* Error packet received */
return('A'); /* abort */
case FALSE: /* Didn't get packet */
spack((char)'N',_packnum,0,NULL); /* Return a NAK */
return(_state); /* Keep trying */
default: return ('A'); /* Some other packet, "abort" */
}
}
/*
* r d a t a
*
* Receive Data
*/
char rdata()
{
static int num; /* Packet number */
static int len; /* length */
if (!rpack_done) goto rpack_continue;
num = len = 0;
if (error_count++ > MAXTRY) return('A'); /* "abort" if too many tries */
rpack_continue:
switch(rpack(&len,&num,_packet)) /* Get packet */
{
case 'I': return(_state); /* Incomplete */
case 'D': /* Got Data packet */
if (num != _packnum) /* Right packet? */
{ /* No */
if (_oldtry++ > MAXTRY)
return('A'); /* If too many tries, abort */
if (num == ((_packnum==0) ? 63:_packnum-1)) /* Else check packet number */
{ /* Previous packet again? */
spack((char)'Y',num,0,_packet); /* Yes, re-ACK it */
error_count = 0; /* Reset try counter */
return(_state); /* Don't write out data! */
}
else return('A'); /* sorry, wrong number */
}
/* Got data with right packet number */
bufemp(_packet,len); /* Write the data to the file */
if (io_len == -1) return('A');
spack((char)'Y',_packnum,0,NULL); /* Acknowledge the packet */
_oldtry = error_count; /* Reset the try counters */
error_count = 0; /* ... */
_packnum = (_packnum+1)%64; /* Bump packet number, mod 64 */
block_count++;
return('D'); /* Remain in data state */
case 'F': /* Got a File Header */
if (_oldtry++ > MAXTRY)
return('A'); /* If too many tries, "abort" */
if (num == ((_packnum==0) ? 63:_packnum-1)) /* Else check packet number */
{ /* It was the previous one */
spack((char)'Y',num,0,NULL); /* ACK it again */
error_count = 0; /* Reset try counter */
return(_state); /* Stay in Data state */
}
else return('A'); /* Not previous packet, "abort" */
case 'Z': /* End-Of-File */
if (num != _packnum) return('A'); /* Must have right packet number */
spack((char)'Y',_packnum,0,NULL); /* OK, ACK it. */
DosClose(transfer_handle); /* Close the file */
_packnum = (_packnum+1)%64; /* Bump packet number */
block_count++;
return('F'); /* Go back to Receive File state */
case 'E': /* Error packet received */
return('A'); /* abort */
case FALSE: /* Didn't get packet */
spack((char)'N',_packnum,0,NULL); /* Return a NAK */
return(_state); /* Keep trying */
default: return('A'); /* Some other packet, "abort" */
}
}
/*
* s p a c k
*
* Send a Packet
*/
spack(type,num,len,data)
char type, *data;
int num, len;
{
int i, j; /* Character loop counters */
char chksum, buffer[100]; /* Checksum, packet buffer */
register char *bufp; /* Buffer pointer */
bufp = buffer; /* Set up buffer pointer */
for (i=1; i<=_pad; i++)
write_tty(&_padchar, 1); /* Issue any padding */
*bufp++ = SOH; /* Packet marker, ASCII 1 (SOH) */
*bufp++ = tochar(len+3); /* Send the character count */
chksum = tochar(len+3); /* Initialize the checksum */
*bufp++ = tochar(num); /* Packet number */
chksum += tochar(num); /* Update checksum */
*bufp++ = type; /* Packet type */
chksum += type; /* Update checksum */
for (i=0; i<len; i++) /* Loop for all data characters */
{
*bufp++ = data[i]; /* Get a character */
chksum += data[i]; /* Update checksum */
}
chksum = (((chksum&0300) >> 6)+chksum)&077; /* Compute final checksum */
*bufp++ = tochar(chksum); /* Put it in the packet */
*bufp = _eol; /* Extra-packet line terminator */
j = bufp - buffer + 1;
write_tty(buffer, j); /* Send the packet */
return(0);
}
/*
* r p a c k
*
* Read a Packet
*/
char rpack(len,num,data)
int *len;
int *num; /* Packet length, number */
char *data; /* Packet data */
{
static int i; /* Data character number */
static char t; /* Current input character */
static int ti; /* Current input character */
static char type; /* Packet type */
static char cchksum; /* Our (computed) checksum */
static char rchksum; /* Checksum received from other host */
static int rp_state;
if (rp_state == 0)
{
i = t = type = cchksum = rchksum = 0;
timeout_ticks = tick_counter + 18l + (long) (_timint * 18);
rp_state = 1;
}
read_tty:
if (!output_queue_empty)
{
timeout_ticks = tick_counter + 18l + (long) (_timint * 18);
next_fg_slice = tick_counter;
rpack_done = FALSE;
return('I');
}
ti = get_modem();
if (ti == -1)
{
if (tick_counter > timeout_ticks)
{
rpack_done = TRUE;
rp_state = 0;
return(FALSE);
}
rpack_done = FALSE;
return('I');
}
t = (unsigned char) ti;
switch (rp_state)
{
case 1 : goto rp_soh;
case 2 : goto rp_len;
case 3 : goto rp_num;
case 4 : goto rp_type;
case 5 : goto rp_dat;
case 6 : goto rp_chksum;
case 7 : goto rp_eol;
default: goto read_tty;
}
rp_soh:
t &= 0177; /* Handle parity */
if (t == SOH) rp_state = 2;
goto read_tty;
rp_len:
if (!_image) t &= 0177; /* Handle parity */
if (t == SOH) goto rp_soh; /* Resynchronize if SOH */
cchksum = t; /* Start the checksum */
*len = unchar(t) - 3; /* Character count */
rp_state = 3;
goto read_tty;
rp_num:
if (!_image) t &= 0177; /* Handle parity */
if (t == SOH) goto rp_soh; /* Resynchronize if SOH */
cchksum = cchksum + t; /* Update checksum */
*num = unchar(t); /* Packet number */
rp_state = 4;
goto read_tty;
rp_type:
if (!_image) t &= 0177; /* Handle parity */
if (t == SOH) goto rp_soh; /* Resynchronize if SOH */
cchksum = cchksum + t; /* Update checksum */
type = t; /* Packet type */
if (*len == 0)
rp_state = 6;
else
rp_state = 5;
goto read_tty;
rp_dat:
if (!_image) t &= 0177; /* Handle parity */
if (t == SOH) goto rp_soh; /* Resynch if SOH */
cchksum = cchksum + t; /* Update checksum */
data[i] = t; /* Put it in the data buffer */
if (++i == *len)
rp_state = 6;
goto read_tty;
rp_chksum:
data[*len] = 0; /* Mark the end of the data */
rchksum = unchar(t); /* Convert to numeric */
rp_state = 7;
goto read_tty;
rp_eol:
if (!_image) t &= 0177; /* Handle parity */
if (t == SOH) goto rp_soh; /* Resynchronize if SOH */
rpack_done = TRUE; /* Got checksum, done */
rp_state = 0;
/* Fold in bits 7,8 to compute */
/* final checksum */
cchksum = (((cchksum&0300) >> 6)+cchksum)&077;
if (cchksum != rchksum) return(FALSE);
return(type); /* All OK, return packet type */
}
/*
* b u f i l l
*
* Get a bufferful of data from the file that's being sent.
* Only control-quoting is done; 8-bit & repeat count prefixes are
* not handled.
*/
bufill(buffer)
char buffer[]; /* Buffer */
{
int i = 0; /* Loop index */
char t = 0; /* Char read from file */
char t7 = 0; /* 7-bit version of above */
i = 0; /* Init data buffer pointer */
while ((io_len = DosRead(transfer_handle, &t, 1)) != 0)
{
if (io_len == -1) return -1;
t7 = t & 0177; /* Get low order 7 bits */
if (t7 < SP || t7==DEL || t7==_quote) /* Does this char require */
{ /* special handling? */
if (t=='\n' && !_image)
{ /* Do LF->CRLF mapping if !_image */
buffer[i++] = _quote;
buffer[i++] = ctl('\r');
}
buffer[i++] = _quote; /* Quote the character */
if (t7 != _quote)
{
t = ctl(t); /* and uncontrolify */
t7 = ctl(t7);
}
}
if (_image)
buffer[i++] = t; /* Deposit the character itself */
else
buffer[i++] = t7;
if (i >= _spsiz-8) return(i); /* Check length */
}
if (i==0) return(-1); /* Wind up here only on EOF */
return(i); /* Handle partial buffer */
}
/*
* b u f e m p
*
* Put data from an incoming packet into a file.
*/
bufemp(buffer,len)
char buffer[]; /* Buffer */
int len; /* Length */
{
int i; /* Counter */
char t; /* Character holder */
for (i=0; i<len; i++) /* Loop thru the data field */
{
t = buffer[i]; /* Get character */
if (t == MYQUOTE) /* Control _quote? */
{ /* Yes */
t = buffer[++i]; /* Get the _quoted character */
if ((t & 0177) != MYQUOTE) /* Low order bits match _quote char? */
t = ctl(t); /* No, uncontrollify it */
}
if (t==CR && !_image) /* Don't pass CR if in _image mode */
continue;
io_len = DosWrite(transfer_handle, &t, 1);
if (io_len == -1)
return -1;
}
return(0);
}
/*
* g n x t f l
*
* Get next file in a file group
*/
gnxtfl()
{
if (_filecount == 0)
return(FALSE); /* If no more, fail */
strcpy(filename, *_filelist);
_filelist++;
_filecount--;
return(TRUE); /* else succeed */
}
/*
* s p a r
*
* Fill the data array with my send-init parameters
*
*/
spar(data)
char data[];
{
data[0] = tochar(MAXPACKSIZ); /* Biggest packet I can receive */
data[1] = tochar(MYTIME); /* When I want to be timed out */
data[2] = tochar(MYPAD); /* How much padding I need */
data[3] = ctl(MYPCHAR); /* Padding character I want */
data[4] = tochar(MYEOL); /* End-Of-Line character I want */
data[5] = MYQUOTE; /* Control-Quote character I send */
data[6] = (char) 'N'; /* Say no to 8th-bit quoting */
data[7] = (char) '1'; /* Single-char Checksum */
data[8] = (char) ' '; /* Repeat char (none) */
data[9] = (char) ' '; /* No particular capabilities */
return(0);
}
/* r p a r
*
* Get the other host's send-init parameters
*
*/
rpar(data)
char data[];
{
_spsiz = unchar(data[0]); /* Maximum send packet size */
_timint = unchar(data[1]); /* When I should time out */
_pad = unchar(data[2]); /* Number of pads to send */
_padchar = ctl(data[3]); /* Padding character to send */
_eol = unchar(data[4]); /* EOL character I must send */
_quote = data[5]; /* Incoming data _quote character */
if (_timint < MINTIM) _timint = MINTIM;
if (_timint > MAXTIM) _timint = MAXTIM;
return(0);
}
void background_kermit_send(void)
{
if (transfer_init)
{
transfer_init = FALSE;
_state = 'S'; /* Send initiate is the start state */
_packnum = 0; /* Initialize message number */
_timint = MYTIME;
if (gnxtfl() == FALSE)
{
transferring_file = FALSE;
return;
}
}
if (user_abort)
{
xfr_abort = TRUE;
user_abort = FALSE;
beep();
delay(100);
beep();
transferring_file = FALSE;
return;
}
if (!output_queue_empty)
{
next_fg_slice = tick_counter;
return;
}
sendsw();
}
void background_kermit_recv(void)
{
if (transfer_init)
{
transfer_init = FALSE;
_state = 'R'; /* Receive-Init is the start state */
_packnum = 0; /* Initialize message number */
_timint = MYTIME;
}
if (user_abort)
{
xfr_abort = TRUE;
user_abort = FALSE;
beep();
delay(100);
beep();
unlink(filename);
transferring_file = FALSE;
return;
}
recsw();
}
void background_ascii_send(void)
{
int r, i;
char c;
if (transfer_init)
{
transfer_init = FALSE;
oldx = oldy = 1;
transfer_handle = DosOpen(filename, 0);
if (transfer_handle == -1)
{
transferring_file = FALSE;
xfr_abort = TRUE;
return;
}
}
if (user_abort)
{
DosClose(transfer_handle);
xfr_abort = TRUE;
user_abort = FALSE;
beep();
transferring_file = FALSE;
return;
}
if (in_popup)
{
window(2, 17, 79, 24);
gotoxy(oldx, oldy);
textcolor(msg_fg);
textbackground(msg_bg);
while (tick_counter < next_fg_slice - 1l
&& (i = get_modem()) != -1 )
display_char( (char) i);
}
if (!output_queue_empty)
{
next_fg_slice = tick_counter;
goto bg_ascii_exit;
}
io_len = DosRead(transfer_handle, xmodem_area, 512);
if (io_len <= 0)
{
transferring_file = FALSE;
DosClose(transfer_handle);
beep();
goto bg_ascii_exit;
}
for (r=0; r<io_len; r++)
{
c = xmodem_area[r];
if ( (c != LINEFEED) || (c == LINEFEED && send_crlf) )
send_char(c);
delay(char_delay);
if (c == CR)
delay(line_delay);
}
if (in_popup)
while (tick_counter < next_fg_slice
&& (i = get_modem()) != -1 )
display_char( (char) i);
byte_count += (long) io_len;
bg_ascii_exit:
if (in_popup)
{
oldx = wherex();
oldy = wherey();
window(1, 1, 80, 25);
}
}
void background_ascii_recv(void)
{
char c;
if (transfer_init)
{
transfer_init = FALSE;
oldx = oldy = 1;
transfer_handle = DosCreate(filename);
if (transfer_handle == -1)
{
transferring_file = FALSE;
xfr_abort = TRUE;
return;
}
}
if (user_abort)
{
xfr_abort = TRUE;
user_abort = FALSE;
DosClose(transfer_handle);
beep();
transferring_file = FALSE;
return;
}
if (in_popup)
{
window(2, 17, 79, 24);
gotoxy(oldx, oldy);
textcolor(msg_fg);
textbackground(msg_bg);
}
if ((xc = get_modem()) != -1)
{
c = (char) xc;
if (in_popup) display_char(c);
io_len = DosWrite(transfer_handle, &c, 1);
if (io_len == -1)
{
xfr_abort = TRUE;
user_abort = FALSE;
DosClose(transfer_handle);
beep();
transferring_file = FALSE;
return;
}
timeout_ticks = tick_counter + timeout_value;
byte_count++;
}
else
if (tick_counter > timeout_ticks)
{
timeout_ticks = tick_counter + timeout_value;
beep();
delay(100);
beep();
}
if (in_popup)
{
oldx = wherex();
oldy = wherey();
window(1, 1, 80, 25);
}
}
/* ----------------------------------------------- */
void do_transfer(void)
{
if (tick_counter < next_bg_slice)
return;
if (in_popup)
goto calc_slice;
disable();
old_ss = _SS;
old_sp = _SP;
_SS = our_ss;
_SP = our_sp;
enable();
break_state = getcbrk();
oldint1b = getvect(0x1b);
setvect(0x1b, int1b);
oldint1c = getvect(0x1c);
setvect(0x1c, int1c);
oldint23 = getvect(0x23);
setvect(0x23, int23);
oldint24 = getvect(0x24);
setvect(0x24, int24);
olddta_ptr = getdta();
setdta(ourdta_ptr);
_AX = 0x5100;
geninterrupt(0x21);
oldpsp = _BX;
_AX = 0x5000;
_BX = ourpsp;
geninterrupt(0x21);
calc_slice:
if (in_popup)
next_fg_slice = tick_counter + 9l;
else
next_fg_slice = tick_counter + background_ticks;
while (transferring_file && tick_counter < next_fg_slice)
{
switch (transfer_type)
{
case XMODEM_RECV : {background_xy_recv(); break;}
case YMODEM_RECV : {background_xy_recv(); break;}
case XMODEM_SEND : {background_xy_send(); break;}
case YMODEM_SEND : {background_xy_send(); break;}
case KERMIT_SEND : {background_kermit_send(); break;}
case KERMIT_RECV : {background_kermit_recv(); break;}
case ASCII_SEND : {background_ascii_send(); break;}
case ASCII_RECV : {background_ascii_recv(); break;}
default : {
if (capturing && !in_popup)
get_modem();
break;
}
}
}
if (in_popup)
{
next_bg_slice = tick_counter + 1l;
return;
}
if (transferring_file && tick_counter > commit_ticks)
{
if (capturing)
DosClose(dup(capture_handle));
if (transfer_type != NO_TRANSFER)
DosClose(dup(transfer_handle));
commit_ticks = tick_counter + 182l;
}
next_bg_slice = tick_counter + foreground_ticks;
_AX = 0x5000;
_BX = oldpsp;
geninterrupt(0x21);
setdta(olddta_ptr);
setvect(0x24, oldint24);
setvect(0x23, oldint23);
setvect(0x1c, oldint1c);
setvect(0x1b, oldint1b);
setcbrk(break_state);
reset_bg_stack:
disable();
_SS = old_ss;
_SP = old_sp;
enable();
}
void do_popup(void)
{
disable();
old_ss = _SS;
old_sp = _SP;
_SS = our_ss;
_SP = our_sp;
enable();
if (de_install)
{
if (!okay_to_unload()) goto do_popup_exit;
_AX = 0x5000;
_BX = ourpsp;
geninterrupt(0x21);
close_port();
setvect(0x08, oldint08);
setvect(0x28, oldint28);
setvect(0x09, oldint09);
setvect(0x10, oldint10);
setvect(0x13, oldint13);
setvect(0x16, oldint16);
setvect(0x21, oldint21);
_ES = ourpsp;
_BX = 0x2c;
asm mov es, es:[bx]
_AH = 0x49;
geninterrupt(0x21);
_ES = ourpsp;
_AH = 0x49;
geninterrupt(0x21);
asm mov ax, word ptr next_mcb+2
asm inc ax
asm mov es, ax
_AH = 0x49;
geninterrupt(0x21);
_AX = 0x4c00;
geninterrupt(0x21);
}
process_popup:
curr_vid_mode = get_vid_mode();
if (curr_vid_mode != 2
&& curr_vid_mode != 3
&& curr_vid_mode != 7)
{
beep();
delay(100);
beep();
hot_flag = FALSE;
goto do_popup_exit;
}
if (in_background) goto regain_com_port;
break_state = getcbrk();
oldint1b = getvect(0x1b);
setvect(0x1b, int1b);
oldint1c = getvect(0x1c);
setvect(0x1c, int1c);
oldint23 = getvect(0x23);
setvect(0x23, int23);
oldint24 = getvect(0x24);
setvect(0x24, int24);
olddta_ptr = getdta();
setdta(ourdta_ptr);
_AX = 0x5100;
geninterrupt(0x21);
oldpsp = _BX;
_AX = 0x5000;
_BX = ourpsp;
geninterrupt(0x21);
regain_com_port:
switch (port_id)
{
case 1 : vecthold = getvect(0x0c); break;
case 2 : vecthold = getvect(0x0b); break;
case 3 : vecthold = getvect(0x0c); break;
case 4 : vecthold = getvect(0x0b); break;
default: vecthold = NULL;
}
if (vectsave != vecthold)
open_port(port_id,speedsave,paritysave,bitssave,stop_bitsave);
save_screen(1,1,80,25, app_screen,
&app_cursor_save, &app_cursor_type);
actual_popup();
restore_screen(1,1,80,25, app_screen,
&app_cursor_save, &app_cursor_type);
if (in_background) goto do_popup_exit;
_AX = 0x5000;
_BX = oldpsp;
geninterrupt(0x21);
setdta(olddta_ptr);
setvect(0x24, oldint24);
setvect(0x23, oldint23);
setvect(0x1c, oldint1c);
setvect(0x1b, oldint1b);
setcbrk(break_state);
do_popup_exit:
disable();
_SS = old_ss;
_SP = old_sp;
enable();
}
/* ------------------------------------------- */
void main(int argc, char *argv[])
{
getdate(&today);
_AX = 'SN';
geninterrupt(0x16);
if (_AX == 'sn')
{
cprintf("\r\n");
cprintf("The background comm. program was already loaded.\r\n");
cprintf("Use ALT/RIGHT-SHIFT to activate it.\r\n");
exit(1);
}
if (_osmajor < 2)
{
cprintf("\r\n");
cprintf("Early versions of DOS not supported...\r\n");
exit(1);
}
if ( (our_stack = malloc(MY_STK_SIZE)) == NULL)
{
cprintf("\r\n");
cprintf("Insufficient memory...\r\n");
exit(1);
}
our_ss = _DS;
our_sp = (unsigned) our_stack + (MY_STK_SIZE - 2);
flow_control = TRUE;
rpack_done = TRUE;
setmem(holdstr, 81, 0);
init_line_pointers();
mouse_exists = TRUE;
if ((get_config("comm.cfg")) != 0)
{
sprintf(string1, "Error with 'comm.cfg': %s.",
config_msg[config_error]);
cprintf("\r\n");
cprintf("Program not loaded. The configuration file is in error.\r\n");
cprintf("%s\r\n", string1);
cprintf(
"Please use the text editor to correct the 'comm.cfg' file.\r\n");
exit(1);
}
if (mouse_exists)
mouse_init();
if (mouse_exists && mouse_shared)
show_mouse();
_AX = 0x3400;
geninterrupt(0x21);
temp2 = _BX;
temp1 = _ES;
indos_ptr = MK_FP(temp1, temp2);
if (_osmajor == 2)
indos2_ptr = MK_FP(temp1, temp2 + 1);
else
indos2_ptr = MK_FP(temp1, temp2 - 1);
delay(10);
prtsc_flag_ptr = MK_FP(0x0050, 0x0000);
kbd_flag_ptr = MK_FP(0x0040, 0x0017);
oldint0b = getvect(0x0b);
oldint0c = getvect(0x0c);
i = open_port(our_port,our_speed,our_par,our_bits,our_stop);
if (i == -1)
{
cprintf("\r\n");
cprintf(
"Program not loaded -- comm port %d could not be initialized.\r\n", our_port);
cprintf(
"Please use the text editor to correct the 'comm.cfg' file.\r\n");
exit (1);
}
if (!carrier())
if (strlen(modem_init) != 0)
{
flag_save = echo_flag;
echo_flag = FALSE;
cprintf("\r\nInitializing modem....");
send_string(modem_init);
echo_flag = flag_save;
}
cprintf("\r\n\r\n");
cprintf("Background Communications Program is loaded.\r\n");
cprintf("Press ALT/RIGHT-SHIFT to activate the program.\r\n\r\n");
ourdta_ptr = getdta();
_AX = 0x5100;
geninterrupt(0x21);
ourpsp = _BX;
our_mcb = MK_FP(ourpsp-1, 0);
our_mcb_size = MK_FP(ourpsp-1, 3);
oldint08 = getvect(0x08);
oldint09 = getvect(0x09);
oldint10 = getvect(0x10);
oldint13 = getvect(0x13);
oldint16 = getvect(0x16);
oldint21 = getvect(0x21);
oldint28 = getvect(0x28);
asm mov ax, word ptr oldint10
asm mov word ptr cs:[0004h], ax
asm mov ax, word ptr oldint10+2
asm mov word ptr cs:[0006h], ax
asm mov ax, word ptr oldint13
asm mov word ptr cs:[0008h], ax
asm mov ax, word ptr oldint13+2
asm mov word ptr cs:[000Ah], ax
asm mov ax, word ptr oldint21
asm mov word ptr cs:[0000h], ax
asm mov ax, word ptr oldint21+2
asm mov word ptr cs:[0002h], ax
setvect(0x10, int10);
setvect(0x13, int13);
setvect(0x16, int16);
setvect(0x21, int21);
setvect(0x09, int09);
setvect(0x28, int28);
setvect(0x08, int08);
hot_flag = TRUE;
paragraphs = (our_ss + (our_sp >> 4) + 1) - ourpsp;
keep(0, paragraphs);
}