home *** CD-ROM | disk | FTP | other *** search
- -----------------------------------------------------------------------
- // // September 9, 1991
- // R E M O T E . B T S //
- // //
- -----------------------------------------------------------------------
-
- -- REMOTE.BTS, STalker™ "Remote Mode" script.
- --
- -- Copyright © 1991, Strata Software, All Rights Reserved.
- -- Exclusive worldwide marketing and distributing by Gribnif Software.
- --
- -- This file is for the exclusive use of registered STalker™ owners
- -- and may not be distributed, in whole or in part, without the express
- -- written permission of Strata Software.
- --
- -- Permission has been granted by Strata Software to distribute
- -- this file on bulletin boards, paid access networks, and public
- -- domain and shareware disks, provided:
- --
- -- That this header remains intact, and
- -- All modifications are mentioned in the header before
- -- redistribution.
- --
- -- Modified by Scott Dowdle (L.DOWDLE1) in the spring of 1992 to
- -- show the remote user their location in the system at all times
- -- (i.e. C:\TELECOMM\)
- --
- -- Modified by Bob Morrow (R.MORROW10) on 12/10/92 to delete the
- -- requirement for using a password to enter remote mode when in
- -- local echo. Being in local isn't any different from quitting
- -- the program and doing damage that way. To exit from local
- -- mode, you're forced to put up with a message "Quitting from
- -- local mode" after you've decided to. Sorry, it was the only
- -- way to deal with exiting once I had removed the password
- -- requirement in local. However, it's a simple [return] that
- -- exits you for good. There isn't a "yes/no" option; that caused
- -- a lot of problems. This does not affect half or full echo
- -- operations.
-
- include "stalker.bth"
-
- int carrier_at_start; -- TRUE/FALSE based on DCD state when we begin
- // Set these based on the duplex mode so we don't have to keep
- // checking. One of these three is TRUE, the others are false.
- int mode_echo; -- Are we in ECHO (half-duplex) mode?
- int mode_full; -- Are we in FULL mode?
- int mode_local; -- Are we in LOCAL mode?
- string newline; -- Holds CR/LF, something we use often.
- int output_blocked; -- TRUE if user has typed ^S. ^Q resets.
- int saved_key; -- Room to hold one saved keypress.
- int whatnow; -- Asks for user input when reading files.
-
- function get_key returns int;
- function get_string returns int;
- function keyboard_check;
- function output_char;
- function output_string;
- function parse_filename;
- function remote_loop returns int;
- function run_cli;
- function show_files;
- function upload_file;
-
-
- ------------------------------
- // carrier_dropped //
- -----------------------------
- function carrier_dropped() returns int
- if carrier_at_start then
- return not port_carrier();
- else
- return FALSE;
- endif
- endfunction
-
- ------------------------------
- // change_dir //
- -----------------------------
- function change_dir()
- string dir[128];
-
- dir[0] = file_get_drive();
- dir[1] = ':';
- file_get_dir(0, dir + 2);
- output_string("\r\nCurrent location is:\r\n ");
- output_string(dir);
- output_string("\r\n\nNew location: ");
-
- if get_string(dir, sizeof(dir), FALSE) > 0 then
- file_change_dir(dir);
- endif
- endfunction
-
-
- ------------------------------
- // check_key //
- -----------------------------
- function check_key() returns int
- int ch;
-
- keyboard_check();
-
- ch = 0;
-
- if mode_local then
- if saved_key then
- ch = saved_key;
- saved_key = 0;
- endif
- else
- if port_instat() then
- ch = port_getchar();
- endif
- endif
-
- return ch;
- endfunction
-
-
- ------------------------------
- // check_local //
- -----------------------------
- function check_local() returns int
- if mode_local then
- output_string("\nInvalid operation in LOCAL mode.\r\n");
- return TRUE;
- endif
- return FALSE;
- endfunction
-
-
- ------------------------------
- // display_file //
- -----------------------------
- function display_file()
- int count;
- int file_handle;
- string input[128];
- string message[128];
-
- output_string("File to show: ");
- if get_string(input, sizeof(input), FALSE) > 0 then
- output_string(newline);
- printf("Ctrl-S stops, Ctrl-Q continues\r\n");
- wait(12);
- endif
- if (file_handle = file_open(input, FO_READ)) < 0 then
- sprintf(message, "File '%.80s' couldn't be opened (error %d).\r\n",
- input, file_handle);
- output_string(message);
- endif
- while (count = file_gets(input, sizeof(input), file_handle)) > 0 and
- not (check_key() == 3 or carrier_dropped()) do
- output_string(input);
- endwhile
- endfunction
-
- ------------------------------
- // download_file //
- -----------------------------
- function download_file()
- int choice;
- string filename[128];
- string fullname[128];
- string input[128];
- int old_protocol;
- int success;
-
- if check_local() then
- return; ------------------------------------------------------>
- endif
-
- old_protocol = get_protocol();
-
- output_string("\nProtocols Available:\r\n[A]SCII, [X]Modem, XModem-1[K], [Y]Modem, [Z]Modem\r\n\nYour choice: ");
- choice = toupper(get_key(TRUE));
- output_string(newline);
-
- if strchr("AXKYZ", choice) == NULL then
- choice = 0;
- else
- if choice == 'X' then
- set_protocol(PROTO_XMODEM);
- endif
-
- if choice == 'K' then
- set_protocol(PROTO_XMODEM1K);
- endif
-
- if choice == 'Y' then
- set_protocol(PROTO_YMODEM);
- endif
-
- if choice == 'Z' then
- set_protocol(PROTO_ZMODEM);
- endif
- endif
-
- if choice then
- output_string("File to download: ");
- if get_string(input, sizeof(input), FALSE) > 0 then
- parse_filename(input, fullname, filename);
- output_string("Begin downloading now...\r\n");
-
- if choice == 'A' then
- success = ascii_send(fullname);
- else
- success = upload(fullname);
- endif
- if not success then
- output_string("\r\nThe download was not completed successfully.");
- endif
- endif
- endif
-
- set_protocol(old_protocol);
-
- output_char('\n');
- endfunction
-
-
- ------------------------------
- // get_key //
- -----------------------------
- function get_key(
- int echo_it
- ) returns int
- int ch;
-
- while not ((ch = check_key()) or carrier_dropped()) do
- ; -- Wait for a key
- endwhile
-
- if echo_it and ch then
- output_char(ch);
- endif
-
- return ch;
- endfunction
-
-
- ------------------------------
- // get_password //
- -----------------------------
- -- Returns TRUE if the password is typed correctly, FALSE otherwise
- function get_password() returns int
- int attempts;
- string entered_password[10];
- string password[10];
-
- get_string_param(REMOTE_PARAM, REMOTE_PASSWORD, password, sizeof(password));
-
- if !password[0] then
- return TRUE;
- endif
-
- if mode_local then
- output_char('\n');
- return TRUE;
- else
-
- show_message("validating password", FALSE);
-
- attempts = 0;
- repeat
- output_string("\r\nWelcome to the Conehead BBS!!!\r\n");
- output_string("About 30MB online.\r\n\n");
- output_string("Password: ");
- get_string(entered_password, sizeof(entered_password), TRUE);
- if carrier_dropped() then
- return FALSE;
- endif
- if !strcmp(entered_password, password) then
- output_char('\n');
- return TRUE;
- else
- output_string("Incorrect password\n");
- endif
- until (attempts = attempts + 1) >= 3;
-
- output_string("\r\nSlamming the door now-see ya!\r\n");
-
- return FALSE;
- endif
- endfunction
-
-
- ------------------------------
- // get_string //
- -----------------------------
- -- Allows the user to type and edit a string. The number of characters
- -- read is returned, or -1 if the operation is aborted due to ^C or a
- -- carrier drop.
- function get_string(
- string buffer, -- Where to store the characters read
- int buffer_size, -- Max # chars we can put in 'buffer'
- int echo_stars -- Should we echo characters as '*'?
- ) returns int -- Returns: the # of chars read; -1 on error.
-
- string blot;
- int ch;
- int done;
- int i;
-
- blot = "\b \b";
-
- if buffer_size <= 0 then
- return -1; ------------------------------------------------------>
- endif
-
- buffer_size = buffer_size -1; -- Leave room for a null byte.
-
- done = FALSE;
- i = 0;
- while i < buffer_size and not done do
- ch = get_key(FALSE);
- if carrier_dropped() then
- return -1; -------------------------------------------------->
- endif
- if ch == '\r' or ch == '\n' then
- done = TRUE;
- else
- if ch == 3 then -- ^C
- return -1; ---------------------------------------------->
- endif
- if ch == '\b' or ch == 127 then -- Backspace or Delete
- if i then
- output_string(blot);
- i = i -1;
- endif
- else
- if ch == 24 then -- ^X
- if i then
- repeat
- output_string(blot);
- until (i = i - 1) == 0;
- endif
- else
- if ch then -- Make sure it's non-zero
- buffer[i] = ch;
- i = i + 1;
- if echo_stars then
- ch = '*';
- endif
- output_char(ch);
- endif
- endif
- endif
- endif
- endwhile
-
- buffer[i] = 0;
- output_string(newline);
- return i;
- endfunction
-
-
- ------------------------------
- // keyboard_check //
- -----------------------------
- function keyboard_check()
- int ch;
-
- if instat() then
- if (ch = getchar()) == 19 then -- 19 is ^S, or XOFF
- output_blocked = TRUE;
- else
- if ch == 17 then -- 17 is ^Q, or XON
- output_blocked = FALSE;
- else
- saved_key = ch;
- endif
- endif
- endif
- endfunction
-
-
- ------------------------------
- // main //
- -----------------------------
- -- This is the top-level routine for the remote mode script. If
- -- it returns a value of 0, STalker will hang-up and prepare for the
- -- next caller. A non-zero return value tells STalker to hang-up and
- -- then terminate remote mode.
- function main() returns int
- int duplex;
-
- carrier_at_start = port_carrier();
-
- -- Set up the 'mode_' variables.
- duplex = get_duplex();
- mode_echo = (duplex == DUPLEX_ECHO);
- mode_full = (duplex == DUPLEX_FULL);
- mode_local = (duplex == DUPLEX_LOCAL);
-
- newline = "\r\n";
-
- -- Set the file transfer parameters to be the way we want them
- set_string_param(XFER_PARAM, ASCII_BLANK_EXPAND, "");
- set_string_param(XFER_PARAM, ASCII_HOST_PROMPT, "");
- set_int_param(XFER_PARAM, ASCII_ADD_LF , TRUE);
- set_int_param(XFER_PARAM, ASCII_LINE_WAIT , 0);
- set_int_param(XFER_PARAM, ASCII_STRIP_LF , FALSE);
- set_int_param(XFER_PARAM, ASCII_USE_CTRL_Z , FALSE);
- set_int_param(XFER_PARAM, ZMODEM_RCV_OPTION , ZOPT_NONE);
- set_int_param(XFER_PARAM, ZMODEM_RCV_MODE , ZCONV_AUTO);
- set_int_param(XFER_PARAM, ZMODEM_SEND_OPTION, ZOPT_NONE);
- set_int_param(XFER_PARAM, ZMODEM_SEND_MODE , ZCONV_AUTO);
-
- if !get_password() then
- -- They didn't type the right password, but we still return
- -- a value of 0 since we don't want remote mode to be aborted.
- return 0;
- endif
-
- return remote_loop();
- endfunction
-
-
- ------------------------------
- // output_char //
- -----------------------------
- function output_char(
- int ch
- )
- string str[2];
-
- str[0] = ch;
- str[1] = 0;
- output_string(str);
- endfunction
-
-
- ------------------------------
- // output_string //
- -----------------------------
- -- Outputs the passed string to the remote system, or the terminal
- -- window, or both, depending on the mode.
- function output_string(
- string str
- )
- int ch;
-
- keyboard_check(); -- Pick up any keypresses waiting for us
-
- if mode_local then
- while output_blocked do
- keyboard_check();
- endwhile
- endif
-
- if not mode_full then
- puts(str); -- Show the string in the terminal window
- endif
-
- if not mode_local then
- while (ch = str[0]) do
- str = str + 1;
- while !port_outstat() do
- if carrier_dropped() then
- return; -- Carrier dropped, let's get outta here.
- endif
- endwhile
- port_putchar(ch);
- endwhile
- endif
- endfunction
-
-
- ------------------------------
- // parse_filename //
- -----------------------------
- function parse_filename(
- string name, -- Input: Something like \DIR\FILENAME.EXT
- string full, -- Output: C:\DIR\FILENAME.EXT
- string file -- Output: FILENAME.EXT
- )
- -- See if name[] has a drive specifier
- if name[1] == ':' then
- full[0] = toupper(name[0]);
- full[1] = name[1];
- name = name + 2;
- else
- full[0] = file_get_drive();
- full[1] = ':';
- endif
- full[2] = 0;
-
- -- Make sure the drive letter is legit, in case something
- -- like 1:\file.txt is passed in.
- if not isalpha(full[0]) then
- full[0] = 'A';
- endif
-
- -- See if name[] has an explicit directory spec.
- if name[0] != '\\' then
- file_get_dir(full[0] - 0x40, full + 2);
- strcat(full, "\\");
- endif
- strcat(full, name);
-
- -- Now parse out the filename.ext
- strcpy(file, strrchr(full, '\\') + 1);
- endfunction
-
-
- ------------------------------
- // remote_loop //
- -----------------------------
- -- Return a value of 0 unless you want STalker to exit remote mode.
- function remote_loop() returns int -- Returns an exit status.
- int command;
- int duplex;
- string dir[128];
-
- while TRUE do
- if carrier_dropped() then
- return 0;
- endif
-
- show_message("waiting for a command", FALSE);
-
- output_string("\r\n[B]rief file listing [C]hange directory [D]ownload a file\r\n");
- output_string("[F]ull file listing [G]oodbye [R]un shell program\r\n");
- output_string("[S]how text file [T]alk to SysOp [U]pload a file\r\n");
-
- dir[0] = file_get_drive();
- dir[1] = ':';
- file_get_dir(0, dir + 2);
- output_string("\r\nCurrent location ---> ");
- output_string(dir);
-
- output_string("\r\n\nCommand? ");
- command = toupper(get_key(TRUE));
- output_string(newline);
-
- if strchr("BCDFGRSTU", command) == NULL then
- output_string("\r\nInvalid Command - Please try again!\r\n\n");
- while check_key() do
- -- Get rid of any extra input in case it was a burst of line
- -- noise that caused the invalid command in the first place.
- ;
- endwhile
- else
- if command == 'B' then
- show_files(FALSE);
- endif
-
- if command == 'C' then
- change_dir();
- endif
-
- if command == 'D' then
- download_file();
- endif
-
- if command == 'F' then
- show_files(TRUE);
- endif
-
- if command == 'G' then
- if mode_local then
- mode_local = alert("[0][Quitting remote mode ][Ok]");
- if mode_local == 1 then
- exit(1);
- endif
- else
- output_string("\r\n\nGoodbye, and thanks for calling.\r\n");
- return 0;
- endif
- endif
-
- if command == 'R' then
- run_cli();
- endif
-
- if command == 'S' then
- display_file();
- endif
-
- if command == 'T' then
- if !check_local() then
- output_string("Type ^C when done.\r\n");
- show_message("in TALK mode. Type UNDO to end", FALSE);
- play_sound(SOUND_SECRET);
- chat_mode();
- endif
- endif
-
- if command == 'U' then
- upload_file();
- endif
- endif
- endwhile
- endfunction
-
-
- ------------------------------
- // run_program //
- -----------------------------
- function run_cli()
- string cli_name[128];
- string cli_password[10];
- string entered_password[10];
- int error;
-
- cli_name[0] = 0;
- get_string_param(REMOTE_PARAM, REMOTE_CLI_NAME, cli_name, sizeof(cli_name));
-
- if !cli_name[0] then
- output_string("No CLI specified in my remote settings.\r\n");
- return; // No CLI specified -------------------------------------->
- endif
-
- if !file_exists(cli_name) then
- output_string("The specified CLI (");
- output_string(cli_name);
- output_string(") does not exist.\r\n");
- return; ---------------------------------------------------------->
- endif
-
- get_string_param(REMOTE_PARAM, REMOTE_CLI_PASSWORD, cli_password, sizeof(cli_password));
-
- if cli_password[0] then
- output_string("\r\nCLI password: ");
- if get_string(entered_password, sizeof(entered_password), TRUE) <= 0 then
- return; ------------------------------------------------------>
- endif
- if strcmp(entered_password, cli_password) then
- output_string("Wrong password\r\n");
- return; ------------------------------------------------------>
- endif
- endif
-
- output_char('\n');
-
- show_message("Running the CLI program", FALSE);
-
- if (error = run_program(cli_name, "", !mode_local)) then
- if error == -1 then
- output_string("\r\nI'm unable to redirect program output to the current port.\r\n");
- else
- output_string("\r\nThere's been an error in running the CLI program.\r\n");
- endif
- endif
- endfunction
-
-
- ------------------------------
- // show_files //
- -----------------------------
- function show_files(int full_listing)
- int count;
- string dir_buf[24];
- int error;
- int is_dir;
- string name[16];
- string output[128];
- string time_string[80];
-
- output_string("File search pattern [*.*] ?");
- count = get_string(output, sizeof(output), FALSE);
- if count < 0 then
- return;
- endif
- if count == 0 then
- strcpy(output, "*.*");
- endif
-
- output_char('\n');
-
- count = 0;
-
- error = file_dir_first(output, 0x3F, dir_buf);
- while error do
- is_dir = dir_buf[0] & 0x10;
- if full_listing then
- strftime(time_string, sizeof(time_string), "%c",
- (dir_buf[3] << 24) + (dir_buf[4] << 16) + (dir_buf[1] << 8) + dir_buf[2]);
- sprintf(output, "%-14.14s %.30s %8d", dir_buf + 9,
- time_string,
- (dir_buf[5] << 24) + (dir_buf[6] << 16) + (dir_buf[7] << 8) + dir_buf[8]);
- if is_dir then
- strcat(output, " <DIR>");
- endif
- strcat(output, newline);
- else
- if is_dir then
- sprintf(name, "[%s]", dir_buf + 9);
- else
- strcpy(name, dir_buf + 9);
- endif
- sprintf(output, "%-15.15s", name);
- if (count = count + 1) >= 5 then
- strcat(output, newline);
- count = 0;
- endif
- endif
-
- output_string(output);
- if check_key() == 3 or carrier_dropped() then
- error = FALSE; -- Force an exit from the loop
- else
- error = file_dir_next(dir_buf);
- endif
- endwhile
-
- output_char('\n');
- endfunction
-
-
- ------------------------------
- // upload_file //
- -----------------------------
- function upload_file()
- string filename[32];
- string fullname[128];
- string input[128];
- string letters;
- int overwrite;
- int protocol;
- int success;
- string s;
-
- if check_local() then
- return; ---------------------------------------------------------->
- endif
-
- letters = "AXKYGZ";
-
- output_string("\nProtocols Available:\r\n[A]SCII, [X]Modem, XModem-1[K], [Y]Modem, YModem-[G], [Z]Modem\r\n\nYour choice: ");
- protocol = toupper(get_key(TRUE));
- output_string(newline);
-
- if (s = strchr(letters, protocol)) != NULL then
- if protocol != 'A' then
- -- 's' points into the string 'letters'. Take advantage of the fact
- -- that the order of the letters matches the protocol numbers, but
- -- subtract one since 'letters' starts with 'A' rather than 'X'.
- set_protocol(s - letters - 1);
- endif
-
- if s >= letters + 3 then
- -- It's Y, G, or Z; batch protocols.
- strcpy(input, "RECEIVED.FIL");
- else
- output_string("File to upload: ");
- if get_string(input, sizeof(input), FALSE) <= 0 then
- input[0] = 0;
- endif
- endif
-
- if input[0] then
- parse_filename(input, fullname, filename);
- overwrite = TRUE;
- if file_exists(fullname) then
- output_string("File exists! Overwrite it [Y/N] ? ");
- overwrite = toupper(get_key(TRUE)) == 'Y';
- output_string(newline);
- endif
- if overwrite then
- success = FALSE;
- if protocol == 'A' then
- output_string("Type ^C when done.\r\n");
- if (success = ascii_receive(fullname, FALSE)) then
- -- STalker automatically aborts an operation in progress when
- -- the remote user types ^C in REMOTE mode, just as if the
- -- UNDO key had been pressed. We just need to sit and wait
- -- until they do so. Note that this doesn't work if you
- -- invoke the script the normal way, since STalker won't be
- -- in REMOTE mode.
- wait_until(2000, 1, 1, 0, 0, 0);
- success = ascii_receive(NULL);
- endif
- else
- output_string("Begin uploading now...\r\n");
- success = download(fullname);
- endif
- if !success then
- output_string("\r\nThe upload was not completed successfully.");
- endif
- endif
- endif
- endif
-
- output_char('\n');
- endfunction
-