#!/usr/skunk/bin/gawk -f #!/usr/bin/awk -f # @(#) send.awk 1.9 94/04/23 # 91/02/26 john h. dubois iii (john@armory.com) # 91/04/25 added ability to handle multiple files, and progress report # 91/04/30 added help and ability to read stdin # 91/05/28 changed to use hostname instead of hard coded host name; # removed hard coding of destination; # fixed test for readability and X-Name of stdin # 91/07/22 changed to use env. variable SEND # 91/09/29 fixed to strip off entire directory component of filename # 91/11/08 added -u option; added splitting into MAXMAILMSG-size pieces # 92/05/03 Moved all code inside of awk script; changed to #!awk script # 92/05/11 Modified to not silently send an empty message (header only) # when a file can not be read. Now prints an error message & # does not send anything. # 92/11/22 Added -o option. # 94/03/09 Use gawk so - options can be given # 94/04/23 Use .sendrc BEGIN { rcfile = ".sendrc" if (ARGV[1] ~ "^[-+]h") { print \ "send: send files by mail.\n" \ "Syntax: send [-uho] [user] ...\n" \ "If no file names are given, the standard input will be read. The files\n" \ "are sent by mail to the specified user. If the first argument contains\n" \ "a '@' or a '!', it is taken to be the name of the user to send the files\n" \ "to. Otherwise, the user is taken from the environment variable SEND, or\n"\ "if it is not set, the file .sendrc in the invoking user's home directory.\n"\ "The mail will have a subject of \"%%recfile%%\" and the header will\n" \ "contain an extra field \"X-Name\" which gives the name of the file with\n" \ "any directories removed from it, or with the name \"stdin\" if the\n" \ "standard input was read for the file. If the environment variable\n" \ "MAXMAILMSG is set, the file will be split into multiple pieces, each with\n" \ "a size less than or equal to MAXMAILMSG. The first piece will have\n" \ "the same X-Name that an unsplit file would. The rest of the pieces\n" \ "will have successive integers appended to the name, starting with 2.\n"\ "Options:\n" \ "-h: Print this help.\n" \ "-u: Uuencode the file before sending. The X-Name will be the original\n" \ " filename with \".u\" appended. If the file is split, the sequence\n" \ " number will be appended after the \".u\".\n" \ "-o: Send one file with a destination name different than the source name.\n" \ " Either one or two file names should be given. The second or only name\n" \ " gives the name that the file should have at the destination.\n" \ " If one name is given, the file to send is read from stdin." exit(0) } MaxSize = ENVIRON["MAXMAILMSG"] USER = ENVIRON["USER"] NAME = ENVIRON["NAME"] Date = strftime("%c") # "date" | getline Date "hostname" | getline HostName if (MaxSize == "") MaxSize = 2000000000 ArgInd = 1 while (ArgInd < ARGC && ARGV[ArgInd] ~ "^[-+]") { if (ARGV[ArgInd] ~ "u") UUEnc = 1 if (ARGV[ArgInd] ~ "o") OneFile = 1 ArgInd++ } if (ARGV[ArgInd] ~ "[@!]") Dest = ARGV[ArgInd++] else if ("SEND" in ENVIRON) Dest = SEND else if ("HOME" in ENVIRON) { rc = ENVIRON["HOME"] "/" rcfile if ((getline line < rc) == 1) Dest = line close(rc) } if (Dest == "") { print "No destination. Exiting." exit(1) } ProtoHeader = \ "From: " USER "@" HostName " (" NAME ")\n" \ "To: " Dest "\n" \ "Subject: %%recfile%%\n" \ "Date: " Date "\n" \ "X-Name: " if (OneFile) { DestFileName = ARGV[--ARGC] if (ArgInd > ARGC) { print "No destination filename given with +o. Exiting." exit 1 } if ((ARGC - ArgInd) > 1) { print "Too many filenames given with +o option. Exiting." exit 1 } } if (ArgInd >= ARGC) { if (SendFile("/dev/stdin",DestFileName,ProtoHeader)) printf "Error reading stdin\n" } else for (; ArgInd < ARGC; ArgInd++) if (SendFile(ARGV[ArgInd],DestFileName,ProtoHeader)) printf "Error reading %s\n",ARGV[ArgInd] } function SendFile(File,RemoteName,ProtoHeader, RemoteName,ret,DestFile) { # RemoteName is the name the (possily uuencoded) file will be saved to at # the remote end. # DestFile is the name the file will be given at the remote end # (after uudecoding, if it is to be uuencoded). # File is the name of the file being read. # Remove path DestFile = File sub(".*/","",DestFile) if (RemoteName == "") { RemoteName = DestFile if (UUEnc) RemoteName = RemoteName ".u" } if (UUEnc) UUAct = " uuencoded" printf "Sending \"%s\"%s as \"%s\"...\n",File,UUAct,RemoteName Header = ProtoHeader RemoteName FirstHeader = Header "\n\n" CharsWritten = 0 # BSD sh has no -x test MailProc = \ "m=/usr/lib/mail/execmail;[ -f $m ]||m=/usr/lib/sendmail;exec $m " Dest SequenceNum = 1 # Print header into mailproc after reading file to ensure that # no mailproc is started up if file can not be read if (UUEnc) while ((ret = ("uuencode " File " " DestFile | getline Line)) == 1) { ProcLine(FirstHeader Line) FirstHeader = "" } else while ((ret = (getline Line < File)) == 1) { ProcLine(FirstHeader Line) FirstHeader = "" } close(MailProc) return ret } function ProcLine(Line) { CharsWritten += length(Line) + 1 # adding 0 to MaxSize neccessary for BSD awk if (CharsWritten > (MaxSize + 0)) { close(MailProc) printf "Sending part %d...\d",++SequenceNum printf Header SequenceNum "\n\n" "%s\n",Line | MailProc CharsWritten = length(Line) + length(Header) + 3 } else printf "%s\n",Line | MailProc }