/************************************************************************ * * * My First Terminal, version 1.0 Written in Pure C v1.0 * * * * Source code created at Jul 1992 by Koos Kuil as a part of the way * * to learn the C language. * * * * This code is original developed using Sozobon C v1.33, but later * * rewritten & redebugged using Pure C. * * * * Special Thanks to all the people with useful ideas and suggestions * * and critique about my routines in C. * * * * if you have ideas or problems about this terminal, you can contact * * me (Koos Kuil) on Fidonet 2:282/397 or NeST 90:4001/103 * * * * or call my BBS in Holland, (+31)-(0)5978-18087 for ATARI ST Soft. * * * ************************************************************************/ #include #include #include #include #include #include #define AUX 1 /* Serial port device */ #define CONSOLE 2 /* Console (screen) device */ #define ENVIRONMENT "" #define DIAL "ATDT " /* modem dial string */ #define RESET "ATZ" /* modem reset string */ #define ANSWER "ATA" /* modem answer string */ #define CR "\r" /* carrige return */ #define CRLF "\n" /* carrige return & line f */ #define gotoxy(x,y) printf ("\33Y%c%c",(y)+32,(x)+32); #define DIALDIR "myterm.dir" /* Telephone directory */ #define LOGFILE "myterm.log" /* Logfile name */ #define CONFIGFILE "myterm.cfg" /* Configuration file */ #define HELP 0x62 /* Scancodes for keys. */ #define CURS_DN 0x50 #define CURS_UP 0x48 #define ALT_A 0x1e #define ALT_B 0x30 #define ALT_C 0x2e #define ALT_D 0x20 #define ALT_E 0x12 #define ALT_F 0x21 #define ALT_H 0x23 #define ALT_I 0x17 #define ALT_L 0x26 #define ALT_M 0x32 #define ALT_P 0x19 #define ALT_R 0x13 #define ALT_X 0x2d #define ESCAPE 0x01 /* Scancodes for keys, only the name */ #define S_KEY 0x1f /* different to the ALT_. defines. I */ #define C_KEY 0x2e /* use this to get normal keys & func */ #define D_KEY 0x20 /* -tion keys in config_menu() */ #define A_KEY 0x1e #define START_BD 2 /* Set default baudrate to 2400 baud. */ /** ** Global Variables **/ char woord[200], /* Buffers used by strings. */ buf[200], /* Buffer for general use. */ bd=0, /* Actual baudrate. */ *funckey[10]; /* Function keys macros. */ int ext_p=0, /* number of external protocols. */ flow_ctl=0, /* flow control. */ localecho=0, /* Local echo (Half Duplex) */ begin=0; /* Begin of numbers dial directory */ unsigned int baud[6][2] = { 300,9, 1200,7, 2400,4, 4800,2, 9600,1, 19200,0 /* baudrates for use with Rsconf() */ }; char *flow[3] = { "None","Xon/Xoff","Rts/Cts" }; /* Flow control status */ char *logstat[2] = { "Closed","Open" }; /* String for logfile status. */ char *echostat[2]= { "Off","On" }; /* String for Local Echo status */ /** ** Record structure for Dial directory 'Myterm.dir' **/ #define DIAL_LEN 58 /* record size for dial directory */ struct { char name[40]; char number[15]; int baudrate; } dial_dir; /** ** External protocols array **/ #define NPROTOCOLS 20 char *protocoltype[2]={"One file","Batch"}; struct extprot { int type; /* Type of protocol, batch or not */ char *f_name, /* Full name of external protocols. */ *s_name, /* startup name */ *up_cli, /* upload array */ *down_cli; /* download array */ } extprotocol[NPROTOCOLS]; /** ** Function Prototypes. **/ void getconfig ( void ); void mdmreset ( void ); void send ( void ); void dialmenu (void ); void configmenu ( void ); void dropdtr ( void ); int input ( int ); void purge ( void ); void displaybaudrates ( void ); long GetHz200 ( void ); /** ** Main function **/ void main(void) { int end_term = 0, /* flag end of terminal */ log=0, /* logfile open/closed */ scancode = 0, /* Scancode variable, prepared from key */ b=0; long key=0; /* return value of Bconin */ FILE *ifp; /* file descriptor pointer */ printf(" \33E\33v\33eMy first terminal in C, press \33p Help \33q for Help\n\n"); getconfig(); /* load external up/download protocols. */ mdmreset (); /* Reset the modem. */ while (!end_term){ /* End of terminal ? */ if (Bconstat (CONSOLE)) { /* Key pressed ? */ key=Bconin (CONSOLE); if ((int) key == 0) { /* Is it a normal char or a Scancode ? */ scancode =(int) (key >> 16); /* Get scancode */ switch (scancode) /* Look, if it's a terminal option. */ { case ALT_A : /* Answer incoming call */ printf ("\r\33KAnswering incoming call ...\n"); strcpy (buf,ANSWER); strcat (buf,CR); send(); break; case ALT_B : /* Set a new baudrate. */ if (++bd > 5) bd=0; printf ("\r\33KSetting baudrate to %d baud.\n",baud[bd][0]); Rsconf (baud[bd][1], flow_ctl,-1,-1,-1,-1); break; case ALT_C : /* Clear screen & recover colors */ printf("\33q\33bc\33cd\33v\33E"); break; case ALT_D : /* Jump to the dial directory. */ dialmenu (); break; case ALT_E : /* Toggle Local echo on or off */ localecho = !localecho; printf("\r\33KLocal Echo now %s\n",echostat[localecho]); break; case ALT_F : /* Toggle flow control. */ if (++flow_ctl > 2) flow_ctl = 0; printf ("\r\33KSetting Flow Control to : %s\n", flow[flow_ctl]); Rsconf (baud[bd][1], flow_ctl,-1,-1,-1,-1); break; case ALT_H : /* Drop DTR signal for end of connection.*/ printf ("\r\33KDisconnecting ... \n"); dropdtr (); break; case ALT_I : /* Display information screen ... */ printf("\33E\n\33p My first terminal \33q is developed using Pure C v1.0 and\n" "written to learn a little bit of the C language.\n\n" "Special Thanks goes to all the people with useful ideas or suggestions\n" "on my source code written in C.\n\n" "If you have ideas or suggestions about my source code or this terminal,\n" "please contact me (Koos Kuil) on Fidonet 2:282/397 or NeST 90:4001/103\n\n" "or you can call my own BBS in Holland (+31)(0)5978-18087.\n\n" "You may copy this programm to al your (lady) friends only for nothing,\n" "not for money.\n\n Have fun with it, Koos Kuil\n\n" "Strike a key when ready ..."); Bconin(CONSOLE); /* Wait for a keypress ... */ printf("\r\33K"); /* Cleanup last line Esc-K (Vt52) */ break; case ALT_L : /* Open or close the logfile. */ if (log == 0) { if ((ifp = fopen (LOGFILE, "a")) == 0) /* Error opening logfile ? */ printf ("Can't open logfile.\n"); else log = 1; /* Everything allright ? Okay. */ } else { log = 0; fclose (ifp); } printf ("\rLogfile now %s\n", logstat[log]); break; case ALT_P : /* Install external protocols & change * * function key macros. */ configmenu(); break; case ALT_R : /* Set default baudrate & reset modem. */ printf ("\r\33KReintializing modem ... \n"); mdmreset (); break; case ALT_X : /* Quit terminal ? */ printf("\r\33KQuit terminal y/n ? "); key=(int) Bconin(CONSOLE); if (key != 89 && key != 121) printf("\r\33K"); else { printf ("\n\nThanks for using My first terminal, have a nice day.\n"); end_term = 1; /* End of terminal flag. */ } break; case HELP : /* Panic!, Display help information */ printf("\33E\n\33p My First Terminal, developed using Pure C, by Koos Kuil \33q\n" "version 1.0, created at %s on %s\n\n" " ALT-A Answer incoming call.\n" " ALT-B Toggle baudrate, now %d baud.\n" " ALT-C Clear screen & recover VT52 colors\n" " ALT-D Telephone numbers dial directory.\n" " ALT-E Toggle local echo %s\n" " ALT-F Toggle flow control, current flow : %s.\n" " ALT-H Hangup your connection.\n" " ALT-I Information about this terminal.\n" " ALT-L Logfile '%s' now %s.\n" " ALT-P Protocol & Function key configuration menu.\n" " ALT-R Reintialize modem.\n" " ALT-X Quit My first Terminal.\n\n" " F1..F10 Send Function key macro to other side.\n" " Ctrl-Up Upload files with external protocols\n" " Ctrl-Dn Download files with external protocols\n\n" "Strike a key when ready ..." ,__DATE__,__TIME__,baud[bd][0],echostat[!localecho],flow[flow_ctl],LOGFILE,logstat[log]); Bconin(CONSOLE); /* Wait on a keypress ... */ printf ("\r\33K"); /* Cleanup last line Esc-K (Vt52) */ break; case CURS_DN : /* Cursor key down ? */ if (Kbshift(-1) & 0x04) { /* Check Control key. */ if (ext_p){ printf ("\n\33p Download protocol \33q\n\n"); for (b = 0;b < ext_p; ++b) printf ("%d. %s\n",b+1,extprotocol[b].s_name); printf ("\nSelect : "); if (input (2)) { b=atoi (woord); if (b>=1 && b<=ext_p) { /* dec 1, array begins with 0 */ strcpy (buf+1,extprotocol[--b].down_cli); /* One file transfer download like Xmodem ? */ if (extprotocol[b].type == 0 ) { printf("\n\nPlease enter filename for %s download : ",extprotocol[b].s_name); woord[0]=' '; /* add extra space char */ strcat (buf+1,woord); /* after commandline */ if (input (12)) strcat (buf+1,woord); else strcat (buf+1,"noname.dwn\0"); } buf[0]=strlen (buf+1); printf ("\n\nStarting external %s ...\n",extprotocol[b].s_name); Pexec (0,extprotocol[b].f_name,buf,ENVIRONMENT); printf ("\rBack to My first terminal\n"); } else printf("\r\33KWrong number entered.\n"); } else printf("\r\33K"); } else printf("\nNo external download protocols available.\n"); } break; case CURS_UP : /* Cursor up ? */ if (Kbshift(-1) & 0x04) { /* Check Control key. */ if (ext_p) { printf ("\n\33p Upload protocol \33q\n\n"); for (b = 0;b < ext_p; ++b) printf ("%d. %s\n",b+1,extprotocol[b].s_name); printf ("\nSelect : "); if (input(2)){ b=atoi(woord); if (b >= 1 && b <= ext_p) { printf ("\n\nEnter filename(s) for upload :"); input (100); if (!strlen (woord)) printf ("\r\33KNo filenames entered for upload\n"); else { strcpy (buf,woord); /* add after the commanline */ woord[0]=' '; /* a extra space char and */ strcpy (woord+1,buf); /* the filenames to upload. */ buf[1]=0; /* Clear commanline buffer. * * copy the cli for your * * selected upload protocol */ strcpy (buf+1,extprotocol[--b].up_cli); strcat (buf+1,woord); /* Add upload filenames. */ buf[0]=strlen(buf+1); /* Size commandline. */ printf ("\n\nStarting external %s ...\n",extprotocol[b].s_name); Pexec (0,extprotocol[b].f_name,buf,ENVIRONMENT); printf ("\rBack to My first terminal\n"); } } else printf ("\r\33KWrong number entered.\n"); } else printf ("\r\33K"); } else printf ("\nNo external upload protocols available.\n"); } break; default: if (scancode >= 0x3b && scancode <= 0x44) { /* Function key ? */ strcpy (buf,funckey[scancode - 0x3b]); /* Copy func. key to buf */ strcat (buf,CR); /* Add return char */ send (); /* Send it. */ } } } else { Bconout(AUX,(int) key); if (localecho) putchar ((int) key); /* Local echo on ? */ } } if (Bconstat(AUX)) { /* Something on serial port? */ b=(int) Bconin(AUX); /* Get it. */ putchar (b); if (log) putc( (char) b,ifp); /* Write it to logfile. */ } } if (log) fclose(ifp); /* Logfile open ? Close it. */ } /************************************************************************ * * * Procedure : send(); * * Return : No return value. * * * * Send string array buf[] to the serial port. * * * ************************************************************************/ void send(void) { int i=0; while (buf[i]) Bconout (AUX,buf[i++]); } /************************************************************************ * * * Procedure : Purge(); * * Return : No return value. * * * * Cleanup the serial port for one second. * * * ************************************************************************/ void purge(void) { long timer = GetHz200(); /* 200 Hz timer, Sozobon C */ do { while (Bconstat(AUX)) { timer = GetHz200(); /* 200 Hz timer, for wait a */ Bconin(AUX); /* second to purge serial port.*/ } } while ( (timer + 200 >= GetHz200()) && (Bconstat (CONSOLE)) == 0 ); /* serial port 1 second clean? */ } /************************************************************************ * * * Procedure : mdmreset(); * * Return : No return value. * * * * Set startup baudrate, purge serial port & Reset modem. * * * ************************************************************************/ void mdmreset(void) { Rsconf (baud[START_BD][1], flow_ctl,-1,-1,-1,-1); bd=START_BD; /* startup baudrate. */ purge (); /* Clear input buffer. */ strcpy (buf,RESET); /* prepare reset string. */ strcat (buf,CR); send (); /* and reset modem ... */ } /************************************************************************ * * * Procedure : dropdtr(); * * Return : No return value. * * * * Drop the modem DTR signal for one second & cleanup the serial port. * * * ************************************************************************/ void dropdtr(void) { Ongibit (16); /* Drop DTR signal */ sleep (1); /* Wait one second */ Offgibit (239); /* DTR high again. */ purge(); } /************************************************************************ * * * Procedure : input(length); * * Return : NULL, For everything allright, user entered something. * * ONE, If the user has escaped from input by pressing * * the escape key. * * * * Get a limited string from the keyboard, length is maximum size that * * can entered. The entered string comes into string array woord[] * * * ************************************************************************/ int input (length) { int i=0, a=0; while ((a =(char) Bconin(CONSOLE)) != 13 && (a != 27)){ if (a == 8) { if (i) { woord[--i]=0; /* Get backspace from keyboard. */ printf("\b \b"); /* Send destructive backspace char. */ } else putchar (7); /* Backspace not possible. Beep ! */ } else { if (i >= length) putchar (7); /* Maximum size, beep */ else { woord[i++]=a; /* Append key to string. */ putchar (a); /* and display it on screen. */ } } } woord[i]=0; /* end of string char. */ if (a == 27) /* Escape from input ? return zero */ return(0); else return(1); /* Everything okay ... */ } /************************************************************************ * * * Procedure : dial_menu(); * * Return : No return value. * * * * Telephone number directory, including options for change, append & * * delete numbers, Autodial function etc.. * * * ************************************************************************/ void dialmenu(void) { /* * Protypes */ void displaybadrate ( void ); long offset=0; /* offset pointer for fseek() */ int numbers = 0, /* Total numbers in dial list */ i = 0, /* Used for calculation... */ a = 0, b = 0, end = 0, /* End of number directory */ dial_exit = 0; /* Exit flag */ FILE *ifp, *ifp_b; /* file descriptor pointers */ DTA *DtaBuf = Fgetdta(); /* Get DTA address */ if (Fsfirst (DIALDIR,1) >= 0) /* Does DIALDIR exist ? */ numbers = (int) (DtaBuf -> d_length / DIAL_LEN); /* Get size DIALDIR */ if (begin+15 <= numbers) /* calculating begin/end for */ end=begin+15; /* dial directory. */ else end=numbers; do { printf("\33E\n\33p Telephone number directory ... \33q\n" "--------------- Bulletin Board Name -------------- Telephone ---- Baud --\n\n"); if (numbers) { ifp=fopen (DIALDIR,"r"); /* Open dial directory */ offset=begin*DIAL_LEN; fseek (ifp,offset,0); for (i = begin ;i < end; ++i ){ fread (&dial_dir,DIAL_LEN,1,ifp); if (i < 9) printf (" "); printf ("%d. %s",i+1,dial_dir.name); /* display name */ gotoxy (49, (i-begin)+4); /* jump to x,y */ printf("| %s",dial_dir.number); /* display number. */ gotoxy (64, (i-begin)+4); /* jump to x,y */ printf ("| %d\n",baud[dial_dir.baudrate][0]); } fclose(ifp); } else { printf("No telephone numbers in this dial listing.\n"); } printf("\nOptions : \33p Esc \33q Exit \33p A \33q Append \33p C \33q Change \33p D \33q Delete \n\n"); printf("Enter a option, dial list number or telephone number : "); if (input(20)) { /* Input telephone number */ if (strlen (woord)) { switch (toupper (woord[0])) { case ('A') : printf ("\r\33K\33p Append \33q\33j The name of the new BBS : "); if (input(39)) { strcpy (dial_dir.name,woord); printf ("\33k\33K\33j The telephone number of this new BBS : "); if (input(14)) { strcpy (dial_dir.number,woord); displaybaudrates(); /* display baudrates */ input(2); i=atoi (woord); /* get value from string. */ if (i >= 1 && i <= 6) dial_dir.baudrate=i-1; else dial_dir.baudrate=START_BD; /* wrong baudrate,default.*/ ifp=fopen (DIALDIR,"a"); /* open dial directory... */ fwrite (&dial_dir,DIAL_LEN,1,ifp); /* and append it. */ fclose (ifp); /* close it. */ ++numbers; /* increase numbers. */ if (begin+15 > end) ++end; /* increas dial directory */ } } break; case ('C') : if (numbers){ printf("\r\33K\33p Change \33q\33j Enter number of the BBS : "); if (input(2)) { if (strlen(woord)){ i=atoi(woord); if ((i >=1) & (i <= numbers)){ ifp=fopen(DIALDIR,"r+"); offset=(i-1)*DIAL_LEN; /* Calculate offset */ fseek (ifp,offset,0); fread (&dial_dir,DIAL_LEN,1,ifp); printf("\33k\33K\33j Enter the new BBS name : "); if (input(39)){ if (strlen (woord)) strcpy (dial_dir.name, woord); printf("\33k\33K\33j Enter the new BBS telephone number : "); if (input(14)) { if (strlen (woord)) strcpy (dial_dir.number, woord); displaybaudrates(); input(2); i=atoi (woord); /* Get value from string. */ if (i >= 1 && i <= 6) dial_dir.baudrate=i-1; fseek (ifp,offset,0); /* Seek to offset & */ fwrite (&dial_dir,DIAL_LEN,1,ifp); /* write new record */ fclose (ifp); /* close dial dir. */ } } } } } } break; case ('D') : if (numbers){ printf("\r\33K\33p Delete \33q Enter number of the BBS : "); if (input(2)) { if (strlen(woord)){ i=atoi(woord); if ((i >=1) & (i <= numbers)){ ifp=fopen(DIALDIR,"r"); ifp_b=fopen("temp.$$$","w"); for (b=0;bnumbers) end=numbers; } } } } break; default : i=atoi(woord); /* get value from string like Val(a$) */ if ((i >= 1) & (i <= numbers)){ ifp=fopen(DIALDIR,"r"); offset=(i-1)*DIAL_LEN; /* calculate offset */ fseek (ifp,offset,1); /* Seek to offset... */ fread (&dial_dir,DIAL_LEN,1,ifp); /* & read dial record */ fclose(ifp); } else { strcpy (dial_dir.name,"The Unknown BBS at "); strcat (dial_dir.name,woord); /* add unknown number.*/ dial_dir.baudrate=bd; /* actual baudrate. */ strcpy(dial_dir.number,woord); /* telephone number */ } strcpy (buf,DIAL); /* prepare modem dial */ strcat (buf,dial_dir.number); /* string. */ strcat (buf,CR); printf("\r\33KDialing %s ...",dial_dir.name); Rsconf(baud[dial_dir.baudrate][1], flow_ctl,-1,-1,-1,-1); purge(); send(); /* and dial number... */ a = 0; /* pointer for result modem string after dial. */ woord[0]='\0'; do { long timer = GetHz200(); /* Get 200 Hz timer */ do { while (Bconstat (AUX)) { timer = GetHz200(); /* Wait a second to */ woord[a++]=Bconin (AUX); /* purge serial port. */ woord[a+1]='\0'; } } while (timer+100 > GetHz200()); /* serial port clean? */ if (strstr(woord,"BUSY") || strstr(woord,"NO CARRIER") || strstr(woord,"NO DIALTONE")){ printf("\r\33KNo carrier or Busy ..."); a=0; woord[0]='\0'; purge(); timer = GetHz200(); /* Get 200 Hz timer * * Wait 10 Seconds... */ while ( (!Bconstat(CONSOLE)) && (timer + 2000 > GetHz200()) ); if (!Bconstat(CONSOLE)) { printf("\r\33KDialing %s ...",dial_dir.name); send(); } } } while ((strstr(woord,"CONNECT") == 0) && (Bconstat(CONSOLE) == 0)); if (Bconstat(CONSOLE)) { printf("\nAuto Dial session aborted.\n"); dropdtr(); } else printf("\nConnect...\07\n"); dial_exit=1; } } else { if (begin+15 <= numbers) begin+=15; else begin=0; if (begin+15 <= numbers) end=begin+15; else end=numbers; } } else { dial_exit=1; } } while (!dial_exit); /* Dial list exit flag. */ printf("\r\33K"); /* Cleanup line. */ } /************************************************************************ * * * Procedure : display_baudrates(); * * Return : No return value. * * * * Display the baudrates for use with the Change & Append option in * * the telephone number directory. * * * ************************************************************************/ void displaybaudrates(void) { int i; printf ("\33k\33K Baudrate :\33j "); for (i = 0; i < 6; ++i) printf ("\33p %d \33q %d ",i+1,baud[i][0]); printf ("\33k"); } /************************************************************************ * * * Procedure : config_menu(); * * Return : No return value. * * * * Install & Change external installed up & download protocols or * * function keys or Save the changed option into file CONFIGFILE * * * ************************************************************************/ void configmenu(void) { int configexit = 0, /* Configuration menu exit flag. */ b = 0, /* local variables */ select = 0, scancode = 0, a = 0; long key = 0; FILE *ifp; /* File descriptor pointer. */ do { printf ("\33E\n\33p Configuration Menu for protocols & function keys \33q\n\n"); for (b = 0; b < 10; ++b){ /* Display function keys */ printf ("F%d.",b+1); if (b < 9) printf (" "); printf ("%s\n",funckey[b]); } printf ("\n\33p External installed up & download protocols listing \33q\n\n"); for (b = 0; b < ext_p; ++b){ /* Display names of external protocols */ if (b < 6) { /* into 2 columns. */ gotoxy (0,16+b); } else gotoxy (40,16+(b-6)); if (b < 9) printf (" "); printf ("%d. %s\n",b+1,extprotocol[b].s_name); } gotoxy (0,23); printf ("\33p Esc \33q Exit \33p F1...F10 \33q \33p A \33q Append \33p C \33q Change \33p D \33q Delete \33p S \33q Save Select: "); do { /* End of configuration menu ? */ key=Bconin (CONSOLE); /* Get scancode */ scancode = (int) (key >> 16); } while (!( (scancode == S_KEY) || (scancode == A_KEY) || (scancode == C_KEY) || (scancode == D_KEY) || (scancode == ESCAPE) || (scancode >=0x3a && scancode <=0x44) )); switch (scancode) { case A_KEY : if (ext_p < 12) { for (b = 16; b < 22; ++b) { /* Cleanup window */ gotoxy (0,b); printf ("\33K"); } gotoxy (0,16); printf ("\33p Full name : \33q \n" "\33p Protocol type : \33q \n" "\33p Start up name : \33q \n" "\33p Upload Commandline : \33q \n" "\33p Download Commandline : \33q \n\n"); select = ext_p; gotoxy (25,16); if (input(40)) { extprotocol[select].s_name = calloc (strlen(woord)+1, sizeof(char)); strcpy (extprotocol[select].s_name, woord); gotoxy (25,17); printf ("\33p O \33q One file transfer or \33p B \33q Batch transfer ? : "); if (( toupper ((char) Bconin(CONSOLE))) == 'B') extprotocol[select].type=1; else extprotocol[select].type=0; gotoxy (25,17); printf ("\33K%s",protocoltype[extprotocol[select].type]); gotoxy (25,18); if (input(40)) { extprotocol[select].f_name = calloc (strlen(woord)+1, sizeof(char)); strcpy (extprotocol[select].f_name, woord); gotoxy (25,19); if (input(40)) { extprotocol[select].up_cli = calloc (strlen(woord)+1, sizeof(char)); strcpy (extprotocol[select].up_cli, woord); gotoxy (25,20); if (input(40)) { extprotocol[select].down_cli = calloc (strlen(woord)+1, sizeof(char)); strcpy (extprotocol[select].down_cli, woord); ++ext_p; } } } } } else { printf("\r\33K You can not install more then 12 external protocols."); Bconin(CONSOLE); } break; case C_KEY : if (ext_p) { printf("\r\33K\33p Change \33q External protocol number : "); if (input(2)){ select=atoi(woord); if (select >= 1 && select <= ext_p) { for (b = 16; b < 22; ++b) { /* Cleanup window */ gotoxy (0,b); printf ("\33K"); } select--; gotoxy (0,16); printf ("\33p Full name : \33q %s\n" "\33p Protocol type : \33q %s\n" "\33p Start up name : \33q %s\n" "\33p Upload Commandline : \33q %s\n" "\33p Download Commandline : \33q %s\n\n" ,extprotocol [select].s_name,protocoltype [extprotocol [select].type], extprotocol [select].f_name,extprotocol [select].up_cli, extprotocol [select].down_cli); gotoxy (0,23); printf ("\33K\33p Change \33q\33j Enter the new Full name : "); if (input(40)) { if (strlen(woord)) { extprotocol[select].s_name = calloc (strlen(woord)+1, sizeof(char)); strcpy (extprotocol[select].s_name, woord); } printf ("\33k\33K\33j \33q \33p O \33q One file transfer or \33p B \33q Batch transfer ? : "); if (( toupper ((char) Bconin(CONSOLE))) == 'B') extprotocol[select].type=1; else extprotocol[select].type=0; printf ("\33k\33K\33j Enter the new Startup name : "); if (input(40)) { if (strlen(woord)) { extprotocol[select].f_name = calloc (strlen(woord)+1, sizeof(char)); strcpy (extprotocol[select].f_name, woord); } printf ("\33k\33K\33j Enter the new Upload CLI : "); if (input(40)) { if (strlen(woord)) { extprotocol[select].up_cli = calloc (strlen(woord)+1, sizeof(char)); strcpy (extprotocol[select].up_cli, woord); } printf ("\33k\33K\33j Enter the new Download CLI : "); if (input(40)) { if (strlen(woord)) { extprotocol[select].down_cli = calloc (strlen(woord)+1, sizeof(char)); strcpy (extprotocol[select].down_cli, woord); } } } } } } } } else { printf("\r\33K You can't change a external protocol if there is none..."); Bconin(CONSOLE); } break; case D_KEY : printf("\r\33K\33p Delete \33q External protocol number : "); if (input(2)){ select=atoi(woord); if (select >= 1 && select <= ext_p) { printf ("\r\33K\33p Delete \33q Delete this protocol ? y/n "); if (input(2)) { if (strlen (woord)) { if (toupper(woord[0]) == 'Y' ) { --select; for (b = ext_p; b > select; --b) { extprotocol[b-1].s_name = extprotocol[b].s_name; extprotocol[b-1].f_name = extprotocol[b].f_name; extprotocol[b-1].up_cli = extprotocol[b].up_cli; extprotocol[b-1].down_cli = extprotocol[b].down_cli; } --ext_p; } } } } } break; case S_KEY : printf("\r\33K\33p Saving \33q Function keys & Installed protocols into file %s ...",CONFIGFILE); if ((ifp = fopen (CONFIGFILE,"w")) != 0) { for (b = 0;b < 10; ++b) { fputs (funckey[b], ifp); fputs (CRLF, ifp); /* add cr+lf */ } for (b = 0;b < ext_p; ++b) { fprintf (ifp, "%d\n",extprotocol[b].type); fputs (extprotocol[b].s_name, ifp); fputs (CRLF, ifp); fputs (extprotocol[b].f_name, ifp); fputs (CRLF, ifp); fputs (extprotocol[b].up_cli, ifp); fputs (CRLF, ifp); fputs (extprotocol[b].down_cli, ifp); fputs (CRLF, ifp); } fclose (ifp); } break; case ESCAPE : /* Escape ? */ configexit=1; break; } /* Function key pressed ? */ if (scancode >= 0x3b && scancode <= 0x44) { a = scancode - 0x3a; /* Get function key number */ printf ("\r\33K\33p Change \33q Function key %d to : ",a); if (input(40)) { funckey[--a]=calloc (strlen(woord)+1,sizeof(char)); strcpy (funckey[a],woord); } } } while (!configexit); printf("\r\33K"); } /************************************************************************ * * * Procedure : get config(); * * Return : No return value. * * * * Read funtion key macros & the external upload & download protocols, * * into structure array *extprotocol[]. * * * * The Clean ascii file CONFIGFILE is used for this. * * * ************************************************************************/ void getconfig(void) { char line[50], /* work room. */ *pointer; /* pointer for calloc() */ int i; long length; FILE *ifp; /* local file descriptor pointer */ if (Fsfirst(CONFIGFILE,0) == 0) { /* does CONFIGFILE exist ? */ if ((ifp = fopen (CONFIGFILE,"r")) != 0 ) { for (i = 0;(i < 10 && (fgets (line,40,ifp) != 0)); ++i) { length=strlen (line); if (length) { line[length-1]='\0'; /* strip CR char */ funckey[i] = calloc (length, sizeof(char)); strcpy (funckey[i],line); } } do { length = 0; for (i = 0;(i <= 4 && (fgets (line,50,ifp) != 0)); ++i) { length=strlen (line); if (length) { line[length-1]='\0'; /* strip CR char */ if (i) { pointer = calloc (length, sizeof(char)); strcpy (pointer,line); } switch (i) { case 0 : extprotocol[ext_p].type = atoi (line); case 1 : extprotocol[ext_p].s_name = pointer ; break; case 2 : extprotocol[ext_p].f_name = pointer ; break; case 3 : extprotocol[ext_p].up_cli = pointer ; break; case 4 : extprotocol[ext_p].down_cli = pointer ; ++ext_p; } } } } while (length); fclose(ifp); } else printf ("Unable to open configuration file.\n"); printf ("%d Up/Download protocols installed.\n",ext_p); } else printf("No Up/Download protocols installed.\n"); } /************************************************************************ * * * Procedure : GetHz200(); * * Return : long 200 Hz timer * * * * Returns 200 Hz timer of Supervisor address 0x4ba, for waiting a few * * seconds. * * * ************************************************************************/ long GetHz200 (void) { long old_super_stack = Super (0L), /* Get into Supervisor mode */ timer = 0; timer = (* ( long *) 0x4ba ); /* Get 200 Hz timer */ Super ((void *) old_super_stack ); /* Get Back to user mode */ return (timer); }