#!/bin/bash # By Ainsley Pereira # This script is designed to be a primitive web/ftp client, to pull a file # from somewhere on the Internet when you have nothing but the base # LFS. Generally, it's recommended that you use it one time -- to pull # a Web or FTP client to get the rest of the stuff you need. # If somebody doesn't know how to call the script, tell them. if [ x$1 = "x" ] then echo "USAGE: $0 " fi # Pick apart the URL, and break it into the pieces we need. URL=${1##http://} && SERVER=${URL%%/*} && FULLFILENAME=${URL#$SERVER} && FILENAME=${FULLFILENAME##*/} echo URL=$URL echo SERVER=$SERVER echo FULLNAME=$FULLFILENAME echo FILENAME=$FILENAME # There are two important (and somewhat unusual pieces to this # next command (or series of commands -- it gets tricky trying to # say which it is.) # The first is the "3<>" part. This says to open file descriptor # 3 for BOTH input and output. # The second important piece is "/dev/tcp". There is no actual entry in /dev # for this -- it's a construct of bash (actually, more properly # it's a construct of readline). It allows you to do TCP interactions # with any machine. The format is "/dev/tcp/
/".
can # be either an IP address or a hostname. A hostname gets resolved just like # it does with any other TCP/IP application. Since we are using HTTP # in this case, the port will be 80. # First, we send the HTTP command to file descriptor 3. Note the "&" on # the end. Without that, we'll never get out of the command so that we # can execute the next one. (echo -e "GET $FULLFILENAME HTTP/0.9\r\n\r\n" 1>&3 & # Just like we rerouted stdout (file descriptor 1) to FD3 in the last # command, we reroute stdin (FD0) from FD3 in this one. # We also tell bash that we want to open FD3 for both input and output # at the same time. # Since our earlier command was written to it, what happens once FD3 # is built and associated with the remote server, is that that server # gets sent "GET HTTP/0.9". The server very obediently # sends back that file. cat 0<&3) 3<> /dev/tcp/$SERVER/80 |\ ( # The "(" and ")" around all of these statements form a subshell. # One reason it is done is that it only requires one output # statement to handle all the commands in the subshell. In this # case, it has a more important purpose: it allows us to feed info # to all the commands with one INPUT. (The pipe, which we can only # have one of. # Without the subshell, the pipe would read into the first "read i", # and that's all that would ever happen. # Prime the variable "i" so the while will work properly. read i # As long as there's HTTP text coming back from the GET request, keep # reading. while [ x"$(echo $i | tr -d '\r')" != "x" ] do read i done # Copy whatever's coming in (from fd3) to stdout (which is about to # be redirected to $FILENAME). cat ) >$FILENAME