/////////////////////////////////////////// // // hostmode.cs version 2 // by Patrick Clark // Century Software Inc. // 14 October 2002 // // This script uses an existing RS232 // connection to connect to a modem and // listen for an incoming call. // // It then answers the phone and presents // the caller with a menu of file transfer // options. // // To use this script, configure TinyTERM // for an RS232 connection to a COM port // with a modem attached. // // Only modems that accept the Hayes AT // command set are supported. // // Version 2 adds a function which creates // the users.dat file and adds users to it. // /////////////////////////////////////////// // Variable declaration and initial values // Change the following values to match your modem and preferences var t_init = "&FE1Q0"; // initialization string var t_offhook = "A"; // answer call string var t_attn = "+++"; // modem attention string var t_hangup = "HZ"; // hangup string var t_mdmwait = 5; // number of seconds to wait for modem response var t_ok = "OK"; // expected modem OK response var t_ring = "RING"; // expected modem response for ring detected var t_newuser = 0; // set to 1 to allow new users to login var t_tries = 3; // 3 tries to login, then fail out var t_upload = "C:\\Upload"; // directory for uploading files var t_dnload = "C:\\Download"; // directory for files available to download var t_flist = GetSysDir() + "/files.txt"; // where to put directory listing var t_userfile = GetSysDir() + "/users.dat"; // user and password data file var t_log = GetSysDir() + "/hostmode.log"; // log file // additional variables used for script processing var t_chk, t_choice, t_xprot, t_xmode, t_test, t_count, t_file; var u_login, u_password, u_test, u_match, u_msg, u_filspec; var a_msg, fil_nam, new_user, new_pass1, new_pass2, new_out; // add new users option t_chk = msgbox("Do you wish to add new users?","Add Users",2); if ((t_chk == 0)) { add_users(); } else { // check for user data file // create if non-existent, else open for read or write depending on t_newuser if (!(exists(t_userfile))) { fcreate(1,t_userfile); } else if ((t_newuser)) { fopen(1,t_userfile,"UA"); } else { fopen(1,t_userfile,"RA"); } } // file transfer settings FTSetXferStat(0); // turn off transfer status window FtSetSync(1); // pause script execution until transfer finishes // initialize connection if ( !(te.isconnected)) { te.connect(); // connect to COM port if not already connected } send_modem(t_init); if ((test_modem() != 0)) { msgbox("No response received from modem.\r\nReturning to TinyTERM","Hostmode failed",0); te.displaynl("\r\nDISCONNECTED\r\n"); te.disconnect(); return(0); } // start hostmode t_chk = msgbox("Initializing hostmode.\r\nType ^C to exit.","Modem response " + t_ok,1); logfile(t_log); if ((t_chk != 0)) { // cancel clicked te.displaynl("\r\nDISCONNECTED\r\n"); te.disconnect(); return(0); } else { te.displaynl("\r\nHOSTMODE INITIALIZED\r\nType ^C to cancel"); log_stamp("Hostmode initialized"); // call wait and answer while ((te.wait(t_ring,0) == 0)) { // Wait for incoming call with no timeout te.displaynl("\r\nRING DETECTED"); log_stamp("Ring detected"); send_modem(t_offhook); // Pick up the call if ((user_login() == 0)) { // Valid user login user_menu(); // Send menu to caller } else { // Invalid user login te.xmit("\r\nLogin attempts exceeded.\r\nHanging up . . .\r\n"); te.display("\r\nLogin attempts exceeded.\r\nHanging up . . .\r\n"); te.xmit(t_attn); send_modem(t_hangup); } te.displaynl("Call disconnected.\r\n\r\nWaiting for new call.\r\nType ^C to exit.\r\n\r\n"); } // the following will only execute if ^C is typed while waiting for ring admin_break(); logfile_close(); return(0); } // AT command send function function send_modem(t_input) { te.xmit("AT" + t_input + "\r"); } // wait for OK function function test_modem() { t_chk = te.wait(t_ok,t_mdmwait); if ((t_chk == -1)) { // timeout msgbox(t_ok + " not received","Modem not responding",0); te.disconnect(); return(1); } else if ((t_chk == -2)) { // ^C typed admin_break(); return(1); } else { // OK received return(0); } } // user interrupt received function admin_break() { msgbox("User interrupt received","Ending hostmode",0); log_stamp("Hostmode ended on user interrupt"); te.xmit(t_attn); send_modem(t_hangup); te.disconnect(); } // log a message with date and time function log_stamp(a_msg) { writelog(cdate(time()) + " " + ctime(time()) + " " + a_msg + "\r\n"); } // test for valid user ID function user_login() { t_count = 1; while ((t_count <= t_tries)) { u_login = ""; u_password = ""; u_match = 0; // get username t_test = 1; te.xmit("Enter your username: "); te.display("Enter your username: "); do { t_tmp = te.cread(0,1,0); if (!(_IsSpace(_asc(t_tmp)))) { // space, tab, CR or newline not typed u_login = u_login + t_tmp; te.xmit(t_tmp); te.display(t_tmp); } else { t_test = 0; te.xmit("\r\n"); te.display("\r\n"); } } while ((t_test)); // get password te.xmit("Enter password for user " + u_login + "\r\n"); te.display("Enter password for user " + u_login + "\r\n"); te.xmit("Password will not display: "); t_test = 1; do { t_tmp = te.cread(0,1,0); if (!(_IsSpace(_asc(t_tmp)))) { // space, tab, CR or newline not typed u_password = u_password + t_tmp; } else { t_test = 0; te.xmit("\r\n"); te.display("\r\n"); } } while ((t_test)); // check username and password against user file fseek(1,0,0); // beginning of user file t_chk = 0; u_match = 0; do { u_test = freadln(1,-1); if ((u_login == field(u_test,1,_asc("=")))) { if ((Encrypt(u_password) == Field(u_test,2,_asc("=")))) { t_chk = 1; // valid username and password u_match = 1; } else { te.xmit("\r\nUsername and password don't match\r\n"); te.display("\r\nUsername and password don't match\r\n"); u_match = 1; log_stamp("User " + u_login + " entered invalid password"); } } } while (!(t_chk) || !(feof(1)) || !(u_match)); if ((t_chk)) { // valid login te.xmit("\r\nWelcome, " + u_login + "\r\n"); te.displaynl("\r\nWelcome, " + u_login); log_stamp("User " + u_login + " logged in"); return(0); } else if ((u_match) || !(t_newuser)) { // bad password or username te.xmit("\r\nLogin invalid.\r\n"); te.display("\r\nLogin invalid.\r\n"); t_count++; } else if ((t_newuser) && (feof(1))) { // new users allowed fwriteln(1,u_login + "=" + encrypt(u_password),-1); te.xmit("\r\nWelcome, new user " + u_login + "\r\n"); te.display("\r\nWelcome, new user " + u_login + "\r\n"); log_stamp("New user " + u_login + " registered and logged in"); return(0); } } // the following only happens if the user fails to login too many times return(1); } // menu that drives the user's experience function user_menu() { t_chk = 1; while ((t_chk)) { te.xmit("\r\n\r\n"); te.xmit("Main Menu\r\n"); te.xmit(" [1] Upload file from your PC\r\n"); te.xmit(" [2] Download file to your PC\r\n"); te.xmit(" [3] Listing of current directory\r\n"); te.xmit(" [4] Send message to host\r\n"); te.xmit(" [9] Quit session and logout\r\n"); te.xmit("\r\nEnter your selection: "); te.display("\r\n\r\n"); te.display("Main Menu\r\n"); te.display(" [1] Upload file from your PC\r\n"); te.display(" [2] Download file to your PC\r\n"); te.display(" [3] Listing of current directory\r\n"); te.display(" [4] Send message to host\r\n"); te.display(" [9] Quit session and logout\r\n"); te.display("\r\nEnter your selection: "); t_choice=te.cread(0,1,0); te.xmit(t_choice + "\r\n\r\n"); te.display(t_choice + "\r\n\r\n"); switch (_val(t_choice)) { case 1 : upload_file(); break; case 2 : download_file(); break; case 3 : list_dir(); break; case 4 : host_msg(); break; case 9 : te.xmit("Are you sure you want to quit (Y/N)? "); te.display("Are you sure you want to quit (Y/N)? "); t_choice = te.cread(0,1,0); te.xmit(t_choice + "\r\n"); te.display(t_choice + "\r\n"); if ((_tolower(t_choice) == "y")) { t_chk = 0; te.xmit("Logout accepted. Hanging up . . .\r\n\r\n"); te.display("Logout accepted. Hanging up . . .\r\n\r\n"); te.xmit(t_attn); send_modem(t_hangup); log_stamp("User logged out"); } break; default : te.xmit("Invalid option. Please select a valid option.\r\n"); te.display("Invalid option. Please select a valid option.\r\n"); } } } // upload file to host PC function upload_file() { set_prot(); chdir(t_upload); if ((left(_toLower(FTGetProtocolName(FTGetProtocolID() + 1)),6) == "XMODEM")) { t_test = 1; do { te.xmit("\r\nEnter filename to receive: "); te.display("\r\nEnter filename to receive: "); t_file = ""; t_tmp = te.cread(0,1,0); if (!(_IsSpace(_asc(t_tmp)))) { // space, tab, CR or newline not typed t_file = t_file + t_tmp; te.xmit(t_tmp); te.display(t_tmp); } else if (exists(t_file)) { te.xmit(t_file + " already exists. Please enter a new filename.\r\n"); te.display(t_file + " already exists. Please enter a new filename.\r\n"); } else { t_test = 0; te.xmit("\r\n"); te.display("\r\n"); } } while ((t_test)); } log_stamp("Upload file " + t_file); te.xmit("\r\nReady to receive file" + t_file + "\r\n"); te.display("\r\nReady to receive file" + t_file + "\r\n"); FTRecv(t_file,t_upload); } // download file from host PC function download_file() { set_prot(); chdir(t_dnload); t_file = ""; t_test = 1; te.xmit("\r\nEnter filename to send: "); te.display("\r\nEnter filename to send: "); do { t_tmp = te.cread(0,1,0); if (!(_IsSpace(_asc(t_tmp)))) { // space, tab, CR or newline not typed t_file = t_file + t_tmp; te.xmit(t_tmp); te.display(t_tmp); } else { t_test = 0; te.xmit("\r\n"); te.display("\r\n"); } } while ((t_test)); if (exists(t_file)) { te.xmit("Ready to send file " + t_file + "\r\n"); te.xmit("Press Enter when ready to receive . . ."); te.display("Ready to send file " + t_file + "\r\n"); te.display("Press Enter when ready to receive . . ."); te.read("",false); log_stamp("Download file " + t_file); te.xmit("\r\nStart your receive process now . . .\r\n"); te.display("\r\nStart your receive process now . . .\r\n"); FTSend(t_file,".",0); } else { te.xmit("\r\nFile " + t_file + " does not exist.\r\n"); te.xmit("Returning to main menu.\r\n\r\n"); te.display("\r\nFile " + t_file + " does not exist.\r\n"); te.display("Returning to main menu.\r\n\r\n"); } } // list current directory function list_dir() { te.xmit("\r\nEnter file specification to list (default *.*): "); te.display("\r\nEnter file specification to list (default *.*): "); u_filspec = ""; t_tmp = te.cread(0,1,0); while (!(_IsSpace(_asc(t_tmp)))) { u_filspec = u_filspec + t_tmp; t_tmp = te.cread(0,1,0); } if (_sizeof(u_filspec) == 0) { // Enter hit immediately for default u_filspec = "*.*"; } tsl_forinit(u_filspec); while( ( fil_nam = tsl_fornext()) != "") { te.xmit(fil_nam + "\r\n"); te.display(fil_nam + "\r\n"); } log_stamp("List directory " + u_filspec); } // send message to host function host_msg() { u_msg = ""; te.xmit("Enter message below: "); te.display("Enter message below:\r\n"); te.displaynl("\r\n\007\007\007\007\007*** INCOMING MESSAGE ***\007\007\007\007\007\r\n"); t_tmp = te.cread(0,1,0); while (!(_IsSpace(_asc(t_tmp)))) { u_msg = u_msg + t_tmp; t_tmp = te.cread(0,1,0); } te.displaynl(u_msg); log_stamp("Message received for host"); log_stamp(u_msg); } // set file transfer protocol function set_prot() { t_chk = 1; while ((t_chk)) { te.xmit("\r\n\r\nAvailable file transfer protocols\r\n"); te.xmit(" [1] WTERMCRC\r\n"); te.xmit(" [2] TERMCRC\r\n"); te.xmit(" [3] ZMODEM\r\n"); te.xmit(" [4] YMODEM\r\n"); te.xmit(" [5] XMODEM\r\n"); te.xmit(" [6] XMODEM-CRC\r\n"); te.xmit(" [7] KERMIT\r\n"); te.xmit("\r\nEnter your selection: "); te.display("\r\n\r\nAvailable file transfer protocols\r\n"); te.display(" [1] WTERMCRC\r\n"); te.display(" [2] TERMCRC\r\n"); te.display(" [3] ZMODEM\r\n"); te.display(" [4] YMODEM\r\n"); te.display(" [5] XMODEM\r\n"); te.display(" [6] XMODEM-CRC\r\n"); te.display(" [7] KERMIT\r\n"); te.display("\r\nEnter your selection: "); t_xprot = te.cread(0,1,0); te.xmit(t_choice + "\r\n"); te.display(t_choice + "\r\n"); switch (_asc(t_choice)) { case 1 : FTSetProtocol("WTERMCRC"); te.xmit("Protocol set to WTERMCRC\r\n"); te.display("Protocol set to WTERMCRC\r\n"); log_stamp("Protocol set to WTERMCRC"); t_chk = 0; break; case 2 : FTSetProtocol("TERMCRC"); te.xmit("Protocol set to TERMCRC\r\n"); te.display("Protocol set to TERMCRC\r\n"); log_stamp("Protocol set to TERMCRC"); t_chk = 0; break; case 3 : FTSetProtocol("ZMODEM"); te.xmit("Protocol set to ZMODEM\r\n"); te.display("Protocol set to ZMODEM\r\n"); log_stamp("Protocol set to ZMODEM"); t_chk = 0; break; case 4 : FTSetProtocol("YMODEM"); te.xmit("Protocol set to YMODEM\r\n"); te.display("Protocol set to YMODEM\r\n"); log_stamp("Protocol set to YMODEM"); t_chk = 0; break; case 5 : FTSetProtocol("XMODEM"); te.xmit("Protocol set to XMODEM\r\n"); te.display("Protocol set to XMODEM\r\n"); log_stamp("Protocol set to XMODEM"); t_chk = 0; break; case 6 : FTSetProtocol("XMODEM-CRC"); te.xmit("Protocol set to XMODEM-CRC\r\n"); te.display("Protocol set to XMODEM-CRC\r\n"); log_stamp("Protocol set to XMODEM-CRC"); t_chk = 0; break; case 7 : FTSetProtocol("KERMIT"); te.xmit("Protocol set to KERMIT\r\n"); te.display("Protocol set to KERMIT\r\n"); log_stamp("Protocol set to KERMIT"); t_chk = 0; break; default : te.xmit("\r\nInvalid selection.\r\n"); } } t_xmode = ""; while ((t_xmode != "a") || (t_xmode != "a")) { te.xmit("\r\nASCII or Binary transfer (A/B)?"); t_xmode=_tolower(te.cread(0,1,0)); te.xmit(t_xmode + "\r\n"); te.display(t_xmode + "\r\n"); } if ((t_xmode == "a")) { FTSetAsciiMode(1); log_stamp("ASCII transfer mode"); } else { FTSetAsciiMode(0); log_stamp("Binary transfer mode"); } } // add new users function function add_users() { if ((exists(t_userfile))) { fopen(1,t_userfile,"UA"); fseek(1,0,2); } else { fcreate(1,t_userfile); } do { te.cls(); te.displaynl("\r\n\r\n\r\n"); new_user = te.read("Enter username to add or hit Enter to exit: ",1); if ((_SizeOf(new_user) != 0)) { do { new_pass1 = te.read("Enter password for user " + new_user + ". Password will not display: ",0); new_pass2 = te.read("\r\nRe-enter password to confirm: ",0); te.displaynl("\r\n\r\n"); } while (( new_pass1 != new_pass2)); new_out = new_user + "=" + encrypt(new_pass1); fwriteln(1,new_out,-1); } } while (_SizeOf(new_user) > 0); fclose(1); msgbox("Add users complete.","Add Users",0); return(0); }