void tftpd_general(void *p_info, int socket_ID) { connect_info_S *p_con_info=(connect_info_S *)p_info; FILE *f; int result=255; if (p_con_info->job==RRQ) { f=fopen(p_con_info->p_name,"rb"); if(f == NULL) { nak(socket_ID, &p_con_info->adresse, errno,strerror(errno)); tftp_free(p_con_info->p_name); tftp_free(p_con_info); close(socket_ID); return ; } result=tftp_send(&p_con_info->adresse,p_con_info->p_name,"octet",0,TFTPsread,f); fclose(f); } else if (p_con_info->job==WRQ) { result=tftp_receive(&p_con_info->adresse,p_con_info->p_name,"octet",0,TFTPswrite,f); } else { DEBUG_MSG("TFTP op code is not correct \n"); } if (result!=0) DEBUG_MSG("TFTP error\n"); tftp_free(p_con_info->p_name); tftp_free(p_con_info); return ; }
static void tftp_recvfile(int peer, const char *mode) { uint16_t block; struct timeval now1, now2; struct tftp_stats ts; gettimeofday(&now1, NULL); if (debug&DEBUG_SIMPLE) tftp_log(LOG_DEBUG, "Receiving file"); write_init(0, file, mode); block = 0; tftp_receive(peer, &block, &ts, NULL, 0); write_close(); gettimeofday(&now2, NULL); if (debug&DEBUG_SIMPLE) { double f; if (now1.tv_usec > now2.tv_usec) { now2.tv_usec += 1000000; now2.tv_sec--; } f = now2.tv_sec - now1.tv_sec + (now2.tv_usec - now1.tv_usec) / 100000.0; tftp_log(LOG_INFO, "Download of %jd bytes in %d blocks completed after %0.1f seconds\n", (intmax_t)ts.amount, block, f); } return; }
/* * Receive a file. */ void recvfile(int peer, char *port, int fd, char *name, char *mode) { struct tftphdr *rp; uint16_t block; char recvbuffer[MAXPKTSIZE]; int n, i; struct tftp_stats tftp_stats; stats_init(&tftp_stats); rp = (struct tftphdr *)recvbuffer; if (port == NULL) { struct servent *se; se = getservbyname("tftp", "udp"); ((struct sockaddr_in *)&peer_sock)->sin_port = se->s_port; } else ((struct sockaddr_in *)&peer_sock)->sin_port = htons(atoi(port)); for (i = 0; i < 12; i++) { struct sockaddr_storage from; /* Tell the other side what we want to do */ if (debug&DEBUG_SIMPLE) printf("Requesting %s\n", name); n = send_rrq(peer, name, mode); if (n > 0) { printf("Cannot send RRQ packet\n"); return; } /* * The first packet we receive has the new destination port * we have to send the next packets to. */ n = receive_packet(peer, recvbuffer, MAXPKTSIZE, &from, timeoutpacket); /* We got something useful! */ if (n >= 0) { ((struct sockaddr_in *)&peer_sock)->sin_port = ((struct sockaddr_in *)&from)->sin_port; break; } /* We should retry if this happens */ if (n == RP_TIMEOUT) { printf("Try %d, didn't receive answer from remote.\n", i + 1); continue; } /* Otherwise it is a fatal error */ break; } if (i == 12) { printf("Transfer timed out.\n"); return; } if (rp->th_opcode == ERROR) { tftp_log(LOG_ERR, "Error code %d: %s", rp->th_code, rp->th_msg); return; } if (write_init(fd, NULL, mode) < 0) { warn("write_init"); return; } /* * If the first packet is an OACK packet instead of an DATA packet, * handle it different. */ if (rp->th_opcode == OACK) { if (!options_rfc_enabled) { printf("Got OACK while options are not enabled!\n"); send_error(peer, EBADOP); return; } parse_options(peer, rp->th_stuff, n + 2); n = send_ack(peer, 0); if (n > 0) { printf("Cannot send ACK on OACK.\n"); return; } block = 0; tftp_receive(peer, &block, &tftp_stats, NULL, 0); } else { block = 1; tftp_receive(peer, &block, &tftp_stats, rp, n); } write_close(); if (tftp_stats.amount > 0) printstats("Received", verbose, &tftp_stats); return; }