www.pudn.com > commutil.zip > TRANSFER.CPP


// ******************************************************************** // 
//                                                                      // 
//      TRANSFER.CPP                                                    // 
//      Copyright (c) 1993, Michael Holmes and Bob Flanders             // 
//      C++ Communication Utilities                                     // 
//                                                                      // 
//      Chapter 6: Transferring Files                                   // 
//      Last changed in chapter 6                                       // 
//                                                                      // 
//      This file contains the functions that are used to process       // 
//      the Alt-TransferFile menu tree.  This menu group is available   // 
//      from the main menu.  These functions initiate, process and      // 
//      terminate the protocol transfer functions.                      // 
//                                                                      // 
// ******************************************************************** // 
 
 
 
/* ******************************************************************** * 
 * 
 *  overwrite() -- prompt user to overwrite file, rtn TRUE if deny 
 * 
 * ******************************************************************** */ 
 
int     overwrite(Window *w,                // window to prompt in 
                  int r)                    // row to prompt on 
{ 
int     rc = 0;                             // return code 
char   *reply;                              // response buffer pointer 
 
w->AtSay(1, r, dl_msg[1]);                  // display overwrite prompt 
reply = (char *) malloc_chk(2);             // get a work buffer 
strcpy(reply, "Y");                         // ..initialize it 
 
while (rc == 0)                             // wait for a proper response 
    { 
    if (field_edit(w, strlen(dl_msg[1]) + 1,// q. user hit ESC? 
                r, &reply, 1) == 0) 
        { 
        w->AtSay(strlen(dl_msg[1]) + 1,     // a. yes .. force screen 
                r, "N");                    // ..to user's response 
        rc = 2;                             // set up return code 
        break;                              // ..and exit loop 
        } 
 
    switch (*reply)                         // based on user reply 
        { 
        case ' ':                           // positive responses 
        case 'Y':                           // 
        case 'y':                           // 
            rc = 1;                         // set up return code 
            break;                          // ..then exit loop 
 
        case 'N':                           // negative responses 
        case 'n':                           // 
            rc = 2;                         // set up return code 
            break;                          // ..and exit loop 
 
        default:                            // error response 
            printf(BELL);                   // ..give user a warning 
        } 
    } 
 
free(reply);                                // release response buffer 
return(rc - 1);                             // rtn with user's response 
 
} 
 
 
 
/* ******************************************************************** * 
 * 
 *  xm_stat() -- xmodem status routine 
 * 
 * ******************************************************************** */ 
 
int     xm_stat(struct xm_stat *x,          // xmodem status control block 
                int msgtype)                // message type 
{ 
char    buf[50];                            // formatting buffer 
 
if (msgtype)                                // q. startup message? 
    {                                       // a. yes .. 
    sprintf(buf, dl_msg[9],                 // .. format the message 
                 x->dir ? "Sending"         // .. direction 
                        : "Receiving", 
                 x->crc ? "XMODEM-CRC"      // .. and protocol 
                        : "XMODEM"); 
 
    ((Window *) (x->work))->Display(buf);   // display in msg window 
    return(0);                              // ..and return to caller 
    } 
 
 
 
if (x->done) 
    { 
    sprintf(buf, dl_msg[7], x->user,        // format completion message 
        x->crc ? "with CRC" : "");          // ..with final byte count 
    ((Window *) (x->work))->Display(buf);   // display in msg window 
    return(0);                              // ..and return to caller 
    } 
 
if (get_key(NO_ALT) == ESC)                 // q. user pressed ESC key? 
    return(1);                              // a. yes .. end transfer 
 
sprintf(buf, dl_msg[6],                     // format a status message 
            x->pktcnt, x->error);           // ..with current counts 
((Window *) (x->work))->Display(buf);       // display in msg window 
return(0);                                  // ..and return all ok 
 
} 
 
 
 
/* ******************************************************************** * 
 * 
 *  ym_stat() -- ymodem status routine 
 * 
 * ******************************************************************** */ 
 
int     ym_stat(struct ym_stat *y,          // ymodem status control block 
                int msgtype)                // type of message 
{ 
char    buf[80];                            // formatting buffer 
static 
long    prvleft;                            // previous amount left 
 
 
switch (msgtype)                            // type of message 
    { 
    case 0:                                 // regular status 
       if (get_key(NO_ALT) == ESC)          // q. user pressed ESC key? 
           return(1);                       // a. yes .. end transfer 
 
       if (y->left+y->error+prvleft == 0)   // q. anything to show? 
           return(0);                       // a. no .. return now 
 
       sprintf(buf, dl_msg[13],             // format a status message 
                   y->left, y->error);      // .. with current counts 
       prvleft = y->left;                   // .. save the old left amount 
       break; 
 
    case 1:                                 // new file 
       sprintf(buf, dl_msg[11], y->filename,// .. format the message 
                    y->filelen); 
       prvleft = y->filelen;                // .. set previous left 
       break; 
 
    case 2:                                 // display final counts 
       prvleft = 0;                         // .. reset previous left 
       sprintf(buf, dl_msg[8], y->nfiles,   // .. format the message 
                    y->totalbytes); 
       break; 
 
    case 3:                                 // opening message 
       prvleft = 0;                         // .. reset previous left 
       sprintf(buf, dl_msg[9]+2,            // .. format the message 
                    y->dir ? "Sending"      // .. direction 
                           : "Receiving", 
                    "YMODEM-Batch");        // .. protocol 
    } 
 
((Window *) (y->work))->Display(buf);       // display in msg window 
return(0);                                  // ..and return all ok 
} 
 
 
 
