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
}