TRANSFER.CPP
上传用户:xr_qian
上传日期:2007-01-05
资源大小:443k
文件大小:27k
源码类别:

通讯/手机编程

开发平台:

DOS

  1. // ******************************************************************** //
  2. //                                                                      //
  3. //      TRANSFER.CPP                                                    //
  4. //      Copyright (c) 1993, Michael Holmes and Bob Flanders             //
  5. //      C++ Communication Utilities                                     //
  6. //                                                                      //
  7. //      Chapter 7: Receiving a FAX                                      //
  8. //      Last changed in chapter 7                                       //
  9. //                                                                      //
  10. //      This file contains the functions which are used to process      //
  11. //      the Alt-TransferFile menu tree.  This menu group is available   //
  12. //      from the main menu.  These functions initiate, process and      //
  13. //      terminate the protocol transfer functions.                      //
  14. //                                                                      //
  15. // ******************************************************************** //
  16. /* ******************************************************************** *
  17.  *
  18.  *  overwrite() -- prompt user to overwrite file, rtn TRUE if deny
  19.  *
  20.  * ******************************************************************** */
  21. int     overwrite(Window *w,                // window to prompt in
  22.                   int r)                    // row to prompt on
  23. {
  24. int     rc = 0;                             // return code
  25. char   *reply;                              // response buffer pointer
  26. w->AtSay(1, r, dl_msg[1]);                  // display overwrite prompt
  27. reply = (char *) malloc_chk(2);             // get a work buffer
  28. strcpy(reply, "Y");                         // ..initialize it
  29. while (rc == 0)                             // wait for a proper response
  30.     {
  31.     if (field_edit(w, strlen(dl_msg[1]) + 1,// q. user hit ESC?
  32.                 r, &reply, 1) == 0)
  33.         {
  34.         w->AtSay(strlen(dl_msg[1]) + 1,     // a. yes .. force screen
  35.                 r, "N");                    // ..to user's response
  36.         rc = 2;                             // set up return code
  37.         break;                              // ..and exit loop
  38.         }
  39.     switch (*reply)                         // based on user reply
  40.         {
  41.         case ' ':                           // positive responses
  42.         case 'Y':                           //
  43.         case 'y':                           //
  44.             rc = 1;                         // set up return code
  45.             break;                          // ..then exit loop
  46.         case 'N':                           // negative responses
  47.         case 'n':                           //
  48.             rc = 2;                         // set up return code
  49.             break;                          // ..and exit loop
  50.         default:                            // error response
  51.             printf(BELL);                   // ..give user a warning
  52.         }
  53.     }
  54. free(reply);                                // release response buffer
  55. return(rc - 1);                             // rtn with user's response
  56. }
  57. /* ******************************************************************** *
  58.  *
  59.  *  xm_stat() -- xmodem status routine
  60.  *
  61.  * ******************************************************************** */
  62. int     xm_stat(struct xm_stat *x,          // xmodem status control block
  63.                 int msgtype)                // message type
  64. {
  65. char    buf[50];                            // formatting buffer
  66. if (msgtype)                                // q. startup message?
  67.     {                                       // a. yes ..
  68.     sprintf(buf, dl_msg[9],                 // .. format the message
  69.                  x->dir ? "Sending"         // .. direction
  70.                         : "Receiving",
  71.                  x->crc ? "XMODEM-CRC"      // .. and protocol
  72.                         : "XMODEM");
  73.     ((Window *) (x->work))->Display(buf);   // display in msg window
  74.     return(0);                              // ..and return to caller
  75.     }
  76. if (x->done)
  77.     {
  78.     sprintf(buf, dl_msg[7], x->user,        // format completion message
  79.         x->crc ? "with CRC" : "");          // ..with final byte count
  80.     ((Window *) (x->work))->Display(buf);   // display in msg window
  81.     return(0);                              // ..and return to caller
  82.     }
  83. if (get_key(NO_ALT) == ESC)                 // q. user pressed ESC key?
  84.     return(1);                              // a. yes .. end transfer
  85. sprintf(buf, dl_msg[6],                     // format a status message
  86.             x->pktcnt, x->error);           // ..with current counts
  87. ((Window *) (x->work))->Display(buf);       // display in msg window
  88. return(0);                                  // ..and return all ok
  89. }
  90. /* ******************************************************************** *
  91.  *
  92.  *  ym_stat() -- ymodem status routine
  93.  *
  94.  * ******************************************************************** */
  95. int     ym_stat(struct ym_stat *y,          // ymodem status control block
  96.                 int msgtype)                // type of message
  97. {
  98. char    buf[80];                            // formatting buffer
  99. static
  100. long    prvleft;                            // previous amount left
  101. switch (msgtype)                            // type of message
  102.     {
  103.     case 0:                                 // regular status
  104.        if (get_key(NO_ALT) == ESC)          // q. user pressed ESC key?
  105.            return(1);                       // a. yes .. end transfer
  106.        if (y->left+y->error+prvleft == 0)   // q. anything to show?
  107.            return(0);                       // a. no .. return now
  108.        sprintf(buf, dl_msg[13],             // format a status message
  109.                    y->left, y->error);      // .. with current counts
  110.        prvleft = y->left;                   // .. save the old left amount
  111.        break;
  112.     case 1:                                 // new file
  113.        sprintf(buf, dl_msg[11], y->filename,// .. format the message
  114.                     y->filelen);
  115.        prvleft = y->filelen;                // .. set previous left
  116.        break;
  117.     case 2:                                 // display final counts
  118.        prvleft = 0;                         // .. reset previous left
  119.        sprintf(buf, dl_msg[8], y->nfiles,   // .. format the message
  120.                     y->totalbytes);
  121.        break;
  122.     case 3:                                 // opening message
  123.        prvleft = 0;                         // .. reset previous left
  124.        sprintf(buf, dl_msg[9]+2,            // .. format the message
  125.                     y->dir ? "Sending"      // .. direction
  126.                            : "Receiving",
  127.                     "YMODEM-Batch");        // .. protocol
  128.     }
  129. ((Window *) (y->work))->Display(buf);       // display in msg window
  130. return(0);                                  // ..and return all ok
  131. }
  132. /* ******************************************************************** *
  133.  *
  134.  *  fax_stat() -- FAX status routine
  135.  *
  136.  * ******************************************************************** */
  137. int     fax_stat(int fn,                    // function code
  138.                  struct FxStat *fs)         // pointer to structure
  139. {
  140. Window  *w;                                 // window pointer
  141. w = (Window *) fs->f_parm;                  // get window pointer parm
  142. switch(fn)                                  // based on the function
  143.     {
  144.     case 0:                                 // ESC key pressed = TRUE
  145.        rc = (get_key(NO_ALT) == ESC);
  146.        break;
  147.     case 1:                                 // display a message
  148.        w->Display(fs->f_msg);               // .. display it
  149.        rc = 0;                              // .. return OK
  150.        break;
  151.     case 2:                                 // display a message by pointer
  152.        w->Display(fs->f_ptr);               // .. display it
  153.        rc = 0;                              // .. return OK
  154.        break;
  155.     }
  156. return(rc);                                 // return to caller
  157. }
  158. /* ******************************************************************** *
  159.  *
  160.  *  dl_xmodem() -- xmodem download menu routine
  161.  *
  162.  * ******************************************************************** */
  163. int     dl_xmodem(int c, int r)             // column and row for window
  164. {
  165. int     loop = 1;                           // loop control
  166. char   *filename = 0;                       // download filename pointer
  167. Window  dl_win(c, r,                        // define temporary window
  168.             c + 45, r + 6,                  // ..to hold message
  169.             menu_cn, menu_cr);              // ..using system colors
  170. XModem  xmodem(comm, xm_stat, &dl_win);     // define XMODEM instance
  171. dl_win.Open(double_line);                   // open window with a border
  172. dl_win.Display(dl_msg[0]);                  // give filename prompt
  173. if (field_edit(&dl_win,                     // q. prompt for the filename
  174.             strlen(dl_msg[0]) + 1, 1,       // ..on the 1st row, did we
  175.             &filename, 32) == 0)            // ..get a good user response?
  176.     return(0);                              // a. no .. return to caller
  177. if (NOT first_nonblank(filename))           // q. empty string?
  178.     {
  179.     free(filename);                         // a. yes .. release memory
  180.     return(0);                              // ..and return to caller
  181.     }
  182. dl_win.GotoXY(1, 2);                        // set up window for 2nd line
  183. while (loop)                                // loop till request not to
  184.     {
  185.     switch (rc = xmodem.Receive(filename))  // try to get a file
  186.         {
  187.         case 0:                             // successful transfer
  188.             loop = 0;                       // clear loop control
  189.             break;                          // ..and exit switch
  190.         case 1:                             // duplicate filename
  191.             if (overwrite(&dl_win, 2))      // q. overwrite this file?
  192.                 {
  193.                 free(filename);             // a. no .. release memory
  194.                 wait_ms(1500L);             // ..wait a bit
  195.                 return(0);                  // ..and then return
  196.                 }
  197.             delete_file(filename);          // delete/unlink file
  198.             break;                          // ..and try again
  199.         case 2:                             // user cancelled transfer
  200.         case 3:                             // fatal protocol error
  201.         case 4:                             // sender cancelled download
  202.         case 5:                             // output file error
  203.             dl_win.Display(dl_msg[rc]);     // give user a message
  204.             loop = 0;                       // ..clear loop control
  205.             break;                          // ..and exit loop
  206.         }
  207.     }
  208. free(filename);                             // release memory
  209. wait_ms(3000L);                             // ..wait a bit
  210. return(ESC);                                // ..then return to caller
  211. }
  212. /* ******************************************************************** *
  213.  *
  214.  *  dl_ymodem() -- ymodem download menu routine
  215.  *
  216.  * ******************************************************************** */
  217. int     dl_ymodem(int c, int r)             // column and row for window
  218. {
  219. Window  dl_win(c, r,                        // define temporary window
  220.             c + 45, r + 10,                 // ..to hold message
  221.             menu_cn, menu_cr);              // ..using system colors
  222. YModem  ymodem(comm, ym_stat, &dl_win);     // define YMODEM instance
  223. dl_win.Open(double_line);                   // open window with a border
  224. if ((rc = ymodem.Receive()) != 0)           // q. anything but successful?
  225.    dl_win.Display(dl_msg[rc]);              // a. yes .. show the user
  226. wait_ms(3000L);                             // ..and wait a bit
  227. return(ESC);                                // ..and return to caller
  228. }
  229. /* ******************************************************************** *
  230.  *
  231.  *  ul_xmodem() -- xmodem upload menu routine
  232.  *
  233.  * ******************************************************************** */
  234. int     ul_xmodem(int c, int r)             // column and row for window
  235. {
  236. int     loop = 1;                           // loop control
  237. char   *filename = 0;                       // download filename pointer
  238. Window  ul_win(c, r,                        // define temporary window
  239.             c + 45, r + 6,                  // ..to hold message
  240.             menu_cn, menu_cr);              // ..using system colors
  241. XModem  xmodem(comm, xm_stat, &ul_win);     // define XMODEM instance
  242. ul_win.Open(double_line);                   // open window with a border
  243. ul_win.Display(dl_msg[0]);                  // give filename prompt
  244. if (field_edit(&ul_win,                     // q. prompt for the filename
  245.             strlen(dl_msg[0]) + 1, 1,       // ..on the 1st row, did we
  246.             &filename, 30) == 0)            // ..get a good user response?
  247.     return(0);                              // a. no .. return to caller
  248. if (NOT first_nonblank(filename))           // q. empty string?
  249.     {
  250.     free(filename);                         // a. yes .. release memory
  251.     return(0);                              // ..and return to caller
  252.     }
  253. ul_win.GotoXY(1, 2);                        // set up window for 2nd line
  254. while (loop)                                // loop till request not to
  255.     {
  256.     switch (rc = xmodem.Send(filename))     // try to send a file
  257.         {
  258.         case 0:                             // successful transfer
  259.             loop = 0;                       // clear loop control
  260.             break;                          // ..and exit switch
  261.         case 1:                             // file not found
  262.         case 2:                             // user cancelled transfer
  263.         case 3:                             // fatal protocol error
  264.         case 4:                             // receiver cancelled download
  265.         case 5:                             // file error
  266.         case 14:                            // user cancelled upload
  267.             ul_win.Display(dl_msg[rc]);     // give user a message
  268.             loop = 0;                       // ..clear loop control
  269.             break;                          // ..and exit loop
  270.         }
  271.     }
  272. free(filename);                             // release memory
  273. wait_ms(3000L);                             // ..wait a bit
  274. return(ESC);                                // ..then return to caller
  275. }
  276. /* ******************************************************************** *
  277.  *
  278.  *  ul_ymodem() -- ymodem upload menu routine
  279.  *
  280.  * ******************************************************************** */
  281. int     ul_ymodem(int c, int r)             // column and row for window
  282. {
  283. Window  ul_win(c, r,                        // define temporary window
  284.             c + 45, r + 7,                  // ..to hold message
  285.             menu_cn, menu_cr);              // ..using system colors
  286. char   *st[5] = { 0, 0, 0, 0, 0},           // send table
  287.        *wc,                                 // work pointer
  288.        *blanks = "            ";            // blanks
  289. YModem  ymodem(comm, ym_stat, &ul_win);     // define YMODEM instance
  290. int     idx = 0,                            // current index
  291.         i,                                  // work variable
  292.         k,                                  // keystroke
  293.         loop = 1;                           // loop indicator
  294. ul_win.Open(double_line);                   // open window with a border
  295. ul_win.Display(dl_msg[16]);                 // initialize the window
  296. idx = 2;                                    // initial entry ..
  297. while (loop)                                // loop till user exits
  298.     {
  299.     for (i = 0; i < 5; i++)                 // for each entry
  300.         {
  301.         ul_win.GotoXY(3, i+2);              // position the cursor
  302.         if (st[i])                          // q. entry filled in?
  303.             touppers(st[i]);                // a. yes .. uppercase it
  304.         if ((i + 2) == idx)                 // q. current entry?
  305.              ul_win.DisplayReverse(         // a. yes .. in reverse
  306.                 st[i] ? st[i] : blanks);    // .. display field or blanks
  307.          else
  308.              ul_win.Display(                // else .. in normal
  309.                 st[i] ? st[i] : blanks);    // .. display field or blanks
  310.         }
  311.     while (NOT (k = get_key(NO_ALT)))       // wait for a key
  312.         ;                                   // ..before continuing
  313.     switch (k)                              // based on keyboard input
  314.         {
  315.         case SPACE:                         // edit selected entry
  316.             field_edit(&ul_win, 3, idx,     // edit the field
  317.                &st[idx - 2], 12);
  318.             if (! first_nonblank(st[idx-2]))// q. empty string?
  319.                 {
  320.                 free(st[idx-2]);            // a. yes .. release memory
  321.                 st[idx-2] = NULL;           // .. kill the pointer
  322.                 }
  323.             break;
  324.         case CR:                            // send the files
  325.             loop = 0;                       // ..exit the loop
  326.             break;
  327.         case UP:                            // move up list
  328.             if (--idx < 2)                  // q. already at top of list?
  329.                 idx = 6;                    // a. yes .. go to bottom
  330.             break;                          // wait for next key
  331.         case DOWN:                          // move down list
  332.             if (++idx == 7)                 // q. already at bottom?
  333.                 idx = 2;                    // a. yes .. goto top of list
  334.             break;                          // wait for next key
  335.         case ESC:                           // escape from this menu
  336.             k = 0;                          // set key value to zero
  337.                                             // ..and fall into next case
  338.         case LEFT:                          // move left
  339.         case RIGHT:                         // ..or move right
  340.             for (i = 0; i < 5; i++)         // for each entry in SendTable
  341.                 if (st[i])                  // q. entry used?
  342.                     {                       // a. yes ..
  343.                     free(st[i]);            // .. free the memory
  344.                     st[i] = NULL;           // .. clear the pointer
  345.                     }
  346.             return(k);                      // just rtn with the keystroke
  347.         default:                            // error case
  348.             printf(BELL);                   // ..just ring the bell
  349.         }
  350.     }
  351. for (i = 0; i < 5; i++)                     // remove trailing blanks
  352.     if ((wc = strchr(st[i], ' ')) != 0)     // q. blank found?
  353.         *wc = 0;                            // a. yes .. end string there
  354. ul_win.Clear();                             // clear upload window
  355. ul_win.GotoXY(1, 1);                        // start from new position
  356. ymodem.Send(st);                            // perform the upload
  357. for (i = 0; i < 5; i++)                     // for each entry in SendTable
  358.     if (st[i])                              // q. entry used?
  359.        {                                    // a. yes ..
  360.        free(st[i]);                         // .. free the memory
  361.        st[i] = NULL;                        // .. clear the pointer
  362.        }
  363. wait_ms(3000L);                             // ..and wait a bit
  364. return(ESC);                                // ..and return to caller
  365. }
  366. /* ******************************************************************** *
  367.  *
  368.  *  fax_list() -- select phone book entry for fax number
  369.  *
  370.  * ******************************************************************** */
  371. char   *fax_list(int c, int r)              // column and row for window
  372. {
  373. int     i,                                  // loop counter
  374.         k,                                  // keyboard input
  375.         idx;                                // line index
  376. char    b[40],                              // work buffer
  377.        *p;                                  // work pointer
  378. Window  faxno_win(c, r, c + 35,             // define temporary window
  379.             r + COUNT(phonebook) + 1,       // ..to hold fax number list
  380.             menu_cn, menu_cr);              // ..using system colors
  381. faxno_win.Open(double_line);                // open window with a border
  382. idx = 0;                                    // set up for first entry
  383. while(1)                                    // loop till user exits
  384.     {
  385.     for (i = 0; i < COUNT(phonebook); i++)  // walk thru phonebook
  386.         {
  387.         if ((p = phonebook[i].PB_NAME) == 0)// q. name available?
  388.             p = "";                         // a. no .. point at null str
  389.         sprintf(b, "%2d. %-27.27s",         // format a buffer with name
  390.                 i + 1, p);                  // ..and line number
  391.         faxno_win.GotoXY(2, i + 1);         // position to start of line
  392.         if (i == idx)                       // q. selected line?
  393.             faxno_win.DisplayReverse(b);    // a. yes .. highlight line
  394.          else
  395.             faxno_win.Display(b);           // else .. just display it
  396.         }
  397.     while (NOT (k = get_key(NO_ALT)))       // wait for a key
  398.         ;                                   // ..before continuing
  399.     switch (k)                              // based on keyboard input
  400.         {
  401.         case CR:                            // entry selected
  402.             return(phonebook[idx].PB_FAX);  // ..return the fax number
  403.         case UP:                            // move up list
  404.             if (--idx < 0)                  // q. already at top of list?
  405.                 idx = COUNT(phonebook) - 1; // a. yes .. goto bottom
  406.             break;                          // wait for next key
  407.         case DOWN:                          // move down list
  408.             if (++idx == COUNT(phonebook))  // q. already at bottom?
  409.                 idx = 0;                    // a. yes .. goto top of list
  410.             break;                          // wait for next key
  411.         case ESC:                           // escape from this menu
  412.             return(NULL);                   // set key value to zero
  413.                                             // ..and fall into next case
  414.         default:                            // error case
  415.             printf(BELL);                   // ..just ring the bell
  416.         }
  417.     }
  418. }
  419. /* ******************************************************************** *
  420.  *
  421.  *  rcv_fax() -- receive a fax
  422.  *
  423.  * ******************************************************************** */
  424. int     rcv_fax(int c, int r)               // column and row for window
  425. {
  426. Window  fax_win(c-20, r,                    // define temporary window
  427.             c + 25, r + 18,                 // ..to hold message
  428.             menu_cn, menu_cr);              // ..using system colors
  429. Fax     fax(comm,                           // define Fax instance
  430.             user_commands.Find("SID"),
  431.             fax_stat, &fax_win);
  432. char   *filename = 0,                       // file to receive
  433.         msgbuf[50];                         // message buffer
  434. fax_win.Open(double_line);                  // open window with a border
  435. fax_win.Display(fax_msgs[40]);              // give filename prompt
  436. if (field_edit(&fax_win,                    // q. prompt for the filename
  437.             strlen(dl_msg[0]) + 1, 1,       // ..on the 1st row, did we
  438.             &filename, 12) == 0)            // ..get a good user response?
  439.     return(ESC);                            // a. no .. return to caller
  440. if (NOT first_nonblank(filename))           // q. empty string?
  441.     {
  442.     free(filename);                         // a. yes .. release memory
  443.     return(ESC);                            // ..and return to caller
  444.     }
  445. touppers(filename);                         // uppercase the file name
  446. fax_win.Clear();                            // clear the window
  447. sprintf(msgbuf, fax_msgs[0], "Receiving",   // format initial message
  448.                              filename);
  449. fax_win.DisplayReverse(msgbuf);             // display initial message
  450. fax.Receive(filename);                      // receive a fax
  451. free(filename);                             // free the file name buffer
  452. fax_win.DisplayReverse(                     // display request for a key
  453.     " -- Press any key to continue -- ");
  454. while (NOT get_key(NO_ALT))                 // wait for a key
  455.     ;                                       // ..before closing down
  456. return(ESC);                                // ..and return to caller
  457. }
  458. /* ******************************************************************** *
  459.  *
  460.  *  send_fax() -- send a fax
  461.  *
  462.  * ******************************************************************** */
  463. int     send_fax(int c, int r)              // column and row for window
  464. {
  465. Window  fax_win(c-20, r,                    // define temporary window
  466.             c + 25, r + 18,                 // ..to hold message
  467.             menu_cn, menu_cr);              // ..using system colors
  468. Fax     fax(comm,                           // define Fax instance
  469.             user_commands.Find("SID"),
  470.             fax_stat, &fax_win);
  471. char   *faxno,                              // pointer to fax telephone no.
  472.        *filename = 0,                       // file to receive
  473.         msgbuf[50];                         // message buffer
  474. faxno = fax_list(c, r);                     // select an entry
  475. if (faxno)                                  // q. any fax number?
  476.     {                                       // a. yes ..
  477.     fax_win.Open(double_line);              // open window with a border
  478.     fax_win.Display(fax_msgs[40]);          // give filename prompt
  479.     if (field_edit(&fax_win,                // q. prompt for the filename
  480.             strlen(dl_msg[0]) + 1, 1,       // ..on the 1st row, did we
  481.             &filename, 12) == 0)            // ..get a good user response?
  482.         return(ESC);                        // a. no .. return to caller
  483.     if (NOT first_nonblank(filename))       // q. empty string?
  484.         {                                   // a. yee ..
  485.         free(filename);                     // .. release memory
  486.         return(ESC);                        // ..and return to caller
  487.         }
  488.     touppers(filename);                     // uppercase the file name
  489.     fax_win.Clear();                        // clear the window
  490.     sprintf(msgbuf, fax_msgs[0], "Sending", // format initial message
  491.                     filename);
  492.     fax_win.DisplayReverse(msgbuf);         // display initial message
  493.     sprintf(msgbuf, "Calling: %srn",      // format calling message
  494.                     faxno);
  495.     fax_win.Display(msgbuf);                // display calling message
  496.     fax.Send(filename, faxno);              // send a fax
  497.     free(filename);                         // free the file name buffer
  498.     fax_win.DisplayReverse(                 // display request for a key
  499.        " -- Press any key to continue -- ");
  500.     while (NOT get_key(NO_ALT))             // wait for a key
  501.         ;                                   // ..before closing down
  502.     }
  503. return(ESC);                                // ..and return to caller
  504. }