summaryrefslogtreecommitdiffstats
path: root/Utilities/cmcurl/lib/tftp.c
diff options
context:
space:
mode:
Diffstat (limited to 'Utilities/cmcurl/lib/tftp.c')
-rw-r--r--Utilities/cmcurl/lib/tftp.c82
1 files changed, 27 insertions, 55 deletions
diff --git a/Utilities/cmcurl/lib/tftp.c b/Utilities/cmcurl/lib/tftp.c
index 3f1d1b5..11150af 100644
--- a/Utilities/cmcurl/lib/tftp.c
+++ b/Utilities/cmcurl/lib/tftp.c
@@ -129,8 +129,6 @@ struct tftp_state_data {
int retries;
int retry_time;
int retry_max;
- time_t start_time;
- time_t max_time;
time_t rx_time;
struct Curl_sockaddr_storage local_addr;
struct Curl_sockaddr_storage remote_addr;
@@ -184,6 +182,7 @@ const struct Curl_handler Curl_handler_tftp = {
tftp_disconnect, /* disconnect */
ZERO_NULL, /* readwrite */
ZERO_NULL, /* connection_check */
+ ZERO_NULL, /* attach connection */
PORT_TFTP, /* defport */
CURLPROTO_TFTP, /* protocol */
CURLPROTO_TFTP, /* family */
@@ -206,8 +205,6 @@ static CURLcode tftp_set_timeouts(struct tftp_state_data *state)
timediff_t timeout_ms;
bool start = (state->state == TFTP_STATE_START) ? TRUE : FALSE;
- time(&state->start_time);
-
/* Compute drop-dead time */
timeout_ms = Curl_timeleft(state->data, NULL, start);
@@ -217,41 +214,17 @@ static CURLcode tftp_set_timeouts(struct tftp_state_data *state)
return CURLE_OPERATION_TIMEDOUT;
}
- if(start) {
-
+ if(timeout_ms > 0)
maxtime = (time_t)(timeout_ms + 500) / 1000;
- state->max_time = state->start_time + maxtime;
-
- /* Set per-block timeout to total */
- timeout = maxtime;
-
- /* Average restart after 5 seconds */
- state->retry_max = (int)timeout/5;
-
- if(state->retry_max < 1)
- /* avoid division by zero below */
- state->retry_max = 1;
-
- /* Compute the re-start interval to suit the timeout */
- state->retry_time = (int)timeout/state->retry_max;
- if(state->retry_time<1)
- state->retry_time = 1;
-
- }
- else {
- if(timeout_ms > 0)
- maxtime = (time_t)(timeout_ms + 500) / 1000;
- else
- maxtime = 3600;
+ else
+ maxtime = 3600; /* use for calculating block timeouts */
- state->max_time = state->start_time + maxtime;
+ /* Set per-block timeout to total */
+ timeout = maxtime;
- /* Set per-block timeout to total */
- timeout = maxtime;
+ /* Average reposting an ACK after 5 seconds */
+ state->retry_max = (int)timeout/5;
- /* Average reposting an ACK after 5 seconds */
- state->retry_max = (int)timeout/5;
- }
/* But bound the total number */
if(state->retry_max<3)
state->retry_max = 3;
@@ -265,9 +238,9 @@ static CURLcode tftp_set_timeouts(struct tftp_state_data *state)
state->retry_time = 1;
infof(state->data,
- "set timeouts for state %d; Total %ld, retry %d maxtry %d\n",
- (int)state->state, (long)(state->max_time-state->start_time),
- state->retry_time, state->retry_max);
+ "set timeouts for state %d; Total % " CURL_FORMAT_CURL_OFF_T
+ ", retry %d maxtry %d\n",
+ (int)state->state, timeout_ms, state->retry_time, state->retry_max);
/* init RX time */
time(&state->rx_time);
@@ -347,7 +320,7 @@ static CURLcode tftp_parse_option_ack(struct tftp_state_data *state,
const char *option, *value;
tmp = tftp_option_get(tmp, ptr + len - tmp, &option, &value);
- if(tmp == NULL) {
+ if(!tmp) {
failf(data, "Malformed ACK packet, rejecting");
return CURLE_TFTP_ILLEGAL;
}
@@ -460,7 +433,7 @@ static CURLcode tftp_send_first(struct tftp_state_data *state,
CURLcode result = CURLE_OK;
/* Set ascii mode if -B flag was used */
- if(data->set.prefer_ascii)
+ if(data->state.prefer_ascii)
mode = "netascii";
switch(event) {
@@ -804,7 +777,7 @@ static CURLcode tftp_tx(struct tftp_state_data *state, tftp_event_t event)
return result;
state->sbytes += (int)cb;
state->data->req.upload_fromhere += cb;
- } while(state->sbytes < state->blksize && cb != 0);
+ } while(state->sbytes < state->blksize && cb);
sbytes = sendto(state->sockfd, (void *) state->spacket.data,
4 + state->sbytes, SEND_4TH_ARG,
@@ -1215,33 +1188,32 @@ static CURLcode tftp_receive_packet(struct Curl_easy *data)
* Check if timeouts have been reached
*
**********************************************************/
-static long tftp_state_timeout(struct Curl_easy *data, tftp_event_t *event)
+static timediff_t tftp_state_timeout(struct Curl_easy *data,
+ tftp_event_t *event)
{
time_t current;
struct connectdata *conn = data->conn;
struct tftp_state_data *state = conn->proto.tftpc;
+ timediff_t timeout_ms;
if(event)
*event = TFTP_EVENT_NONE;
- time(&current);
- if(current > state->max_time) {
- DEBUGF(infof(data, "timeout: %ld > %ld\n",
- (long)current, (long)state->max_time));
+ timeout_ms = Curl_timeleft(state->data, NULL,
+ (state->state == TFTP_STATE_START));
+ if(timeout_ms < 0) {
state->error = TFTP_ERR_TIMEOUT;
state->state = TFTP_STATE_FIN;
return 0;
}
+ time(&current);
if(current > state->rx_time + state->retry_time) {
if(event)
*event = TFTP_EVENT_TIMEOUT;
time(&state->rx_time); /* update even though we received nothing */
}
- /* there's a typecast below here since 'time_t' may in fact be larger than
- 'long', but we estimate that a 'long' will still be able to hold number
- of seconds even if "only" 32 bit */
- return (long)(state->max_time - current);
+ return timeout_ms;
}
/**********************************************************
@@ -1257,11 +1229,11 @@ static CURLcode tftp_multi_statemach(struct Curl_easy *data, bool *done)
CURLcode result = CURLE_OK;
struct connectdata *conn = data->conn;
struct tftp_state_data *state = conn->proto.tftpc;
- long timeout_ms = tftp_state_timeout(data, &event);
+ timediff_t timeout_ms = tftp_state_timeout(data, &event);
*done = FALSE;
- if(timeout_ms <= 0) {
+ if(timeout_ms < 0) {
failf(data, "TFTP response timeout");
return CURLE_OPERATION_TIMEDOUT;
}
@@ -1285,7 +1257,7 @@ static CURLcode tftp_multi_statemach(struct Curl_easy *data, bool *done)
failf(data, "%s", Curl_strerror(error, buffer, sizeof(buffer)));
state->event = TFTP_EVENT_ERROR;
}
- else if(rc != 0) {
+ else if(rc) {
result = tftp_receive_packet(data);
if(result)
return result;
@@ -1420,14 +1392,14 @@ static CURLcode tftp_setup_connection(struct Curl_easy *data,
switch(command) {
case 'A': /* ASCII mode */
case 'N': /* NETASCII mode */
- data->set.prefer_ascii = TRUE;
+ data->state.prefer_ascii = TRUE;
break;
case 'O': /* octet mode */
case 'I': /* binary mode */
default:
/* switch off ASCII */
- data->set.prefer_ascii = FALSE;
+ data->state.prefer_ascii = FALSE;
break;
}
}