/* ******************************************************************** * 
 * 
 *  dl_xmodem() -- xmodem download menu routine 
 * 
 * ******************************************************************** */ 
 
int     dl_xmodem(int c, int r)             // column and row for window 
{ 
int     loop = 1;                           // loop control 
char   *filename = 0;                       // download filename pointer 
Window  dl_win(c, r,                        // define temporary window 
            c + 45, r + 6,                  // ..to hold message 
            menu_cn, menu_cr);              // ..using system colors 
XModem  xmodem(comm, xm_stat, &dl_win);     // define XMODEM instance 
 
dl_win.Open(double_line);                   // open window with a border 
dl_win.Display(dl_msg[0]);                  // give filename prompt 
 
if (field_edit(&dl_win,                     // q. prompt for the filename 
            strlen(dl_msg[0]) + 1, 1,       // ..on the 1st row, did we 
            &filename, 32) == 0)            // ..get a good user response? 
    return(0);                              // a. no .. return to caller 
 
if (NOT first_nonblank(filename))           // q. empty string? 
    { 
    free(filename);                         // a. yes .. release memory 
    return(0);                              // ..and return to caller 
    } 
 
dl_win.GotoXY(1, 2);                        // set up window for 2nd line 
 
while (loop)                                // loop till request not to 
    { 
    switch (rc = xmodem.Receive(filename))  // try to get a file 
        { 
        case 0:                             // successful transfer 
            loop = 0;                       // clear loop control 
            break;                          // ..and exit switch 
 
        case 1:                             // duplicate filename 
            if (overwrite(&dl_win, 2))      // q. overwrite this file? 
                { 
                free(filename);             // a. no .. release memory 
                wait_ms(1500L);             // ..wait a bit 
                return(0);                  // ..and then return 
                } 
 
            delete_file(filename);          // delete/unlink file 
            break;                          // ..and try again 
 
        case 2:                             // user cancelled transfer 
        case 3:                             // fatal protocol error 
        case 4:                             // sender cancelled download 
        case 5:                             // output file error 
            dl_win.Display(dl_msg[rc]);     // give user a message 
            loop = 0;                       // ..clear loop control 
            break;                          // ..and exit loop 
        } 
    } 
 
free(filename);                             // release memory 
wait_ms(3000L);                             // ..wait a bit 
return(ESC);                                // ..then return to caller 
 
} 
 
 
 
/* ******************************************************************** * 
 * 
 *  dl_ymodem() -- ymodem download menu routine 
 * 
 * ******************************************************************** */ 
 
int     dl_ymodem(int c, int r)             // column and row for window 
{ 
Window  dl_win(c, r,                        // define temporary window 
            c + 45, r + 10,                 // ..to hold message 
            menu_cn, menu_cr);              // ..using system colors 
YModem  ymodem(comm, ym_stat, &dl_win);     // define YMODEM instance 
 
dl_win.Open(double_line);                   // open window with a border 
 
if ((rc = ymodem.Receive()) != 0)           // q. anything but successful? 
   dl_win.Display(dl_msg[rc]);              // a. yes .. show the user 
 
wait_ms(3000L);                             // ..and wait a bit 
return(ESC);                                // ..and return to caller 
 
} 
 
 
 
/* ******************************************************************** * 
 * 
 *  ul_xmodem() -- xmodem upload menu routine 
 * 
 * ******************************************************************** */ 
 
int     ul_xmodem(int c, int r)             // column and row for window 
{ 
int     loop = 1;                           // loop control 
char   *filename = 0;                       // download filename pointer 
Window  ul_win(c, r,                        // define temporary window 
            c + 45, r + 6,                  // ..to hold message 
            menu_cn, menu_cr);              // ..using system colors 
XModem  xmodem(comm, xm_stat, &ul_win);     // define XMODEM instance 
 
ul_win.Open(double_line);                   // open window with a border 
ul_win.Display(dl_msg[0]);                  // give filename prompt 
 
if (field_edit(&ul_win,                     // q. prompt for the filename 
            strlen(dl_msg[0]) + 1, 1,       // ..on the 1st row, did we 
            &filename, 30) == 0)            // ..get a good user response? 
    return(0);                              // a. no .. return to caller 
 
if (NOT first_nonblank(filename))           // q. empty string? 
    { 
    free(filename);                         // a. yes .. release memory 
    return(0);                              // ..and return to caller 
    } 
 
ul_win.GotoXY(1, 2);                        // set up window for 2nd line 
 
while (loop)                                // loop till request not to 
    { 
    switch (rc = xmodem.Send(filename))     // try to send a file 
        { 
        case 0:                             // successful transfer 
            loop = 0;                       // clear loop control 
            break;                          // ..and exit switch 
 
        case 1:                             // file not found 
        case 2:                             // user cancelled transfer 
        case 3:                             // fatal protocol error 
        case 4:                             // receiver cancelled download 
        case 5:                             // file error 
        case 14:                            // user cancelled upload 
            ul_win.Display(dl_msg[rc]);     // give user a message 
            loop = 0;                       // ..clear loop control 
            break;                          // ..and exit loop 
        } 
    } 
 
free(filename);                             // release memory 
wait_ms(3000L);                             // ..wait a bit 
return(ESC);                                // ..then return to caller 
 
} 
 
 
 
