Listing 1 superserver/subserver, superclient/subclient
quartet
SG.AWK -------------------------------------------------------------
#!/bin/awk -f
# sg.awk PORT_NUMBER SUBSERVER_PORT_CUR SUBSERVER_PORT_BEG SUBSERVER_PORT_END
#
# This superserver spawns subservers to service requests to transfer
# files on the server to remote clients. When the superserver is contacted
# by a superclient, it is passed the type of file being transferred. The
# superserver uses a block of port numbers whose extremes are passed on the
# cmdline. The current port number in use is held in ARGV[2]. It then spawns
# a subserver, sg2.awk, passing it on the commandline the port on which to
# service and the type of file, ?/b, being transferred to the superclient.
# The superserver then writes the port number being used by the spawned
# server to the socket connected to the superclient. The superclient will
# spawn a client to complete the transaction on the passed port. The
# superserver then closes the socket and spawns another copy of itself to
# service the superport.
#
# Superserver SG.AWK pairs with superclient CP.AWK.
# Superserver SG.AWK spawns subserver SG2.AWK.
# Superclient CP.AWK spawns subclient CP2.AWK.
BEGIN {
# Client picks up port here.
system("echo " ARGV[1] " > /var/run/sg.port")
Net = ("/inet/tcp/" ARGV[1] "/localhost/0")
# Sit on the socket, awaiting a Client. Client transmits
# (host filetype)
Net |& getline
if (NF<2) {
print $0
print "Bad argument count: 2 expected."
} else {
# Spawn SUBSERVER. In this order, pass HOST PORT FILETYPE
sys = sprintf ("/cmn/scr/sg2.awk %s %d %s &",$1,ARGV[2],$2)
system (sys)
# Give the SUBSERVER time to establish a port.
system("sleep 2")
# Tell the SUPERCLIENT what port the SUBCLIENT should talk on.
print ARGV[2] |& Net
close (Net)
# Calculate next port number.
port=ARGV[2]+1
if (port > ARGV[4]) port=ARGV[3]
}
close (Net)
# Get forked.
sys=sprintf("/cmn/scr/sg.awk %d %d %d %d &",ARGV[1],port,ARGV[3],ARGV[4])
system (sys)
}
SG2.AWK ------------------------------------------------------------
#!/bin/awk -f
# sg2.awk REMOTE_HOST PORT_NUMBER ?/b &
#
# This subserver is passed the following commandline parameters:
# ARGV[1]: ip number of remote host
# ARGV[2]: port to connect to on localhost on which to talk to SUBCLIENT.
# ARGV[3]: type of file being transferred. ?/b for text/binary.
#
# From the SUBCLIENT, this subserver receives the following items in this order:
# 1. In one transmission, two items separated by space:
# - $1 : A string of permissions to be applied to the created file.
# - $2 : The name of a file to create on this server's box.
# 2. Streaming content copied to the local file named in [1].
#
# This subserver is spawned by superserver SG.AWK.
BEGIN {
Net = ("/inet/tcp/" ARGV[2] "/localhost/0")
# Sit on the socket, awaiting the SUBCLIENT.
Net |& getline
# Get permissions to apply and name of file to create.
perm = $1
file = $2
# Transfer algorithm dictated by filetype.
if (ARGV[3]=="b") {
n=1
while (1) {
rc1 = Net |& getline rec1
if (rc1<=0) {
printf "%s",rec2 > file
break
}
if (n>1) print rec2 > file
rc2 = Net |& getline rec2
if (rc2<=0) {
printf "%s",rec1 > file
break
}
print rec1 > file
++n
}
} else {
while ((Net |& getline rec) > 0) print rec > file
}
close (Net)
system ("chmod " perm " " file)
system ("date >> /var/log/sg2")
l = sprintf("/cmn/scr/sg2.awk %s %s (file=%s, perm=%s)",ARGV[1],ARGV[2],file,perm)
print l >> "/var/log/sg2"
}
CP.AWK ------------------------------------------------------------
#!/bin/awk -f
# cp.awk remotehost permissions ftype local-file [remote-file]
#
# This superclient contacts a remote superserver in order to initiate a file
# transfer from the remote server to the client. The superclient contacts the
# superserver by sending it the name of the client's host and a character:
# ?/b, for the type of file being requested. The superclient then sits on the
# socket awaiting the port number on which to transfer the file. When it
# receives the port number, the superclient spawns a subclient to receive the
# file. It passes along its commandline data to the subclient plus the port
# number on which to perform the transfer.
#
# Superclient CP.AWK spawns subclient CP2.AWK.
# Superclient CP.AWK pairs with superserver SG.AWK.
BEGIN {
if (ARGC<5) {
print ("cp.awk " ARGV[1] " " ARGV[2] " " ARGV[3] " " ARGV[4])
print "cp.awk remotehost permissions ftype local-file [remote-file]"
print "if ARGV[5] is absent, ARGV[5]=ARGV[4]"
print "cp.awk galleon u+x [?,b] /local/file /remote/file"
# 0 1 2 3 4 5
} else {
# Get port on which to talk to a remote SG.AWK
getline < "/var/run/sg.port"
if (NF==0) {
print "cp.awk: no file: /var/run/sg.port"
exit 1
}
# Sanity check
if (ENVIRON["HOSTNAME"]=="") {
print "cp.awk: environment variable HOSTNAME is null."
exit
}
# Setup tcp/ip
Net = ("/inet/tcp/0/" ARGV[1] "/" $1)
# If no [5], the path/file is identical on the remote host.
if (ARGC<6) ARGV[5]=ARGV[4]
# Transmit (host filetype) to the remote server
sys=sprintf ("%s %s",ENVIRON["HOSTNAME"],ARGV[3])
print sys |& Net
# Await the transaction subport
Net |& getline subport
close (Net)
# Invoke subclient
sys = sprintf ("/cmn/scr/cp2.awk %s %s %s %s %s \
&",ARGV[1],subport,ARGV[2],ARGV[4],ARGV[5])
system (sys)
}
}
CP2.AWK ----------------------------------------------------------------
#!/bin/awk -f
# This subclient transmits three items in this order to a subserver:
# 1. A string of permissions to be applied to the file on the server's end.
# 2. The name of a file to be created by the server on the server's machine.
# 3. The content of the file named in [1].
#
# This subclient is spawned by superclient CP.AWK.
# This subclient pairs with subserver SG2.AWK.
#
# Usage: cp2.awk remotehost port permissions local-file remote-file
BEGIN {
if (ARGC<6) {
print "cp2.awk remotehost port permissions local-file remote-file"
print "cp2.awk galleon port u+x /local/file /remote/file"
# 0 1 2 3 4 5
} else {
Net = ("/inet/tcp/0/" ARGV[1] "/" ARGV[2])
args = (ARGV[3] " " ARGV[5])
print args |& Net
while ((getline rec < ARGV[4]) > 0) print rec |& Net
close (Net)
system ("date >> /var/log/cp2")
l = sprintf("/cmn/scr/cp2.awk %s %s %s %s \
%s",ARGV[1],ARGV[2],ARGV[3],ARGV[4],ARGV[5])
print l >> "/var/log/cp2"
}
}
|