Loading lib/tftp.c +42 −26 Original line number Diff line number Diff line Loading @@ -151,8 +151,8 @@ typedef struct tftp_state_data { /* Forward declarations */ static void 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_rx(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) ; /********************************************************** Loading Loading @@ -249,12 +249,16 @@ static unsigned short getrpacketblock(tftp_packet_t *packet) 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; 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; CURLcode res; /* Set ascii mode if -B flag was used */ if(data->set.ftp_ascii) Loading @@ -269,7 +273,7 @@ static void tftp_send_first(tftp_state_data_t *state, tftp_event_t event) if(state->retries>state->retry_max) { state->error = TFTP_ERR_NORESPONSE; state->state = TFTP_STATE_FIN; return; return res; } if(data->set.upload) { Loading Loading @@ -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"); state->state = TFTP_STATE_TX; tftp_set_timeouts(state); tftp_tx(state, event); break; return tftp_tx(state, event); case TFTP_EVENT_DATA: /* connected for receive */ infof(data, "%s\n", "Connected for receive"); state->state = TFTP_STATE_RX; tftp_set_timeouts(state); tftp_rx(state, event); break; return tftp_rx(state, event); case TFTP_EVENT_ERROR: state->state = TFTP_STATE_FIN; Loading @@ -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"); break; } return res; } /********************************************************** Loading @@ -328,7 +331,7 @@ static void tftp_send_first(tftp_state_data_t *state, tftp_event_t event) * 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 rblock; Loading @@ -348,7 +351,7 @@ static void tftp_rx(tftp_state_data_t *state, tftp_event_t event) if (state->retries>state->retry_max) { failf(data, "tftp_rx: giving up waiting for block %d\n", state->block+1); return; return CURLE_TFTP_ILLEGAL; } } /* This is the expected block. Reset counters and ACK it. */ Loading Loading @@ -381,7 +384,8 @@ static void tftp_rx(tftp_state_data_t *state, tftp_event_t event) if(state->retries > state->retry_max) { state->error = TFTP_ERR_TIMEOUT; state->state = TFTP_STATE_FIN; } else { } else { /* Resend the previous ACK */ sbytes = sendto(state->sockfd, (void *)&state->spacket, 4, SEND_4TH_ARG, Loading @@ -404,6 +408,7 @@ static void tftp_rx(tftp_state_data_t *state, tftp_event_t event) } Curl_pgrsSetDownloadCounter(data, (curl_off_t) state->block*TFTP_BLOCKSIZE); return CURLE_OK; } /********************************************************** Loading @@ -413,11 +418,12 @@ static void tftp_rx(tftp_state_data_t *state, tftp_event_t event) * 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; int sbytes; int rblock; CURLcode res = CURLE_OK; switch(event) { Loading @@ -432,10 +438,11 @@ static void tftp_tx(tftp_state_data_t *state, tftp_event_t event) state->retries++; /* Bail out if over the maximum */ if(state->retries>state->retry_max) { failf(data, "%s\n", "tftp_tx: giving up waiting for block %d ack", failf(data, "tftp_tx: giving up waiting for block %d ack", state->block); } else { res = CURLE_SEND_ERROR; } else { /* Re-send the data packet */ sbytes = sendto(state->sockfd, (void *)&state->spacket, 4+state->sbytes, SEND_4TH_ARG, Loading @@ -444,9 +451,10 @@ static void tftp_tx(tftp_state_data_t *state, tftp_event_t event) /* Check all sbytes were sent */ if(sbytes<0) { 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 block */ Loading @@ -456,9 +464,11 @@ static void tftp_tx(tftp_state_data_t *state, tftp_event_t event) setpacketblock(&state->spacket, state->block); if(state->block > 1 && state->sbytes < TFTP_BLOCKSIZE) { 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, 4+state->sbytes, SEND_4TH_ARG, (struct sockaddr *)&state->remote_addr, Loading Loading @@ -502,6 +512,8 @@ static void tftp_tx(tftp_state_data_t *state, tftp_event_t event) /* Update the progress meter */ Curl_pgrsSetUploadCounter(data, (curl_off_t) state->block*TFTP_BLOCKSIZE); return res; } /********************************************************** Loading @@ -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, tftp_event_t event) { CURLcode res = CURLE_OK; struct SessionHandle *data = state->conn->data; switch(state->state) { case TFTP_STATE_START: DEBUGF(infof(data, "TFTP_STATE_START\n")); tftp_send_first(state, event); res = tftp_send_first(state, event); break; case TFTP_STATE_RX: DEBUGF(infof(data, "TFTP_STATE_RX\n")); tftp_rx(state, event); res = tftp_rx(state, event); break; case TFTP_STATE_TX: DEBUGF(infof(data, "TFTP_STATE_TX\n")); tftp_tx(state, event); res = tftp_tx(state, event); break; case TFTP_STATE_FIN: infof(data, "%s\n", "TFTP finished"); Loading @@ -534,9 +547,10 @@ static CURLcode tftp_state_machine(tftp_state_data_t *state, default: DEBUGF(infof(data, "STATE: %d\n", state->state)); failf(data, "%s\n", "Internal state machine error"); res = CURLE_TFTP_ILLEGAL; break; } return CURLE_OK; return res; } Loading Loading @@ -711,8 +725,8 @@ CURLcode Curl_tftp(struct connectdata *conn, bool *done) } /* Update the progress meter */ Curl_pgrsUpdate(conn); if(Curl_pgrsUpdate(conn)) return CURLE_ABORTED_BY_CALLBACK; } } Loading @@ -731,7 +745,9 @@ CURLcode Curl_tftp(struct connectdata *conn, bool *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(state->error) { Loading Loading
lib/tftp.c +42 −26 Original line number Diff line number Diff line Loading @@ -151,8 +151,8 @@ typedef struct tftp_state_data { /* Forward declarations */ static void 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_rx(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) ; /********************************************************** Loading Loading @@ -249,12 +249,16 @@ static unsigned short getrpacketblock(tftp_packet_t *packet) 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; 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; CURLcode res; /* Set ascii mode if -B flag was used */ if(data->set.ftp_ascii) Loading @@ -269,7 +273,7 @@ static void tftp_send_first(tftp_state_data_t *state, tftp_event_t event) if(state->retries>state->retry_max) { state->error = TFTP_ERR_NORESPONSE; state->state = TFTP_STATE_FIN; return; return res; } if(data->set.upload) { Loading Loading @@ -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"); state->state = TFTP_STATE_TX; tftp_set_timeouts(state); tftp_tx(state, event); break; return tftp_tx(state, event); case TFTP_EVENT_DATA: /* connected for receive */ infof(data, "%s\n", "Connected for receive"); state->state = TFTP_STATE_RX; tftp_set_timeouts(state); tftp_rx(state, event); break; return tftp_rx(state, event); case TFTP_EVENT_ERROR: state->state = TFTP_STATE_FIN; Loading @@ -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"); break; } return res; } /********************************************************** Loading @@ -328,7 +331,7 @@ static void tftp_send_first(tftp_state_data_t *state, tftp_event_t event) * 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 rblock; Loading @@ -348,7 +351,7 @@ static void tftp_rx(tftp_state_data_t *state, tftp_event_t event) if (state->retries>state->retry_max) { failf(data, "tftp_rx: giving up waiting for block %d\n", state->block+1); return; return CURLE_TFTP_ILLEGAL; } } /* This is the expected block. Reset counters and ACK it. */ Loading Loading @@ -381,7 +384,8 @@ static void tftp_rx(tftp_state_data_t *state, tftp_event_t event) if(state->retries > state->retry_max) { state->error = TFTP_ERR_TIMEOUT; state->state = TFTP_STATE_FIN; } else { } else { /* Resend the previous ACK */ sbytes = sendto(state->sockfd, (void *)&state->spacket, 4, SEND_4TH_ARG, Loading @@ -404,6 +408,7 @@ static void tftp_rx(tftp_state_data_t *state, tftp_event_t event) } Curl_pgrsSetDownloadCounter(data, (curl_off_t) state->block*TFTP_BLOCKSIZE); return CURLE_OK; } /********************************************************** Loading @@ -413,11 +418,12 @@ static void tftp_rx(tftp_state_data_t *state, tftp_event_t event) * 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; int sbytes; int rblock; CURLcode res = CURLE_OK; switch(event) { Loading @@ -432,10 +438,11 @@ static void tftp_tx(tftp_state_data_t *state, tftp_event_t event) state->retries++; /* Bail out if over the maximum */ if(state->retries>state->retry_max) { failf(data, "%s\n", "tftp_tx: giving up waiting for block %d ack", failf(data, "tftp_tx: giving up waiting for block %d ack", state->block); } else { res = CURLE_SEND_ERROR; } else { /* Re-send the data packet */ sbytes = sendto(state->sockfd, (void *)&state->spacket, 4+state->sbytes, SEND_4TH_ARG, Loading @@ -444,9 +451,10 @@ static void tftp_tx(tftp_state_data_t *state, tftp_event_t event) /* Check all sbytes were sent */ if(sbytes<0) { 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 block */ Loading @@ -456,9 +464,11 @@ static void tftp_tx(tftp_state_data_t *state, tftp_event_t event) setpacketblock(&state->spacket, state->block); if(state->block > 1 && state->sbytes < TFTP_BLOCKSIZE) { 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, 4+state->sbytes, SEND_4TH_ARG, (struct sockaddr *)&state->remote_addr, Loading Loading @@ -502,6 +512,8 @@ static void tftp_tx(tftp_state_data_t *state, tftp_event_t event) /* Update the progress meter */ Curl_pgrsSetUploadCounter(data, (curl_off_t) state->block*TFTP_BLOCKSIZE); return res; } /********************************************************** Loading @@ -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, tftp_event_t event) { CURLcode res = CURLE_OK; struct SessionHandle *data = state->conn->data; switch(state->state) { case TFTP_STATE_START: DEBUGF(infof(data, "TFTP_STATE_START\n")); tftp_send_first(state, event); res = tftp_send_first(state, event); break; case TFTP_STATE_RX: DEBUGF(infof(data, "TFTP_STATE_RX\n")); tftp_rx(state, event); res = tftp_rx(state, event); break; case TFTP_STATE_TX: DEBUGF(infof(data, "TFTP_STATE_TX\n")); tftp_tx(state, event); res = tftp_tx(state, event); break; case TFTP_STATE_FIN: infof(data, "%s\n", "TFTP finished"); Loading @@ -534,9 +547,10 @@ static CURLcode tftp_state_machine(tftp_state_data_t *state, default: DEBUGF(infof(data, "STATE: %d\n", state->state)); failf(data, "%s\n", "Internal state machine error"); res = CURLE_TFTP_ILLEGAL; break; } return CURLE_OK; return res; } Loading Loading @@ -711,8 +725,8 @@ CURLcode Curl_tftp(struct connectdata *conn, bool *done) } /* Update the progress meter */ Curl_pgrsUpdate(conn); if(Curl_pgrsUpdate(conn)) return CURLE_ABORTED_BY_CALLBACK; } } Loading @@ -731,7 +745,9 @@ CURLcode Curl_tftp(struct connectdata *conn, bool *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(state->error) { Loading