/* ******************************************************************** * 
 * 
 *  ul_ymodem() -- ymodem upload menu routine 
 * 
 * ******************************************************************** */ 
 
 
int     ul_ymodem(int c, int r)             // column and row for window 
{ 
Window  ul_win(c, r,                        // define temporary window 
            c + 45, r + 7,                  // ..to hold message 
            menu_cn, menu_cr);              // ..using system colors 
 
char   *st[5] = { 0, 0, 0, 0, 0},           // send table 
       *wc,                                 // work pointer 
       *blanks = "            ";            // blanks 
 
YModem  ymodem(comm, ym_stat, &ul_win);     // define YMODEM instance 
 
int     idx = 0,                            // current index 
        i,                                  // work variable 
        k,                                  // keystroke 
        loop = 1;                           // loop indicator 
 
 
ul_win.Open(double_line);                   // open window with a border 
ul_win.Display(dl_msg[16]);                 // initialize the window 
idx = 2;                                    // initial entry .. 
 
 
while (loop)                                // loop till user exits 
    { 
    for (i = 0; i < 5; i++)                 // for each entry 
        { 
        ul_win.GotoXY(3, i+2);              // position the cursor 
 
        if (st[i])                          // q. entry filled in? 
            touppers(st[i]);                // a. yes .. uppercase it 
 
        if ((i + 2) == idx)                 // q. current entry? 
             ul_win.DisplayReverse(         // a. yes .. in reverse 
                st[i] ? st[i] : blanks);    // .. display field or blanks 
         else 
             ul_win.Display(                // else .. in normal 
                st[i] ? st[i] : blanks);    // .. display field or blanks 
        } 
 
    while (NOT (k = get_key(NO_ALT)))       // wait for a key 
        ;                                   // ..before continuing 
 
    switch (k)                              // based on keyboard input 
        { 
        case SPACE:                         // edit selected entry 
            field_edit(&ul_win, 3, idx,     // edit the field 
               &st[idx - 2], 12); 
 
            if (! first_nonblank(st[idx-2]))// q. empty string? 
                { 
                free(st[idx-2]);            // a. yes .. release memory 
                st[idx-2] = NULL;           // .. kill the pointer 
                } 
            break; 
 
 
        case CR:                            // send the files 
            loop = 0;                       // ..exit the loop 
            break; 
 
 
        case UP:                            // move up list 
            if (--idx < 2)                  // q. already at top of list? 
                idx = 6;                    // a. yes .. go to bottom 
            break;                          // wait for next key 
 
        case DOWN:                          // move down list 
            if (++idx == 7)                 // q. already at bottom? 
                idx = 2;                    // a. yes .. goto top of list 
            break;                          // wait for next key 
 
        case ESC:                           // escape from this menu 
            k = 0;                          // set key value to zero 
                                            // ..and fall into next case 
 
        case LEFT:                          // move left 
        case RIGHT:                         // ..or move right 
            for (i = 0; i < 5; i++)         // for each entry in SendTable 
                if (st[i])                  // q. entry used? 
                    {                       // a. yes .. 
                    free(st[i]);            // .. free the memory 
                    st[i] = NULL;           // .. clear the pointer 
                    } 
 
            return(k);                      // just rtn with the keystroke 
 
        default:                            // error case 
            printf(BELL);                   // ..just ring the bell 
        } 
    } 
 
for (i = 0; i < 5; i++)                     // remove trailing blanks 
    if ((wc = strchr(st[i], ' ')) != 0)     // q. blank found? 
        *wc = 0;                            // a. yes .. end string there 
 
ul_win.Clear();                             // clear upload window 
ul_win.GotoXY(1, 1);                        // start from new position 
 
ymodem.Send(st);                            // perform the upload 
 
for (i = 0; i < 5; i++)                     // for each entry in SendTable 
    if (st[i])                              // q. entry used? 
       {                                    // a. yes .. 
       free(st[i]);                         // .. free the memory 
       st[i] = NULL;                        // .. clear the pointer 
       } 
 
 
wait_ms(3000L);                             // ..and wait a bit 
return(ESC);                                // ..and return to caller 
 
}