check more return codes and skip the initial slash in given file names
This commit is contained in:
parent
3b7359a27a
commit
094ceeba14
68
lib/tftp.c
68
lib/tftp.c
@ -151,8 +151,8 @@ typedef struct tftp_state_data {
|
|||||||
|
|
||||||
|
|
||||||
/* Forward declarations */
|
/* Forward declarations */
|
||||||
static void tftp_rx(tftp_state_data_t *state, tftp_event_t event) ;
|
static CURLcode tftp_rx(tftp_state_data_t *state, tftp_event_t event) ;
|
||||||
static void tftp_tx(tftp_state_data_t *state, tftp_event_t event) ;
|
static CURLcode tftp_tx(tftp_state_data_t *state, tftp_event_t event) ;
|
||||||
void tftp_set_timeouts(tftp_state_data_t *state) ;
|
void tftp_set_timeouts(tftp_state_data_t *state) ;
|
||||||
|
|
||||||
/**********************************************************
|
/**********************************************************
|
||||||
@ -249,12 +249,16 @@ static unsigned short getrpacketblock(tftp_packet_t *packet)
|
|||||||
return (packet->data[2] << 8) | packet->data[3];
|
return (packet->data[2] << 8) | packet->data[3];
|
||||||
}
|
}
|
||||||
|
|
||||||
static void tftp_send_first(tftp_state_data_t *state, tftp_event_t event)
|
static CURLcode tftp_send_first(tftp_state_data_t *state, tftp_event_t event)
|
||||||
{
|
{
|
||||||
int sbytes;
|
int sbytes;
|
||||||
const char *mode = "octet";
|
const char *mode = "octet";
|
||||||
char *filename = state->conn->path;
|
|
||||||
|
/* As RFC3617 describes the separator slash is not actually part of the file
|
||||||
|
name so we skip the always-present first letter of the path string. */
|
||||||
|
char *filename = &state->conn->path[1];
|
||||||
struct SessionHandle *data = state->conn->data;
|
struct SessionHandle *data = state->conn->data;
|
||||||
|
CURLcode res;
|
||||||
|
|
||||||
/* Set ascii mode if -B flag was used */
|
/* Set ascii mode if -B flag was used */
|
||||||
if(data->set.ftp_ascii)
|
if(data->set.ftp_ascii)
|
||||||
@ -269,7 +273,7 @@ static void tftp_send_first(tftp_state_data_t *state, tftp_event_t event)
|
|||||||
if(state->retries>state->retry_max) {
|
if(state->retries>state->retry_max) {
|
||||||
state->error = TFTP_ERR_NORESPONSE;
|
state->error = TFTP_ERR_NORESPONSE;
|
||||||
state->state = TFTP_STATE_FIN;
|
state->state = TFTP_STATE_FIN;
|
||||||
return;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(data->set.upload) {
|
if(data->set.upload) {
|
||||||
@ -301,15 +305,13 @@ static void tftp_send_first(tftp_state_data_t *state, tftp_event_t event)
|
|||||||
infof(data, "%s\n", "Connected for transmit");
|
infof(data, "%s\n", "Connected for transmit");
|
||||||
state->state = TFTP_STATE_TX;
|
state->state = TFTP_STATE_TX;
|
||||||
tftp_set_timeouts(state);
|
tftp_set_timeouts(state);
|
||||||
tftp_tx(state, event);
|
return tftp_tx(state, event);
|
||||||
break;
|
|
||||||
|
|
||||||
case TFTP_EVENT_DATA: /* connected for receive */
|
case TFTP_EVENT_DATA: /* connected for receive */
|
||||||
infof(data, "%s\n", "Connected for receive");
|
infof(data, "%s\n", "Connected for receive");
|
||||||
state->state = TFTP_STATE_RX;
|
state->state = TFTP_STATE_RX;
|
||||||
tftp_set_timeouts(state);
|
tftp_set_timeouts(state);
|
||||||
tftp_rx(state, event);
|
return tftp_rx(state, event);
|
||||||
break;
|
|
||||||
|
|
||||||
case TFTP_EVENT_ERROR:
|
case TFTP_EVENT_ERROR:
|
||||||
state->state = TFTP_STATE_FIN;
|
state->state = TFTP_STATE_FIN;
|
||||||
@ -319,6 +321,7 @@ static void tftp_send_first(tftp_state_data_t *state, tftp_event_t event)
|
|||||||
failf(state->conn->data, "tftp_send_first: internal error\n");
|
failf(state->conn->data, "tftp_send_first: internal error\n");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**********************************************************
|
/**********************************************************
|
||||||
@ -328,7 +331,7 @@ static void tftp_send_first(tftp_state_data_t *state, tftp_event_t event)
|
|||||||
* Event handler for the RX state
|
* Event handler for the RX state
|
||||||
*
|
*
|
||||||
**********************************************************/
|
**********************************************************/
|
||||||
static void tftp_rx(tftp_state_data_t *state, tftp_event_t event)
|
static CURLcode tftp_rx(tftp_state_data_t *state, tftp_event_t event)
|
||||||
{
|
{
|
||||||
int sbytes;
|
int sbytes;
|
||||||
int rblock;
|
int rblock;
|
||||||
@ -348,7 +351,7 @@ static void tftp_rx(tftp_state_data_t *state, tftp_event_t event)
|
|||||||
if (state->retries>state->retry_max) {
|
if (state->retries>state->retry_max) {
|
||||||
failf(data, "tftp_rx: giving up waiting for block %d\n",
|
failf(data, "tftp_rx: giving up waiting for block %d\n",
|
||||||
state->block+1);
|
state->block+1);
|
||||||
return;
|
return CURLE_TFTP_ILLEGAL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* This is the expected block. Reset counters and ACK it. */
|
/* This is the expected block. Reset counters and ACK it. */
|
||||||
@ -381,7 +384,8 @@ static void tftp_rx(tftp_state_data_t *state, tftp_event_t event)
|
|||||||
if(state->retries > state->retry_max) {
|
if(state->retries > state->retry_max) {
|
||||||
state->error = TFTP_ERR_TIMEOUT;
|
state->error = TFTP_ERR_TIMEOUT;
|
||||||
state->state = TFTP_STATE_FIN;
|
state->state = TFTP_STATE_FIN;
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
/* Resend the previous ACK */
|
/* Resend the previous ACK */
|
||||||
sbytes = sendto(state->sockfd, (void *)&state->spacket,
|
sbytes = sendto(state->sockfd, (void *)&state->spacket,
|
||||||
4, SEND_4TH_ARG,
|
4, SEND_4TH_ARG,
|
||||||
@ -404,6 +408,7 @@ static void tftp_rx(tftp_state_data_t *state, tftp_event_t event)
|
|||||||
}
|
}
|
||||||
Curl_pgrsSetDownloadCounter(data,
|
Curl_pgrsSetDownloadCounter(data,
|
||||||
(curl_off_t) state->block*TFTP_BLOCKSIZE);
|
(curl_off_t) state->block*TFTP_BLOCKSIZE);
|
||||||
|
return CURLE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**********************************************************
|
/**********************************************************
|
||||||
@ -413,11 +418,12 @@ static void tftp_rx(tftp_state_data_t *state, tftp_event_t event)
|
|||||||
* Event handler for the TX state
|
* Event handler for the TX state
|
||||||
*
|
*
|
||||||
**********************************************************/
|
**********************************************************/
|
||||||
static void tftp_tx(tftp_state_data_t *state, tftp_event_t event)
|
static CURLcode tftp_tx(tftp_state_data_t *state, tftp_event_t event)
|
||||||
{
|
{
|
||||||
struct SessionHandle *data = state->conn->data;
|
struct SessionHandle *data = state->conn->data;
|
||||||
int sbytes;
|
int sbytes;
|
||||||
int rblock;
|
int rblock;
|
||||||
|
CURLcode res = CURLE_OK;
|
||||||
|
|
||||||
switch(event) {
|
switch(event) {
|
||||||
|
|
||||||
@ -432,10 +438,11 @@ static void tftp_tx(tftp_state_data_t *state, tftp_event_t event)
|
|||||||
state->retries++;
|
state->retries++;
|
||||||
/* Bail out if over the maximum */
|
/* Bail out if over the maximum */
|
||||||
if(state->retries>state->retry_max) {
|
if(state->retries>state->retry_max) {
|
||||||
failf(data, "%s\n",
|
failf(data, "tftp_tx: giving up waiting for block %d ack",
|
||||||
"tftp_tx: giving up waiting for block %d ack",
|
|
||||||
state->block);
|
state->block);
|
||||||
} else {
|
res = CURLE_SEND_ERROR;
|
||||||
|
}
|
||||||
|
else {
|
||||||
/* Re-send the data packet */
|
/* Re-send the data packet */
|
||||||
sbytes = sendto(state->sockfd, (void *)&state->spacket,
|
sbytes = sendto(state->sockfd, (void *)&state->spacket,
|
||||||
4+state->sbytes, SEND_4TH_ARG,
|
4+state->sbytes, SEND_4TH_ARG,
|
||||||
@ -444,9 +451,10 @@ static void tftp_tx(tftp_state_data_t *state, tftp_event_t event)
|
|||||||
/* Check all sbytes were sent */
|
/* Check all sbytes were sent */
|
||||||
if(sbytes<0) {
|
if(sbytes<0) {
|
||||||
failf(data, "%s\n", Curl_strerror(state->conn, Curl_sockerrno()));
|
failf(data, "%s\n", Curl_strerror(state->conn, Curl_sockerrno()));
|
||||||
|
res = CURLE_SEND_ERROR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return;
|
return res;
|
||||||
}
|
}
|
||||||
/* This is the expected packet. Reset the counters and send the next
|
/* This is the expected packet. Reset the counters and send the next
|
||||||
block */
|
block */
|
||||||
@ -456,9 +464,11 @@ static void tftp_tx(tftp_state_data_t *state, tftp_event_t event)
|
|||||||
setpacketblock(&state->spacket, state->block);
|
setpacketblock(&state->spacket, state->block);
|
||||||
if(state->block > 1 && state->sbytes < TFTP_BLOCKSIZE) {
|
if(state->block > 1 && state->sbytes < TFTP_BLOCKSIZE) {
|
||||||
state->state = TFTP_STATE_FIN;
|
state->state = TFTP_STATE_FIN;
|
||||||
return;
|
return CURLE_OK;
|
||||||
}
|
}
|
||||||
Curl_fillreadbuffer(state->conn, TFTP_BLOCKSIZE, &state->sbytes);
|
res = Curl_fillreadbuffer(state->conn, TFTP_BLOCKSIZE, &state->sbytes);
|
||||||
|
if(res)
|
||||||
|
return res;
|
||||||
sbytes = sendto(state->sockfd, (void *)state->spacket.data,
|
sbytes = sendto(state->sockfd, (void *)state->spacket.data,
|
||||||
4+state->sbytes, SEND_4TH_ARG,
|
4+state->sbytes, SEND_4TH_ARG,
|
||||||
(struct sockaddr *)&state->remote_addr,
|
(struct sockaddr *)&state->remote_addr,
|
||||||
@ -502,6 +512,8 @@ static void tftp_tx(tftp_state_data_t *state, tftp_event_t event)
|
|||||||
|
|
||||||
/* Update the progress meter */
|
/* Update the progress meter */
|
||||||
Curl_pgrsSetUploadCounter(data, (curl_off_t) state->block*TFTP_BLOCKSIZE);
|
Curl_pgrsSetUploadCounter(data, (curl_off_t) state->block*TFTP_BLOCKSIZE);
|
||||||
|
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**********************************************************
|
/**********************************************************
|
||||||
@ -514,19 +526,20 @@ static void tftp_tx(tftp_state_data_t *state, tftp_event_t event)
|
|||||||
static CURLcode tftp_state_machine(tftp_state_data_t *state,
|
static CURLcode tftp_state_machine(tftp_state_data_t *state,
|
||||||
tftp_event_t event)
|
tftp_event_t event)
|
||||||
{
|
{
|
||||||
|
CURLcode res = CURLE_OK;
|
||||||
struct SessionHandle *data = state->conn->data;
|
struct SessionHandle *data = state->conn->data;
|
||||||
switch(state->state) {
|
switch(state->state) {
|
||||||
case TFTP_STATE_START:
|
case TFTP_STATE_START:
|
||||||
DEBUGF(infof(data, "TFTP_STATE_START\n"));
|
DEBUGF(infof(data, "TFTP_STATE_START\n"));
|
||||||
tftp_send_first(state, event);
|
res = tftp_send_first(state, event);
|
||||||
break;
|
break;
|
||||||
case TFTP_STATE_RX:
|
case TFTP_STATE_RX:
|
||||||
DEBUGF(infof(data, "TFTP_STATE_RX\n"));
|
DEBUGF(infof(data, "TFTP_STATE_RX\n"));
|
||||||
tftp_rx(state, event);
|
res = tftp_rx(state, event);
|
||||||
break;
|
break;
|
||||||
case TFTP_STATE_TX:
|
case TFTP_STATE_TX:
|
||||||
DEBUGF(infof(data, "TFTP_STATE_TX\n"));
|
DEBUGF(infof(data, "TFTP_STATE_TX\n"));
|
||||||
tftp_tx(state, event);
|
res = tftp_tx(state, event);
|
||||||
break;
|
break;
|
||||||
case TFTP_STATE_FIN:
|
case TFTP_STATE_FIN:
|
||||||
infof(data, "%s\n", "TFTP finished");
|
infof(data, "%s\n", "TFTP finished");
|
||||||
@ -534,9 +547,10 @@ static CURLcode tftp_state_machine(tftp_state_data_t *state,
|
|||||||
default:
|
default:
|
||||||
DEBUGF(infof(data, "STATE: %d\n", state->state));
|
DEBUGF(infof(data, "STATE: %d\n", state->state));
|
||||||
failf(data, "%s\n", "Internal state machine error");
|
failf(data, "%s\n", "Internal state machine error");
|
||||||
|
res = CURLE_TFTP_ILLEGAL;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return CURLE_OK;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -711,8 +725,8 @@ CURLcode Curl_tftp(struct connectdata *conn, bool *done)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Update the progress meter */
|
/* Update the progress meter */
|
||||||
Curl_pgrsUpdate(conn);
|
if(Curl_pgrsUpdate(conn))
|
||||||
|
return CURLE_ABORTED_BY_CALLBACK;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -731,7 +745,9 @@ CURLcode Curl_tftp(struct connectdata *conn, bool *done)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Tell curl we're done */
|
/* Tell curl we're done */
|
||||||
Curl_Transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
|
code = Curl_Transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
|
||||||
|
if(code)
|
||||||
|
return code;
|
||||||
|
|
||||||
/* If we have encountered an error */
|
/* If we have encountered an error */
|
||||||
if(state->error) {
|
if(state->error) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user