/* tftp.c 4.6 83/06/12 */
* TFTP User Program -- Protocol Machines
extern struct sockaddr_in sin
;
if (timeout
>= maxtimeout
) {
printf("Transfer timed out.\n");
* Send the requested file.
register struct tftphdr
*tp
= (struct tftphdr
*)buf
;
register int block
= 0, size
, n
, amount
= 0;
time_t start
= time(0), delta
;
size
= makerequest(WRQ
, name
) - 4;
size
= read(fd
, tp
->th_data
, SEGSIZE
);
tp
->th_opcode
= htons((u_short
)DATA
);
tp
->th_block
= htons((u_short
)block
);
(void) setjmp(timeoutbuf
);
tpacket("sent", tp
, size
+ 4);
n
= sendto(f
, buf
, size
+ 4, 0, (caddr_t
)&sin
, sizeof (sin
));
n
= recvfrom(f
, buf
, sizeof (buf
), 0,
(caddr_t
)&from
, &fromlen
);
perror("tftp: recvfrom");
tpacket("received", tp
, n
);
/* should verify packet came from server */
tp
->th_opcode
= ntohs(tp
->th_opcode
);
tp
->th_block
= ntohs(tp
->th_block
);
if (tp
->th_opcode
== ERROR
) {
printf("Error code %d: %s\n", tp
->th_code
,
} while (tp
->th_opcode
!= ACK
&& block
!= tp
->th_block
);
} while (size
== SEGSIZE
|| block
== 1);
printf("Sent %d bytes in %d seconds.\n", amount
, delta
);
register struct tftphdr
*tp
= (struct tftphdr
*)buf
;
register int block
= 1, n
, size
, amount
= 0;
time_t start
= time(0), delta
;
int fromlen
, firsttrip
= 1;
size
= makerequest(RRQ
, name
);
tp
->th_opcode
= htons((u_short
)ACK
);
tp
->th_block
= htons((u_short
)(block
));
(void) setjmp(timeoutbuf
);
tpacket("sent", tp
, size
);
if (sendto(f
, buf
, size
, 0, (caddr_t
)&sin
,
n
= recvfrom(f
, buf
, sizeof (buf
), 0,
(caddr_t
)&from
, &fromlen
);
perror("tftp: recvfrom");
tpacket("received", tp
, n
);
/* should verify client address */
tp
->th_opcode
= ntohs(tp
->th_opcode
);
tp
->th_block
= ntohs(tp
->th_block
);
if (tp
->th_opcode
== ERROR
) {
printf("Error code %d: %s\n", tp
->th_code
,
} while (tp
->th_opcode
!= DATA
&& block
!= tp
->th_block
);
size
= write(fd
, tp
->th_data
, n
- 4);
} while (size
== SEGSIZE
);
tp
->th_opcode
= htons((u_short
)ACK
);
tp
->th_block
= htons((u_short
)block
);
(void) sendto(f
, buf
, 4, 0, &sin
, sizeof (sin
));
printf("Received %d bytes in %d seconds.\n", amount
, delta
);
makerequest(request
, name
)
register struct tftphdr
*tp
;
tp
= (struct tftphdr
*)buf
;
tp
->th_opcode
= htons((u_short
)request
);
strcpy(tp
->th_stuff
, name
);
cp
= tp
->th_stuff
+ strlen(name
);
cp
+= sizeof ("netascii") - 1;
{ EUNDEF
, "Undefined error code" },
{ ENOTFOUND
, "File not found" },
{ EACCESS
, "Access violation" },
{ ENOSPACE
, "Disk full or allocation exceeded" },
{ EBADOP
, "Illegal TFTP operation" },
{ EBADID
, "Unknown transfer ID" },
{ EEXISTS
, "File already exists" },
{ ENOUSER
, "No such user" },
* Send a nak packet (error message).
* Error code passed in is one of the
* standard TFTP codes, or a UNIX errno
register struct tftphdr
*tp
;
register struct errmsg
*pe
;
extern char *sys_errlist
[];
tp
= (struct tftphdr
*)buf
;
tp
->th_opcode
= htons((u_short
)ERROR
);
tp
->th_code
= htons((u_short
)error
);
for (pe
= errmsgs
; pe
->e_code
>= 0; pe
++)
pe
->e_msg
= sys_errlist
[error
- 100];
strcpy(tp
->th_msg
, pe
->e_msg
);
length
= strlen(pe
->e_msg
) + 4;
tpacket("sent", tp
, length
);
if (send(f
, &sin
, buf
, length
) != length
)
{ "#0", "RRQ", "WRQ", "DATA", "ACK", "ERROR" };
register char *cp
, *file
;
u_short op
= ntohs(tp
->th_opcode
);
if (op
< RRQ
|| op
> ERROR
)
printf("%s opcode=%x ", s
, op
);
printf("%s %s ", s
, opcodes
[op
]);
file
= cp
= tp
->th_stuff
;
printf("<file=%s, mode=%s>\n", file
, cp
+ 1);
printf("<block=%d, %d bytes>\n", ntohs(tp
->th_block
), n
- 4);
printf("<block=%d>\n", ntohs(tp
->th_block
));
printf("<code=%d, msg=%s>\n", ntohs(tp
->th_code
), tp
->th_msg
);