#! /usr/local/bin/perl # File: tftp-put # Purpose: Ethernet downloader using UDP protocol # Author: Phil Bunce (pjb@carmel.com) # Revision History: # 970503 Created # 970508 Working!! # 970508 Also working under Win95! # 970512 Modified to read /windows/hosts # 970715 Added tick # 980330 Having probs with system hanging on win95 (2x ctl-alt-del # required). Tried adding select(), but that causes an instant # reboot. The script works fine w or w/o select() on UNIX. # 980330 Prob with hang and crash seems to be fixed. All I did was # comment out everything to do with flush.pl. I even added # a resend on timeout that seems to work. # 980406 Added resend to open. Changed to use for instead of goto. # 981207 Added die to gethostbyname # 981207 Use windir to open /windows/hosts file. # use strict; # require 5.002; # use Socket; # use Carp; # use Sys::Hostname; #require "flush.pl"; if ($#ARGV != 1) { print "usage: tftp-put host file\n"; exit 1; } #@ticklst = ('|','/','-','\\'); # #sub tick { # printflush(STDOUT,"\r $ticklst[$tickinx]"); # $tickinx++; # if ($tickinx > $#ticklst) {$tickinx = 0;} #} # Dump a packed value sub printPacked { local($value) = @_; local($i); for ($i=0;$i) { chomp; next if /^#/; next if ! /loghost/; ($ip,$hostname,$junk) = split; } close(HF); } else { chop($hostname = `hostname`);} #print "hostname=$hostname\n"; print "sending $file from $hostname to $them via UDP\n"; ($name,$aliases,$proto) = getprotobyname('udp'); #print "proto=$proto\n"; socket(S, $AF_INET, $SOCK_DGRAM, $proto) || die "socket: $!"; ($name,$aliases,$type,$len,@thisaddr) = gethostbyname($hostname) || die "gethostbyname: $!"; ($a,$b,$c,$d) = unpack('C4', $thisaddr[0]); #print "name=$name aliases=$aliases type=$type thisaddr=$a.$b.$c.$d\n"; $this = pack($socketaddr, $AF_INET, 0, $thisaddr[0]); #&printPacked($this); bind(S, $this) || die "bind fail: $!\n"; ($name,$aliases,$type,$len,@thataddr) = gethostbyname($them); ($a,$b,$c,$d) = unpack('C4', $thataddr[0]); #print("name=$name aliases=$aliases type=$type thataddr=$a.$b.$c.$d\n"); $that = pack($socketaddr, $AF_INET, $port, $thataddr[0]); #&printPacked($that); $x = length($file)+1; $openhdr = pack("C2 a$x a9",0,2,$file,"netascii"); #&printPacked($openhdr); $rin = ""; vec($rin,fileno(S),1) = 1; for ($cnt=0;;$cnt++) { send(S, $openhdr, 0, $that) || die "send fail: $!\n"; ($nfound,$timeleft) = select($rout=$rin,undef,undef,3.0); last if $nfound != 0; if ($cnt > 3) {die "unable to contact $them: $!\n";} print "timeout. resending open...\n"; } $msg = ""; recv(S, $msg, 128, 0) || die "recv fail: $!\n"; open(IF,$file) || die "can't open $file\n"; while () { $x = length($_); $msg = pack("C4 a$x",0,3,0,1,$_); for ($cnt=0;;$cnt++) { send(S, $msg, 0, $that) || die "send fail: $!\n"; ($nfound,$timeleft) = select($rout=$rin,undef,undef,3.0); last if $nfound != 0; if ($cnt > 3) {die "unable to contact $them: $!\n";} print "timeout. resending data...\n"; } recv(S, $msg, 128, 0) || die "recv fail: $!\n"; #&tick(); } close(IF);