home *** CD-ROM | disk | FTP | other *** search
/ Beijing Paradise BBS Backup / PARADISE.ISO / software / BBSDOORW / HOSTBBS.ARJ / HOSTBBS.SLT < prev    next >
Encoding:
Text File  |  1990-01-30  |  137.1 KB  |  4,020 lines

  1. ///////////////////////////////////////////////////////////////////////////////
  2. //                                         //
  3. //   H O S T B B S . S L T                             //
  4. //                                         //
  5. //   original source code: HOST.SLT of Telix package                 //
  6. //                                         //
  7. //   Commented, modified and enhanced by Chester H. Lin with Telix 3.10 in   //
  8. //   September - October, 1989                             //
  9. //                                         //
  10. //   Revised after the release of Telix 3.12 by Chester H. Lin in         //
  11. //   January, 1990                                 //
  12. //                                         //
  13. ///////////////////////////////////////////////////////////////////////////////
  14.  
  15. //-----------------------------------------------------------------------------
  16. // Parameters which can be configured by sysop
  17. //-----------------------------------------------------------------------------
  18. str sysop_password[] = "dummy_1",         // The Sysop's password
  19.     shellpass[] = "dummy_2",               // the password to Reset & enter DOS shell
  20.     host_downloads[] = "C:\BBSFILES\",    // where users may download from
  21.     host_uploads[] = "C:\BBSUPLDS\",      // where uploaded files go
  22.     host_message[] = "C:\BBSMSG\",        // where messages are stored
  23.     temp_message[] = "C:\TEMP.MSG",       // temporary file for message storage
  24.     user_list[] = "USERLIST.TXT",         // user list of the system
  25.     bulletin_title[] = "BLTN.MSG",        // title screen for bulletins
  26.     tty_bulletin_title[] = "BLTN.TTY",
  27.     knowledge_title[] = "KNLG.MSG",       // title screen for knowledge
  28.     tty_knowledge_title[] = "KNLG.TTY",
  29.     logo_file[] = "LOGO.MSG",             // BBS logo file name
  30.     tty_logo_file[] = "LOGO.TTY",
  31.     welcome_file[] = "WELCOME.MSG",       // Initial welcome screen file
  32.     tty_welcome_file[] = "WELCOME.TTY",
  33.     question_file[] = "QUESTION.MSG",     // greeting for first time user
  34.     tty_question_file[] = "QUESTION.TTY",
  35.     goodbye_file[] = "TLXBYE.MSG",        // Good bye screen file
  36.     tty_goodbye_file[] = "TLXBYE.TTY",
  37.     help_file[] = "HELP.MSG",             // Help display
  38.     tty_help_file[] = "HELP.TTY",
  39.     testansi_file[] = "ASKANSI.TXT",      // File to ask for ANSI mode
  40.     logon_file[] = "HOSTBBS.LOG",         // Logon record file
  41.     logon_list[] = "LOGON.LST",           // Logon user list file
  42.     capfname[] = "HOSTBBS.CAP",           // capture file name
  43.     file_list[] = "FILES.DIR",            // file listing for files
  44.     fst_lst_msg[] = "FSTLAST.MSG",        // first_last message file
  45.     sysop_first[] = "dummy_3",            // sysop's first
  46.     sysop_last[] = "dummy_4";             // and last name
  47.  
  48. //-----------------------------------------------------------------------------
  49. // The following variables hold current user's personal data
  50. //-----------------------------------------------------------------------------
  51. str user_password[23],              // user's password
  52.     user_age[4],              // user's age
  53.     user_phone[20],              // user's phone number
  54.     user_occupation[40],          // user's occupation
  55.     user_location[40],              // user's location
  56.     current_caller_first[23],          // current caller's first name
  57.     current_caller_last[23],          // current caller's last name
  58.     current_caller_full[50];          // current caller's full name
  59.  
  60.  
  61. //-----------------------------------------------------------------------------
  62. // Default settings of this host BBS
  63. // For direct computer-to-computer linkage: direct_connect = 1
  64. // For modem-to-modem linkage through phone line: direct_connect = 0
  65. // Default baud rate = 2400
  66. // Default ring count before modem picks up phone hook = 1
  67. //-----------------------------------------------------------------------------
  68. int direct_connect = 0,
  69.     def_baud = 2400;
  70. str ring_count[] = "1",
  71.     conn300[]= "CONNECT^M",                 // Modem response if linkage
  72.     conn1200[] = "CONNECT 1200",            // is established
  73.     conn2400[] = "CONNECT 2400",
  74.     conn9600[] = "CONNECT 9600",
  75.     conn19200[] = "CONNECT 19200";
  76.  
  77. //-----------------------------------------------------------------------------
  78. // The following variables are used as temporary storage for message processing
  79. //-----------------------------------------------------------------------------
  80. str name_to_reply[50],                // name to reply
  81.     topic_to_reply[40],             // topic of a reply message
  82.     tmp_fname[64],                // used as temporary file name
  83.     linemsg[81],                // line buffer of message
  84.     editline[81],                // line to edit
  85.     msg_caller_first[23],
  86.     msg_caller_last[23],
  87.     receiver[40],
  88.     topic[40],
  89.     date_str[10],
  90.     time_str[10];
  91.  
  92. //-----------------------------------------------------------------------------
  93. // The following variables hold file names of bulletin message files
  94. //-----------------------------------------------------------------------------
  95. str  bulletin_1[] = "BLTN_1.MSG",        // bulletin text file names holder
  96.      bulletin_2[] = "BLTN_2.MSG",        // to add a bulletin text file, just
  97.      bulletin_3[] = "BLTN_3.MSG",        // change the corresponding string
  98.      bulletin_4[] = "BLTN_4.MSG",        // to the file name that is available.
  99.      bulletin_5[] = "BLTN_5.MSG",
  100.      bulletin_6[] = "BLTN_6.MSG",
  101.      bulletin_7[] = "BLTN_7.MSG",
  102.      bulletin_8[] = "BLTN_8.MSG",
  103.      bulletin_9[] = "BLTN_9.MSG",
  104.     bulletin_10[] = "BLTN_10.MSG",
  105.     bulletin_11[] = "BLTN_11.MSG",
  106.     bulletin_12[] = "BLTN_12.MSG",
  107.     bulletin_13[] = "BLTN_13.MSG",
  108.     bulletin_14[] = "BLTN_14.MSG",
  109.     bulletin_15[] = "BLTN_15.MSG",
  110.     bulletin_16[] = "BLTN_16.MSG",
  111.     bulletin_17[] = "BLTN_17.MSG",
  112.     bulletin_18[] = "BLTN_18.MSG",
  113.     bulletin_19[] = "BLTN_19.MSG",
  114.     bulletin_20[] = "BLTN_20.MSG";
  115.  
  116. //-----------------------------------------------------------------------------
  117. // The following variables hold system flags indicating various conditions
  118. //-----------------------------------------------------------------------------
  119. int finished_caller = 0,      // set to TRUE when must return to top
  120.     ansi_mode = 0,          // set to TRUE by user if can support ANSI
  121.     first_time_caller = 0,      // set to TRUE when caller never came before
  122.     local_mode = 0,          // set to TRUE when local test mode
  123.     carrier_counts = 1,       // TRUE if Carrier Detect (CD) line is useful
  124.     already_connected = 0,      // indicating already connected or not
  125.     sysop_call = 0,          // default: assume it is user
  126.     exit_requested = 0,       // set to TRUE if Sysop has pressed HOME
  127.     connection_lost = 0,      // set to TRUE when carrier lost
  128.     kill_user = 0,          // set to TRUE when user must be purged
  129.     warned = 0,           // 3-min warning issued flag
  130.     abnormal_logoff = 1;      // always assume abnormal logoff
  131.  
  132. //-----------------------------------------------------------------------------
  133. // The following variables are for system's house-keeping tasks
  134. //-----------------------------------------------------------------------------
  135. int last_read,              // caller's last read message#
  136.     last_read_pos,          // caller's last read pos in file
  137.     sysop_last_read,          // sysop's last read message#
  138.     grand_timer,          // grand timer controls total logon time
  139.     start_time,           // logon time
  140.     end_time,              // logoff time
  141.     f_list,              // logon list file
  142.     logon_speed,          // logon modem speed
  143.     reply_to,              // mes# to reply to
  144.     first_msg,              // first and
  145.     last_msg;              // last message's number
  146.  
  147. //-----------------------------------------------------------------------------
  148. // The following variables are for TELIX's status before this script is called
  149. //-----------------------------------------------------------------------------
  150. int old_scr_chk_key,            // storage for some system variables
  151.     old_cisb_auto,            // which we have to modify and put
  152.     old_zmod_auto,            // back to what they were when done
  153.     old_sound;
  154. str old_down_dir[64],
  155.     old_up_dir[64],
  156.     old_ans_str[64];
  157.  
  158. //-----------------------------------------------------------------------------
  159. // system queue holds characters received from communication port
  160. // (not used in this version of HOSTBBS)
  161. //-----------------------------------------------------------------------------
  162. str system_queue[240];          // system queue
  163. int next_queue_put = 0,       // next character pos to put
  164.     next_queue_read = -1;      // next character pos to read
  165.  
  166.  
  167. //-----------------------------------------------------------------------------
  168. //
  169. // main function:
  170. //   program starts executing here
  171. //
  172. //-----------------------------------------------------------------------------
  173.  
  174. main()
  175.  
  176. {
  177.  int c, i, fhandle;
  178.  str fmsg[81] = "", msgnbr[8];
  179.  
  180.  //------------------------------------------
  181.  // check if certain directories existed
  182.  // if not (return value == -1) then exit
  183.  // program.
  184.  //------------------------------------------
  185.  if (chkdir() == -1)
  186.      return -1;
  187.  
  188.  //----------------------------------------------------------
  189.  // Don't let user abort the script when executing
  190.  //----------------------------------------------------------
  191.  old_scr_chk_key = _scr_chk_key;
  192.  _scr_chk_key = 0;
  193.  
  194.  //----------------------------------------------------------
  195.  // Disable CompuServe Quick B auto file transfer
  196.  //----------------------------------------------------------
  197.  old_cisb_auto = _cisb_auto;
  198.  _cisb_auto = 0;
  199.  
  200.  //----------------------------------------------------------
  201.  // Zmodem auto download is disabled
  202.  //----------------------------------------------------------
  203.  old_zmod_auto = _zmod_auto;
  204.  _zmod_auto = 0;
  205.  
  206.  //----------------------------------------------------------
  207.  // All sound is shut off
  208.  //----------------------------------------------------------
  209.  old_sound = _sound_on;
  210.  _sound_on = 0;
  211.  
  212.  //----------------------------------------------------------
  213.  // Set up default upload/download directory
  214.  //----------------------------------------------------------
  215.  old_down_dir = _down_dir;
  216.  _down_dir = host_uploads;   // these are reversed because we are now the Host
  217.  old_up_dir = _up_dir;
  218.  _up_dir = host_downloads;   // these are reversed because we are now the Host
  219.  
  220.  //----------------------------------------------------------
  221.  // Set up auto answer string for modem
  222.  //----------------------------------------------------------
  223.  old_ans_str = _auto_ans_str;
  224.  _auto_ans_str = "~~~AT S0=";
  225.  strcat(_auto_ans_str, ring_count);
  226.  strcat(_auto_ans_str, "^M~~~");
  227.  
  228.  //----------------------------------------------------------
  229.  // set up communication parameters
  230.  //----------------------------------------------------------
  231.  if (direct_connect)        // direct connect with another computer
  232.     carrier_counts = 0;     // so we don't care about carrier detect line
  233.  else {             // connect through a modem
  234.     carrier_counts = 1;     // so we must watch for carrier detect line
  235.     if (carrier()) {        // modem connection is established !!!
  236.        already_connected = 1;    // so remember it and set to fastest mode
  237.        set_cparams(def_baud, get_parity(), get_datab(), get_stopb());
  238.     }
  239.     else {            // not yet connected through a modem...
  240.        clear_scr();        // clear the screen and initialize the modem
  241.        prints("Initializing modem...");
  242.        //--------------------------------
  243.        // set modem to the fastest mode
  244.        // then initialize it.
  245.        //--------------------------------
  246.        set_cparams(def_baud, get_parity(), get_datab(), get_stopb());
  247.        cputs_tr(_mdm_init_str);
  248.        cputs_tr(_auto_ans_str);
  249.     }
  250.  }
  251.  
  252.  set_defprot('Z');              // Zmodem is the default file transfer protocol
  253.  set_terminal("ANSI-BBS");      // set terminal to ANSI mode
  254.  update_term();         // update status bar
  255.  
  256.  initfile();            // create temporary file for entering msg
  257.  
  258.  //----------------------------------------------------------
  259.  // read in first & last message number of message area
  260.  // also read in sysop's last read message
  261.  //----------------------------------------------------------
  262.  fmsg = host_message;
  263.  strcat(fmsg, fst_lst_msg);
  264.  fhandle = fopen(fmsg, "r");
  265.  if (fhandle != 0){            // if open file successfully
  266.     fgets(msgnbr, 5, fhandle);        // read first and second message numbers
  267.     first_msg = stoi(msgnbr);        // then remember them.
  268.     fgets(msgnbr, 5, fhandle);        // also read in sysop's last read msg#
  269.     last_msg = stoi(msgnbr);
  270.     fgets(msgnbr, 5, fhandle);
  271.     sysop_last_read = stoi(msgnbr);
  272.     fclose(fhandle);
  273.  }
  274.  else{                  // file open failed
  275.     fhandle = fopen(fmsg, "w+");  // open file for writing
  276.     msgnbr = "0^M^J";             // reset message # to zero
  277.     fwrite(msgnbr, strlen(msgnbr), fhandle);     // first msg # written
  278.     fwrite(msgnbr, strlen(msgnbr), fhandle);     // last msg # written
  279.     fwrite(msgnbr, strlen(msgnbr), fhandle);     // sysop last msg # written
  280.     fclose(fhandle);
  281.  }
  282.  
  283.  clear_scr();             // clear the screen and initialize the modem
  284.  
  285.  //----------------------------------------------------------
  286.  // An endless loop unless sysop press HOME to terminate
  287.  // it.  This loop does the following three things:
  288.  // (1) Wait for call patiently
  289.  // (2) Deal with the call when it comes
  290.  // (3) Back to step 1. when call terminate by user or
  291.  //    exit if this script is terminated by sysop
  292.  //----------------------------------------------------------
  293.  while (1)
  294.   {
  295.    finished_caller = kill_user = 0;
  296.    abnormal_logoff = 1;
  297.  
  298.    if (direct_connect)           // if direct connect with another computer
  299.        carrier_counts = 0;       // then we ignore the carrier detect line
  300.    else                // if connect through modem
  301.        carrier_counts = 1;       // then we will watch out carrier detect line
  302.  
  303.    update_term();           // update status bar
  304.  
  305.    if (!direct_connect) {       // if not computer-to-computer direct connection
  306.        printsc_trm("^M^JHost BBS Mode: Waiting for call...");
  307.        printsc_trm("^M^J(Press HOME to exit, 'L'");
  308.        printsc_trm(" for local test mode),^M^J");
  309.        //---------------------------------------------------------
  310.        // repeat until one of the following conditions happens:
  311.        //   1) connection established by modem
  312.        //   2) sysop invokes local test mode by pressing 'L'
  313.        //   3) sysop aborts host by pressing 'HOME' key --> exit_requested = 1
  314.        //---------------------------------------------------------
  315.        do {
  316.      if (carrier()) {       // connection established
  317.        local_mode = 0;
  318.        break;
  319.      }
  320.      c = inkey();           // read a character from keyboard buffer
  321.      if (c) {           // if keypressed...
  322.        if (c == 0x4700) {       // if it is a HOME --> sysop aborts host
  323.          exit_requested = 1;
  324.          break;
  325.        }
  326.        else if (toupper(c) == 'L') {     // L --> local test mode
  327.          prints("Local test mode entered");
  328.          local_mode = 1;
  329.          carrier_counts = 0;
  330.        }
  331.      }    // if keypressed
  332.        } while (toupper(c) != 'L');
  333.    } // if not direct connect
  334.  
  335.    //--------------------------------------------------------------
  336.    // if sysop did not abort HOST by pressing HOME key
  337.    //--------------------------------------------------------------
  338.    if (!exit_requested) {
  339.        printsc("Incoming call. Sysop: ");
  340.        printsc_trm("press HOME to exit, ");
  341.        printsc_trm("or END to terminate user.");
  342.        prints("");
  343.  
  344.        do_one_caller();
  345.  
  346.        //----------------------------------------------------------
  347.        // adding a record to the user logon list file
  348.        // (users only, not for sysop's call)
  349.        //----------------------------------------------------------
  350.        if (!sysop_call) {
  351.       end_time = curtime();
  352.       f_list = fopen(logon_list, "r+");
  353.       fseek(f_list, 0, 2);
  354.  
  355.         date(start_time, tmp_fname);       // logon date
  356.         fputs(tmp_fname, f_list);
  357.         fputs("   ", f_list);
  358.  
  359.         time(start_time, tmp_fname);       // logon time
  360.         fputs(tmp_fname, f_list);
  361.         fputs("   ", f_list);
  362.  
  363.         time(end_time, tmp_fname);        // logoff time
  364.         fputs(tmp_fname, f_list);
  365.         fputs("   ", f_list);
  366.  
  367.         itos(logon_speed, tmp_fname);    // logon speed
  368.         fputs(tmp_fname, f_list);
  369.         fputs("   ", f_list);
  370.  
  371.         if (abnormal_logoff)         // goodbye method
  372.           fputc('*', f_list);                // Abnormal
  373.         else
  374.           fputc(' ', f_list);                // Normal
  375.         fputs("   ", f_list);
  376.  
  377.         if (ansi_mode)             // record user's mode
  378.           fputs("ANSI   ", f_list);
  379.         else
  380.           fputs(" TTY   ", f_list);
  381.  
  382.         fputs(current_caller_full, f_list);  // caller's name
  383.         fputs("^M^J", f_list);
  384.  
  385.       fclose(f_list);
  386.        } // if not sysop calling...
  387.  
  388.        current_caller_first = "";
  389.        current_caller_last = "";
  390.        current_caller_full = "";
  391.        sysop_call = 0;
  392.        warned = 0;
  393.  
  394.        //----------------------------------------------------------
  395.        // close logon file so that everything is written down
  396.        //----------------------------------------------------------
  397.        if (!sysop_call)
  398.        usagelog("*CLOSE*");               // close usage log file
  399.  
  400.        if ((connection_lost || kill_user) && carrier_counts && carrier()) {
  401.        hangup();                // make sure nobody sneaks in
  402.        set_cparams(def_baud, get_parity(), get_datab(), get_stopb());
  403.        cputs_tr(_mdm_init_str);        // then initialize modem
  404.        }
  405.    }     // if sysop did not abort HOST by pressing HOME key
  406.  
  407.    already_connected = 0;
  408.  
  409.    if (exit_requested) {            // sysop aborts host
  410.      if (!carrier() && !direct_connect) {   // if not connected
  411.      set_cparams(def_baud, get_parity(), get_datab(), get_stopb());
  412.      cputs_tr(_mdm_init_str);        // then initialize modem
  413.      cputs_tr(old_ans_str);         // and put it back to old answer mode
  414.      }
  415.  
  416.      _scr_chk_key = old_scr_chk_key;        // restore all old settings
  417.      _cisb_auto = old_cisb_auto;
  418.      _zmod_auto = old_zmod_auto;
  419.      _sound_on = old_sound;
  420.      _down_dir = old_down_dir;
  421.      _up_dir = old_up_dir;
  422.      _auto_ans_str = old_ans_str;
  423.  
  424.      prints("^M^JHost BBS Mode script finished.");
  425.      return 1;                    // terminate program
  426.    }    // if sysop aborts host
  427.   }    // while (an endless loop until HOME is pressed by sysop)
  428. }    // main
  429.  
  430. //////////////////////////////////////////////////////////////////////////////
  431. //
  432. // caller is here so serve him/her
  433. //
  434. //////////////////////////////////////////////////////////////////////////////
  435.  
  436. do_one_caller()
  437.  
  438. {
  439.  str strn[20], last_rd_buf[8], last_rd_str[8];
  440.  int option, search_code, f_user,
  441.      c, i;
  442.  
  443.  //----------------------------------------------------------
  444.  // start the grand timer which controls total logon time
  445.  // current setting = 1 hour
  446.  //----------------------------------------------------------
  447.  grand_timer = curtime();            // get current time
  448.  start_time = grand_timer;
  449.  
  450.  if (already_connected)             // If already connected then do nothing except
  451.      prints("Already Connected!^M^J");          // informing the caller.  If not already connected
  452.  else if (carrier_counts) {            // but CD line is high then try to determine the
  453.    if (!determine_baud())            // baud rate.
  454.     ;
  455.  }
  456.  
  457.  logon_speed = get_baud();
  458.  
  459.  update_term();                 // update status bar
  460.  
  461.  delay(10);                    // wait for one second (but why?)
  462.  
  463.  type_file(testansi_file);            // ask if user's terminal can support ANSI
  464.  ask_ANSI();
  465.  
  466.  if (ansi_mode)
  467.     type_file(logo_file);            // display the first title to the caller
  468.  else
  469.     type_file(tty_logo_file);
  470.  
  471.  flushbuf();                    // discard all garbage in the remote input buffer
  472.  
  473.  reply_to = 0;                    // reset msg# to reply to
  474.  
  475.  if (!read_user_name())             // let user input his/her name
  476.    return;
  477.  
  478.  //----------------------------------------------------------
  479.  // open the usage log file if this is not sysop call
  480.  //----------------------------------------------------------
  481.  if (!sysop_call)
  482.      usagelog(logon_file);
  483.  
  484.  if (!strcmpi(current_caller_first, sysop_first) &&
  485.      !strcmpi(current_caller_last, sysop_last)) {    // SysOp is calling!!!
  486.      if (!verify_sysop()) {            // verification fails!    Not a sysop.
  487.     sysop_call = 0;             // so that the next caller is a user
  488.     ustamp("User called in the name of sysop but in vain.", 1, 1);
  489.     return;                 // tries to invade here as a sysop.
  490.      }
  491.      else {                    // it IS sysop here so get the last read msg#
  492.     sysop_call = 1;             // flag it!
  493.     last_read = sysop_last_read;
  494.      }
  495.  }
  496.  else {                     // It's other users......
  497.    //-------------------------------------------------------------------------
  498.    // search_code == 0 if connection lost
  499.    //             1 if user is found
  500.    //             2 if user is firt-time caller
  501.    // get_access returns:
  502.    //             0 if password is wrong
  503.    //             1 if password is right or first-time caller
  504.    //-------------------------------------------------------------------------
  505.    if (!(search_code = search_user_list()))    // search for user list
  506.       return;
  507.    if (!get_access(search_code))        // requesting for access to this board
  508.       return;                    // but request is denied
  509.  }
  510.  
  511.  if (ansi_mode)
  512.     type_file(welcome_file);               // welcome message for caller
  513.  else
  514.     type_file(tty_welcome_file);
  515.  
  516.  host_send("^M^JPress any key to continue...");
  517.  host_input();
  518.  
  519.  showtime();
  520.  
  521.  //--------------------------------------------------------------------------------
  522.  // this is an endless loop unless one of the following conditions happens:
  523.  //    1) connection is lost for every possible reason (sysop kills user, phone
  524.  //       line drops, sysop terminate host, or user hangs phone.
  525.  //    2) user chooses (G)oodbye option
  526.  //--------------------------------------------------------------------------------
  527.  while (1) {
  528.  
  529.    if (finished_caller)             // finished_caller is set by host_input if
  530.       return;                    // connection is lost.
  531.  
  532.    top_level_cmd();                // display top level BBS commands
  533.  
  534.    //---------------------------------------------------------
  535.    // Input the option by user
  536.    //---------------------------------------------------------
  537.    host_input_strn(strn, 15, 0);
  538.    option = toupper(subchr(strn, 0));
  539.    host_send("^M^J");
  540.  
  541.    //---------------------------------------------------------
  542.    // File Menu invoked
  543.    //---------------------------------------------------------
  544.    if (option == 'F') {
  545.        if (!sysop_call)
  546.        ustamp("User invoked File functions.", 1, 1);
  547.        do {
  548.       filecmd();
  549.        } while (do_files() != 'Q' && !finished_caller);
  550.    }
  551.    //---------------------------------------------------------
  552.    // Invoke Message functions
  553.    //---------------------------------------------------------
  554.    else if (option == 'M'){
  555.        if (!sysop_call)
  556.        ustamp("User invoked Message functions.", 1, 1);
  557.        do_message();
  558.    }
  559.    //---------------------------------------------------------
  560.    // System functions
  561.    //---------------------------------------------------------
  562.    else if (option == 'S'){
  563.        if (!sysop_call)
  564.         ustamp("User invoked System functions.", 1, 1);
  565.        do_system();
  566.    }
  567.    //---------------------------------------------------------
  568.    // Bulletins
  569.    //---------------------------------------------------------
  570.    else if (option == 'B'){
  571.        if (!sysop_call)
  572.        ustamp("User invoked Bulletin functions.", 1, 1);
  573.        do_bulletin();
  574.    }
  575.    //---------------------------------------------------------
  576.    //Help screen
  577.    //---------------------------------------------------------
  578.    else if (option == 'H'){
  579.        if (!sysop_call)
  580.        ustamp("User looked at help screen.", 1, 1);
  581.        if (ansi_mode)
  582.       type_file(help_file);
  583.        else
  584.       type_file(tty_help_file);
  585.        host_send("Press any key to continue...");
  586.        host_input();
  587.        if (ansi_mode)
  588.       host_send("^M");
  589.        else
  590.       host_send("^M^J");
  591.    }
  592.    //---------------------------------------------------------
  593.    // Say Goodbye
  594.    //---------------------------------------------------------
  595.    else if (option == 'G') {          // Goodbye (Hang-up)
  596.      host_send("^M^JDo you want to disconnect? (Y/N) ");
  597.      host_input_strn(strn, 10, 0);
  598.      host_send("^M^J");
  599.      if (toupper(subchr(strn, 0)) == 'Y') {
  600.     if (!sysop_call) {             // sysop does not have last read msg#
  601.         itos(last_read, last_rd_buf);         // convert last read msg#
  602.         last_rd_str = "";                        // to string
  603.         for (i = 1; i <= (4 - strlen(last_rd_buf)); ++i)
  604.         strcat(last_rd_str, " ");            // padding with blanks
  605.         strcat(last_rd_str, last_rd_buf);
  606.         strcat(last_rd_str, "^M^J");             // now last_rd_str ready...
  607.         f_user = fopen(user_list, "r+");         // to update last read msg#
  608.         fseek(f_user, last_read_pos, 0);         // move file pointer
  609.         fwrite(last_rd_str, strlen(last_rd_str), f_user);
  610.         fclose(f_user);
  611.     }
  612.  
  613.     host_send("^M^JGoodbye!^M^J");
  614.     if (ansi_mode)
  615.         type_file(goodbye_file);         // send the good-bye message
  616.     else
  617.         type_file(tty_goodbye_file);
  618.     abnormal_logoff = 0;         // this is a normal logoff
  619.  
  620.     if (!sysop_call){
  621.         ustamp("Logged off by ", 1, 0);
  622.         ustamp(current_caller_full, 0, 0);
  623.         ustamp("", 0, 1);
  624.     }
  625.     if (carrier_counts)
  626.      {
  627.         //------------------------------------------------
  628.         // delay for a whie to let good-bye message be
  629.         // transmitted over modem before hanging up
  630.         //------------------------------------------------
  631.         if (get_baud() == 300)        // 300 bps --> wait for 20 seconds
  632.            delay (200);
  633.         else if (get_baud() == 1200)    // 1200 bps --> wait for 5 seconds
  634.            delay (50);
  635.         else if (get_baud() == 2400)    // 2400 bps --> wait for 2.5 seconds
  636.            delay(25);
  637.         hangup();                // actually hanging up
  638.         delay(15);
  639.         prints("^M^JReset modem...");
  640.         set_cparams(def_baud, get_parity(), get_datab(), get_stopb());
  641.         cputs_tr(_mdm_init_str);
  642.      }
  643.      return;
  644.      }    // if confirmed to disconnect
  645.    }
  646.   }  // while... endless loop
  647. }  // do_one_caller
  648.  
  649. //////////////////////////////////////////////////////////////////////////////
  650. // do_files
  651. // return value: 'L', `T', 'D', 'U' if one of them selected
  652. // return value: 'Q' if 'Q' selected
  653. //////////////////////////////////////////////////////////////////////////////
  654.  
  655. do_files()
  656.  
  657. {
  658.    str strn[80], fname[80];
  659.    int status, option;
  660.  
  661.    host_input_strn(strn, 10, 0);
  662.    if (strlen(strn) == 0) {           // if only RET pressed
  663.        host_send("^M^J");              // return L to repeat command
  664.        return 'L';
  665.    }
  666.    option = toupper(subchr(strn, 0));
  667.    host_send("^M^J");
  668.  
  669.    //----------------------------------------
  670.    // List files
  671.    //----------------------------------------
  672.    if (option == 'L') {
  673.      if (!sysop_call)
  674.      ustamp("User invoked Listing files functions.", 1, 1);
  675.      if (sysop_call) {               // this is a sysop here!
  676.                        // no limit to files can be seen
  677.        host_send("Enter 'filespec' or press Return for *.*,^M^J: ");
  678.        host_input_strn(fname, 64, 0);
  679.        host_send("^M^J");
  680.        if (just_filename(fname)) {     // if fname is just a file name
  681.      strn = host_downloads;        // then look for download area
  682.      strcat(strn, fname);           // else look for the specified path
  683.        }
  684.        else                   // not just a file name (a path...)
  685.      strn = fname;               // so make no assumption about path
  686.      }
  687.      else                   // lower access level, i.e. user
  688.        fname = "";                     // empty string means detailed file info
  689.  
  690.      if (strlen(fname) == 0)           // if only <RET> is hit
  691.        type_file(file_list);           // then display detailed file info
  692.      else{                   // else invoke DOS dir type info
  693.        if (local_mode)
  694.      show_directory(strn, 0, carrier_counts);   // listing only on screen
  695.        else
  696.      show_directory(strn, 1, carrier_counts);   // listing on screen & through modem
  697.      }
  698.      if (ansi_mode)
  699.     host_send("^M");
  700.      else
  701.     host_send("^M^J");
  702.      return 'L';
  703.    }
  704.    //----------------------------------------
  705.    // Type a file
  706.    //----------------------------------------
  707.    else if (option == 'T') {
  708.      host_send("Type what file? ");
  709.      host_input_strn(strn, 64, 0);
  710.      host_send("^M^J");
  711.      if (!sysop_call)            // sysop --> full path name allowed
  712.      fnstrip(strn, 3, fname);    // user --> only file name & extension
  713.      else
  714.      fname = strn;            // typing all related data
  715.      if (just_filename(fname)) {    // if fname is just a file name
  716.        strn = host_downloads;        // then look for download directory
  717.        strcat(strn, fname);
  718.        fname = strn;
  719.      }
  720.      if (!filefind(fname, 0, strn)) {    // file specified can't be found
  721.        host_send("Unable to find ");
  722.        host_send(fname);
  723.        host_send("^M^J");
  724.      }
  725.      else {
  726.        type_file(fname);
  727.        if (!sysop_call){
  728.       ustamp("User Typed file ", 1, 0);
  729.       ustamp(fname, 0, 1);
  730.        }
  731.      }
  732.      if (ansi_mode)
  733.     host_send("^M");
  734.      else
  735.     host_send("^M^J");
  736.      return 'T';
  737.    }
  738.    //----------------------------------------
  739.    // Upload file(s)
  740.    //----------------------------------------
  741.    else if (option == 'U') {
  742.       option = host_get_prot("<Upload>");        // get the protocol used
  743.       if (!option)                 // if no protocol specified
  744.       return 'U';                            // abort uploading
  745.       status = 1;
  746.       if (option == 'T' || option == 'M' || option == 'S' ||   // auto_receive
  747.       option == 'Y' || option == 'Z' || option == 'E') {
  748.       send_transfer_msg();
  749.       status = receive(option, "");
  750.       }
  751.       else {
  752.       host_send("Upload what file? ");
  753.       host_input_strn(strn, 48, 0);
  754.       host_send("^M^J");
  755.       if (!strn)
  756.          return 'U';
  757.       if (!sysop_call)          // if ordinary user only file name & ext allowed
  758.           fnstrip(strn, 3, fname);
  759.       else
  760.           fname = strn;          // sysop: any disk drive and path
  761.  
  762.       if (just_filename(fname)) {      // only file name in fname, so
  763.          strn = host_uploads;      // default is host_uploads
  764.          strcat(strn, fname);
  765.          fname = strn;
  766.       }
  767.  
  768.       if (filefind(fname, 23, strn))
  769.           host_send("File already exists!^M^J");
  770.       else {
  771.           send_transfer_msg();
  772.           status = receive(option, fname);
  773.       }
  774.       }
  775.       if (status == -2)                // Carrier lost
  776.       connection_lost = finished_caller = 1;
  777.       else if (status == -1)               // File(s) not received.
  778.       host_send("^GOne or more files not received by HOST BBS!^M^J");
  779.       else
  780.       host_send("Uploading succeeds.^M^J");
  781.       return 'U';
  782.    }
  783.    //----------------------------------------
  784.    // Download file(s)
  785.    //----------------------------------------
  786.    else if (option == 'D') {
  787.      option = host_get_prot("<Download>");
  788.      if (!option)
  789.     return 'D';
  790.      host_send("Download what file(s)? ");
  791.      host_input_strn(strn, 48, 0);
  792.      host_send("^M^J");
  793.      if (!strn)
  794.     return 'D';
  795.      if (!sysop_call)       // if not sysop, keep only name & ext
  796.       fnstrip(strn, 3, fname);
  797.      else
  798.       fname = strn;
  799.  
  800.      if (just_filename(fname)) {
  801.        strn = host_downloads;
  802.        strcat(strn, fname);
  803.        fname = strn;
  804.      }
  805.  
  806.      if (!filefind(fname, 0, strn)) {
  807.        host_send("Unable to find any matching file(s)!^M^J");
  808.        return 'D';
  809.      }
  810.  
  811.      status = 1;
  812.      send_transfer_msg();
  813.      status = send(option, fname);
  814.      if (status == -2)                  // Carrier lost
  815.       connection_lost = finished_caller = 1;
  816.      else if (status == -1)
  817.       host_send("^GOne or more files not received by user!^M^J");
  818.      else
  819.       host_send("Downloading succeeds.^M^J");
  820.      return 'D';
  821.    }
  822.    //----------------------------------------
  823.    // Quit file menu
  824.    //----------------------------------------
  825.    else if (option == 'Q') {
  826.      host_send("^M^J");
  827.      return 'Q';
  828.    }
  829. }   // do files
  830.  
  831. //////////////////////////////////////////////////////////////////////////////
  832. // do_system
  833. //////////////////////////////////////////////////////////////////////////////
  834.  
  835. do_system()
  836.  
  837. {
  838.    str strn[20];
  839.    int c, i, j, option = 'A', used_time;
  840.  
  841.    do {
  842.       syscmd();               // display system commands
  843.       host_input_strn(strn, 10, 0);      // then get input
  844.       if (strlen(strn) == 0)          // if only RET pressed then add one
  845.       host_send("^M^J");              // blank line to advance the output
  846.       option = toupper(subchr(strn, 0));
  847.       host_send("^M^J");
  848.       //----------------------------------------
  849.       // Page SysOp
  850.       // Asking for a chat.  Sysop may press F1
  851.       // in order to enter the chat mode.
  852.       //----------------------------------------
  853.       if (option == 'P') {
  854.        printsc_trm("^M^JSysop: Press F1 to chat, any other key not to.^M^J");
  855.        c = 0;                // initialize keyboard input as 0
  856.        _sound_on = 1;            // turn on speaker!
  857.        for (i = 8; i && !c; --i) {        // at most 8 beeps to page sysop
  858.          if (carrier_counts && !carrier()) {
  859.            prints("^M^JConnection has been lost, call terminated.^M^J");
  860.            connection_lost = 1;
  861.            finished_caller = 1;
  862.            break;
  863.          }
  864.          cputc('^G');                   // send 'BEEP' to comm port
  865.          tone(523, 20);  tone(659, 20); // making sound alerting sysop...
  866.          tone(523, 20);  tone(659, 20);
  867.          tone(523, 20);  tone(659, 20);
  868.          for (j = 30; j && (c = inkey()) == 0; --j)    // checks kbd input for 30 times most
  869.           delay(1);            // pause for 1/10 second doing nothing
  870.        }
  871.        _sound_on = 0;            // turn off speaker...
  872.        if (finished_caller)
  873.           continue;
  874.        if (c != 0x3b00 || !c) {        // if response is not F1 or no response
  875.           host_send("^M^JSorry, the Sysop is unavailable^M^J^M^J");
  876.           if (!sysop_call)
  877.           ustamp("User paged Sysop ... but in vain.", 1, 1);
  878.           continue;
  879.        }
  880.        if (!sysop_call)
  881.            ustamp("User paged Sysop and they started chating.", 1, 1);
  882.        used_time = curtime() - grand_timer;
  883.        call("chatmode", local_mode, carrier_counts, capfname);
  884.        grand_timer = curtime() - used_time;
  885.        if (!sysop_call)
  886.            ustamp("Chat ended.", 1, 1);
  887.       }
  888.       //----------------------------------------
  889.       // Logon User List
  890.       //----------------------------------------
  891.       if (option == 'L') {
  892.      if (!sysop_call)
  893.          ustamp("User reviewed user logon list.", 1, 1);
  894.      if (ansi_mode)
  895.          host_send("");
  896.      else
  897.          host_send("^M^J");
  898.      disp_bar(77);
  899.      host_send("^M^JDate       Logon      Logoff     Speed      Mode   Name^M^J");
  900.      disp_bar(77);
  901.      type_file(logon_list);
  902.       }
  903.       //----------------------------------------
  904.       // Reset computer
  905.       // execute RESET.COM.  This program just
  906.       // jumps to ROM BIOS's reset routine
  907.       //----------------------------------------
  908.       else if (option == 'R') {
  909.      if (sysop_call) {                // If this call is from sysop
  910.        if (ask_for_pass(3, shellpass) != 0)     // still asking for password
  911.          run("RESET", "", 0);                       // reset computer!!!
  912.      }
  913.      else {
  914.        if (ansi_mode)
  915.          host_send("^M^J^G^GOnly SysOp The Great can reset the computer!^M^J");
  916.        else
  917.          host_send("^M^J^G^GOnly SysOp The Great can reset the computer!^M^J");
  918.        if (!sysop_call)
  919.            ustamp("User tried to reset the computer.", 1, 1);
  920.      }
  921.       }
  922.       //------------------------------------------------------
  923.       // Shell to DOS: two versions, use only one of them.
  924.       // Comment out one version while using another version.
  925.       // Distributed package uses the original version
  926.       //------------------------------------------------------
  927.       else if (option == 'S') {
  928.     if (sysop_call) {
  929.       if (get_port() != 1 && get_port() != 2) {   // comm port must be 1 or 2
  930.         host_send("Remote Shell not supported on this comm port due to DOS limits!^M^J");
  931.         continue;
  932.       }
  933.       if (ask_for_pass(3, shellpass) != 0) { // asking for password
  934.  
  935.         //----------------------------------------------------------
  936.         //
  937.         //    You may use the following line of code instead of the
  938.         //    original one.  Using Doorway makes HOSTBBS a more
  939.         //    robust system by preventing system lock up if phone
  940.         //    line dropped suddenly during DOS shell.  You must
  941.         //    register to the author of Doorway before you can use
  942.         //    that program in your own BBS.
  943.         //
  944.         //    COM1 -- use COM1: in Doorway
  945.         //    /K:0 -- keyboard timeout is disabled
  946.         //    /M:180 -- allow for 180 minutes door time
  947.         //    /L: -- add line feed when cursor is at the bottom of
  948.         //           the screen
  949.         //    /C: -- drop to DOS is desired
  950.         //
  951.         //    You may change second parameter listing to change
  952.         //    Doorway's behavior when dropping to DOS.
  953.         //
  954.         //----------------------------------------------------------
  955.         //    Beginning of DOORWAY version of DOS shell
  956.         //----------------------------------------------------------
  957.  
  958. //        run("DOORWAY", "COM1 /K:0 /M:180 /B:MSZ /L: /J: /C:DOS", 0);
  959.  
  960.         //----------------------------------------------------------
  961.         //    Ending of DOORWAY version of DOS shell
  962.         //----------------------------------------------------------
  963.  
  964.         //----------------------------------------------------------
  965.         //
  966.         //    Using the following lines of code is like CTTY COM
  967.         //    function of DOS.  System will be locked up if phone line
  968.         //    dropped suddenly during DOS shell.
  969.         //
  970.         //----------------------------------------------------------
  971.         //    Beginning of original version of DOS shell
  972.         //----------------------------------------------------------
  973.  
  974.         host_send("^M^JType EXIT and then press Return to come back.^M^J");
  975.         if (get_baud() == 300)
  976.         delay(10);
  977.         strn = "COM";
  978.         setchr(strn, 3, get_port() + '0'); // get right device name for redirect
  979.         if (!local_mode)
  980.          if (redirect_dos(strn) == -1)     // redirect DOS input and output
  981.          continue;
  982.         dos("", 0);                        // actually call the shell
  983.         if (!local_mode)               // very important to put things
  984.            redirect_dos("");               // back to norm
  985.  
  986.         //----------------------------------------------------------
  987.         //    Ending of original version of DOS shell
  988.         //----------------------------------------------------------
  989.       }   // asking for shell password
  990.     }     // if caller is sysop....
  991.     else {
  992.       if (ansi_mode)
  993.          host_send("^M^J^G^GOnly SysOp The Great can shell to DOS!^M^J");
  994.       else
  995.          host_send("^M^J^G^GOnly SysOp The Great can shell to DOS!^M^J");
  996.       if (!sysop_call)
  997.           ustamp("User tried to enter DOS shell.", 1, 1);
  998.     }
  999.       }   // shell to DOS
  1000.       //----------------------------------------
  1001.       // Ask for ANSI mode
  1002.       //----------------------------------------
  1003.       else if (option == 'A') {
  1004.      ask_ANSI();
  1005.       }   // ask for ANSI mode
  1006.    } while (option != 'Q' && !finished_caller);
  1007. }   // do system
  1008.  
  1009. //////////////////////////////////////////////////////////////////////////////
  1010. // do_bulletin
  1011. //////////////////////////////////////////////////////////////////////////////
  1012.  
  1013. do_bulletin ()
  1014.  
  1015. {
  1016.     str bltn_str[15];
  1017.     int bltn_nbr;
  1018.  
  1019.     do {
  1020.       if (ansi_mode)
  1021.      type_file (bulletin_title);
  1022.       else
  1023.      type_file (tty_bulletin_title);
  1024.       host_send("^M^J                       Enter desired bulletin number: ");
  1025.       host_input_strn(bltn_str, 10, 0);
  1026.       if (strlen(bltn_str) == 0) {
  1027.      host_send("^M^J^M^J");
  1028.      break;
  1029.       }
  1030.       bltn_nbr = stoi(bltn_str);
  1031.       if (bltn_nbr <= 20 && bltn_nbr >= 1){
  1032.      if (!sysop_call) {
  1033.         ustamp("User reviewed bulletin# ", 1, 0);
  1034.         ustamp(bltn_str, 0, 1);
  1035.      }
  1036.      if (ansi_mode)
  1037.         host_send("");                 // clear screen before show bulletin
  1038.      else
  1039.         host_send("^M^J");
  1040.      if (bltn_nbr == 1)
  1041.          type_file(bulletin_1);
  1042.      else if (bltn_nbr == 2)
  1043.          type_file(bulletin_2);
  1044.      else if (bltn_nbr == 3)
  1045.          type_file(bulletin_3);
  1046.      else if (bltn_nbr == 4)
  1047.          type_file(bulletin_4);
  1048.      else if (bltn_nbr == 5)
  1049.          type_file(bulletin_5);
  1050.      else if (bltn_nbr == 6)
  1051.          type_file(bulletin_6);
  1052.      else if (bltn_nbr == 7)
  1053.          type_file(bulletin_7);
  1054.      else if (bltn_nbr == 8)
  1055.          type_file(bulletin_8);
  1056.      else if (bltn_nbr == 9)
  1057.          type_file(bulletin_9);
  1058.      else if (bltn_nbr == 10)
  1059.          type_file(bulletin_10);
  1060.      else if (bltn_nbr == 11)
  1061.          type_file(bulletin_11);
  1062.      else if (bltn_nbr == 12)
  1063.          type_file(bulletin_12);
  1064.      else if (bltn_nbr == 13)
  1065.          type_file(bulletin_13);
  1066.      else if (bltn_nbr == 14)
  1067.          type_file(bulletin_14);
  1068.      else if (bltn_nbr == 15)
  1069.          type_file(bulletin_15);
  1070.      else if (bltn_nbr == 16)
  1071.          type_file(bulletin_16);
  1072.      else if (bltn_nbr == 17)
  1073.          type_file(bulletin_17);
  1074.      else if (bltn_nbr == 18)
  1075.          type_file(bulletin_18);
  1076.      else if (bltn_nbr == 19)
  1077.          type_file(bulletin_19);
  1078.      else if (bltn_nbr == 20)
  1079.          type_file(bulletin_20);
  1080.      host_send("Press any key to continue...");
  1081.      host_input();
  1082.      host_send("^M^J");
  1083.       }  // if bulletin number entered is valid
  1084.     } while (1);
  1085. }  // do bulletin
  1086.  
  1087.  
  1088. //////////////////////////////////////////////////////////////////////////////
  1089. // read user's name
  1090. //    return value = 0 if aborted (timeout or disconnected)
  1091. //    return value = 1 if successful in reading user's name
  1092. //////////////////////////////////////////////////////////////////////////////
  1093.  
  1094. read_user_name()
  1095.  
  1096. {
  1097.  int i, j;
  1098.  str answer[15];
  1099.  
  1100.  do {
  1101.  
  1102.    //--------------------------------------------
  1103.    // ask user to enter his/her first name
  1104.    // if name length is zero, repeat the process
  1105.    //--------------------------------------------
  1106.    do {
  1107.      host_send("^M^Jyour FIRST name: ");
  1108.      host_input_strn(current_caller_first, 20, 0);
  1109.      if (finished_caller)
  1110.     return 0;
  1111.    } while (strlen(current_caller_first) == 0);
  1112.  
  1113.    //--------------------------------------------
  1114.    // ask user to enter his/her last name
  1115.    // if name length is zero, repeat the process
  1116.    //--------------------------------------------
  1117.    do {
  1118.      host_send("^M^Jand your LAST name: ");
  1119.      host_input_strn(current_caller_last, 20, 0);
  1120.      host_send("^M^J");
  1121.      if (finished_caller)
  1122.     return 0;
  1123.    } while (strlen(current_caller_last) == 0);
  1124.  
  1125.    //--------------------------------------------
  1126.    // set all other char to lower case and
  1127.    // replace blank " " with underline "_"
  1128.  
  1129.    strlower(current_caller_first);
  1130.    j = strlen(current_caller_first);
  1131.    for (i = 0; i < j; ++i)
  1132.      if (subchr(current_caller_first, i) == ' ')
  1133.      setchr(current_caller_first, i, '_');
  1134.  
  1135.    strlower(current_caller_last);
  1136.    j = strlen(current_caller_last);
  1137.    for (i = 0; i < j; ++i)
  1138.      if (subchr(current_caller_last, i) == ' ')
  1139.      setchr(current_caller_last, i, '_');
  1140.  
  1141.    //--------------------------------------------
  1142.    // set first char to upper case letter
  1143.  
  1144.    setchr(current_caller_first, 0, toupper(subchr(current_caller_first, 0)));
  1145.    setchr(current_caller_last, 0, toupper(subchr(current_caller_last, 0)));
  1146.  
  1147.    if (ansi_mode) {
  1148.       host_send("^M^JIs your name ");
  1149.       host_send(current_caller_first);
  1150.       host_send(" ");
  1151.       host_send(current_caller_last);
  1152.       host_send("");
  1153.    }
  1154.    else {
  1155.       host_send("^M^JIs your name ");
  1156.       host_send(current_caller_first);
  1157.       host_send(" ");
  1158.       host_send(current_caller_last);
  1159.    }
  1160.    host_send(" ? (Y/N) ");
  1161.  
  1162.    host_input_strn(answer, 10, 0);
  1163.    host_send("^M^J");
  1164.  
  1165.    //----------------------------------------------------------
  1166.    // if caller's name is confirmed by caller then combine it
  1167.    // into full name
  1168.    //----------------------------------------------------------
  1169.    if (subchr(answer, 0) == 'y' || subchr(answer, 0) == 'Y') {
  1170.     host_send("^M^J");
  1171.     current_caller_full = "";
  1172.     strcat(current_caller_full, current_caller_first);
  1173.     strcat(current_caller_full, " ");
  1174.     strcat(current_caller_full, current_caller_last);
  1175.     return 1;
  1176.    }
  1177.  } while (1);
  1178.  
  1179. }   // read_user_name
  1180.  
  1181. //////////////////////////////////////////////////////////////////////////////
  1182. // search user's name list
  1183. //    return value = 0 if aborted (timeout or disconnected)
  1184. //    return value = 1 if successful in reading user's name
  1185. //    return value = 2 if first time user has entered his/her data
  1186. //////////////////////////////////////////////////////////////////////////////
  1187.  
  1188. search_user_list()
  1189.  
  1190. {
  1191.     int i, f_user, user_found = 0, logon_count, file_pos;
  1192.     str user_name[50], name_buf[35], age_buf[10], occupation_buf[45],
  1193.     location_buf[25], phone_buf[25], password_buf[25], dummy[25];
  1194.     str logon_str[8], logon_buf[8], last_rd_buf[8], last_rd_str[8];
  1195.     str answer[5];
  1196.  
  1197.     user_name = current_caller_full;
  1198.  
  1199.     f_user = fopen(user_list, "a+");        // open user list file for reading
  1200.                         // create file if it doesn't exist
  1201.     fseek (f_user, 0, 0);            // move pointer to the beginning
  1202.  
  1203.     while (!feof(f_user) && !user_found){
  1204.      fgets(name_buf, 31, f_user);        // read in user's name
  1205.      fgets(age_buf, 5, f_user);        // read in user's age
  1206.      fgets(occupation_buf, 40, f_user); // read in user's occupation
  1207.      fgets(location_buf, 20, f_user);   // read in user's place
  1208.      fgets(phone_buf, 15, f_user);        // read in user's phone number
  1209.      fgets(password_buf, 20, f_user);   // read in user's password
  1210.      file_pos = ftell(f_user);        // mark where to find call times
  1211.      fgets(logon_buf, 6, f_user);        // read logon times of this user
  1212.      last_read_pos = ftell(f_user);     // mark where to find last read#
  1213.      fgets(last_rd_buf, 6, f_user);     // read caller's last read msg
  1214.      fgets(dummy, 18, f_user);        // read past empty line
  1215.      if (strcmpi(current_caller_full, name_buf) == 0){    // user found!
  1216.           user_found = 1;
  1217.           user_age = age_buf;
  1218.           user_phone = phone_buf;
  1219.           user_occupation = occupation_buf;
  1220.           user_password = password_buf;
  1221.           user_location = location_buf;
  1222.           i = 0;                      // record logon times
  1223.           while (subchr(logon_buf, i) == ' ')
  1224.           ++i;
  1225.           substr(logon_buf, i, 4, logon_str);
  1226.           logon_count = stoi(logon_str);
  1227.           logon_count = logon_count + 1;          // and increment it
  1228.           itos(logon_count, logon_buf);
  1229.           logon_str = "";
  1230.           for (i = 1; i <= (4 - strlen(logon_buf)); ++i)
  1231.            strcat(logon_str, " ");
  1232.           strcat(logon_str, logon_buf);
  1233.           strcat(logon_str, "^M^J");
  1234.           fseek(f_user, file_pos, 0);          // move file pointer
  1235.           fwrite(logon_str, strlen(logon_str), f_user);
  1236.           i = 0;                      // record last read msg
  1237.           while (subchr(last_rd_buf, i) == ' ')
  1238.           ++i;
  1239.           substr(last_rd_buf, i, 4, last_rd_str);
  1240.           last_read = stoi(last_rd_str);          // and remember it!
  1241.      }
  1242.     }     // while not the end of user list
  1243.  
  1244.     fclose(f_user);                // close user list file
  1245.  
  1246.     if (user_found) {                // user found
  1247.      logon_count = logon_count - 1;
  1248.      itos(logon_count, logon_buf);
  1249.      if (ansi_mode) {
  1250.          host_send("You are ");
  1251.          host_send(name_buf);
  1252.          host_send("");
  1253.          host_send(".  You have called ");
  1254.          host_send(logon_buf);
  1255.          host_send(" times before this call.^M^J^M^J");
  1256.      }
  1257.      else {
  1258.          host_send("^M^JYou are ");
  1259.          host_send(name_buf);
  1260.          host_send(".  You have called ");
  1261.          host_send(logon_buf);
  1262.          host_send(" times before this call.^M^J^M^J");
  1263.      }
  1264.      return 1;          // and user get a return value 1
  1265.     }
  1266.     else {                    // user not found (new user)
  1267.       if (ansi_mode)
  1268.      host_send("Hi ");
  1269.       else
  1270.      host_send("^M^JHi ");
  1271.       host_send(current_caller_first);
  1272.       host_send(",^M^J");
  1273.       if (ansi_mode)
  1274.       type_file(question_file);        // prompt user for questionaire
  1275.       else
  1276.       type_file(tty_question_file);
  1277.       do {
  1278.      host_send("^M^J    your age: ");   // age
  1279.      if (ansi_mode)
  1280.         host_send("");       // age
  1281.      host_input_strn(age_buf, 5, 0);
  1282.      if (ansi_mode)
  1283.         host_send("");
  1284.      if (finished_caller)
  1285.          return 0;
  1286.  
  1287.      host_send("^M^J  occupation: ");   // job
  1288.      if (ansi_mode)
  1289.         host_send("");
  1290.      host_input_strn(occupation_buf, 40, 0);
  1291.      if (ansi_mode)
  1292.         host_send("");
  1293.      strupper(occupation_buf);
  1294.      if (finished_caller)
  1295.          return 0;
  1296.  
  1297.      host_send("^M^J        city: ");       // location
  1298.      if (ansi_mode)
  1299.          host_send("");
  1300.      host_input_strn(location_buf, 20, 0);
  1301.      if (ansi_mode)
  1302.          host_send("");
  1303.      strupper(location_buf);
  1304.      if (finished_caller)
  1305.          return 0;
  1306.  
  1307.      host_send("^M^Jphone number: ");       // phone number
  1308.      if (ansi_mode)
  1309.         host_send("");
  1310.      host_input_strn(phone_buf, 15, 0);
  1311.      if (ansi_mode)
  1312.         host_send("");
  1313.      strupper(location_buf);
  1314.      if (finished_caller)
  1315.          return 0;
  1316.  
  1317.      host_send("^M^Jnew password: ");       // new password
  1318.      if (ansi_mode)
  1319.          host_send("");
  1320.      host_input_strn(password_buf, 20, 0);
  1321.      if (ansi_mode)
  1322.          host_send("");
  1323.      strupper(password_buf);
  1324.      if (finished_caller)
  1325.          return 0;
  1326.  
  1327.      host_send("^M^J^M^J");
  1328.      host_send(current_caller_first);
  1329.      host_send(", your personal data is:^M^J");
  1330.      host_send("^M^J           age: ");
  1331.      if (ansi_mode) {
  1332.         host_send(""); host_send(age_buf); host_send("");
  1333.         host_send("^M^J    occupation: ");
  1334.         host_send(""); host_send(occupation_buf); host_send("");
  1335.         host_send("^M^J          city: ");
  1336.         host_send(""); host_send(location_buf); host_send("");
  1337.         host_send("^M^J  phone number: ");
  1338.         host_send(""); host_send(phone_buf); host_send("");
  1339.         host_send("^M^J      password: ");
  1340.         host_send(""); host_send(password_buf); host_send("");
  1341.      }
  1342.      else {
  1343.         host_send(age_buf);
  1344.         host_send("^M^J    occupation: ");
  1345.         host_send(occupation_buf);
  1346.         host_send("^M^J          city: ");
  1347.         host_send(location_buf);
  1348.         host_send("^M^J  phone number: ");
  1349.         host_send(phone_buf);
  1350.         host_send("^M^J      password: ");
  1351.         host_send(password_buf);
  1352.      }
  1353.      host_send("^M^J^M^JIs this correct (Y/N)? ");
  1354.  
  1355.      host_input_strn(answer, 4, 0);
  1356.      host_send("^M^J");
  1357.      if (subchr(answer, 0) == 'y' || subchr(answer, 0) == 'Y') {
  1358.  
  1359.           user_age = age_buf;
  1360.           user_phone = phone_buf;
  1361.           user_occupation = occupation_buf;
  1362.           user_password = password_buf;
  1363.           user_location = location_buf;
  1364.  
  1365.           host_send("^M^J");
  1366.           f_user = fopen(user_list, "a");    // open user list file for appending
  1367.           fseek(f_user, 0, 2);         // move to end of file
  1368.  
  1369.           strcat(user_name, "^M^J");
  1370.           fwrite(user_name, strlen(user_name), f_user);
  1371.  
  1372.           strcat(age_buf, "^M^J");
  1373.           fwrite(age_buf, strlen(age_buf), f_user);
  1374.  
  1375.           strcat(occupation_buf, "^M^J");
  1376.           fwrite(occupation_buf, strlen(occupation_buf), f_user);
  1377.  
  1378.           strcat(location_buf, "^M^J");
  1379.           fwrite(location_buf, strlen(location_buf), f_user);
  1380.  
  1381.           strcat(phone_buf, "^M^J");
  1382.           fwrite(phone_buf, strlen(phone_buf), f_user);
  1383.  
  1384.           strcat(password_buf, "^M^J");
  1385.           fwrite(password_buf, strlen(password_buf), f_user);
  1386.  
  1387.           logon_count = 1;            // first time to this board
  1388.           itos(logon_count, logon_buf);
  1389.           logon_str = "   ";            // add three blanks ahead
  1390.           strcat(logon_str, logon_buf); // total four positions for digits
  1391.           strcat(logon_str, "^M^J");
  1392.           fwrite(logon_str, strlen(logon_str), f_user);
  1393.  
  1394.           last_read_pos = ftell(f_user);     // mark where to find last read#
  1395.           last_read = 0;            // last read msg is #0
  1396.           itos(last_read, last_rd_buf);
  1397.           last_rd_str = "   ";
  1398.           strcat(last_rd_str, last_rd_buf);
  1399.           strcat(last_rd_str, "^M^J");
  1400.           fwrite(last_rd_str, strlen(last_rd_str), f_user);
  1401.  
  1402.           fwrite("---------------^M^J", 17, f_user);
  1403.  
  1404.           fclose(f_user);
  1405.           return 2;       // first_time user get a return value 2
  1406.      }  // if
  1407.        } while (1);
  1408.     }
  1409.  
  1410. }   // search_user_list
  1411.  
  1412. //////////////////////////////////////////////////////////////////////////////
  1413. //  get access level
  1414. //  enter with level = 2 if this is the first time user
  1415. //               all other value if not first time user
  1416. //  return value = 1 if access granted
  1417. //           0 if access denied
  1418. //////////////////////////////////////////////////////////////////////////////
  1419.  
  1420. get_access(int level)
  1421.  
  1422. {
  1423.  int access;
  1424.  
  1425.  if (level != 2)                 // not first time user
  1426.      access = ask_for_pass(3, user_password);     // ask for user's previous password
  1427.  else
  1428.      access = 1;                 // first time caller is here...
  1429.  
  1430.  if (!sysop_call) {
  1431.     if (access)
  1432.     ustamp("Logon by ", 1, 0);
  1433.     else
  1434.     ustamp("Failed logon attempt by ", 1, 0);
  1435.     ustamp("", 0, 0);
  1436.     ustamp(current_caller_full, 0, 0);
  1437.     ustamp("", 0, 1);
  1438.  }
  1439.  
  1440.  if (!access) {
  1441.    host_send("Goodbye!^M^J");
  1442.    if (carrier_counts) {
  1443.      delay(10);
  1444.      hangup();
  1445.    }
  1446.    return 0;               // logon fails
  1447.  }
  1448.  else
  1449.    return 1;               // logon succeeds
  1450. }
  1451.  
  1452. //////////////////////////////////////////////////////////////////////////////
  1453. // deal with Message functions
  1454. //////////////////////////////////////////////////////////////////////////////
  1455.  
  1456. do_message()
  1457.  
  1458. {
  1459.   str strn[20];
  1460.   int option, c, i, j, k, msg_sent;
  1461.  
  1462.   while (1) {
  1463.      if (finished_caller)    // finished_caller is set by host_input if
  1464.      return;        // connection is lost.
  1465.  
  1466.      if (sysop_call)
  1467.     msgcmd(sysop_last_read);
  1468.      else
  1469.     msgcmd(last_read);
  1470.  
  1471.      host_input_strn(strn, 10, 0);        // asking for message function
  1472.      option = toupper(subchr(strn, 0));
  1473.      host_send("^M^J");
  1474.  
  1475.      //-----------------------------------------------
  1476.      // Scan messages
  1477.      //-----------------------------------------------
  1478.      if (option == 'S'){
  1479.      if (!sysop_call)
  1480.          ustamp("User scanned messages.", 1, 1);
  1481.      reply_to = 0;
  1482.      host_send("^M^JScan from message#: ");
  1483.      host_input_strn(strn, 10, 0);
  1484.      host_send("^M^J");
  1485.      if (finished_caller)
  1486.           return;
  1487.      option = stoi(strn);
  1488.      if (option == 0)            // if only <RET> pressed then
  1489.          option = first_msg;        // from the first message
  1490.      msg_sent = 0;
  1491.      j = 0;
  1492.      for (i = option; i <= last_msg; ++i) {
  1493.           if (scan_message(i))        // if it does being scanned
  1494.           ++msg_sent;
  1495.           if (msg_sent == 4) {
  1496.           msg_sent = 0;
  1497.           host_send("^M^J-- More ?");
  1498.           j = host_input();
  1499.           host_send("^M            ^M");
  1500.           }
  1501.           if (j == 'N' || j == 'n')
  1502.           i = last_msg + 1;         // if i > last_msg then end
  1503.      }
  1504.      }
  1505.      //-----------------------------------------------
  1506.      // Enter messages
  1507.      //-----------------------------------------------
  1508.      else if (option == 'E'){                // to enter messge
  1509.      reply_to = 0;
  1510.      enter_message();
  1511.      }
  1512.      //-----------------------------------------------
  1513.      // Check messages
  1514.      //-----------------------------------------------
  1515.      else if (option == 'C'){
  1516.      if (!sysop_call)
  1517.          ustamp("User checked his/her message.", 1, 1);
  1518.      reply_to = 0;
  1519.      host_send("^M^JYour mail: ");
  1520.      msg_sent = 0;
  1521.      for (i = first_msg; i <= last_msg; ++i){
  1522.           if (check_message(i))
  1523.           ++msg_sent;
  1524.           if (msg_sent == 10){
  1525.           msg_sent = 0;
  1526.           host_send("^M^J           ");
  1527.           }
  1528.      }
  1529.      host_send("^M^J^M^JMessage# enclosed with [] is from you.^M^J");
  1530.      }
  1531.      //-----------------------------------------------
  1532.      // Non-stop display of messages
  1533.      //-----------------------------------------------
  1534.      else if (option == 'N'){
  1535.      if (!sysop_call)
  1536.          ustamp("User invoked non-stop displaying of messages.", 1, 1);
  1537.      reply_to = 0;
  1538.      host_send("^M^JStarting from message# (<RETURN> = first):");
  1539.      host_input_strn(strn, 10, 0);
  1540.      host_send("^M^J");
  1541.      if (finished_caller)
  1542.           return;
  1543.      option = stoi(strn);
  1544.      if (option == 0)            // if only <RET> pressed then
  1545.          option = first_msg;        // from the first message
  1546.      for (i = option; i <= last_msg; ++i) {
  1547.           if (display_message(i)) {     // if caller see the msg
  1548.          last_read = i;         // update last read msg#
  1549.          if (sysop_call)        // if caller is sysop then
  1550.              sysop_last_read = i;   // update sysop's last read msg#
  1551.          host_send("^M^J<ESC> to stop, <CR> to continue...");
  1552.          do {
  1553.              c = host_input();
  1554.          } while (c != 27 && c != 13);
  1555.          host_send("^M^J");
  1556.          if (c == 27)
  1557.             break;
  1558.           }
  1559.      }
  1560.      }
  1561.      //-----------------------------------------------
  1562.      // Delete a message
  1563.      //-----------------------------------------------
  1564.      else if (option == 'D'){
  1565.      reply_to = 0;
  1566.      host_send("^M^JDelete which message#: ");
  1567.      host_input_strn(strn, 10, 0);
  1568.      host_send("^M^J");
  1569.      if (finished_caller)
  1570.           return;
  1571.      if (stoi(strn)) {            // if valid number entered
  1572.          i = stoi(strn);
  1573.          delete_message(i);         // ok, TRY to delete it...
  1574.      }
  1575.      }
  1576.      //-----------------------------------------------
  1577.      // Reply to a message
  1578.      // only responds when there is something to reply
  1579.      // to -- each time finished reading message is the
  1580.      // time to reply.    any other time will not let
  1581.      // user to use Reply.
  1582.      //-----------------------------------------------
  1583.      else if (option == 'R'){
  1584.      if (reply_to)
  1585.          reply_message(reply_to);
  1586.      }
  1587.      //-----------------------------------------------
  1588.      // Quit the message functions
  1589.      //-----------------------------------------------
  1590.      else if (option == 'Q'){
  1591.      reply_to = 0;
  1592.      if (sysop_call)
  1593.          fstlst();
  1594.      return;
  1595.      }
  1596.      //-----------------------------------------------
  1597.      // If a message number is entered then display it
  1598.      //-----------------------------------------------
  1599.      else if (stoi(strn)){           // a number has been typed,
  1600.      i = stoi(strn);           // i is the number typed
  1601.      if (display_message(i)) {     // if caller see the msg
  1602.         last_read = i;           // update last read msg#
  1603.         reply_to = i;           // update msg# to reply to
  1604.         if (sysop_call)           // if caller is sysop then
  1605.         sysop_last_read = i;   // update sysop's last read msg#
  1606.      }
  1607.      else                   // nothing displayed, so reset
  1608.         reply_to = 0;           // msg# to reply_to
  1609.      }
  1610.      //-----------------------------------------------
  1611.      // If only CR is pressed
  1612.      //-----------------------------------------------
  1613.      else if (strlen(strn) == 0){
  1614.      i = last_read + 1;
  1615.      do {
  1616.         if (i <= last_msg && display_message(i)) {
  1617.         last_read = i;
  1618.         reply_to = i;
  1619.         if (sysop_call)        // if caller is sysop then
  1620.             sysop_last_read = i;   // update sysop's last read msg#
  1621.         break;
  1622.         }
  1623.         else {               // nothing displayed, so reset
  1624.         ++i;               // msg# to reply to
  1625.         reply_to = 0;
  1626.         }
  1627.      } while (i <= last_msg);
  1628.      }
  1629.   }  // while (an endless loop unless 'Q' option is confirmed.
  1630. }   // do message
  1631.  
  1632. //////////////////////////////////////////////////////////////////////////////
  1633. // get transfer protocol
  1634. //////////////////////////////////////////////////////////////////////////////
  1635.  
  1636. host_get_prot(str transfer_way)
  1637.  
  1638. {
  1639.      str prot[10];
  1640.  
  1641.      showprot(transfer_way);
  1642.  
  1643.      host_input_strn(prot, 6, 0);
  1644.      host_send("^M^J");
  1645.  
  1646.      if (strposi("KMSX1GYEZT", prot, 0) == -1)     // if illegal prot
  1647.      prot = "";                                // return 0 since first char
  1648.                            // of empty string is 0.
  1649.      return (toupper(subchr(prot, 0)));      // return first char.
  1650. }   // host_get_prot
  1651.  
  1652. //////////////////////////////////////////////////////////////////////////////
  1653.  
  1654. send_transfer_msg()
  1655.  
  1656. {
  1657.  host_send("Ready to transfer file(s)... Press Ctrl-X at least twice to abort^M^J");
  1658. }
  1659.  
  1660. //////////////////////////////////////////////////////////////////////////////
  1661. // Determine the baud rate once a Carrier Detect Signal has been detected
  1662. // Since no characters were read, the 'CONNECT' string should still be
  1663. // in the receive buffer.
  1664. //    return value = 0 if failed
  1665. //    return value = 1 if succeeded
  1666. //////////////////////////////////////////////////////////////////////////////
  1667.  
  1668. determine_baud()
  1669.  
  1670. {
  1671.  int t3, t12, t24, t96, t192;
  1672.  int tmark, stat;
  1673.  int new_baud = 0;
  1674.  
  1675.  printsc("Determining baud... ");
  1676.  
  1677.  track_free(0);            // stop tracking all strings
  1678.  
  1679.  t3 = track(conn300, 0);       // start tracking connect strings
  1680.  t12 = track(conn1200, 0);     // case is significant (mode 0)
  1681.  t24 = track(conn2400, 0);
  1682.  t96 = track(conn9600, 0);
  1683.  t192 = track(conn19200, 0);
  1684.  
  1685.  tmark = timer_start(30);      // wait up to 3 seconds for string
  1686.  
  1687.  while (!time_up(tmark)) {     // while there is still time
  1688.    if (!carrier()) {           // if we lost connection
  1689.      track_free(0);           // stop tracking all strings
  1690.      return 0;               // zero indicating failure
  1691.    }
  1692.    if (cinp_cnt())           // if something is in the comm buffer
  1693.     track_addchr(cgetc());     // treat incoming char as from terminal handler
  1694.  
  1695.    stat = track_hit(0);        // get the lowest numbered handle of any strings
  1696.    if (stat == 0)           // none did come, so continue
  1697.     continue;
  1698.  
  1699.    if (stat == t3)
  1700.     new_baud = 300;
  1701.    else if (stat == t24)
  1702.     new_baud = 2400;
  1703.    else if (stat == t96)
  1704.     new_baud = 9600;
  1705.    else if (stat == t192)
  1706.     new_baud = 19200;
  1707.    else
  1708.     new_baud = 1200;
  1709.  
  1710.    break;               // have baud rate, get out
  1711.   }   // while there is still time
  1712.  
  1713.  if (!new_baud)            // time-up without CONNECT string
  1714.   {
  1715.    prints("Failed!");
  1716.    track_free(0);           // stop tracking all strings
  1717.    return 0;               // zero indicating failure
  1718.   }
  1719.  
  1720.  printn(new_baud);
  1721.  prints("");
  1722.  
  1723.  //---------------------------------------------------------
  1724.  // set communication parameters: all the same except
  1725.  // the new baud rate.
  1726.  //---------------------------------------------------------
  1727.  set_cparams(new_baud, get_parity(), get_datab(), get_stopb());
  1728.  
  1729.  track_free(0);            // stop tracking all strings
  1730.  return 1;               // indicate success
  1731.  
  1732. }   // determine baud rate
  1733.  
  1734. //////////////////////////////////////////////////////////////////////////////
  1735. // open a text file then output it to the terminal emulator and comm port
  1736. //    return value = -1 if it failed to open the text file
  1737. //    return value = 0 if connection is lost or user inactivity
  1738. //    return value = 1 if Ctrl-C is pressed to abort it
  1739. //////////////////////////////////////////////////////////////////////////////
  1740.  
  1741. type_file(str fname)
  1742.  
  1743. {
  1744.  int f;
  1745.  str buf[200];
  1746.  int k, ichar, lines_sent = 0;
  1747.  
  1748.  f = fopen(fname, "r");                 // open the file for reading
  1749.  if (!f)                // if it can't be open
  1750.     return -1;                // -1 indicating failure
  1751.  
  1752.  host_send("^M^J");
  1753.  
  1754.  while (1) {
  1755.    if (carrier_counts)
  1756.       if (!carrier()) {         // if carrier detect line is not OK
  1757.     connection_lost = 1;
  1758.     finished_caller = 1;
  1759.     fclose(f);
  1760.     return 0;
  1761.       }
  1762.  
  1763.    if (fgets(buf, 195, f) == -1) {    // read at most 195 chars (LF stripped)
  1764.       fclose(f);
  1765.       return 1;
  1766.    }
  1767.  
  1768.    if (feof(f)) {            // end-of-file is reached
  1769.        if (subchr(buf, strlen(buf) - 1) == 26)    // if last char of buf is Ctrl-Z
  1770.        setchr(buf, strlen(buf) - 1, 0);    // remove Ctrl-Z
  1771.    }
  1772.    else
  1773.        host_send(buf);            // output a line to the host & caller
  1774.  
  1775.    host_send("^M^J");                   // add LF explicitly since LF stripped
  1776.  
  1777.    ++lines_sent;
  1778.  
  1779.    while (cinp_cnt()) {         // if something is in comm buffer
  1780.      ichar = cgetc();            // the read it!
  1781.      if (ichar == '^C') {               // is it a Ctrl-C ?
  1782.        host_send("^M^J");               // yes, so stop typing file
  1783.        fclose(f);
  1784.        return 1;
  1785.      }    // is it a Ctrl-C ?
  1786.    }    // while something is in comm buffer
  1787.  
  1788.  
  1789.    if (lines_sent >= 23) {        // have we filled the whole screen?
  1790.      lines_sent = 0;            // yes, so reset the counter
  1791.      host_send("-- More ?");
  1792.      k = host_input();
  1793.      host_send("^M            ^M");
  1794.      if (finished_caller) {        // if user inactivity
  1795.        fclose(f);
  1796.        return 0;
  1797.      }
  1798.      if (k == 'N' || k == 'n')
  1799.        return 1;
  1800.    }
  1801.  
  1802.   } // while: an endless loop if return not used
  1803. }   // type_file
  1804.  
  1805. //////////////////////////////////////////////////////////////////////////////
  1806. // host_send sends the specified string through two routes:
  1807. //    1) terminal emulator, so that ANSI codes can be interpreted locally
  1808. //    2) modem port
  1809. //////////////////////////////////////////////////////////////////////////////
  1810.  
  1811. host_send(str outstr)
  1812.  
  1813. {
  1814.  
  1815.  if (!local_mode)
  1816.     cputs(outstr);        // sends to modem port
  1817.  printsc_trm(outstr);        // sends to screen through terminal emulator
  1818.  
  1819. }
  1820.  
  1821. //////////////////////////////////////////////////////////////////////////////
  1822. // host_send_c sends the specified character through two routes:
  1823. //    1) screen
  1824. //    2) modem port
  1825. //////////////////////////////////////////////////////////////////////////////
  1826.  
  1827. host_send_c(int chr)
  1828.  
  1829. {
  1830.     str c_str[2];
  1831.  
  1832.     setchr(c_str, 0, chr);
  1833.     setchr(c_str, 1, 0);
  1834.     if (!local_mode)
  1835.        cputc(chr);           // sends to modem port
  1836.     printsc_trm(c_str);        // sends to terminal emulator of host
  1837.  
  1838. //  printc(chr);           // prints the character on the terminal screen
  1839.  
  1840. }
  1841.  
  1842. //////////////////////////////////////////////////////////////////////////////
  1843. // host_input_strn waits the sysop/user to input a string or press <CR>
  1844. // return value = 1 if string is not empty
  1845. //          0 if string is empty
  1846. //////////////////////////////////////////////////////////////////////////////
  1847.  
  1848. host_input_strn(str buf, int maximum, int start_point)
  1849.  
  1850. {
  1851.  int i, j, key;
  1852.  
  1853.  i = start_point;
  1854.  while (1) {                // endless loop until... lets see...
  1855.    key = host_input();            // key is from host or user
  1856.    if (!key) {                // timeout or user disconnect
  1857.      setchr(buf, 0, 0);         // set string to empty
  1858.      return 0;                // indicate there is a problem
  1859.    }
  1860.    if (key == '^M') {                   // Carriage return pressed
  1861.       break;                // so terminate the endless loop
  1862.    }
  1863.    if (key == 127 || key == 8) {  // Backspace or Del
  1864.      if (i) {             // if something has been typed
  1865.        --i;
  1866.        host_send_c(key);     // erase one character backwards
  1867.      }
  1868.      continue;             // continue the endless loop
  1869.    }  // if Backspace or Del
  1870.    if (key == 9) {         // Horizontal Tab is converted to up to
  1871.      j = 5;             // five blanks.
  1872.      while (i < maximum && j > 0){
  1873.      setchr(buf, i, ' ');// put char into buffer and
  1874.      ++i;
  1875.      --j;
  1876.      host_send_c(' ');
  1877.      }
  1878.      continue;
  1879.    }
  1880.    if (key == 24) {         // Ctrl-X key pressed by user
  1881.      while (i >= 0) {         // move cursor to starting point
  1882.     host_send_c(8);
  1883.     --i;
  1884.      }
  1885.      i = 0;             // reset i
  1886.      continue;
  1887.    }
  1888.    if (i < maximum) {         // if not more than buffer size
  1889.      setchr(buf, i, key);    // put char into buffer and
  1890.      ++i;             // take a note about number of characters
  1891.    }
  1892.    if (i == maximum)         // if maximum count is reached
  1893.      break;
  1894.   }    // the while endless loop
  1895.  
  1896.  setchr(buf, i, '^0');       // mark the end of string
  1897.  
  1898.  if (subchr(buf, 0))         // if this is not an empty string
  1899.     return 1;             // then return 1
  1900.  else                 // this is an empty string
  1901.     return 0;             // so return 0
  1902.  
  1903. }   // host_input_strn
  1904.  
  1905. //////////////////////////////////////////////////////////////////////////////
  1906. // host input function does this:
  1907. //    it starts up a timer to 5 minutes then enters an endless loop
  1908. //    (No time limit if SysOp is calling this board)
  1909. //    waiting for character coming from keyboard or comm port.
  1910. //    any character presented in the keyboard or comm port will terminate
  1911. //    the endless loop by doing the following:
  1912. //       Keyboard character (from SysOp, of course):
  1913. //           HOME -- sysop wants to exit the session
  1914. //        END -- sysop kicks the user out (kill user)
  1915. //        F1  -- sysop initiates chat mode
  1916. //        F2  -- sysop terminates chat mode
  1917. //        F3  -- sysop check incoming user's basic data
  1918. //        All other char except BS & Del -- sends to screen & modem
  1919. //       Comm port character (from User, of course):
  1920. //        All other char except BS & Del -- sends to screen & modem
  1921. //    return value = 0 if inactivity is too long or connection is lost
  1922. //    return value = ASCII value
  1923. //////////////////////////////////////////////////////////////////////////////
  1924.  
  1925. host_input()
  1926.  
  1927. {
  1928.  int c, t, curt, capst, used_time;
  1929.  
  1930.  if (!sysop_call)          // if caller is not sysop --> set time-out limit
  1931.      t = timer_start(3000);   // 5 minutes inactivity allowed for users
  1932.  
  1933.  while (1) {
  1934.    if (!sysop_call && !direct_connect) {   // if not a sysop & through modem
  1935.       if (time_up(t)) {            // inactivity too long...
  1936.      host_send("^M^J^M^J");
  1937.      host_send("Inactivity period too long. Connection terminated!^M^J");
  1938.      if (carrier_counts)
  1939.         hangup();
  1940.      finished_caller = 1;
  1941.      kill_user = 1;
  1942.      return 0;
  1943.       }
  1944.  
  1945.       curt = curtime();
  1946.  
  1947.       if (!warned)
  1948.      if ((curt - grand_timer) > 3420) {    // only three minutes left
  1949.         _sound_on = 1;
  1950.         host_send("^G^G^M^J^M^JOnly 3 minutes left.^M^J");
  1951.         warned = 1;
  1952.         _sound_on = 0;
  1953.      }
  1954.  
  1955.       if ((curt - grand_timer) > 3600) {       // total logon time expired.
  1956.      host_send("^M^J^M^J");
  1957.      host_send("Logon time expired.  Please call again.^M^J");
  1958.      if (carrier_counts)
  1959.         hangup();
  1960.      finished_caller = 1;
  1961.      kill_user = 1;
  1962.      return 0;
  1963.       }
  1964.    }
  1965.  
  1966.    if (carrier_counts && !carrier()) {
  1967.     prints("^M^JConnection has been lost, call terminated.^M^J");
  1968.     connection_lost = 1;
  1969.     finished_caller = 1;
  1970.     return 0;
  1971.    }
  1972.  
  1973.    if ((c = inkey()) != 0) {    // if keyboard buffer is not empty
  1974.      if (c <= 255) {
  1975.        if (c != 8 && c != 127 && c != 9)  // backspace & delete & tab
  1976.       host_send_c(c);      // sends the character to screen & modem
  1977.        return c;
  1978.      }
  1979.      else if (c == 0x4700) {         // HOME key, sysop wants to exit
  1980.        finished_caller = 1;
  1981.        exit_requested = 1;
  1982.        return 0;
  1983.      }
  1984.      else if (c == 0x4f00) {    // END key, temrinate user
  1985.        prints("^M^JUser terminated!");
  1986.        if (!sysop_call)
  1987.        ustamp("Terminated by SysOp", 1, 1);
  1988.        if (carrier_counts)
  1989.     hangup();
  1990.        finished_caller = 1;
  1991.        kill_user = 1;
  1992.        return 0;
  1993.      }
  1994.      else if (c == 0x3b00) {    // F1 key --> sysop initiates chat
  1995.     if (!sysop_call)
  1996.         ustamp("Sysop initiated chat mode.", 1, 1);
  1997.     used_time = curtime() - grand_timer;
  1998.     call("chatmode", local_mode, carrier_counts, capfname);
  1999.     if (!sysop_call)
  2000.         ustamp("Sysop terminated chat mode.", 1, 1);
  2001.     timer_restart(t, 3000); // 5 minutes inactivity allowed for users
  2002.     grand_timer = curtime() - used_time;       // reset
  2003.      }
  2004.                 // F2 (sysop terminate chat) disabled
  2005.  
  2006.      else if (c == 0x3d00) {    // F3 key --> sysop checks user's personal data
  2007.     if (!sysop_call)
  2008.        showuser();
  2009.      }
  2010.      else if (c == 0x3e00) {    // F4 key --> capture on/off
  2011.      capst = capture_stat();
  2012.      if (capst == 0)    // capture file is closed
  2013.          capture(capfname);
  2014.      else if (capst == 1 || capst == 2)  // capture file is open
  2015.          capture("*CLOSE*");
  2016.      update_term();
  2017.      }
  2018.      else if (c == 0x3f00) {    // F5 key --> capture pause/unpause
  2019.      capst = capture_stat();
  2020.      if (capst == 1)    // capture file is open
  2021.          capture("*PAUSE*");
  2022.      else if (capst == 2)    // capture file is open and paused
  2023.          capture("*UNPAUSE*");
  2024.      update_term();
  2025.      }
  2026.      else if (c == 0x4000) {    // F6 key --> reset user's available time
  2027.        if (!sysop_call) {
  2028.       warned = 0;
  2029.       grand_timer = curtime();
  2030.       resetime();
  2031.        }
  2032.      }
  2033.    }  // if keyboard buffer is not empty
  2034.  
  2035.    if (!local_mode)          // if this is not a local test
  2036.       if (cinp_cnt()) {       // and if something is in the comm buffer
  2037.      c = cgetc();          // then read that character
  2038.      if (c != 8 && c != 127 && c != 9)   // backspace & delete & tab
  2039.         host_send_c(c);      // sends the character to screen & modem (echo)
  2040.      return c;
  2041.       }
  2042.   }    // while
  2043. }    // host_input
  2044.  
  2045. //////////////////////////////////////////////////////////////////////////////
  2046. // verify if it is real sysop by
  2047. // asking for a sysop's password for three times
  2048. //
  2049. //     failure --> return 0
  2050. //     success --> return 2, this is regarded as level 2 access
  2051. //
  2052. // (level 2 access is the same as sysop_call == 1)
  2053. //
  2054. //////////////////////////////////////////////////////////////////////////////
  2055.  
  2056. verify_sysop()
  2057.  
  2058. {
  2059.   int i;
  2060.   str strn[25];
  2061.  
  2062.   for (i = 0; i < 3; ++i) {     // only three times to enter sysop's password
  2063.      if (i)             // the first time will not show this warning.
  2064.     host_send("^M^JWrong! Try again.^M^J");
  2065.      host_send("Enter ");
  2066.      if (ansi_mode)
  2067.     host_send("SysOp's password: ");
  2068.      else
  2069.     host_send("SysOp's password: ");
  2070.      host_input_strn(strn, 20, 0);
  2071.      host_send("^M^J");
  2072.      if (finished_caller)          // connection is lost
  2073.     return 0;
  2074.      strupper(strn);              // change to upper case
  2075.      if (!strcmpi(strn, sysop_password))  // check for sysop's password
  2076.     return 2;              // access
  2077.   }
  2078.   host_send("^M^JYou are not SysOp.  Get out!!!^M^J");
  2079.   return 0;
  2080. }   // verify_sysop
  2081.  
  2082. //////////////////////////////////////////////////////////////////////////////
  2083. // ask for password for maxtries times.
  2084. //    return value: 0 --> access denied
  2085. //              1 --> access granted
  2086. //////////////////////////////////////////////////////////////////////////////
  2087.  
  2088. ask_for_pass(int maxtries, str password)
  2089.  
  2090. {
  2091.   int i;
  2092.   str strn[23];
  2093.  
  2094.   for (i = 0; i < maxtries; ++i) {
  2095.      if (i)
  2096.     host_send("^M^JWrong! Try again.^M^J");
  2097.      host_send("Enter password: ");
  2098.      host_input_strn(strn, 20, 0);
  2099.      host_send("^M^J");
  2100.      if (finished_caller)          // something is wrong
  2101.     return 0;              // access is denied
  2102.      strupper(strn);              // change to upper case
  2103.      if (!strcmpi(strn, password))      // if strn is equal to password
  2104.     return 1;              // access granted
  2105.   }
  2106.   host_send("^M^JNo more chances. Access denied.^M^J");
  2107.   return 0;                  // access denied
  2108. }   // ask_for_pass
  2109.  
  2110. //////////////////////////////////////////////////////////////////////////////
  2111. // returns TRUE if passed filespec is just a filename.
  2112. // returns FALSE if passed filespec is not just a filename (is a path...)
  2113. // Also handles the forward slash as a path separator.
  2114. //////////////////////////////////////////////////////////////////////////////
  2115.  
  2116. just_filename(str filespec)
  2117.  
  2118. {
  2119.  int slash, space;
  2120.  
  2121.  if (strpos(filespec, ":", 0) != -1)   // if filespec contains ':' then returns
  2122.   return 0;                   // FALSE indicating not just a file name
  2123.  if (strpos(filespec, "\", 0) != -1)   // if filespec contains '\' then it
  2124.   return 0;                   // must be containing path
  2125.  if ((slash = strpos(filespec, "/")) == -1) // if '/' is not found then it's
  2126.   return 1;                    // a filename
  2127.  
  2128.  space = strpos(filespec, " ");        // if space is not found then it is
  2129.  if (space == -1)               // a path
  2130.   return 0;
  2131.  if (space < slash)
  2132.   return 1;
  2133.  
  2134.  return 0;                   // not just a filename
  2135.  
  2136. }   // just_filename
  2137.  
  2138. //////////////////////////////////////////////////////////////////////////////
  2139. // show top level commands
  2140. //////////////////////////////////////////////////////////////////////////////
  2141.  
  2142. top_level_cmd()
  2143.  
  2144. {
  2145.    int min, sec, time_left;
  2146.    str min_str[6], sec_str[6], tmp_str[6];
  2147.  
  2148.    if (!sysop_call) {
  2149.       time_left = 3600 - (curtime() - grand_timer);
  2150.       min = time_left / 60;           // 60 secs == 1 minute
  2151.       sec = time_left - (min * 60);
  2152.  
  2153.       itos(min, tmp_str);            // convert minute to minute string
  2154.       if (min < 10) {
  2155.       min_str = "0";
  2156.       strcat(min_str, tmp_str);
  2157.       }
  2158.       else
  2159.       min_str = tmp_str;
  2160.  
  2161.       itos(sec, tmp_str);            // convert second to second string
  2162.       if (sec < 10) {
  2163.       sec_str = "0";
  2164.       strcat(sec_str, tmp_str);
  2165.       }
  2166.       else
  2167.       sec_str = tmp_str;
  2168.       host_send("^M^J");
  2169.       host_send("Online time left = ");
  2170.       host_send(min_str);
  2171.       host_send(" min ");
  2172.       host_send(sec_str);
  2173.       host_send(" sec ");
  2174.    }
  2175.  
  2176.    topcmd();
  2177.  
  2178. }   // top_level_command
  2179.  
  2180. //////////////////////////////////////////////////////////////////////////////
  2181. // enter message
  2182. //////////////////////////////////////////////////////////////////////////////
  2183.  
  2184. enter_message ()
  2185.  
  2186. {
  2187.     str strn[6], msgnbr[5], date_time_str[15];
  2188.     str trail[85], sub_string[85];
  2189.     str atchfile[15];
  2190.     int security, i, j, k, p, q, r, s, line_count, tmp_file, msg_file;
  2191.     int end_enter_option, msg_sent;
  2192.  
  2193.     itos(last_msg + 1, msgnbr);     // display new message number
  2194.     host_send("^M^Jmessage# : ");
  2195.     host_send(msgnbr);
  2196.     host_send("^M^J    from : ");       // display message writer
  2197.     host_send(current_caller_first);
  2198.     host_send(" ");
  2199.     host_send(current_caller_last);
  2200.     host_send("^M^J      to : ");       // asking for receiver
  2201.     host_input_strn(receiver, 30, 0);    // receiver is a global string variable
  2202.     if (finished_caller)        // finished_caller is set by host_input if
  2203.      return;            // connection is lost.
  2204.     if (strlen(receiver) == 0)        // no receiver specified
  2205.      return;            // end enter message function
  2206.     else{                // assume first name & last name
  2207.      strlower(receiver);
  2208.      setchr(receiver, 0, toupper(subchr(receiver, 0)));
  2209.      i = 0;
  2210.      while (subchr(receiver, i) != ' ' && i < strlen(receiver))
  2211.        ++i;
  2212.      if (i < strlen(receiver) - 1) {   // blank found
  2213.        ++i;                // make the next char upper case
  2214.        setchr(receiver, i, toupper(subchr(receiver, i)));
  2215.      }
  2216.     }
  2217.     host_send("      to : ");           // display modified receiver name
  2218.     host_send(receiver);
  2219.     host_send("^M^J   topic : ");       // asking for topic
  2220.     host_input_strn(topic, 30, 0);    // topic is also a global variable
  2221.     if (finished_caller)        // finished_caller is set by host_input if
  2222.      return;            // connection is lost.
  2223.     if (strlen(topic) == 0)        // no topic specified
  2224.      return;            // so end enter message function
  2225.     else
  2226.      strupper(topic);        // turn topic to upper case
  2227.     host_send("   topic : ");           // display modified receiver name
  2228.     host_send(topic);
  2229.     host_send("^M^Jsecurity : ");       // asking for security type
  2230.     if (ansi_mode)
  2231.        host_send("Private or pUblic? ");
  2232.     else
  2233.        host_send("(P)rivate or p(U)blic? ");
  2234.     host_input_strn(strn, 5, 0);
  2235.     if (finished_caller)        // finished_caller is set by host_input if
  2236.      return;            // connection is lost.
  2237.     if (strlen(strn) == 0)        // default security is public
  2238.     security = 'U';
  2239.     else
  2240.     security = toupper(subchr(strn, 0));
  2241.     if (security != 'P' && security != 'U') // illegal security code, then
  2242.     security = 'U';                     // turn it into public
  2243.     host_send("^M^J^M^J");
  2244.     host_send("Message begins, 80 lines max, empty line to end.^M^J");
  2245.     host_send("   [-------------------------------------------------------------------------]");
  2246.     tmp_file = fopen(temp_message, "r+");// open file for temporary storage in RAM disk
  2247.     trail = "";                        // clear garbage in trail
  2248.     //-------------------------------
  2249.     // entering 80 lines of text
  2250.     //-------------------------------
  2251.     line_count = 0;
  2252.     for (i = 1; i <= 80; ++i){           // entering 80 lines of text
  2253.      nextline:               // where Continue goto...
  2254.      itos(i, msgnbr);           // msgnbr is line number
  2255.      if (i < 10)               // if line number is 0 -- 9 then
  2256.         host_send("^M^J ");        // add one more space before number
  2257.      else
  2258.         host_send("^M^J");
  2259.      host_send(msgnbr);           // write line number
  2260.      host_send(": ");
  2261.      if (strlen(trail) > 0) {      // there is word from previous line
  2262.         host_send(trail);           // display it and copy it to
  2263.         substr(trail, 0, strlen(trail), linemsg);  // current line
  2264.         host_input_strn(linemsg, 74, strlen(trail)); // read current line
  2265.         trail = "";
  2266.      }
  2267.      else
  2268.         host_input_strn(linemsg, 74, 0);       // read current line
  2269.      if (finished_caller) {
  2270.           fclose(tmp_file);
  2271.           return;
  2272.      }
  2273.      if (strlen(linemsg) == 74) {       // line buffer is full
  2274.          j = strlen(linemsg) - 1;       // so remove the last word
  2275.          while (subchr(linemsg, j) != ' '    // move before last word
  2276.             && j > 0)
  2277.            --j;            // point j to the first space just before the last word
  2278.          k = j;               // k also points to space
  2279.          substr(linemsg, j + 1, 80, trail);  // copy the last word to trail
  2280.          while (j < strlen(linemsg)){     // erase the last word
  2281.            host_send_c(8);         // in current line on screen
  2282.            ++j;
  2283.          }
  2284.          setchr(linemsg, k, '^0');     // mark the end of string
  2285.      }
  2286.      if (strlen(linemsg) > 0) {        // if this line has contents
  2287.         strcat(linemsg, "^J");          // add LF to end-read
  2288.         fseek(tmp_file, (i - 1) * 80, 0);
  2289.         fputs(linemsg, tmp_file);        // write to file here
  2290.         ++line_count;
  2291.         fflush(tmp_file);            // write out to disk
  2292.      }
  2293.      else
  2294.         i = 100;                // force to end
  2295.     }       // enter 80 lines of message
  2296.  
  2297.     while (1) {
  2298.     end_enter_option = end_enter_msg();    // display end-enter prompt
  2299.     if (end_enter_option == 0) {        // if connection lost...
  2300.         fclose(tmp_file);            // close temporary file
  2301.         return;                // then end do_message
  2302.     }
  2303.     //---------------------------------------
  2304.     // Abort this msg-entering session
  2305.     //---------------------------------------
  2306.     if (end_enter_option == 'A') {          // Abort this message?
  2307.          host_send("^M^JAbort this message ? (Y/N)");
  2308.          host_input_strn(strn, 3, 0);
  2309.          host_send("^M^J");
  2310.          if (toupper(subchr(strn, 0)) == 'Y') {
  2311.          fclose(tmp_file);
  2312.          return;
  2313.          }
  2314.     }
  2315.     //---------------------------------------
  2316.     // Continue this session
  2317.     //---------------------------------------
  2318.     else if (end_enter_option == 'C') {     // Continue?
  2319.          host_send("^M^J");
  2320.          trail = "";
  2321.          i = line_count + 1;
  2322.          goto nextline;
  2323.     }
  2324.     //---------------------------------------
  2325.     // Insert a line into the message
  2326.     //---------------------------------------
  2327.     else if (end_enter_option == 'I') {     // Insert a line
  2328.          host_send("Insert which line # ");
  2329.          host_input_strn(strn, 4, 0);
  2330.          host_send("^M^J");
  2331.          if (finished_caller)        // finished_caller is set by host_input if
  2332.          return;            // connection is lost.
  2333.          i = stoi(strn);
  2334.          if (line_count < 80 && i <= line_count && i >= 1) {   // valid line number to insert
  2335.         if (i < 10)
  2336.             host_send("^M^J ");
  2337.         else
  2338.             host_send("^M^J");
  2339.         host_send(strn);
  2340.         host_send(": ");
  2341.         host_input_strn(trail, 73, 0);
  2342.         if (finished_caller)           // finished_caller is set by host_input if
  2343.             return;               // connection is lost.
  2344.         strcat(trail, "^J");
  2345.         j = line_count;            // old number of lines
  2346.         while (j >= i) {
  2347.             fseek(tmp_file, (j - 1) * 80, 0);
  2348.             fgets(linemsg, 80, tmp_file);   // read line into linemsg
  2349.             strcat(linemsg, "^J");          // add LF to end-of-line
  2350.             fseek(tmp_file, j * 80, 0);
  2351.             fputs(linemsg, tmp_file);        // write to file here
  2352.             --j;
  2353.         }
  2354.         fseek(tmp_file, (i - 1) * 80, 0);
  2355.         fputs(trail, tmp_file);
  2356.         ++line_count;                // increment line count
  2357.         host_send("^M^JLine #");
  2358.         host_send(strn);
  2359.         host_send(" has been inserted.^M^J");
  2360.          }    // valid line number to delete
  2361.          else if (line_count >= 80)
  2362.         host_send("^M^JMax lines entered.  No insertion allowed.^M^J");
  2363.     }
  2364.     //---------------------------------------
  2365.     // Delete a line in this message
  2366.     //---------------------------------------
  2367.     else if (end_enter_option == 'D') {     // Delete a line
  2368.          host_send("Delete which line # ");
  2369.          host_input_strn(strn, 4, 0);
  2370.          host_send("^M^J");
  2371.          if (finished_caller)        // finished_caller is set by host_input if
  2372.          return;            // connection is lost.
  2373.          i = stoi(strn);
  2374.          if (i <= line_count && i >= 1) {    // valid line number to delete
  2375.         ++i;
  2376.         while (i <= line_count) {
  2377.             fseek(tmp_file, (i - 1) * 80, 0);
  2378.             fgets(linemsg, 80, tmp_file);   // read line into linemsg
  2379.             strcat(linemsg, "^J");          // add LF to end-of-line
  2380.             fseek(tmp_file, (i - 2) * 80, 0);
  2381.             fputs(linemsg, tmp_file);        // write to file here
  2382.             ++i;
  2383.         }
  2384.         --line_count;                // decrement line count
  2385.         host_send("^M^JLine #");
  2386.         host_send(strn);
  2387.         host_send(" is deleted.^M^J");
  2388.          }    // valid line number to delete
  2389.     }
  2390.     //---------------------------------------
  2391.     // Edit a line in this message
  2392.     //---------------------------------------
  2393.     else if (end_enter_option == 'E') {     // Edit which line
  2394.          host_send("Edit which line # ");
  2395.          host_input_strn(strn, 4, 0);
  2396.          host_send("^M^J");
  2397.          if (finished_caller)        // finished_caller is set by host_input if
  2398.          return;            // connection is lost.
  2399.          i = stoi(strn);
  2400.          if (i <= line_count && i >= 1) {    // valid line number to edit
  2401.         fseek(tmp_file, (i - 1) * 80, 0);
  2402.         fgets(linemsg, 80, tmp_file);    // read line into linemsg
  2403.         host_send(strn);        // display line# and content
  2404.         host_send(": ");
  2405.         host_send(linemsg);
  2406.         host_send("^M^JEdit with:  /original string/new string/^M^J");
  2407.         host_input_strn(trail, 74, 0);
  2408.         j = 0;
  2409.         while (subchr(trail, j) != '/' && j < strlen(trail))
  2410.            ++j;
  2411.         k = strlen(trail) - 1;
  2412.         while (subchr(trail, k) != '/' && k >= 0)
  2413.            --k;
  2414.         //---------------------------------------
  2415.         // j --> first '/'
  2416.         // k --> last '/'
  2417.         //---------------------------------------
  2418.         if (j < k && j < strlen(trail) && k >= 0) {
  2419.            p = j + 1;
  2420.            while (subchr(trail, p) != '/' && p < k)
  2421.             ++p;
  2422.            if (p < k){           // p --> middle '/'
  2423.             substr(trail, j + 1, p - j  - 1, editline);
  2424.             q = (strposi(linemsg, editline, 0));     // search old str
  2425.             if (q >= 0) {  // substring to be changed is found...
  2426.                  s = strlen(editline);    // s = old string length
  2427.                  editline = "";
  2428.                  i = 0;    // running pointer i
  2429.                  for (r = 0; r < q; ++r) {       // unchanged part 1
  2430.                   setchr(editline, i, subchr(linemsg, r));
  2431.                   ++i;
  2432.                  }
  2433.                  for (r = p + 1; r < k; ++r) { // new string
  2434.                   setchr(editline, i, subchr(trail, r));
  2435.                   ++i;
  2436.                  }
  2437.                  for (r = q + s; r < strlen(linemsg); ++r){ // unchanged part 2
  2438.                   setchr(editline, i, subchr(linemsg, r));
  2439.                   ++i;
  2440.                  }
  2441.                  linemsg = editline;
  2442.                  host_send("^M^J");
  2443.                  host_send(linemsg); // edit complete of this line
  2444.                  i = stoi(strn);
  2445.                  fseek(tmp_file, (i - 1) * 80, 0);
  2446.                  fputs(linemsg, tmp_file);
  2447.                  fputc('^J', tmp_file);
  2448.             }    // successful search for old string
  2449.            }    // valid middle slash
  2450.         }  // valid format
  2451.          }       // valid line number
  2452.     }
  2453.     //---------------------------------------
  2454.     // Change topic of this message
  2455.     //---------------------------------------
  2456.     else if (end_enter_option == 'T') {     // Topic changed to?
  2457.          trail = topic;
  2458.          host_send("Old topic : ");
  2459.          host_send(topic);
  2460.          host_send("^M^JNew topic : ");
  2461.          host_input_strn(topic, 30, 0);
  2462.          if (finished_caller)    // finished_caller is set by host_input if
  2463.          return;        // connection is lost.
  2464.          if (strlen(topic) == 0)
  2465.          topic = trail;
  2466.          else
  2467.          strupper(topic);    // turn topic to upper case
  2468.          host_send("New topic : "); // display modified receiver name
  2469.          host_send(topic);
  2470.     }
  2471.     //---------------------------------------
  2472.     // List this message
  2473.     //---------------------------------------
  2474.     else if (end_enter_option == 'L') {     // List message
  2475.          host_send("Starting from line # ");
  2476.          host_input_strn(strn, 4, 0);
  2477.          host_send("^M^J");
  2478.          if (finished_caller)        // finished_caller is set by host_input if
  2479.          return;            // connection is lost.
  2480.          i = stoi(strn);
  2481.          if (i == 0)            // if no number entered
  2482.          i = 1;             // then start from line# 1
  2483.          if (i <= line_count && i >= 1) {    // valid line number
  2484.         while (i <= line_count) {
  2485.             fseek(tmp_file, (i - 1) * 80, 0);
  2486.             fgets(linemsg, 80, tmp_file); // read into linemsg
  2487.             itos(i, msgnbr);          // msgnbr is line number
  2488.             if (i < 10)           // if line number is 0 -- 9 then
  2489.                host_send("^M^J ");        // add one more space before number
  2490.             else
  2491.                host_send("^M^J");
  2492.             host_send(msgnbr);          // write line number
  2493.             host_send(": ");
  2494.             host_send(linemsg);       // and display it.
  2495.             ++i;
  2496.         }
  2497.         host_send("^M^J");
  2498.          }
  2499.     }
  2500.     //---------------------------------------
  2501.     // Save this message
  2502.     //---------------------------------------
  2503.     else if (end_enter_option == 'S') {     // Save this message
  2504.          ++last_msg;            // increment # of last_msg
  2505.          if (last_msg == 1)         // this is the very first msg
  2506.          first_msg = 1;         // of this system!
  2507.          itos(last_msg, tmp_fname);     // tmp_fname used as temporary str
  2508.          if (last_msg < 10)         // last_msg == 0..9
  2509.           msgnbr = "000";               // so add three leading zeros
  2510.          else if (last_msg < 100)        // last_msg == 10..99
  2511.           msgnbr = "00";                // so add two leading zeros
  2512.          else if (last_msg < 1000)        // last_msg == 100..999
  2513.           msgnbr = "0";                 // add one leading zero
  2514.          strcat(msgnbr, tmp_fname);     // now msgnbr is 4-digit str
  2515.          tmp_fname = host_message;        // get default msg directory
  2516.          strcat(tmp_fname, msgnbr);     // then add 4-digit str as file name
  2517.  
  2518.          msg_file = fopen(tmp_fname, "a");  // open msg file with 4-digit file name
  2519.          itos(curtime(), date_time_str);
  2520.          fputs(date_time_str, msg_file); fputc('^J', msg_file);
  2521.          fputs(current_caller_first, msg_file);  fputc('^J', msg_file);
  2522.          fputs(current_caller_last, msg_file); fputc('^J', msg_file);
  2523.          fputs(receiver, msg_file); fputc('^J', msg_file);
  2524.          fputs(topic, msg_file); fputc('^J', msg_file);
  2525.          fputc(security, msg_file);
  2526.          for (i = 1; i <= line_count; ++i){
  2527.           fseek(tmp_file, (i - 1) * 80, 0);
  2528.           fgets(linemsg, 80, tmp_file); // read into linemsg
  2529.           fputs(linemsg, msg_file);
  2530.           fputc('^J', msg_file);
  2531.          }
  2532.          fclose(msg_file);
  2533.          fclose(tmp_file);
  2534.  
  2535.          fstlst();
  2536.  
  2537.          return;
  2538.     }     // msg saved.
  2539.     }     // while, another endless loop
  2540. }   // enter message
  2541.  
  2542.  
  2543. //////////////////////////////////////////////////////////////////////////////
  2544. //
  2545. // reply message
  2546. // input: reply_number is the message number to which to reply
  2547. //
  2548. //////////////////////////////////////////////////////////////////////////////
  2549.  
  2550. reply_message (int reply_number)
  2551.  
  2552. {
  2553.     str strn[6], msgnbr[5], date_time_str[15];
  2554.     str trail[85], sub_string[85];
  2555.     str atchfile[15];
  2556.     int security, i, j, k, p, q, r, s, line_count, tmp_file, msg_file;
  2557.     int idx_file;
  2558.     int end_enter_option, msg_sent;
  2559.  
  2560.     host_send("^M^JThis is reply to msg# ");
  2561.     if (ansi_mode)
  2562.     host_send("");
  2563.     itos(reply_number, msgnbr);
  2564.     host_send(msgnbr);
  2565.     if (ansi_mode)
  2566.        host_send("");
  2567.     host_send("^M^J");
  2568.     itos(last_msg + 1, msgnbr);     // display new message number
  2569.     host_send("^M^Jmessage# : ");
  2570.     host_send(msgnbr);
  2571.     host_send("^M^J    from : ");       // display message writer
  2572.     host_send(current_caller_first);
  2573.     host_send(" ");
  2574.     host_send(current_caller_last);
  2575.  
  2576.     host_send("^M^J      to : ");       // asking for receiver
  2577.     receiver = name_to_reply;        // get name to reply to
  2578.     host_send(receiver);
  2579.  
  2580.     topic = topic_to_reply;        // get old topic to reply to
  2581.     host_send("^M^J   topic : ");       // asking for topic
  2582.     host_send(topic);            // topic is also a global variable
  2583.     host_input_strn(topic, 30, strlen(topic));     // and continue...
  2584.     if (finished_caller)        // finished_caller is set by host_input if
  2585.      return;            // connection is lost.
  2586.     if (strlen(topic) == 0)        // no topic specified
  2587.      return;            // so end enter message function
  2588.     else
  2589.      strupper(topic);        // turn topic to upper case
  2590.     host_send("   topic : ");           // display modified receiver name
  2591.     host_send(topic);
  2592.     host_send("^M^Jsecurity : ");       // asking for security type
  2593.     if (ansi_mode)
  2594.        host_send("Private or pUblic? ");
  2595.     else
  2596.        host_send("(P)rivate or p(U)blic? ");
  2597.     host_input_strn(strn, 5, 0);
  2598.     if (finished_caller)        // finished_caller is set by host_input if
  2599.      return;            // connection is lost.
  2600.     if (strlen(strn) == 0)        // default security is public
  2601.     security = 'U';
  2602.     else
  2603.     security = toupper(subchr(strn, 0));
  2604.     if (security != 'P' && security != 'U') // illegal security code, then
  2605.     security = 'U';                     // turn it into public
  2606.     host_send("^M^J^M^J");
  2607.     host_send("Message begins, 80 lines max, empty line to end.^M^J");
  2608.     host_send("   [-------------------------------------------------------------------------]");
  2609.     tmp_file = fopen(temp_message, "r+");// open file for temporary storage in RAM disk
  2610.     trail = "";                        // clear garbage in trail
  2611.     //-------------------------------
  2612.     // entering 80 lines of text
  2613.     //-------------------------------
  2614.     line_count = 0;
  2615.     for (i = 1; i <= 80; ++i){           // entering 80 lines of text
  2616.      nextline:               // where Continue goto...
  2617.      itos(i, msgnbr);           // msgnbr is line number
  2618.      if (i < 10)               // if line number is 0 -- 9 then
  2619.         host_send("^M^J ");        // add one more space before number
  2620.      else
  2621.         host_send("^M^J");
  2622.      host_send(msgnbr);           // write line number
  2623.      host_send(": ");
  2624.      if (strlen(trail) > 0) {      // there is word from previous line
  2625.         host_send(trail);           // display it and copy it to
  2626.         substr(trail, 0, strlen(trail), linemsg);  // current line
  2627.         host_input_strn(linemsg, 74, strlen(trail)); // read current line
  2628.         trail = "";
  2629.      }
  2630.      else
  2631.         host_input_strn(linemsg, 74, 0);       // read current line
  2632.      if (finished_caller) {
  2633.           fclose(tmp_file);
  2634.           return;
  2635.      }
  2636.      if (strlen(linemsg) == 74) {       // line buffer is full
  2637.          j = strlen(linemsg) - 1;       // so remove the last word
  2638.          while (subchr(linemsg, j) != ' '    // move before last word
  2639.             && j > 0)
  2640.            --j;            // point j to the first space just before the last word
  2641.          k = j;               // k also points to space
  2642.          substr(linemsg, j + 1, 80, trail);  // copy the last word to trail
  2643.          while (j < strlen(linemsg)){     // erase the last word
  2644.            host_send_c(8);         // in current line on screen
  2645.            ++j;
  2646.          }
  2647.          setchr(linemsg, k, '^0');     // mark the end of string
  2648.      }
  2649.      if (strlen(linemsg) > 0) {        // if this line has contents
  2650.         strcat(linemsg, "^J");          // add LF to end-read
  2651.         fseek(tmp_file, (i - 1) * 80, 0);
  2652.         fputs(linemsg, tmp_file);        // write to file here
  2653.         ++line_count;
  2654.         fflush(tmp_file);            // write out to disk
  2655.      }
  2656.      else
  2657.         i = 100;                // force to end
  2658.     }       // enter 80 lines of message
  2659.  
  2660.     while (1) {
  2661.     end_enter_option = end_enter_msg();    // display end-enter prompt
  2662.     if (end_enter_option == 0) {        // if connection lost...
  2663.         fclose(tmp_file);            // close temporary file
  2664.         return;                // then end do_message
  2665.     }
  2666.     //---------------------------------------
  2667.     // Abort this msg-entering session
  2668.     //---------------------------------------
  2669.     if (end_enter_option == 'A') {          // Abort this message?
  2670.          host_send("^M^JAbort this message ? (Y/N)");
  2671.          host_input_strn(strn, 3, 0);
  2672.          host_send("^M^J");
  2673.          if (toupper(subchr(strn, 0)) == 'Y') {
  2674.          fclose(tmp_file);
  2675.          return;
  2676.          }
  2677.     }
  2678.     //---------------------------------------
  2679.     // Continue this session
  2680.     //---------------------------------------
  2681.     else if (end_enter_option == 'C') {     // Continue?
  2682.          host_send("^M^J");
  2683.          trail = "";
  2684.          i = line_count + 1;
  2685.          goto nextline;
  2686.     }
  2687.     //---------------------------------------
  2688.     // Insert a line into the message
  2689.     //---------------------------------------
  2690.     else if (end_enter_option == 'I') {     // Insert a line
  2691.          host_send("Insert which line # ");
  2692.          host_input_strn(strn, 4, 0);
  2693.          host_send("^M^J");
  2694.          if (finished_caller)        // finished_caller is set by host_input if
  2695.          return;            // connection is lost.
  2696.          i = stoi(strn);
  2697.          if (line_count < 80 && i <= line_count && i >= 1) {   // valid line number to insert
  2698.         if (i < 10)
  2699.             host_send("^M^J ");
  2700.         else
  2701.             host_send("^M^J");
  2702.         host_send(strn);
  2703.         host_send(": ");
  2704.         host_input_strn(trail, 73, 0);
  2705.         if (finished_caller)           // finished_caller is set by host_input if
  2706.             return;               // connection is lost.
  2707.         strcat(trail, "^J");
  2708.         j = line_count;            // old number of lines
  2709.         while (j >= i) {
  2710.             fseek(tmp_file, (j - 1) * 80, 0);
  2711.             fgets(linemsg, 80, tmp_file);   // read line into linemsg
  2712.             strcat(linemsg, "^J");          // add LF to end-of-line
  2713.             fseek(tmp_file, j * 80, 0);
  2714.             fputs(linemsg, tmp_file);        // write to file here
  2715.             --j;
  2716.         }
  2717.         fseek(tmp_file, (i - 1) * 80, 0);
  2718.         fputs(trail, tmp_file);
  2719.         ++line_count;                // increment line count
  2720.         host_send("^M^JLine #");
  2721.         host_send(strn);
  2722.         host_send(" has been inserted.^M^J");
  2723.          }    // valid line number to delete
  2724.          else if (line_count >= 80)
  2725.         host_send("^M^JMax lines entered.  No insertion allowed.^M^J");
  2726.     }
  2727.     //---------------------------------------
  2728.     // Delete a line in this message
  2729.     //---------------------------------------
  2730.     else if (end_enter_option == 'D') {     // Delete a line
  2731.          host_send("Delete which line # ");
  2732.          host_input_strn(strn, 4, 0);
  2733.          host_send("^M^J");
  2734.          if (finished_caller)        // finished_caller is set by host_input if
  2735.          return;            // connection is lost.
  2736.          i = stoi(strn);
  2737.          if (i <= line_count && i >= 1) {    // valid line number to delete
  2738.         ++i;
  2739.         while (i <= line_count) {
  2740.             fseek(tmp_file, (i - 1) * 80, 0);
  2741.             fgets(linemsg, 80, tmp_file);   // read line into linemsg
  2742.             strcat(linemsg, "^J");          // add LF to end-of-line
  2743.             fseek(tmp_file, (i - 2) * 80, 0);
  2744.             fputs(linemsg, tmp_file);        // write to file here
  2745.             ++i;
  2746.         }
  2747.         --line_count;                // decrement line count
  2748.         host_send("^M^JLine #");
  2749.         host_send(strn);
  2750.         host_send(" is deleted.^M^J");
  2751.          }    // valid line number to delete
  2752.     }
  2753.     //---------------------------------------
  2754.     // Edit a line in this message
  2755.     //---------------------------------------
  2756.     else if (end_enter_option == 'E') {     // Edit which line
  2757.          host_send("Edit which line # ");
  2758.          host_input_strn(strn, 4, 0);
  2759.          host_send("^M^J");
  2760.          if (finished_caller)        // finished_caller is set by host_input if
  2761.          return;            // connection is lost.
  2762.          i = stoi(strn);
  2763.          if (i <= line_count && i >= 1) {    // valid line number to edit
  2764.         fseek(tmp_file, (i - 1) * 80, 0);
  2765.         fgets(linemsg, 80, tmp_file);    // read line into linemsg
  2766.         host_send(strn);        // display line# and content
  2767.         host_send(": ");
  2768.         host_send(linemsg);
  2769.         host_send("^M^JEdit with:  /original string/new string/^M^J");
  2770.         host_input_strn(trail, 74, 0);
  2771.         j = 0;
  2772.         while (subchr(trail, j) != '/' && j < strlen(trail))
  2773.            ++j;
  2774.         k = strlen(trail) - 1;
  2775.         while (subchr(trail, k) != '/' && k >= 0)
  2776.            --k;
  2777.         //---------------------------------------
  2778.         // j --> first '/'
  2779.         // k --> last '/'
  2780.         //---------------------------------------
  2781.         if (j < k && j < strlen(trail) && k >= 0) {
  2782.            p = j + 1;
  2783.            while (subchr(trail, p) != '/' && p < k)
  2784.             ++p;
  2785.            if (p < k){           // p --> middle '/'
  2786.             substr(trail, j + 1, p - j  - 1, editline);
  2787.             q = (strposi(linemsg, editline, 0));     // search old str
  2788.             if (q >= 0) {  // substring to be changed is found...
  2789.                  s = strlen(editline);    // s = old string length
  2790.                  editline = "";
  2791.                  i = 0;    // running pointer i
  2792.                  for (r = 0; r < q; ++r) {       // unchanged part 1
  2793.                   setchr(editline, i, subchr(linemsg, r));
  2794.                   ++i;
  2795.                  }
  2796.                  for (r = p + 1; r < k; ++r) { // new string
  2797.                   setchr(editline, i, subchr(trail, r));
  2798.                   ++i;
  2799.                  }
  2800.                  for (r = q + s; r < strlen(linemsg); ++r){ // unchanged part 2
  2801.                   setchr(editline, i, subchr(linemsg, r));
  2802.                   ++i;
  2803.                  }
  2804.                  linemsg = editline;
  2805.                  host_send("^M^J");
  2806.                  host_send(linemsg); // edit complete of this line
  2807.                  i = stoi(strn);
  2808.                  fseek(tmp_file, (i - 1) * 80, 0);
  2809.                  fputs(linemsg, tmp_file);
  2810.                  fputc('^J', tmp_file);
  2811.             }    // successful search for old string
  2812.            }    // valid middle slash
  2813.         }  // valid format
  2814.          }       // valid line number
  2815.     }
  2816.     //---------------------------------------
  2817.     // Change topic of this message
  2818.     //---------------------------------------
  2819.     else if (end_enter_option == 'T') {     // Topic changed to?
  2820.          trail = topic;
  2821.          host_send("Old topic : ");
  2822.          host_send(topic);
  2823.          host_send("^M^JNew topic : ");
  2824.          host_input_strn(topic, 30, 0);
  2825.          if (finished_caller)    // finished_caller is set by host_input if
  2826.          return;        // connection is lost.
  2827.          if (strlen(topic) == 0)
  2828.          topic = trail;
  2829.          else
  2830.          strupper(topic);    // turn topic to upper case
  2831.          host_send("New topic : "); // display modified receiver name
  2832.          host_send(topic);
  2833.     }
  2834.     //---------------------------------------
  2835.     // List this message
  2836.     //---------------------------------------
  2837.     else if (end_enter_option == 'L') {     // List message
  2838.          host_send("Starting from line # ");
  2839.          host_input_strn(strn, 4, 0);
  2840.          host_send("^M^J");
  2841.          if (finished_caller)        // finished_caller is set by host_input if
  2842.          return;            // connection is lost.
  2843.          i = stoi(strn);
  2844.          if (i == 0)            // if no number entered
  2845.          i = 1;             // then start from line# 1
  2846.          if (i <= line_count && i >= 1) {    // valid line number
  2847.         while (i <= line_count) {
  2848.             fseek(tmp_file, (i - 1) * 80, 0);
  2849.             fgets(linemsg, 80, tmp_file); // read into linemsg
  2850.             itos(i, msgnbr);          // msgnbr is line number
  2851.             if (i < 10)           // if line number is 0 -- 9 then
  2852.                host_send("^M^J ");        // add one more space before number
  2853.             else
  2854.                host_send("^M^J");
  2855.             host_send(msgnbr);          // write line number
  2856.             host_send(": ");
  2857.             host_send(linemsg);       // and display it.
  2858.             ++i;
  2859.         }
  2860.         host_send("^M^J");
  2861.          }
  2862.     }
  2863.     //---------------------------------------
  2864.     // Save this message
  2865.     //---------------------------------------
  2866.     else if (end_enter_option == 'S') {     // Save this message
  2867.          ++last_msg;            // increment # of last_msg
  2868.          if (last_msg == 1)         // this is the very first msg
  2869.          first_msg = 1;         // of this system!
  2870.          itos(last_msg, tmp_fname);     // tmp_fname used as temporary str
  2871.          if (last_msg < 10)         // last_msg == 0..9
  2872.           msgnbr = "000";               // so add three leading zeros
  2873.          else if (last_msg < 100)        // last_msg == 10..99
  2874.           msgnbr = "00";                // so add two leading zeros
  2875.          else if (last_msg < 1000)        // last_msg == 100..999
  2876.           msgnbr = "0";                 // add one leading zero
  2877.          strcat(msgnbr, tmp_fname);     // now msgnbr is 4-digit str
  2878.          tmp_fname = host_message;        // get default msg directory
  2879.          strcat(tmp_fname, msgnbr);     // then add 4-digit str as file name
  2880.          msg_file = fopen(tmp_fname, "a");  // open msg file with 4-digit file name
  2881.          itos(curtime(), date_time_str);
  2882.          fputs(date_time_str, msg_file); fputc('^J', msg_file);
  2883.          fputs(current_caller_first, msg_file);  fputc('^J', msg_file);
  2884.          fputs(current_caller_last, msg_file); fputc('^J', msg_file);
  2885.          fputs(receiver, msg_file); fputc('^J', msg_file);
  2886.          fputs(topic, msg_file); fputc('^J', msg_file);
  2887.          fputc(security, msg_file);
  2888.          for (i = 1; i <= line_count; ++i){
  2889.           fseek(tmp_file, (i - 1) * 80, 0);
  2890.           fgets(linemsg, 80, tmp_file); // read into linemsg
  2891.           fputs(linemsg, msg_file);
  2892.           fputc('^J', msg_file);
  2893.          }
  2894.          fclose(msg_file);
  2895.          fclose(tmp_file);
  2896.  
  2897.          fstlst();
  2898.  
  2899.          strcat(tmp_fname, ".IDX");         // message index
  2900.          idx_file = fopen(tmp_fname, "a");  // open index file
  2901.          fseek(idx_file, 0, 2);        // move to end-of-file
  2902.          itos(reply_number, msgnbr);    // then write down which msg#
  2903.          fputs(msgnbr, idx_file);        // is receiving this reply.
  2904.          fputc('^J', idx_file);
  2905.          fclose(idx_file);
  2906.  
  2907.          itos(reply_number, tmp_fname);    // open the replied msg index
  2908.          if (reply_number < 10)        // to store forward reference.
  2909.           msgnbr = "000";               // For example, if replied msg
  2910.          else if (reply_number < 100)    // is #3 and replying msg is
  2911.           msgnbr = "00";                // #5 then reply_number.IDX has
  2912.          else if (reply_number < 1000)    // #5 while the new message's
  2913.           msgnbr = "0";                 // index has #3.  So that when
  2914.          strcat(msgnbr, tmp_fname);     // a msg is diaplayed, system
  2915.          tmp_fname = host_message;        // can display "Also see..."
  2916.          strcat(tmp_fname, msgnbr);     // information for convenient
  2917.          strcat(tmp_fname, ".IDX");         // reference.
  2918.          idx_file = fopen(tmp_fname, "a");
  2919.          fseek(idx_file, 0, 2);
  2920.          itos(last_msg, msgnbr);
  2921.          fputs(msgnbr, idx_file);
  2922.          fputc('^J', idx_file);
  2923.          fclose(idx_file);
  2924.  
  2925.          return;
  2926.     }     // msg saved.
  2927.     }     // while, another endless loop
  2928. }   // reply message
  2929.  
  2930. //////////////////////////////////////////////////////////////////////////////
  2931. // end enter message prompt
  2932. // return value: 0 if connection is lost
  2933. //         option represented by a letter
  2934. //////////////////////////////////////////////////////////////////////////////
  2935.  
  2936. end_enter_msg ()
  2937.  
  2938. {
  2939.    str strn[10];
  2940.    int option;
  2941.  
  2942.    do {
  2943.       endenter();
  2944.       host_input_strn(strn, 8, 0);
  2945.    } while (strlen(strn) == 0);
  2946.  
  2947.    option = toupper(subchr(strn, 0));
  2948.    host_send("^M^J");
  2949.  
  2950.    if (finished_caller)      // finished_caller is set by host_input if
  2951.       return 0;          // connection is lost --> return 0.
  2952.    else
  2953.       return option;         // option choose --> return it.
  2954.  
  2955. }   // end_entering message
  2956.  
  2957.  
  2958. //////////////////////////////////////////////////////////////////////////////
  2959. // check_message
  2960. //////////////////////////////////////////////////////////////////////////////
  2961.  
  2962. check_message (int i)
  2963.  
  2964. {
  2965.    str msgnbr[5], strn[5], date_time_str[15];
  2966.    int msg_file, ismsg = 0;
  2967.  
  2968.    tmp_fname = host_message;     // get message directory
  2969.    if (i < 10)             // if message number is smaller than 10 then
  2970.     msgnbr = "000";          // add three zeros for file name matching.
  2971.    else if (i < 100)
  2972.     msgnbr = "00";
  2973.    else if (i < 1000)
  2974.     msgnbr = "0";
  2975.    itos(i, strn);         // convert message number to number string
  2976.    strcat(msgnbr, strn);     // add zeros before this number
  2977.    strcat(tmp_fname, msgnbr);     // now tmp_fname got the path & file name
  2978.    msg_file = fopen(tmp_fname, "r"); // open message file for reading only
  2979.    if (msg_file != 0){         // file is opened successfully
  2980.     fgets(date_time_str, 20, msg_file);    // read date/time string
  2981.     fgets(msg_caller_first, 20, msg_file); // read sender's first name
  2982.     fgets(msg_caller_last, 20, msg_file);  // and his/her last name
  2983.     fgets(receiver, 35, msg_file);           // and receiver's full name
  2984.  
  2985.     //---------------------------------------------
  2986.     // this message is written by current caller
  2987.     //---------------------------------------------
  2988.     if (!strcmpi(msg_caller_first, current_caller_first) &&
  2989.         !strcmpi(msg_caller_last, current_caller_last)) {
  2990.         host_send("[");
  2991.         host_send(strn);
  2992.         host_send("]  ");
  2993.         ismsg = 1;
  2994.     }
  2995.     //---------------------------------------------
  2996.     // this message is for current caller
  2997.     //---------------------------------------------
  2998.     else if (!strcmpi(receiver, current_caller_full)) {
  2999.         if (i > last_read){        // assume caller never saw this msg
  3000.           if (ansi_mode) {
  3001.          host_send("");       // so highlighten it.
  3002.          host_send(strn);
  3003.          host_send("  ");
  3004.           }
  3005.           else {
  3006.          host_send(strn);
  3007.          host_send("  ");
  3008.           }
  3009.         }
  3010.         else{
  3011.           host_send(strn);
  3012.           host_send("  ");
  3013.         }
  3014.         ismsg = 1;
  3015.     }
  3016.     fclose(msg_file);
  3017.    }   // message file open successfully
  3018.    return ismsg;
  3019. }   // check_message
  3020.  
  3021. //////////////////////////////////////////////////////////////////////////////
  3022. // scan_message
  3023. // input value i is message number to scan
  3024. //////////////////////////////////////////////////////////////////////////////
  3025.  
  3026. scan_message(int i)
  3027.  
  3028. {
  3029.    str msgnbr[5], strn[5], date_time_str[20];
  3030.    int msg_file, date_time, scanned = 0, security;
  3031.  
  3032.    tmp_fname = host_message;     // get message directory
  3033.    if (i < 10)             // if message number is smaller than 10 then
  3034.     msgnbr = "000";          // add three zeros for file name matching.
  3035.    else if (i < 100)
  3036.     msgnbr = "00";
  3037.    else if (i < 1000)
  3038.     msgnbr = "0";
  3039.    itos(i, strn);         // convert message number to number string
  3040.    strcat(msgnbr, strn);     // add zeros before this number
  3041.    strcat(tmp_fname, msgnbr);     // now tmp_fname got the path & file name
  3042.    msg_file = fopen(tmp_fname, "r"); // open message file for reading only
  3043.    if (msg_file != 0){         // file is opened successfully
  3044.     fgets(date_time_str, 20, msg_file);    // read msg creating date/time
  3045.     date(stoi(date_time_str), date_str);
  3046.     time(stoi(date_time_str), time_str);
  3047.     fgets(msg_caller_first, 20, msg_file); // read sender's first name
  3048.     fgets(msg_caller_last, 20, msg_file);  // and his/her last name
  3049.     fgets(receiver, 35, msg_file);           // and receiver's full name
  3050.     fgets(topic, 35, msg_file);           // and the topic
  3051.     security = fgetc(msg_file);           // and security type
  3052.     //-------------------------------------------------------
  3053.     // Everybody can see this message title in a scan
  3054.     //-------------------------------------------------------
  3055.     host_send("^M^J");
  3056.  
  3057.     host_send("Message No: ");   // message number, date, and time
  3058.     if (ansi_mode)
  3059.         host_send("");
  3060.     host_send(strn);
  3061.     if (ansi_mode)
  3062.         host_send(".");
  3063.     host_send("     ");
  3064.     host_send(date_str);  host_send("  ");  host_send(time_str);
  3065.     host_send("     ");
  3066.     if (ansi_mode)
  3067.        host_send("");
  3068.  
  3069.     if ((security & 127) == 'U')  // display security status of this msg
  3070.         host_send("(Public)");
  3071.     else if ((security & 127) == 'P')
  3072.         host_send("(Private)");
  3073.     if ((security & 128) == 128)
  3074.         host_send("     (Received)");
  3075.     if (ansi_mode)
  3076.        host_send("");
  3077.     host_send("^M^J");
  3078.     host_send("      From: ");    // the sender of the message
  3079.     if (ansi_mode)
  3080.        host_send("");
  3081.     host_send(msg_caller_first);  host_send(" ");
  3082.     host_send(msg_caller_last);
  3083.     if (ansi_mode)
  3084.         host_send("");
  3085.     host_send("^M^J");            // the receiver
  3086.     host_send("        To: ");
  3087.     if (ansi_mode)
  3088.         host_send("");
  3089.     host_send(receiver);
  3090.     if (ansi_mode)
  3091.         host_send("");
  3092.     host_send("^M^J");            // topic of this message
  3093.     host_send("     Topic: ");
  3094.     if (ansi_mode)
  3095.         host_send("");
  3096.     host_send(topic);
  3097.     if (ansi_mode)
  3098.         host_send("");
  3099.     host_send("^M^J");    // contents of this message now...
  3100.     fclose(msg_file);
  3101.     scanned = 1;
  3102.    }   // message file open successfully
  3103.    return scanned;
  3104. }   // scan_message
  3105.  
  3106. //////////////////////////////////////////////////////////////////////////////
  3107. // delete_message
  3108. // input value i is message number to delete
  3109. //////////////////////////////////////////////////////////////////////////////
  3110.  
  3111. delete_message (int i)
  3112.  
  3113. {
  3114.    str msgnbr[5], strn[5], cmdstr[50], date_time_str[15];
  3115.    int msg_file, security, date_time;
  3116.    int lines_sent, ichar, isread = 0;
  3117.  
  3118.    tmp_fname = host_message;     // get message directory
  3119.    if (i < 10)             // if message number is smaller than 10 then
  3120.     msgnbr = "000";          // add three zeros for file name matching.
  3121.    else if (i < 100)
  3122.     msgnbr = "00";
  3123.    else if (i < 1000)
  3124.     msgnbr = "0";
  3125.    itos(i, strn);         // convert message number to number string
  3126.    strcat(msgnbr, strn);     // add zeros before this number
  3127.    strcat(tmp_fname, msgnbr);     // now tmp_fname got the path & file name
  3128.    msg_file = fopen(tmp_fname, "r"); // open message file for reading only
  3129.    if (msg_file != 0){         // file is opened successfully
  3130.     fgets(date_time_str, 20, msg_file);    // read date/time of msg
  3131.     fgets(msg_caller_first, 20, msg_file); // read sender's first name
  3132.     fgets(msg_caller_last, 20, msg_file);  // and his/her last name
  3133.     fgets(receiver, 35, msg_file);           // and receiver's full name
  3134.     fgets(topic, 35, msg_file);           // and the topic
  3135.     security = fgetc(msg_file);           // and security type
  3136.     fclose(msg_file);
  3137.     //-------------------------------------------
  3138.     // only the sender, receiver, and sysop can
  3139.     // delete the message
  3140.     //-------------------------------------------
  3141.     if ((!strcmpi(current_caller_first, msg_caller_first) &&
  3142.          !strcmpi(current_caller_last, msg_caller_last)) ||
  3143.         (!strcmpi(current_caller_full, receiver)) || sysop_call){
  3144.           cmdstr = "ERASE ";
  3145.           strcat(cmdstr, tmp_fname);
  3146.           dos(cmdstr, 0);
  3147.           host_send("^M^JMessage #");
  3148.           host_send(strn);
  3149.           host_send(" has been deleted.^M^J");
  3150.           if (i == first_msg) {        // the first message is deleted
  3151.           for (i = first_msg + 1; i <= last_msg; ++i)
  3152.               if (msg_exist(i)) {
  3153.               first_msg = i;    // update first_msg
  3154.               i = last_msg + 1;
  3155.               }
  3156.           }
  3157.           else if (i == last_msg) {     // the last message is deleted
  3158.           for (i = last_msg - 1; i >= first_msg; --i)
  3159.               if (msg_exist(i)) {   // update last_msg
  3160.               last_msg = i;
  3161.               i = first_msg - 1;
  3162.               }
  3163.           }
  3164.           fstlst();
  3165.     }   // if this caller can delete this message
  3166.     else {
  3167.           host_send("^M^JYou have no right to delete other people's message.^M^J");
  3168.     }
  3169.    }   // message file open successfully
  3170.    else {
  3171.     host_send("^M^JThat message is not here.  No way to delete it.^M^J");
  3172.    }
  3173. }   // delete_message
  3174.  
  3175.  
  3176. //////////////////////////////////////////////////////////////////////////////
  3177. // display_message
  3178. // input value i is message number to display
  3179. // return value: 0 if not read by caller
  3180. //         1 if read by caller
  3181. //////////////////////////////////////////////////////////////////////////////
  3182.  
  3183. display_message(int i)
  3184.  
  3185. {
  3186.    str msgnbr[5], strn[5], date_time_str[15];
  3187.    int msg_file, security, sec_pos, date_time;
  3188.    int lines_sent, ichar, isread = 0, k;
  3189.  
  3190.    tmp_fname = host_message;     // get message directory
  3191.    if (i < 10)             // if message number is smaller than 10 then
  3192.     msgnbr = "000";          // add three zeros for file name matching.
  3193.    else if (i < 100)
  3194.     msgnbr = "00";
  3195.    else if (i < 1000)
  3196.     msgnbr = "0";
  3197.    itos(i, strn);         // convert message number to number string
  3198.    strcat(msgnbr, strn);     // add zeros before this number
  3199.    strcat(tmp_fname, msgnbr);     // now tmp_fname got the path & file name
  3200.    msg_file = fopen(tmp_fname, "r+");          // reading & writing
  3201.    if (msg_file != 0){                   // file is opened successfully
  3202.     fgets(date_time_str, 20, msg_file);    // read msg creating date/time
  3203.     date(stoi(date_time_str), date_str);
  3204.     time(stoi(date_time_str), time_str);
  3205.     fgets(msg_caller_first, 20, msg_file); // read sender's first name
  3206.     fgets(msg_caller_last, 20, msg_file);  // and his/her last name
  3207.     fgets(receiver, 35, msg_file);           // and receiver's full name
  3208.     fgets(topic, 35, msg_file);           // and the topic
  3209.     sec_pos = ftell(msg_file);           // get security code position
  3210.     security = fgetc(msg_file);           // and security type
  3211.     if ((security & 127) == 'U') {         // this message can be seen by everybody
  3212.        //-------------------------------------------------------
  3213.        // Everybody can see this message since it is registered
  3214.        // as "pUblic".
  3215.        //-------------------------------------------------------
  3216.          host_send("^M^J^M^JMessage No: ");
  3217.          if (ansi_mode)
  3218.          host_send("");   // message number, date, and time
  3219.          host_send(strn);
  3220.          if (ansi_mode)
  3221.          host_send(".");
  3222.          host_send("   ");
  3223.          host_send(date_str);  host_send("  ");  host_send(time_str);
  3224.          if (ansi_mode)
  3225.          host_send("  ");
  3226.          else
  3227.          host_send("  ");
  3228.          host_send("(Public)");
  3229.          if ((security & 128) == 128)
  3230.          host_send("     (Received)");
  3231.          if (ansi_mode)
  3232.          host_send("");
  3233.          host_send("^M^J      From: ");
  3234.          if (ansi_mode)
  3235.          host_send("");      // public in cyan
  3236.          host_send(msg_caller_first);  host_send(" ");
  3237.          host_send(msg_caller_last);
  3238.          if (ansi_mode) {
  3239.          host_send("^M^J        To: ");   // sender
  3240.          host_send(receiver);
  3241.          host_send("^M^J     Topic: ");
  3242.          host_send(topic);
  3243.          host_send("");
  3244.          show_see_also(i);
  3245.          host_send("^M^J");        // contents of this message now...
  3246.          }
  3247.          else {
  3248.          host_send("^M^J        To: ");   // sender
  3249.          host_send(receiver);
  3250.          host_send("^M^J     Topic: ");
  3251.          host_send(topic);
  3252.          show_see_also(i);
  3253.          host_send("^M^J");        // contents of this message now...
  3254.          }
  3255.          lines_sent = 7;
  3256.          fgets(linemsg, 80, msg_file); // read the first line...
  3257.          do {
  3258.         host_send(linemsg);       // display it...
  3259.         host_send("^M^J");
  3260.         ++lines_sent;
  3261.         if (lines_sent >= 23) {    // have we filled the whole screen?
  3262.            lines_sent = 0;       // yes, so reset the counter
  3263.            host_send("-- More ?");
  3264.            k = host_input();
  3265.            host_send("^M            ^M");
  3266.            if (finished_caller) {  // if user inactivity
  3267.              fclose(msg_file);
  3268.              return;
  3269.            }
  3270.            if (k == 'N' || k == 'n') {
  3271.              fclose(msg_file);
  3272.              return;
  3273.            }
  3274.         }
  3275.         while (cinp_cnt()) {        // if something is in comm buffer
  3276.           ichar = cgetc();        // then read it!
  3277.           if (ichar == '^C') {      // is it a Ctrl-C ?
  3278.             host_send("^M^J");      // yes, so stop typing file
  3279.             fclose(msg_file);
  3280.             return;
  3281.           }  // is it a Ctrl-C ?
  3282.         }    // while something is in comm buffer
  3283.         fgets(linemsg, 80, msg_file);  // read it...
  3284.          } while (!feof(msg_file));     // while not end-of-message
  3285.          isread = 1;
  3286.          name_to_reply = "";            // get name to reply in Reply
  3287.          strcat(name_to_reply, msg_caller_first);
  3288.          strcat(name_to_reply, " ");
  3289.          strcat(name_to_reply, msg_caller_last);
  3290.          topic_to_reply = topic;
  3291.     }
  3292.     else if ((security & 127) == 'P') { // this message is for private
  3293.        //-------------------------------------------------------
  3294.        // only if current caller is the sender or receiver can
  3295.        // he/she read this private message
  3296.        // However, SysOp can see ALL messages...
  3297.        //-------------------------------------------------------
  3298.          if ((!strcmpi(current_caller_first, msg_caller_first) &&
  3299.           !strcmpi(current_caller_last, msg_caller_last)) ||
  3300.          (!strcmpi(current_caller_full, receiver)) || sysop_call){
  3301.              host_send("^M^J^M^JMessage No: ");   // message number, date, and time
  3302.              if (ansi_mode)
  3303.             host_send("");
  3304.              host_send(strn);
  3305.              if (ansi_mode)
  3306.             host_send(".");
  3307.              host_send("   ");
  3308.              host_send(date_str);  host_send("  ");  host_send(time_str);  host_send("  ");
  3309.              if (ansi_mode)
  3310.              host_send("");
  3311.              host_send("(Private)");
  3312.              if ((security & 128) == 128)
  3313.              host_send("     (Received)");
  3314.              if (ansi_mode) {
  3315.              host_send("^M^J      From: ");  // private in blue
  3316.              host_send(msg_caller_first);  host_send(" ");
  3317.              host_send(msg_caller_last);
  3318.              host_send("^M^J        To: ");    // the receiver
  3319.              host_send(receiver);
  3320.              host_send("^M^J     Topic: ");
  3321.              host_send(topic);
  3322.              host_send("");
  3323.              show_see_also(i);
  3324.              host_send("^M^J");        // contents of this message now...
  3325.              }
  3326.              else {
  3327.              host_send("^M^J      From: ");  // private in blue
  3328.              host_send(msg_caller_first);  host_send(" ");
  3329.              host_send(msg_caller_last);
  3330.              host_send("^M^J        To: ");    // the receiver
  3331.              host_send(receiver);
  3332.              host_send("^M^J     Topic: ");
  3333.              host_send(topic);
  3334.              show_see_also(i);
  3335.              host_send("^M^J");        // contents of this message now...
  3336.              }
  3337.              lines_sent = 7;
  3338.              fgets(linemsg, 80, msg_file);  // read the first line
  3339.              do {
  3340.             host_send(linemsg);       // display it...
  3341.             host_send("^M^J");
  3342.             ++lines_sent;
  3343.             if (lines_sent >= 23) {    // have we filled the whole screen?
  3344.                lines_sent = 0;       // yes, so reset the counter
  3345.                host_send("-- More ?");
  3346.                k = host_input();       // wait for key press
  3347.                host_send("^M            ^M");
  3348.                if (finished_caller) {  // if user inactivity
  3349.                  fclose(msg_file);
  3350.                  return;
  3351.                }
  3352.                if (k == 'N' || k == 'n') {
  3353.                  fclose(msg_file);
  3354.                  return;
  3355.                }
  3356.             }
  3357.             while (cinp_cnt()) {        // if something is in comm buffer
  3358.               ichar = cgetc();        // then read it!
  3359.               if (ichar == '^C') {      // is it a Ctrl-C ?
  3360.                 host_send("^M^J");      // yes, so stop typing file
  3361.                 fclose(msg_file);
  3362.                 return;
  3363.               }  // is it a Ctrl-C ?
  3364.             }    // while something is in comm buffer
  3365.             fgets(linemsg, 80, msg_file);  // read it...
  3366.              } while (!feof(msg_file));     // while not end-of-message
  3367.              isread = 1;
  3368.              name_to_reply = "";
  3369.              strcat(name_to_reply, msg_caller_first);
  3370.              strcat(name_to_reply, " ");
  3371.              strcat(name_to_reply, msg_caller_last);
  3372.              topic_to_reply = topic;
  3373.          }     // if this caller can read this message
  3374.          else {    // access to private message is denied
  3375.          host_send("^M^JSorry!  That's private message #");
  3376.          host_send(strn);
  3377.          host_send(".^M^J");
  3378.          }
  3379.     }  // if this message is for PRIVATE
  3380.     if (security < 128) {
  3381.          if (!strcmpi(current_caller_full, receiver)) {
  3382.          security = security + 128;
  3383.          fseek(msg_file, sec_pos, 0);
  3384.          fputc(security, msg_file);
  3385.          }
  3386.     }
  3387.     fclose(msg_file);
  3388.    }   // message file open successfully
  3389.    else {
  3390.      if (i < last_msg) {
  3391.      host_send("^M^JMessage #");
  3392.      host_send(strn);
  3393.      host_send(" does not exist.^M^J");
  3394.      }
  3395.      else
  3396.      host_send("^M^JNo more message.^M^J");
  3397.    }
  3398.    return isread;
  3399. }   // display_message
  3400.  
  3401. //////////////////////////////////////////////////////////////////////////////
  3402. // exist: test if a file is present
  3403. //      entry value: fname must include full path of that file
  3404. //      return value: 0 if file is not present
  3405. //            1 if file is there
  3406. //////////////////////////////////////////////////////////////////////////////
  3407.  
  3408. exist(str fname)
  3409.  
  3410. {
  3411.     int fh;
  3412.  
  3413.     fh = fopen(fname, "r");            // file handle is zero if no such file
  3414.     if (fh == 0)               // no such file
  3415.     return 0;
  3416.     else {                   // file is there
  3417.     fclose(fh);               // so close it
  3418.     return 1;               // then return 1
  3419.     }
  3420. }   // test a file's existence
  3421.  
  3422.  
  3423. //////////////////////////////////////////////////////////////////////////////
  3424. // msg_exist: test if a message file is present
  3425. //      entry value: i
  3426. //      return value: 0 if file is not present
  3427. //            1 if file is there
  3428. //////////////////////////////////////////////////////////////////////////////
  3429.  
  3430. msg_exist(int i)
  3431.  
  3432. {
  3433.     str fname[20], nbr[5];
  3434.  
  3435.     fname = host_message;
  3436.     if (i < 10)
  3437.     strcat(fname, "000");
  3438.     else if (i < 100)
  3439.     strcat(fname, "00");
  3440.     else if (i < 1000)
  3441.     strcat(fname, "0");
  3442.     itos(i, nbr);
  3443.     strcat(fname, nbr);
  3444.     return(exist(fname));
  3445.  
  3446. }   // test a file's existence
  3447.  
  3448. //////////////////////////////////////////////////////////////////////////////
  3449. //
  3450. // show_see_also
  3451. //
  3452. //////////////////////////////////////////////////////////////////////////////
  3453. show_see_also (int i)
  3454.  
  3455. {
  3456.    str msgnbr[7], strn[7], fname[48];
  3457.    int msg_file;
  3458.  
  3459.    fname = host_message;     // get message directory
  3460.    if (i < 10)             // if message number is smaller than 10 then
  3461.     msgnbr = "000";          // add three zeros for file name matching.
  3462.    else if (i < 100)
  3463.     msgnbr = "00";
  3464.    else if (i < 1000)
  3465.     msgnbr = "0";
  3466.    itos(i, strn);         // convert message number to number string
  3467.    strcat(msgnbr, strn);     // add zeros before this number
  3468.    strcat(fname, msgnbr);     // now fname got the path & file name
  3469.    strcat(fname, ".IDX");
  3470.    msg_file = fopen(fname, "r"); // open message file for reading only
  3471.    if (msg_file != 0) {      // index file open successfully
  3472.        host_send("^M^J  Also see: ");
  3473.        fgets(msgnbr, 5, msg_file);
  3474.        if (ansi_mode)
  3475.       host_send("");
  3476.        host_send(msgnbr);            // display first reference
  3477.        if (ansi_mode)
  3478.       host_send("");
  3479.        do {
  3480.        if (fgets(msgnbr, 5, msg_file) != -1) {
  3481.           host_send(", ");
  3482.           if (ansi_mode)
  3483.           host_send("");
  3484.           host_send(msgnbr);
  3485.           if (ansi_mode)
  3486.           host_send("");
  3487.        }
  3488.        else
  3489.           break;
  3490.        } while (1);
  3491.        fclose(msg_file);
  3492.    }
  3493.    if (ansi_mode)
  3494.        host_send("");
  3495.    host_send("^M^J");
  3496. }  // show_see_also
  3497.  
  3498. ask_ANSI()
  3499.  
  3500. {
  3501.     int c;
  3502.     str strn[15];
  3503.  
  3504.     host_send("^M^JDo you use ANSI code? (Y/N) ");
  3505.     host_input_strn(strn, 10, 0);
  3506.     if (finished_caller)               // finished_caller is set by host_input if
  3507.        return;                       // connection is lost.
  3508.     host_send("^M^J^M^JSession is set to ");
  3509.     if (toupper(subchr(strn, 0)) == 'Y'){
  3510.        ansi_mode = 1;
  3511.        host_send("ANSI mode.");
  3512.     }
  3513.     else if (toupper(subchr(strn, 0)) == 'N'){
  3514.        ansi_mode = 0;
  3515.        host_send("TTY mode.");
  3516.     }
  3517.     else {
  3518.        ansi_mode = 0;
  3519.        host_send("TTY mode.");
  3520.     }
  3521. }
  3522.  
  3523. disp_bar(int i)
  3524. {
  3525.     int c;
  3526.     for (c = 0; c < i; ++c)
  3527.       host_send("-");
  3528. }
  3529.  
  3530.  
  3531. ////////////////////////////////////////////////////////////////////////////
  3532. //
  3533. //   Check if the three directories of upload, download, and message are
  3534. //   there.  If not there then return with -1 else return with 1
  3535. //
  3536. ////////////////////////////////////////////////////////////////////////////
  3537.  
  3538. chkdir()
  3539.  
  3540. {
  3541.  
  3542.  clear_scr();        // clear the screen
  3543.  //---------------------------------------------------------------
  3544.  // check the validity of upload, download, and message directory
  3545.  // if they are not valid then terminate the whole program
  3546.  //---------------------------------------------------------------
  3547.  if (!check_directories(host_downloads)) {
  3548.    prints("The default download directory is not found.");
  3549.    printsc("Please create a default download directory as: ");
  3550.    prints(host_downloads);
  3551.    prints("");
  3552.    prints("HOST terminated...");
  3553.    prints("");
  3554.    return -1;        // this terminates the whole program
  3555.  }
  3556.  
  3557.  if (!check_directories(host_uploads)) {
  3558.    prints("The default upload directory is not found.");
  3559.    printsc("Please create a default upload directory as: ");
  3560.    prints(host_uploads);
  3561.    prints("");
  3562.    prints("HOST terminated...");
  3563.    prints("");
  3564.    return -1;        // this terminates the whole program
  3565.  }
  3566.  
  3567.  if (!check_directories(host_message)) {
  3568.    prints("The default message directory is not found.");
  3569.    printsc("Please create a default message directory as: ");
  3570.    prints(host_message);
  3571.    prints("");
  3572.    prints("HOST terminated...");
  3573.    prints("");
  3574.    return -1;        // this terminates the whole program
  3575.  }
  3576.  
  3577.  return 1;        // all three directories are there
  3578.  
  3579. }   // main
  3580.  
  3581.  
  3582. //////////////////////////////////////////////////////////////////////////////
  3583. // check for the validity of upload/download directories
  3584. //  return value: 0 --> the default directories are not found
  3585. //          1 --> the default directories are valid
  3586. //////////////////////////////////////////////////////////////////////////////
  3587.  
  3588. check_directories(str directory_name)
  3589.  
  3590. {
  3591.     str s[64];
  3592.     int i, a;
  3593.  
  3594.     s = directory_name;
  3595.     i = strlen(s);
  3596.     if (i > 0)              // first remove trailing slashes
  3597.        if (subchr(s, i - 1) == '\' || subchr(s, i - 1) == '/')
  3598.        setchr(s, i - 1, 0);
  3599.     //---------------------------------------------------------
  3600.     // if host_uploads directory string is not empty
  3601.     // and not a root-directory (C:) format then
  3602.     // check for file attribute of host_uploads directory...
  3603.     // if directory not found or not a directory then return 0
  3604.     //---------------------------------------------------------
  3605.     if (s && !(strlen(s) == 2 && subchr(s, 1) == ':')) {
  3606.        a = fileattr(s);
  3607.        if (a == -1 || !(a & 16))
  3608.       return 0;
  3609.     }
  3610.     return 1;
  3611. }    // check directories
  3612.  
  3613.  
  3614. //////////////////////////////////////////////////////////////////////////////
  3615. //
  3616. //  initialize temporary storage files for this BBS
  3617. //
  3618. //////////////////////////////////////////////////////////////////////////////
  3619.  
  3620. initfile()
  3621.  
  3622. {
  3623.  
  3624.  int fhandle, i;
  3625.  str fmsg[100];
  3626.  
  3627.  //------------------------------------------
  3628.  // open a file for temporary storage of
  3629.  // message content.
  3630.  // fmsg is initialized to a string with 80
  3631.  // blanks.
  3632.  //------------------------------------------
  3633.  fhandle = fopen(temp_message, "w+");  // open file
  3634.  fmsg = "";                            // set fmsg to exactly 80 characters
  3635.  for (i = 1; i <= 80; ++i)
  3636.       strcat(fmsg, " ");
  3637.  for (i = 1; i <= 80; ++i)           // total 6400 characters written to disk
  3638.       fputs(fmsg, fhandle);
  3639.  fclose(fhandle);               // close file
  3640.  
  3641. }   // initialize temporary storage file for entering message
  3642.  
  3643.  
  3644. //////////////////////////////////////////////////////////////////////////////
  3645. //
  3646. //  show end_entering message function
  3647. //
  3648. //////////////////////////////////////////////////////////////////////////////
  3649.  
  3650. endenter()
  3651.  
  3652. {
  3653.  
  3654.       host_send("^M^J^M^J<Message>  <Enter>^M^J");
  3655.       if (ansi_mode) {
  3656.       host_send("Abort  ");
  3657.       host_send("Continue  ");
  3658.       host_send("Insert  ");
  3659.       host_send("Delete  ");
  3660.       host_send("Edit  ");
  3661.       host_send("Topic  ");
  3662.       host_send("List  ");
  3663.       host_send("Save: ");
  3664.       }
  3665.       else {
  3666.       host_send("(A)bort  ");
  3667.       host_send("(C)ontinue  ");
  3668.       host_send("(I)nsert  ");
  3669.       host_send("(D)elete  ");
  3670.       host_send("(E)dit  ");
  3671.       host_send("(T)opic  ");
  3672.       host_send("(L)ist  ");
  3673.       host_send("(S)ave: ");
  3674.       }
  3675.  
  3676. }   // end entering message
  3677.  
  3678.  
  3679. //////////////////////////////////////////////////////////////////////////////
  3680. //
  3681. //  show current date and time
  3682. //
  3683. //////////////////////////////////////////////////////////////////////////////
  3684.  
  3685. showtime()
  3686.  
  3687. {
  3688.      int date_time;
  3689.      int year, month, day;
  3690.      str strn[12];
  3691.  
  3692.      date_time = curtime();
  3693.  
  3694.      year = tyear(date_time);
  3695.      month = tmonth(date_time);
  3696.      day = tday(date_time);
  3697.  
  3698.      host_send("Today is ");
  3699.      if (month == 1)
  3700.      host_send("January ");
  3701.      else if (month == 2)
  3702.      host_send("February ");
  3703.      else if (month == 3)
  3704.      host_send("March ");
  3705.      else if (month == 4)
  3706.      host_send("April ");
  3707.      else if (month == 5)
  3708.      host_send("May ");
  3709.      else if (month == 6)
  3710.      host_send("June ");
  3711.      else if (month == 7)
  3712.      host_send("July ");
  3713.      else if (month == 8)
  3714.      host_send("August ");
  3715.      else if (month == 9)
  3716.      host_send("September ");
  3717.      else if (month == 10)
  3718.      host_send("October ");
  3719.      else if (month == 11)
  3720.      host_send("November ");
  3721.      else if (month == 12)
  3722.      host_send("December ");
  3723.      itos(day, strn);
  3724.      host_send(strn);               // day
  3725.      host_send(", ");
  3726.      itos(year, strn);
  3727.      host_send(strn);               // year
  3728.      host_send("^M^J^M^JCurrent time is ");
  3729.      time(date_time, strn);
  3730.      host_send(strn);
  3731.      host_send("^M^J^M^J");
  3732.  
  3733. }   // show time
  3734.  
  3735.  
  3736. //////////////////////////////////////////////////////////////////////////////
  3737. //
  3738. //  show file command on screen
  3739. //
  3740. //////////////////////////////////////////////////////////////////////////////
  3741.  
  3742. filecmd()
  3743.  
  3744. {
  3745.  
  3746.      host_send("^M^J<File>  ");
  3747.      if (ansi_mode) {
  3748.     host_send("List  ");
  3749.     host_send("Type  ");
  3750.     host_send("Upload  ");
  3751.     host_send("Download  ");
  3752.     host_send("Quit ? ");
  3753.      }
  3754.      else {
  3755.     host_send("(L)ist  ");
  3756.     host_send("(T)ype  ");
  3757.     host_send("(U)pload  ");
  3758.     host_send("(D)ownload  ");
  3759.     host_send("(Q)uit ? ");
  3760.      }
  3761.  
  3762. }   // file command
  3763.  
  3764.  
  3765. //////////////////////////////////////////////////////////////////////
  3766. //
  3767. // update first-last-sysopread message number
  3768. //
  3769. //////////////////////////////////////////////////////////////////////
  3770.  
  3771. fstlst()
  3772.  
  3773. {
  3774.  
  3775.     str fname[25];
  3776.     int fh;
  3777.  
  3778.     fname = host_message;
  3779.     strcat(fname, fst_lst_msg);         // fname = full path name of first_last msg file
  3780.     fh = fopen(fname, "w+");
  3781.  
  3782.     itos(first_msg, fname);
  3783.     strcat(fname, "^M^J");
  3784.     fwrite(fname, strlen(fname), fh);    // write first msg number into file
  3785.  
  3786.     itos(last_msg, fname);
  3787.     strcat(fname, "^M^J");
  3788.     fwrite(fname, strlen(fname), fh);    // write last msg number into file
  3789.  
  3790.     itos(sysop_last_read, fname);
  3791.     strcat(fname, "^M^J");
  3792.     fwrite(fname, strlen(fname), fh);    // write last msg read number of sysop
  3793.  
  3794.     fclose(fh);
  3795.  
  3796. }   // fstlst
  3797.  
  3798.  
  3799. //////////////////////////////////////////////////////////////////////////////
  3800. //
  3801. //  show message command on screen
  3802. //
  3803. //////////////////////////////////////////////////////////////////////////////
  3804.  
  3805. msgcmd(int last_read)
  3806.  
  3807. {
  3808.      str nbrstr[10];
  3809.  
  3810.      host_send("^M^J<Message>  ");
  3811.      if (ansi_mode) {
  3812.     host_send("Messages are from #");      // display available msg
  3813.     itos(first_msg, nbrstr);             // numbers from first to
  3814.     host_send(nbrstr);                 // last.
  3815.     host_send(" to ");
  3816.     itos(last_msg, nbrstr);
  3817.     host_send(nbrstr);
  3818.     host_send(".  ");
  3819.     host_send("You last read #");
  3820.     itos(last_read, nbrstr);
  3821.     host_send(nbrstr);
  3822.     host_send(".^M^J");
  3823.     host_send("Scan  ");
  3824.     host_send("Enter  ");
  3825.     host_send("Check  ");
  3826.     host_send("Non-stop  ");
  3827.     host_send("Delete  ");
  3828.     host_send("Reply  ");
  3829.     host_send("Quit  ");
  3830.     host_send("msg# ? ");
  3831.      }
  3832.      else {
  3833.     host_send("Messages are from #");
  3834.     itos(first_msg, nbrstr);
  3835.     host_send(nbrstr);
  3836.     host_send(" to ");
  3837.     itos(last_msg, nbrstr);
  3838.     host_send(nbrstr);
  3839.     host_send(".  ");
  3840.     host_send("You last read #");
  3841.     itos(last_read, nbrstr);
  3842.     host_send(nbrstr);
  3843.     host_send(".^M^J");
  3844.     host_send("(S)can  ");
  3845.     host_send("(E)nter  ");
  3846.     host_send("(C)heck  ");
  3847.     host_send("(N)on-stop  ");
  3848.     host_send("(D)elete  ");
  3849.     host_send("(R)eply  ");
  3850.     host_send("(Q)uit  ");
  3851.     host_send("msg(#) ? ");
  3852.      }
  3853.  
  3854. }   // msgcmd
  3855.  
  3856.  
  3857. ////////////////////////////////////////////////////////////////////
  3858. //
  3859. //  Reset user's remaining on-line time to 60 minutes
  3860. //
  3861. ////////////////////////////////////////////////////////////////////
  3862. resetime()
  3863.  
  3864. {
  3865.     printsc_trm("s");               // store cursor position
  3866.  
  3867.     box(9, 10, 54, 12, 3, 0, 3);      // cyan background, double hor lines, single ver lines
  3868.  
  3869.     printsc_trm(", 13H");
  3870.     printsc("User's time has been reset to 60 minutes.");
  3871.  
  3872.     printsc_trm("u");               // restore cursor position
  3873. }   // reset user's time
  3874.  
  3875.  
  3876. ///////////////////////////////////////////////////////////////////////////
  3877. //
  3878. // This displays file transfer protocol to be used
  3879. //
  3880. ///////////////////////////////////////////////////////////////////////////
  3881.  
  3882. showprot(str transfer_way)
  3883.  
  3884. {
  3885.  
  3886.      host_send("^M^J^M^J<File>  ");
  3887.      host_send(transfer_way);
  3888.  
  3889.      if (ansi_mode) {
  3890.  
  3891.     host_send("^M^JModem7     ");      // Modem7
  3892.     host_send("SEAlink     ");         // SEALink
  3893.     host_send("Xmodem     ");          // XModem
  3894.     host_send("1k-Xmodem     ");       // 1k-XModem
  3895.     host_send("G-1k-Xmodem^M^J");      // 1k-XModem-g
  3896.  
  3897.     host_send("Ymodem     ");          // YModem
  3898.     host_send("YmodEm-g    ");         // Ymodem-G
  3899.     host_send("Zmodem     ");          // ZModem
  3900.     host_send("Telink        ");       // Telink
  3901.     host_send("Kermit^M^J");           // Kermit
  3902.  
  3903.      }
  3904.      else {
  3905.  
  3906.     host_send("^M^J(M)odem7     ");      // Modem7
  3907.     host_send("(S)EAlink     ");         // SEALink
  3908.     host_send("(X)modem     ");          // XModem
  3909.     host_send("(1)k-Xmodem     ");       // 1k-XModem
  3910.     host_send("(G)-1k-Xmodem^M^J");      // 1k-XModem-g
  3911.  
  3912.     host_send("(Y)modem     ");          // YModem
  3913.     host_send("Ymod(E)m-g    ");         // Ymodem-G
  3914.     host_send("(Z)modem     ");          // ZModem
  3915.     host_send("(T)elink        ");       // Telink
  3916.     host_send("(K)ermit^M^J");           // Kermit
  3917.  
  3918.      }
  3919.      host_send("^M^JWhich protocol? ");
  3920.  
  3921. }   // show protocols
  3922.  
  3923.  
  3924. //////////////////////////////////////////////////////////////////////
  3925. //
  3926. //  Show user's data in a box
  3927. //
  3928. //////////////////////////////////////////////////////////////////////
  3929.  
  3930. showuser()
  3931.  
  3932. {
  3933.     printsc_trm("s");               // store cursor position
  3934.  
  3935.     box(9, 10, 50, 16, 3, 0, 3);      // cyan background, double hor lines, single ver lines
  3936.  
  3937.     printsc_trm(", 13H");
  3938.     printsc("Name: ");
  3939.     printsc(current_caller_full);
  3940.  
  3941.     printsc_trm(", 13H");
  3942.     printsc("Age: ");
  3943.     printsc(user_age);
  3944.  
  3945.     printsc_trm(", 13H");
  3946.     printsc("Occupation: ");
  3947.     printsc(user_occupation);
  3948.  
  3949.     printsc_trm(", 13H");
  3950.     printsc("Location: ");
  3951.     printsc(user_location);
  3952.  
  3953.     printsc_trm(", 13H");
  3954.     printsc("Phone: ");
  3955.     printsc(user_phone);
  3956.  
  3957.     printsc_trm("u");                     // restore cursor position
  3958. }   // show user's data
  3959.  
  3960.  
  3961. //////////////////////////////////////////////////////////////////////////////
  3962. //
  3963. //  show system command on screen
  3964. //
  3965. //////////////////////////////////////////////////////////////////////////////
  3966.  
  3967. syscmd()
  3968.  
  3969. {
  3970.  
  3971.      host_send("^M^J<System>  ");
  3972.      if (ansi_mode) {
  3973.     host_send("Page sysop  ");
  3974.     host_send("Logon list  ");
  3975.     host_send("Reset  ");
  3976.     host_send("Shell  ");
  3977.     host_send("ANSI  ");
  3978.     host_send("Quit ? ");
  3979.      }
  3980.      else {
  3981.     host_send("(P)age sysop  ");
  3982.     host_send("(L)ogon list  ");
  3983.     host_send("(R)eset  ");
  3984.     host_send("(S)hell  ");
  3985.     host_send("(A)NSI  ");
  3986.     host_send("(Q)uit ? ");
  3987.      }
  3988.  
  3989. }   // system command
  3990.  
  3991.  
  3992. //////////////////////////////////////////////////////////////////
  3993. //
  3994. // show top level command on screen
  3995. //
  3996. //////////////////////////////////////////////////////////////////
  3997.  
  3998. topcmd()
  3999.  
  4000. {
  4001.    host_send("^M^J");
  4002.    if (ansi_mode) {
  4003.       host_send("File  ");      // File
  4004.       host_send("Message  ");   // Message
  4005.       host_send("System  ");    // System
  4006.       host_send("Bulletins  "); // Bulletins
  4007.       host_send("Help  ");      // Help
  4008.       host_send("Goodbye ? ");  // Good-bye
  4009.    }
  4010.    else {
  4011.       host_send("(F)ile  ");                          // File
  4012.       host_send("(M)essage  ");                       // Message
  4013.       host_send("(S)ystem  ");                        // System
  4014.       host_send("(B)ulletins  ");                     // Bulletins
  4015.       host_send("(H)elp  ");                          // Help
  4016.       host_send("(G)oodbye ? ");                      // Good-bye
  4017.    }
  4018. }   // top level command
  4019.  
  4020.