home *** CD-ROM | disk | FTP | other *** search
- /*
- BBS.C - Bulletin board system
-
- You are free to use this program as you see fit, with or
- without the copyright notices.
-
- Revisions :
- JHL 12-90 : eliminated all warnings with forward function declarations.
- JHL 01-91 : After connecting over modem, pause 2 seconds for line
- to stabilize.
-
- (C) Copyright 1986, 1987, 1988, 1989, 1991 South Mountain Software, Inc.
- */
-
- #include <stdio.h>
- #include <string.h>
-
- #include "eclproto.h"
- #include "im.h" /* Intelligent modem */
- #include "xm.h" /* XMODEM */
- #include "xc.h" /* Communications services */
- #include "i86.h"
-
- /* Forward declarations of static functions */
- static int intro(void);
- static char *logit(char *string);
- static int is_dead(void);
- static int is_break(void);
- static int passwd(char *prompt);
- static int add(char *password);
- static int search(char *pwd,char *name);
- static int online(void);
- static int download(void);
- static int upload(void);
- static int files(int display);
- static int typefile(void);
- static int send_msg(int display,int inputd);
- static int read_msg(int display,int inputd);
- static int chat(void);
- static int leave(int reason);
- static int idle(void);
- static int echoln(char *string,int option);
- static int echo(char ch,int option);
- static int getinput(char *buffer,int option);
- static int main_menu(void);
- static int options(void);
- static int window(int row,int row_count,int column,char attribute,int flag);
- static void sclear(void);
- static void wclear(void);
- static int dfield(int index);
- static char *int2asc(int ivalue);
- static char *tod(void);
- static int modem_type = 0;
-
-
-
- /* Keyboard definitions */
-
- #define FK1 0x3B00 /* Function key 1 */
- #define FK2 0x3C00 /* Function key 2 */
- #define FK3 0x3D00 /* Function key 3 */
- #define FK4 0x3E00 /* Function key 4 */
- #define FK5 0x3F00 /* Function key 5 */
- #define RUB1 0x08 /* Rubout */
- #define RUB2 0x7F /* Rubout */
- #define RET 0x0D /* CR */
-
- #define RINGS 5 /* Number of rings to answer on */
- #define CTRL_Z 0x1A /* EOFILE */
- #define XON 0x11 /* Enable data transmission */
- #define XOFF 0x13 /* Disable data transmission */
-
- /* Miscellaneous */
-
- #define RETRIES 3 /* Signon retries */
- #define MIN_BUFFERS 8 /* Minimum buffers required */
- #define SCROLL 1 /* Scroll flag value */
- #define CLEARS 0 /* Clear the screen value */
- #define MAXFIELD 79 /* Maximum field */
- #define STATUSROW 24 /* Row address of status row */
- #define SCRWIDTH 79 /* Last column */
- #define STATCOLUMN 31 /* Starting column of rightmost status */
- #define STATWIDTH 48 /* Width of the rightmost status */
-
- #define LOG_INTRO 0 /* logs[...] */
- #define LOG_EXIT 1
- #define LOG_SON 2
- #define LOG_NEW 3
- #define LOG_OLD 4
- #define LOG_OFF 5
- #define LOG_TERM 6
- #define LOG_PASS 7
- #define LOG_CONN 8
- #define LOG_RING 9
- #define LOG_TIMO 10
-
- #define XMODEM 11
- #define SESSION 12
- #define FAILED 13
- #define CANCELLD 14
- #define USERABORT 15
- #define FILEOPEN 16
- #define FILEIO 17
-
- static char *logs[] = {
- "*** BBS Started", /* LOG_INTRO */
- "*** BBS Exited", /* LOG_EXIT */
- "Answered at ", /* LOG_SON */
- " new user on ", /* LOG_NEW */
- " old user on ", /* LOG_OLD */
- " logged off", /* LOG_OFF */
- " aborted by BBS - shutdown ", /* LOG_TERM */
- " aborted by BBS - bad password ", /* LOG_PASS */
- " User lost connection ", /* LOG_CONN */
- " RING acknowledged by BBS ", /* LOG_RING */
- " User timeout ", /* LOG_TIMO */
-
- "Transfer completed",
- "Transfer session error",
- "Transfer failed",
- "Transfer cancelled by user",
- "Transfer was terminated by BBS",
- "Transfer file open error",
- "Transfer file I/O error",
-
- ""
- };
-
- static char logbuf[80];
- static char Username[40];
- static char bbs[] = "BBS";
-
- static char xmodeminfo[] =
- "Blocks transferred [%d] refused [%d] timeouts [%d] garbled [%d]";
- /* File names used by BBS */
- static char log_file[] = "LOG.ASC";
- static char int_file[] = "INTRO.ASC";
- static char msg_file[] = "MESSAGE.ASC";
- static char msg_temp[] = "MESSAGE.$$$";
- static char pas_file[] = "PASSWORD.ASC";
- static char dir_file[] = "FILES.ASC";
-
- static char product[] = "\n\nSouth Mountain Bulletin Board System Rev. 4.0\n";
- static char copyr1[] = "Copyright (C) 1991 South Mountain Software, Inc.\n";
-
- /* Field indices (into the <text> array structure) */
-
- #define MAIN_F1 0
- #define MAIN_EXIT 1
- #define MAIN_STAT 2
- #define OPTN_F1 3
- #define OPTN_F2 4
- #define OPTN_F3 5
- #define OPTN_F4 6
- #define OPTN_EXIT 7
-
- #define NULL_STR 8 /* The last one */
-
- #define COMPORT 28
- #define COMBAUD 30
- #define COMPARITY 38
- #define COMDATA 41
- #define COMSTOP 43
-
- #define COM_HELP 45
- #define COM_ACCEPT 46
- #define COM_ABORT 47
- #define COM_ACP 48
-
-
- static struct {
- int row; /* Row coordinate */
- int col; /* Column coordinate */
- int wid; /* Width */
- char *str; /* Character string */
- } text[] = {
- { STATUSROW, 18, 12, "[F1] options" },
- { STATUSROW, 0, 17, "[Ctrl-Break] Exit" },
- { STATUSROW, STATCOLUMN, STATWIDTH, logbuf },
-
- { STATUSROW, 0, 14, "[F1] Send mail" },
- { STATUSROW, 15, 14, "[F2] Read mail" },
- { STATUSROW, 30, 13, "[F3] File dir" },
- { STATUSROW, 44, 14, "[F4] File load" },
- { STATUSROW, 59, 17, "[Ctrl-Break] Exit" },
-
- { STATUSROW, 0, SCRWIDTH, "" },
- { 0, 0, 0, "" }
- };
-
- static char *baudstr[] = {
- "110 baud", "150 baud", "300 baud", "600 baud",
- "1200 baud", "2400 baud", "4800 baud", "9600 baud",
- "19200 baud", "38400 baud","57K baud","115K baud"
- };
-
- static char Firstname[] = "\nEnter your name : ";
- static char Nouser[] = "\n\007There is no user with that name\n";
- static char Password[] = "\nWelcome back! Please enter your password : ";
- static char Hellonew[] = "\nA new USER! - create a password : ";
- static char Logoff[] = "\nThe BBS is coming down - NOW!\n";
- static char NoResponse[]= "\nYou haven't typed anything in 2 minutes - BYE!\n";
- static char Oops[] = "\007 Please enter a valid command letter\n";
- static char Illpass[] = "\nPassword is not legal\n";
- static char Thanks[] = "\nThank you very much\n";
- static char Chat1[] = "\nEnter characters (press Ctrl-Z to exit):\n";
- static char Nofile[] = "\n\007No files are available for download\n";
- static char Whatfile[] = "\nWhat file do you wish to view : ";
- static char Upfile[] = "\nWhat file do you wish to upload : ";
- static char Downfile[] = "\nWhat file do you wish to download : ";
- static char Towhom[] = "\nSend message to (give user name or 'BBS') : ";
- static char Nofilex[] = "\n\007The file you requested does not exist\n";
- static char Textend[] = "\n[Thank you]\n";
- static char No_msg[] = "\n\007You have no messages\n";
- static char Msgwhen[] = "[Message dated] ";
- static char Msgfrom[] = "\n[From] ";
- static char Msgstart[] = "\n";
- static char Msgend[] = "\n";
- static char Delmsg[] = "\nDo you wish to delete the message (Y or N) : ";
- static char Byebye[] = "\nBye bye - please disconnect your modem\n";
- static char Filereq[] = "\nEnter the filename you wish to load into BBS : ";
- static char Descrip[] = "\nEnter in a brief description : ";
- static char Opt_inst[] = "\nPress one of the function keys below\n\n";
- static char Getready[] = "\nNow, start your PC file transfer\n";
- static char NoModem[] = "\nYour modem is not working!\n";
- static char *Menu[] = {
- "\n\nCommand Choices are:\n\n",
- "R Read messages\n",
- "S Send messages\n",
- "C Chat with the BBS\n",
- "U Upload a file\n",
- "D Download a file\n",
- "F File directory list\n",
- "V View a text file\n",
- "Q Quit\n",
- "\nEnter command desired : ",
- ""
- };
-
-
- #define INPT_COM 64 /* User keyboard entry */
- #define INPT_KEY 32 /* BBS keyboard entry */
- #define INPT_UPR 16 /* Uppercase conversion */
- #define ECHO_SCR 8 /* Send to the screen */
- #define ECHO_COM 4 /* Send to the comm port */
- #define ECHO_DOT 1 /* Display a dot */
-
- /* User or BBS abort status */
-
- #define BBS_OK 0 /* abort_status */
- #define BBS_TERM 1 /* BBS wants to terminate user */
- #define USER_DISC 2 /* User dropped CD */
- #define USER_TIMO 3 /* No response */
-
- static int abort_status = BBS_OK;
-
-
- /* Modem session status */
-
- #define COMM_IDLE 0
- #define COMM_CONN 1
-
- static int comm_status = COMM_IDLE;
- static int bbs_noecho = 0; /* Enable bbs_noecho */
- static int bbs_hardwire = 0; /* linked via null modem if = 1 */
- /* or 2nd command line arg = 'H' */
-
- #define TIMEOUT 1500
- static int timeoutf = 0; /* Flag if set means waiting for input */
-
-
- /* COMMUNICATIONS CONFIGURATION -- ALWAYS COM1! */
-
- #define DEFBAUD BAUD1200
- static int Port = COM1; /* Default communications port */
- static int Baud = DEFBAUD; /* Default baud rate */
- static int Parity = NOPAR; /* Default parity */
- static int Data = DATA8; /* Default data bit size */
- static int Stop = STOP1; /* Default stop bit */
- static int attr_status = 0x70; /* Default attribute */
- static int attr_text = 0x07; /* Text window (emulator) attribute */
-
- static char *days[] = {
- "Sun ", "Mon ", "Tue ", "Wed ", "Thu ", "Fri ", "Sat "
- };
-
- static char buffer[26]; /* Working character buffer */
- static union i86_reg packet; /* DOS interrupt request handler */
-
- static char intbuffer[3]; /* Convert an 8-bit integer to ASCII-decimal */
-
-
- void main(
- int argc,
- char *argv[])
- {
- int i, idx;
-
- if (argc == 3) {
- switch (*argv[1]) {
- case '1': /* Assume 1200, 19200, 115K baud */
- switch (argv[1][1]) {
- case '2': /* Assume 1200 Baud */
- Baud = BAUD1200;
- break;
- case '9': /* Assume 19200 Baud */
- Baud = BAUD19200;
- break;
- case '1': /* Assume 115K Baud */
- Baud = BAUD115K;
- break;
- }
- break;
-
- case '2': /* Assume 2400 baud */
- Baud = BAUD2400;
- break;
-
- case '3':
- if ((argv[1][1]) == '8') /* Assume 38400 baud */
- Baud = BAUD38400;
- else /* Assume 300 baud */
- Baud = BAUD300;
- break;
-
- case '4': /* Assume 4800 baud */
- Baud = BAUD4800;
- break;
-
- case '5': /* Assume 57K baud */
- Baud = BAUD57K;
- break;
-
- case '6': /* Assume 600 baud */
- Baud = BAUD600;
- break;
-
- case '9': /* Assume 9600 baud */
- Baud = BAUD9600;
- break;
- }
-
- if(( *argv[2] == 'H' || *argv[2] == 'h')) {
- bbs_hardwire = 1; /* not going through modem */
- }
- else {
- modem_type = atoi(argv[2]);
- }
-
- if (argc > 3)
- bbs_noecho = 1; /* Disable bbs_noecho */
-
- }
- else {
- printf("\nFORMAT : \nbbs [baud] [mt]");
- printf("\n\nWHERE:\n baud: opening baud rate : 1200 to 155K baud");
- printf("\n mt: modem type");
- printf("\n 0 = Hayes Ultra; 1 = USR Courier; 2 = Microcom QX or UDS Fastalk;");
- printf("\n 3 = Telebit; 4 = MultiTech; 5 = GVC SM96;");
- printf("\n 6 = Ventel; 7 = Digicom Systems; 8 = Generic type;");
- printf("\n 9 = Standard type;");
- printf("\n H = Hardwired togeather without modem");
- return;
- }
-
-
- printf("Setting up BBS on COM1 at %s, 8 data, no parity, 1 stop\n", baudstr[Baud]);
- switch (xc_entr(MIN_BUFFERS)) {
- case 0:
- xc_link(Port, 2);
- xc_init(Port, Baud, Parity, Data, Stop);
- xck_link();
- xct_link();
- if (!bbs_hardwire){
- im_setmodem(Port,modem_type,2);
- if (im_fopen(Port) < IM_OK) {
- echoln(NoModem, ECHO_SCR);
- xc_exit();
- break;
- }
- else
- xctp_pend(Port,36); /* pause 2 secs. */
- im_spkr(Port,IM_SPKR_OFF);
-
- }
- wclear();
- sclear();
- logit(logs[LOG_INTRO]);
- while (abort_status != BBS_TERM) {
- for (idx = 0; (idx < 1); ++idx) { /* Do it once */
- if (idle() < 0)
- break;
- if (modem_type == 9) /* if STANDARD_TYPE MODEM, pause in case
- there is an MNP on the other end. Otherwise
- the intro may get lost while the modems
- finish negotiating */
- {
- xct_link();
- xct_pend(18 * 2); /* wait 2 seconds */
- xct_unlk();
- }
- if (intro() < 0)
- break;
- for (i = 0; ((is_dead() == 0) && (i < RETRIES)); ++i) {
- if (passwd(Firstname) == 0)
- break; /* Found the user */
- }
- if (i == RETRIES) { /* Too many retries ! */
- leave(LOG_PASS);
- } else { /* Signed on! */
- if (is_dead() == 0) /* Handle all of the menus */
- online();
- if (is_dead() == 0)
- leave(LOG_OFF); /* Graceful exit */
- else { /* Error exit */
- switch (abort_status) {
- case BBS_TERM:
- echoln(Logoff, ECHO_SCR | ECHO_COM);
- leave(LOG_TERM);
- break;
- case USER_DISC:
- leave(LOG_CONN); /* User lost connection */
- break;
- case USER_TIMO:
- echoln(NoResponse, ECHO_SCR | ECHO_COM);
- leave(LOG_TIMO);
- break;
- }
- }
- }
- } /* Do it once */
- } /* End of while loop */
-
- echoln(logs[LOG_EXIT], ECHO_SCR | ECHO_COM);
- logit(logs[LOG_EXIT]);
-
- xck_unlk();
- if(!bbs_hardwire)
- im_close(Port);
- xc_unlk(Port);
- wclear();
- sclear();
- xc_exit();
- break;
- case -1:
- printf("XCOMMS is not properly installed\n");
- break;
- case -2:
- printf("Internal error - BBS improperly exited before\n");
- break;
- default:
- xct_unlk();
- xc_exit();
- printf("Not enough buffers are allocated for BBS\n");
- break;
- }
- }
-
- static int intro(void)
- {
- char buffer[82];
- FILE *Stream;
-
- if (echoln(product, ECHO_SCR | ECHO_COM) < 0)
- return(-1);
- if (echoln(copyr1, ECHO_SCR | ECHO_COM) < 0)
- return(-1);
- Stream = fopen(int_file, "r");
- if (Stream) {
- while (fgets(buffer, 80, Stream) != NULL) {
- if (echoln(buffer, ECHO_SCR | ECHO_COM) < 0)
- return(-1);
- }
- fclose(Stream);
- }
- return(0);
- }
-
- /*
- logit Add the character string to the current log file - append
- the date and time. Also, report this status to the user
- on the status line automatically.
- */
-
- static char *logit(char *string)
- {
-
- FILE *Stream;
- Stream = fopen(log_file, "a+");
- if (Stream) {
- strncpy(logbuf, string, 80);
- strcat(logbuf, " ");
- strcat(logbuf, tod());
- dfield(MAIN_STAT);
- fputs(logbuf, Stream);
- fclose(Stream);
- }
- return(0); /* Status is ignored */
- }
-
-
-
- /*
- is_dead VERY IMPORTANT!
- */
-
- static int is_dead(void)
- {
- int status = -1; /* Assume all failed */
- if (abort_status == BBS_OK) {
- if (is_break() == 0) {
- if (comm_status == COMM_CONN) {
- if (xc_dcd(Port) == 0) {
- abort_status = USER_DISC;
- } else { /* Connection (DCD) still on */
- status = 0;
- }
- if (timeoutf) { /* Waiting for user input */
- if (xct_test() == 0) {
- timeoutf = 0; /* Ignore the timeoutf now */
- abort_status = USER_TIMO;
- status = -1;
- }
- }
- } else { /* No connection anyways ... */
- status = 0;
- }
- } else { /* User pressed Ctrl-Break */
- abort_status = BBS_TERM;
- }
- }
- if (!bbs_hardwire || (abort_status == BBS_TERM))
- return(status);
- else
- return(0);
-
- }
-
- static int is_break(void) /* Test for the presence of a Ctrl-Break abort */
- { /* This does not assume a catestrophic error! */
- int status;
-
- status = xck_test();
- if (status) { /* Ctrl-Break pressed */
- while (xck_keyt())
- xck_getc();
- }
- return(status);
- }
-
- static int passwd( /* Log in the user return a 0 if OK, -1 if in error */
- char *prompt) /* Will not let user login as BBS */
- {
- char buff3[81];
- char buffer[81];
- char real_pwd[81];
- int status = 0; /* Assume all is OK */
-
- /* Ask the user for first and last name */
-
- real_pwd[0] = CTRL_Z;
- real_pwd[1] = '\n';
- real_pwd[2] = '\000';
- echoln(prompt, ECHO_SCR | ECHO_COM);
- getinput(Username, ECHO_SCR | ECHO_COM | INPT_UPR | INPT_KEY | INPT_COM);
-
- /* Now search for existence of it */
-
- if (is_dead())
- return(-1); /* OOPS - DROPPED CONNECTION */
-
- if (search(real_pwd, Username) == 0) { /* Found the entry */
- echoln(Password, ECHO_SCR | ECHO_COM);
- getinput(buff3,ECHO_SCR|ECHO_COM|INPT_UPR|INPT_KEY|ECHO_DOT|INPT_COM);
- strcat(buff3, "\n");
- if (is_dead())
- return(-1); /* OOPS - DROPPED CONNECTION */
- if (strcmp(buff3, real_pwd) == 0) {
- echoln(Thanks, ECHO_SCR | ECHO_COM);
- strcpy(buffer, Username);
- strcat(buffer, logs[LOG_OLD]);
- logit(buffer);
- } else {
- status = -1;
- echoln(Illpass, ECHO_SCR | ECHO_COM);
- }
- } else { /* New user */
- echoln(Hellonew, ECHO_SCR | ECHO_COM);
- getinput(buff3,ECHO_SCR|ECHO_COM|INPT_UPR|INPT_KEY|ECHO_DOT|INPT_COM);
- add(buff3);
- strcpy(buffer, Username);
- strcat(buffer, logs[LOG_NEW]);
- logit(buffer);
- }
- comm_status = COMM_CONN; /* User is now connected */
- return(status);
- }
-
- static int add( /* Add a username, password, and original date */
- char *password)
- {
- char buffer[81];
- FILE *Stream;
-
- Stream = fopen(pas_file, "a+");
- strcpy(buffer, Username);
- strcat(buffer, "\n");
- fputs(buffer, Stream);
- strcpy(buffer, password);
- strcat(buffer, "\n");
- fputs(buffer, Stream);
- fputs(tod(), Stream);
- fclose(Stream);
- return(0);
- }
-
- /* User BBS is the default and is quickly qualified */
- static int search( /* Search the password data base for the Username */
- char *pwd, /* Return the password if found */
- char *name) /* Given the name to search */
- {
- int status = -1; /* Assume that there is none */
- char buffer[81];
- char _user[81];
- FILE *Stream;
-
- if (strcmp(name, bbs) != 0) {
-
- if ((Stream = fopen(pas_file, "r")) != NULL) {
- strcpy(_user, name);
- strcat(_user, "\n");
- while ( (char *) fgets(buffer, 80, Stream) != NULL) {
- if (strcmp(buffer, _user) == 0) {
- fgets(pwd, 80, Stream); /* Return the password */
- status = 0; /* Signal successful search */
- break;
- } else {
- fgets(buffer, 80, Stream); /* Read past password */
- fgets(buffer, 80, Stream); /* And startup date */
- }
- }
- fclose(Stream);
- }
- } else
- status = 0;
- return(status);
- }
-
-
- static int online(void) /* Return a 0 if user wishes to exit, -1 if error */
- { /* Stay here as long as user is using the menus */
- int i;
- char buffer[81];
- int exitflag = 0;
- while (exitflag == 0) {
- for (i = 0;(*Menu[i]);++i) { /* Display the user online options */
- echoln(Menu[i], ECHO_SCR | ECHO_COM);
- }
- getinput(buffer, ECHO_SCR | ECHO_COM | INPT_KEY | INPT_COM | INPT_UPR);
- if (echoln("\n", ECHO_SCR | ECHO_COM) < 0)
- return(-1);
- switch (buffer[0]) {
- case 'R':
- read_msg(ECHO_SCR | ECHO_COM, INPT_KEY | INPT_COM);
- break;
- case 'S':
- send_msg(ECHO_SCR | ECHO_COM, INPT_KEY | INPT_COM);
- break;
- case 'C':
- chat();
- break;
- case 'U':
- upload();
- break;
- case 'D':
- download();
- break;
- case 'F':
- files(ECHO_SCR | ECHO_COM | INPT_COM | INPT_KEY);
- break;
- case 'V':
- typefile();
- break;
- case 'Q':
- exitflag = 1;
- break;
- default:
- echoln(Oops, ECHO_SCR | ECHO_COM);
-
- break;
- }
- }
- return(0); /* User wishes to exit now */
- }
-
- static int download(void)
- {
- int row, column;
- char answer[81];
- char buffer[81];
- int status;
- int index;
- char protocol;
-
- status = 1;
- while(status)
- {
- echoln("\n\nDownload Choices Are:\n\n" , ECHO_SCR | ECHO_COM);
- echoln("X XMODEM\n", ECHO_SCR | ECHO_COM);
- echoln("M XMODEM 1K\n", ECHO_SCR | ECHO_COM);
- echoln("Y YMODEM\n", ECHO_SCR | ECHO_COM);
- echoln("K KERMIT\n", ECHO_SCR | ECHO_COM);
- echoln("Q QUIT\n", ECHO_SCR | ECHO_COM);
- echoln("\n Enter your choice: ", ECHO_SCR | ECHO_COM);
-
- getinput(answer, ECHO_SCR | ECHO_COM | INPT_KEY | INPT_COM | INPT_UPR);
- switch(answer[0])
- {
- case 'X':
- case 'M':
- case 'Y':
- case 'K':
- {
- status = 0;
- protocol = answer[0];
- break;
- }
- case 'Q':
- return(0);
- default:
- echoln("\n\n\007Invalid Response\n\n", ECHO_SCR | ECHO_COM);
- }
- }
-
- echoln(Downfile, ECHO_SCR | ECHO_COM);
- getinput(answer, ECHO_SCR | ECHO_COM | INPT_KEY | INPT_COM | INPT_UPR);
- echoln(Getready, ECHO_SCR | ECHO_COM);
-
- xcv_gcur(&row, &column);
- xcv_scur(STATUSROW, 0);
- dfield(NULL_STR);
-
- switch(protocol)
- {
- case 'X':
- index = XMODEM + (- ( status = xmk_putf(Port, answer, xmodeminfo, 1,
- XMODEM_128,XMODEM_CRC)));
- break;
- case 'M':
- index = XMODEM + (- ( status = xmk_putf(Port, answer, xmodeminfo, 1,
- XMODEM_1K,XMODEM_CRC)));
- break;
- case 'Y':
- xct_pend(18*10); /* pause for 10 seconds */
- index = XMODEM + (- ( status = ym_putf(Port, answer, 1, 1)));
- index = (index == 0) ? 0 : -2;
- break;
- case 'K':
- xct_pend(18*10); /* pause for 10 seconds */
- index = XMODEM + (- ( status = km_putf(Port, answer, 1, 1)));
- index = (index == 0) ? 0 : -2;
- break;
- }
-
-
-
- xcv_scur(row, column);
- echoln(logs[index], ECHO_SCR | ECHO_COM);
- strcpy(buffer, answer); /* Log it */
- strcat(buffer, " ");
- strcat(buffer, logs[index]);
- logit(buffer);
- main_menu();
- return(status);
- }
-
- static int upload(void) /* XMODEM upload */
- {
- int row, column;
- char desc[81];
- char buffer[81];
- char answer[81];
- int status;
- FILE *Stream;
- int index;
- char protocol;
-
- status = 1;
- while(status)
- {
- echoln("\n\nUpload Choices Are:\n\n" , ECHO_SCR | ECHO_COM);
- echoln("X XMODEM\n", ECHO_SCR | ECHO_COM);
- echoln("M XMODEM 1K\n", ECHO_SCR | ECHO_COM);
- echoln("Y YMODEM\n", ECHO_SCR | ECHO_COM);
- echoln("K KERMIT\n", ECHO_SCR | ECHO_COM);
- echoln("Q QUIT\n", ECHO_SCR | ECHO_COM);
- echoln("\n Enter your choice: ", ECHO_SCR | ECHO_COM);
-
- getinput(answer, ECHO_SCR | ECHO_COM | INPT_KEY | INPT_COM | INPT_UPR);
- switch(answer[0])
- {
- case 'X':
- case 'M':
- case 'Y':
- case 'K':
- {
- status = 0;
- protocol = answer[0];
- break;
- }
- case 'Q':
- return(0);
- default:
- echoln("\n\n\007Invalid Response\n\n", ECHO_SCR | ECHO_COM);
- }
- }
-
-
- if((protocol != 'K') && (protocol != 'Y'))
- {
- echoln(Upfile, ECHO_SCR | ECHO_COM);
- getinput(answer, ECHO_SCR | ECHO_COM | INPT_KEY | INPT_COM | INPT_UPR);
- }
- echoln(Getready, ECHO_SCR | ECHO_COM);
-
- xcv_gcur(&row, &column);
- xcv_scur(STATUSROW, 0);
- dfield(NULL_STR);
-
- switch(protocol)
- {
- case 'X':
- index = XMODEM + (- ( status = xmk_getf(Port, answer, xmodeminfo, 1,
- XMODEM_128,XMODEM_CRC)));
- break;
- case 'M':
- index = XMODEM + (- ( status = xmk_getf(Port, answer, xmodeminfo, 1,
- XMODEM_1K,XMODEM_CRC)));
- break;
- case 'Y':
- xct_pend(18*10); /* pause for 10 seconds */
- index = XMODEM + (- ( status = ym_getf(Port, "", 1, 1)));
- index = (index == 0) ? 0 : -2;
- break;
- case 'K':
- xct_pend(18*10); /* pause for 10 seconds */
- index = XMODEM + (- ( status = km_getf(Port, "", 1, 1)));
- index = (index == 0) ? 0 : -2;
- break;
- }
-
-
- xcv_scur(row, column);
- echoln(logs[index], ECHO_SCR | ECHO_COM);
-
- strcpy(buffer, answer); /* Log it */
- strcat(buffer, " ");
- strcat(buffer, logs[index]);
- logit(buffer);
-
- if (status >= XM_OK) { /* If successful, then write it */
- echoln(Descrip, ECHO_SCR | ECHO_COM);
- getinput(desc, ECHO_SCR | ECHO_COM | INPT_KEY | INPT_COM);
- if (desc[0] >= ' ') {
- if ((Stream = fopen(dir_file, "a+")) != NULL) {
- fprintf(Stream, "%-15s %s\n", answer, desc, buffer);
- fclose(Stream);
- }
- }
- echoln(Textend, ECHO_SCR | ECHO_COM);
- }
- main_menu();
- return(status);
- }
-
- static int files( /* Display THE DIRECTORY */
- int display)
- {
- int status = 0;
- FILE *Stream;
- char buffer[81];
-
- if ((Stream = fopen(dir_file, "r")) == NULL) {
- echoln(Nofile, display);
- } else {
- while (fgets(buffer, 80, Stream) != NULL) {
- if (echoln(buffer, display) < 0)
- return(-1);
- }
- fclose(Stream);
- }
- return(status);
- }
-
-
- static int typefile(void)
- {
- int status = 0;
- FILE *Stream;
- char buffer[81];
- char filename[81];
-
- echoln(Whatfile, ECHO_SCR | ECHO_COM);
- getinput(filename, ECHO_SCR | ECHO_COM | INPT_KEY | INPT_COM);
- echoln("\n", ECHO_SCR | ECHO_COM);
-
- if ((Stream = fopen(filename, "r")) == NULL) {
- echoln(Nofilex, ECHO_SCR | ECHO_COM);
- } else {
- while (fgets(buffer, 80, Stream) != NULL) {
- if (echoln(buffer, ECHO_SCR | ECHO_COM) < 0)
- return(-1); /* OOPS - DROPPED CONNECTION */
- }
- fclose(Stream);
- }
- return(status);
- }
-
- static int send_msg( /* 0 if sent OK, 1 if no user, -1 if error */
- int display,
- int inputd)
- {
- int status = 0;
- FILE *Stream;
- char buffer[81];
- char receivr[81];
- int exitflag = 0;
-
- echoln(Towhom, display);
- getinput(receivr, display | INPT_UPR | inputd);
- if (search(buffer, receivr) == 0) {
-
- Stream = fopen(msg_file, "a+");
- strcpy(buffer, receivr);
- strcat(buffer, "\n");
- fputs(buffer, Stream);
- strcpy(buffer, Username);
- strcat(buffer, "\n");
- fputs(buffer, Stream);
- fputs(tod(), Stream);
- echoln(Chat1, display);
- while (exitflag == 0) {
- if (is_dead())
- return(-1); /* OOPS - DROPPED CONNECTION */
- getinput(buffer, display | inputd);
- echoln("\n", display);
- if (buffer[0] == CTRL_Z) {
- exitflag = 1;
- buffer[0] = '^';
- buffer[2] = '\000';
- }
- strcat(buffer, "\n");
- fputs(buffer, Stream);
- }
- fclose(Stream);
- } else {
- echoln(Nouser, display);
- status = 1;
- }
- return(status);
- }
-
-
- static int read_msg( /* 0 if message, 1 no message, -1 error */
- int display,
- int inputd)
- {
- int status = 1; /* Assume no message read */
- FILE *INStream;
- FILE *OUTStream;
- char buffer[81];
- char _name[81];
-
- if ((INStream = fopen(msg_file, "r")) != NULL) {
- OUTStream = fopen(msg_temp, "w");
- strcpy(_name, Username);
- strcat(_name, "\n");
-
- while (fgets(buffer, 80, INStream) != NULL) {
- if (is_dead())
- return (-1); /* OOPS - DROPPED CONNECTION */
- if (strcmp(buffer, _name) == 0) {
- status = 0;
- echoln(Msgfrom, display);
- echoln(fgets(buffer, 80, INStream), display);
- echoln(Msgwhen, display);
- echoln(fgets(buffer, 80, INStream), display);
- echoln(Msgstart, display);
- while (fgets(buffer, 80, INStream) != NULL) {
- if (buffer[0] == '^')
- break;
- echoln(buffer, display);
- }
- while (fgets(buffer, 80, INStream) != NULL) {
- fputs(buffer, OUTStream);
- }
- echoln(Msgend, display);
- } else {
- fputs(buffer, OUTStream);
- while (fgets(buffer, 80, INStream) != NULL) {
- fputs(buffer, OUTStream);
- if (buffer[0] == '^')
- break;
- }
- }
- }
-
- fclose(INStream);
- fclose(OUTStream);
- if (status == 0) {
- echoln(Delmsg, display);
- getinput(buffer, display | inputd);
- if ((buffer[0] == 'Y') || (buffer[0] == 'y')) {
- unlink(msg_file);
- rename(msg_temp, msg_file);
- }
- }
- }
- if (status == 1)
- echoln(No_msg, display);
- return(status);
- }
-
- static int chat(void)
- {
- char buffer[81];
-
- echoln(Chat1, ECHO_SCR | ECHO_COM);
- do {
- getinput(buffer, ECHO_SCR | ECHO_COM | INPT_KEY | INPT_COM);
- if (echoln("\n", ECHO_SCR | ECHO_COM) < 0)
- return(-1); /* EXIT DUE TO ERROR */
- } while (buffer[0] != CTRL_Z);
- return(0);
- }
-
-
- /* ================== DISCONNECT ================== */
-
- static int leave( /* Hang up the modem */
- int reason)
- {
- char buffer[81];
-
- echoln(Byebye, ECHO_SCR | ECHO_COM); /* Tell the user to hangup */
- strcpy(buffer, Username); /* Log the occurence */
- strcat(buffer, logs[reason]);
- logit(buffer);
- comm_status = COMM_IDLE; /* Communications now down */
- im_hangu(Port); /* Force the connection down */
- return(0); /* Leave abort_status alone */
- }
-
- static int idle(void) /* Wait for the modem to ring */
- /* Return a -1 if BBS hit Ctrl-Break or the baud rate code */
- {
- char buffer[81];
- int ch;
- int status;
-
- xc_init(Port, Baud, Parity, Data, Stop);
- Username[0] = '\000';
- comm_status = COMM_IDLE; /* === SESSION STATUS === */
- abort_status = BBS_OK; /* === SESSION STATUS === */
- main_menu();
-
- /* Answer the ring */
-
- while (1) {
- if (!bbs_hardwire){
- if (xc_ri(Port) != 0) /* Have a ring ? ... */
- break;
- }
- else { /* direct conection */
- break;
- }
- if (xck_keyt()) { /* BBS user want to do F1 options? */
- ch = xck_getc();
- if (ch == FK1) {
- options();
- } else if ((ch & 0xFF) == RET) {
- break; /* Direct connect forced by BBS owner */
- }
- }
- if (is_break()){
- abort_status = BBS_TERM;
- return(-1);
- }
- }
- strcpy(buffer, logs[LOG_RING]);
- logit(buffer);
-
- if (!bbs_hardwire){
- if ((status = im_answ(Port)) <= IM_OK)
- return(status); /* Answer the phone */
- else {
- if(modem_type == IM_STANDARD_TYPE)
- Baud = status;
- /* pause 2 seconds for new connection to stablize */
- xctp_pend(Port,36);
- }
- }
-
- /* else
- Baud = BAUD9600; */ /* hardwire set to 9600 baud */
-
- xc_init(Port, Baud, Parity, Data, Stop);
- xc_flush(Port);
-
- /* The phone has been answered */
-
- comm_status = COMM_CONN; /* === SESSION STATUS === */
- /*
- if (getinput(buffer, INPT_COM) < 0)
- return(-1);
- */
- strcpy(buffer, logs[LOG_SON]);
- strcat(buffer, baudstr[Baud]);
- logit(buffer);
- main_menu();
- return(Baud);
- }
-
- static int echoln( /* String write, return a -1 if error */
- char *string,
- int option)
- {
- int status = 0;
- char *ch_ptr = string;
- while (*ch_ptr) {
- if (*ch_ptr == '\n')
- status = echo(RET, option);
- status = echo(*ch_ptr, option);
- ch_ptr++;
- }
- return(status);
- }
-
- static int echo( /* Display a character & optionally scroll up one line */
- char ch, /* Return a 0 meaning success or a -1 if we must exit */
- int option)
- {
- int oldrow, oldcol;
-
- if (is_dead()) /* Check the connection */
- return(-1);
-
- /* Echo on the screen only if <bbs_noecho> flag is set to 0 */
-
- if ((option & ECHO_SCR) && (bbs_noecho == 0)) { /* Display on the screen */
- xcv_wtty( (char)((char)(option & ECHO_DOT) ? (char)'.' : (char)ch));
- if (xck_keyt()) {
- if ((xck_getc() & 0xFF) == XOFF) {
- while ((xck_getc() & 0xFF) != XON) {
- if (is_dead())
- return(-1); /* **** OOPS - LOST CONNECTION */
- }
- }
- }
- xcv_gcur(&oldrow, &oldcol);
- if (oldrow == STATUSROW) {
- window(0, STATUSROW, SCRWIDTH, (char)attr_text, SCROLL);
- xcv_scur(oldrow - 1, oldcol);
- }
- }
- /* Display to the comms user only if a session is on */
-
- if ((option & ECHO_COM) && (comm_status == COMM_CONN)) {
- if (xc_test(Port)) {
- if ((xc_getc(Port) & 0xFF) == XOFF) {
- while ((xc_getc(Port) & 0xFF) != XON) {
- if (is_dead())
- return(-1); /* **** OOPS - LOST CONNECTION */
- }
- ;
- }
- }
- xc_putc(Port, (char)((char)(option & ECHO_DOT) ? (char)'.' : (char)ch));
- }
- return(0); /* Always succeeds! */
- }
-
- /*
- getinput - Given the character string buffer address, accept the
- user input string and return the number of characters entered. Accept
- input at the current cursor location. There is a limit of 80 characters.
- Returns:
-
- 0 Only Enter key pressed
- >0 The character string of n characters returned
- -1 Connection down via timeout or otherwise
- */
- static int getinput(
- char buffer[],
- int option)
- {
- int i = 0;
- int exitflag = 0;
- int got_one;
- char ch;
-
- timeoutf = 1;
- xct_set(TIMEOUT); /* Start the timeout */
-
- while (exitflag == 0) {
- if (is_dead()) /* ************************* */
- return(-1); /* OOPS - lost the session ! */
- got_one = 0;
- if (xck_keyt() && (option & INPT_KEY)) {
- got_one = 1;
- ch = (char)xck_getc();
- } else if (xc_test(Port) && (option & INPT_COM)) {
- got_one = 1;
- ch = (char)xc_getc(Port);
- }
- if (got_one) {
- if (i >= 80) {
- buffer[i] = '\000';
- exitflag = 1;
- break;
- }
- if (option & INPT_UPR) {
- if ((ch >= 'a') && (ch <= 'z'))
- ch = ch - ('a' - 'A');
- }
- switch ((ch) & 0xFF) {
- case RET:
- buffer[i] = '\000';
- exitflag = 1; /* Exit file entry */
- break;
- case RUB1:
- case RUB2:
- if (i) {
- --i;
- echo(RUB1, option & (~ ECHO_DOT));
- echo(' ', option & (~ ECHO_DOT));
- echo(RUB1, option & (~ ECHO_DOT));
- }
- break;
- default:
- buffer[i++] = ch;
- if (ch == CTRL_Z) {
- echo('^', option);
- echo('Z', option);
- }
- if ((ch >= ' ') && (ch <= RUB2))
- echo(ch, option);
- }
- }
- }
- timeoutf = 0; /* Reset the flag */
- return(i); /* Return size of answer */
- }
-
- static int main_menu(void)
- {
- sclear();
- if (comm_status == COMM_IDLE)
- dfield(MAIN_F1);
- dfield(MAIN_EXIT);
- dfield(MAIN_STAT);
- return(0); /* Always successful! */
- }
-
- static int options(void) /* Display THE OPTIONS */
- {
- char _old_user[81];
- char name[81];
- char desc[81];
- char buffer[81];
- FILE *Stream;
-
- sclear();
- dfield(OPTN_F1);
- dfield(OPTN_F2);
- dfield(OPTN_F3);
- dfield(OPTN_F4);
- dfield(OPTN_EXIT);
- wclear();
- echoln(Opt_inst, ECHO_SCR);
- for (;;) {
- if (is_break()) {
- wclear();
- break;
- }
- if (xck_keyt()) {
- switch (xck_getc()) {
- case FK1:
- strcpy(_old_user, Username);
- strcpy(Username, "BBS");
- send_msg(ECHO_SCR, INPT_KEY);
- strcpy(Username, _old_user);
- echoln("\n", ECHO_SCR);
- break;
- case FK2:
- strcpy(_old_user, Username);
- strcpy(Username, "BBS");
- read_msg(ECHO_SCR, INPT_KEY);
- strcpy(Username, _old_user);
- echoln("\n", ECHO_SCR);
- break;
- case FK3:
- files(ECHO_SCR | INPT_KEY);
- echoln("\n", ECHO_SCR);
- break;
- case FK4:
- echoln(Filereq, ECHO_SCR);
- getinput(name, ECHO_SCR | INPT_KEY | INPT_UPR);
- if ((Stream = fopen(name, "r")) == NULL) {
- echoln(Nofilex, ECHO_SCR);
- } else {
- fclose(Stream);
- echoln(Descrip, ECHO_SCR);
- getinput(desc, ECHO_SCR | INPT_KEY);
- if ((Stream = fopen(dir_file, "a+")) != NULL) {
- fprintf(Stream, "%-15s %s\n", name, desc, buffer);
- fclose(Stream);
- }
- echoln(Textend, ECHO_SCR);
- }
- break;
- case 0: /* can get this on Ctrl-Break */
- is_break();
- wclear();
- main_menu();
- return(0); /* Always successful! */
- }
- echoln(Opt_inst, ECHO_SCR);
-
- }
- }
- main_menu();
- return(0); /* Always successful! */
- }
-
-
- /*
- window - perform a window scroll up or clear for an entire line
- or lines given the attribute
-
- */
- static int window(
- int row, /* Row address starting at 0 */
- int row_count, /* Number of rows to scroll or clear */
- int column, /* Last column number */
- char attribute, /* Attribute for the window */
- int flag) /* SCROLL or CLEARS flag */
- {
- xcv_scrl(row, 0, row + row_count - 1, column, attribute, flag);
- return(0); /* Always succeeds! */
- }
-
- static void sclear(void) /* Clear status line */
- {
- window(STATUSROW, 1, SCRWIDTH, (char)attr_text, CLEARS);
-
- }
-
- static void wclear(void) /* Clear window text area */
- {
- xcv_scur(0, 0); /* Home cursor */
- window(0, STATUSROW, SCRWIDTH, (char)attr_text, CLEARS);
- }
-
- /*
- dfield - display field on the bottom line using the
- attr_status attribute. The cursor is not moved.
- */
- static int dfield(
- int index) /* Index into text array */
- {
- char _string[MAXFIELD]; /* Maximum string field width */
- int i; /* Counter variable */
- int width = text[index].wid; /* Maximum LEGAL field width */
- int column = text[index].col; /* Number of columns */
- char *string = text[index].str;
- int oldrow, oldcol; /* Old cursor address */
-
- if (width > MAXFIELD)
- width = MAXFIELD; /* Specified field is too big */
- /* Create the fixed field */
- for (i = 0; (_string[i] = *string++) >= ' '; ++i)
- ;
- for (; (i < width); ++i)
- _string[i] = ' ';
- xcv_gcur(&oldrow, &oldcol); /* Save the cursor location */
-
- /* Write out the field */
- for (i = 0; (i < width); ++i) {
- xcv_scur(STATUSROW, column + i);
- xcv_chat(_string[i], attr_status);
- }
- xcv_scur(oldrow, oldcol); /* Restore the cursor */
- return(0); /* Always succeeds! */
- }
-
-
- /*
- bbstod.c - Return the time of day
-
- Copyright (C) 1986, 1987, 1988 Essential Software Incorporated
- Copyright (C) 1986, 1987, 1988 Advanced Firmware Engineering
-
- Return a character string indicating the date and time and \n
-
- 10 20 25
- ....|....|....|....|....|
- DAY MM/DD/YY HH:MM:SS.hh\n
- */
-
- static char *int2asc(
- int ivalue)
- {
- int scratch;
- intbuffer[2] = '\000';
- scratch = ivalue / 10;
- intbuffer[0] = (char) scratch + '0';
- intbuffer[1] = (char) (ivalue - (scratch * 10)) + '0';
-
- return(intbuffer);
- }
-
- static char *tod(void) /* Return the time-of-day */
- {
- packet.breg.AH = 0x2A;
- i86_int(0x21, &packet); /* Get the date */
- strcpy(buffer, days[(int) packet.breg.AL]);
- strcat(buffer, int2asc(packet.breg.DH)); strcat(buffer, "/");
- strcat(buffer, int2asc(packet.breg.DL)); strcat(buffer, "/");
- strcat(buffer, int2asc(packet.wreg.CX - 1900)); strcat(buffer, " ");
-
- packet.breg.AH = 0x2C;
- i86_int(0x21, &packet); /* Get the time */
- strcat(buffer, int2asc(packet.breg.CH)); strcat(buffer, ":");
- strcat(buffer, int2asc(packet.breg.CL)); strcat(buffer, ":");
- strcat(buffer, int2asc(packet.breg.DH)); strcat(buffer, ".");
- strcat(buffer, int2asc(packet.breg.DL)); strcat(buffer, "\n");
- return(buffer);
- }
-