AutoFTP (Crossposting)
David F. Skoll
dfs at doe.carleton.ca
Thu Dec 13 04:57:38 AEST 1990
This program was originally posted on comp.binaries.ibm.pc.d by Kevin
D. Quitt. I posted a patch to it on alt.sources; many people wrote
asking where the original program appeared. So here it is!
(Actually, this is a reposting of a reposting...)
----- REPOSTED ARTICLE ----
>From comp.binaries.ibm.pc.d Wed Dec 12 12:55:30 1990
Path: cunews!utgpu!news-server.csri.toronto.edu!cs.utexas.edu!sdd.hp.com!usc!srhqla!demott!kdq
From: kdq at demott.com (Kevin D. Quitt)
Newsgroups: comp.binaries.ibm.pc.d
Subject: AUTOFTP30 - Here it is!
Message-ID: <1990Dec6.222640.9709 at demott.com>
Date: 6 Dec 90 22:26:40 GMT
Reply-To: kdq at demott.COM (Kevin D. Quitt)
Organization: DeMott Electronics Co., Van Nuys CA
Lines: 1384
I got 10 requests with 6 hours! Note that this is a reposting:
Article xxxx of comp.binaries.ibm.pc.d:
~From: weisen at eniac.seas.upenn.edu (Neil Weisenfeld)
~Newsgroups: comp.binaries.ibm.pc.d
~Date: 30 Mar 90 22:04:44 GMT
^^^^^^^^^
O /
----------------X---------------- Cut Here
O \
#! /bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #! /bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create:
# README
# autoftp30.sh
# checkout.c
# ftpget.c
# nextfile.c
# sample.dat
# This archive created: Tue Jul 18 16:29:20 1989
export PATH; PATH=/bin:/usr/bin:$PATH
echo shar: "extracting 'README'" '(13337 characters)'
if test -f 'README'
then
echo shar: "will not over-write existing file 'README'"
else
sed 's/^ X//' << \SHAR_EOF > 'README'
X
X AutoFtp Version 3.0
X (Previously GET21)
X
X FreeWare
X
X Mingqi Deng
X July 6, 1989
X
X
X Contents
X 1) .......................................... Description
X 2) .............................. Contents of Version 3.0
X 3) ............................................... Set Up
X 4) ............................................ Execution
X 5) .............................................. History
X
X
X AutoFtp is a UNIX Bourne shell program that automates the ftp processes
Xto get a number of files from a site that allows ftp file transfer. It
Xwill repeatedly try for a good connection until all the files requested
Xare transferred. A user need not baby-sit the ftp process, thus is
Xrelieved from the frustration of numerous unsuccessful ftp attempts.
X
X The program is based on GET20 ftp script by Ferd Boundick, and was
Xoriginally written for my own use after a long suffering from ftp into
XSIMTEL20. It has been fully tested. This release has the following new
Xfeatures:
X
X 1) A bug that allows a request for a non-existing file to go on
X forever has been fixed.
X 2) Users now can run a process of name [*]sleep[*] while running the
X autoftp without having any interferences in between. This is
X because the new version of autoftp uses process ID in its actions
X instead of their names as in the old version.
X 3) Changing local directory during ftp and getting directory list are
X supported now.
X 4) This versio will not affect the .netrc file. It simply avoids
X using it.
X 5) A randomized retry timing sequence has been implemented. In the
X previous version, there is a chance that several copies of the
X auto-ftp can get into synchrony. Consequently, none of them can get
X logged into SIMTEL20. This release minimizes this possibility and
X also smoothes the load at SIMTEL20 thus all users will have a better
X chance to login to SIMTEL20 on the average.
X 6) More and better error handlings are implemented. In particular,
X it will complain if the ALARM is too small for a large file.
X 7) The awkward run.sh file in release 2.1 has been replaced by a
X simpler input file.
X 8) The number of working files is reduced to 5 for the entire run
X from 5 for each file requested. Moreover, there is just one
X file for the entire ftp history instead one for each file
X requested.
X
X This release is a complete rewriting of the previous version, as
Xa result of my discussion with Keith Peterson at SIMTEL20. The major
Xpart of the shell script has been replaced by three C programs. This
Xprovides a more natural and better program structure, thus more freedom
Xin analyzing each ftp session.
X
X This is a freeware, meaning that it can be copied and used freely.
XBut the programs must NOT be sold for profit.
X
X Problems, improvements, comments and suggestions can be sent to the
Xauthor at:
X
XE-mail: Postal Mail:
X
X deng at shire.cs.psu.edu 333 Whitmore Lab
X deng at psuvaxs.bitnet Computer Science Department
X deng at psuvaxs.uucp The Pennsylvania State University
X University Park, PA 16802
X========================================================================
X
XAll of the files contained in version 3.0 are:
X
X README this file
X autoftp30.sh the main program
X nextfile.c used by autoftp30.sh to prepare for an ftp attempt
X ftpget.c used by autoftp30.sh for one ftp attempt
X checkout.c used by autoftp30.sh to analyze an ftp's result
X sample.dat a sample input data file for autoftp30.sh,
X consisting of a name list of the requested files
X to be transferred from WSMR-SIMTEL20.ARMY.MIL.
X
X========================================================================
X
XSet Up:
X
X 1. Do a "man ftp" to see if the constant TENEX defined on line 49 in
X nextfile.c needs to be adjusted. Refer to Note #2 in the head
X comment block in nextfile.c for more instructions.
X
X 2. Compile the three C programs by typing:
X
X cc -o checkout checkout.c
X cc -o ftpget ftpget.c
X cc -o nextfile nextfile.c
X
X This will produce three executable files named "checkout", "ftpget"
X and "nextfile".
X
X *NOTE*: Each of the programs has a "Note" section in their head
X comment block that provides information about the pre-
X defined constants used in the program. If anything goes
X suspiciously, adjust them properly.
X
X 3. Place the three compiled C programs in a directory of your choice.
X However, if the directory is not named "bin" and in your home
X directory, you will have to adjust the shell variable FtpLibDir
X in autoftp30.sh (cf. autoftp30.sh). The default is $HOME/bin. For
X example, if your home directory is "/usr/usr/deng", then the
X default directory is "/usr/usr/deng/bin".
X
X 4. Adjust the following three shell variables in autoftp30.sh:
X
X RemoteHost, ALARM, FtpLibDir
X
X Instructions and examples are given in autoftp30.sh.
X
X *NOTE*: You may have to change LocalHost in autoftp30.sh (on the
X lines next to RemoteHost) from "guest" to your machine's
X address, if login to SIMTEL20 is always denied. Refer
X to autoftp30.sh.
X
X 5. If you have any executable files of your own of the following names:
X
X cat chmod cp echo expr grep mv rm sed sh sleep test
X
X then rename them using different names. These are UNIX commands'
X names, thus should not be taken over by a user's own executables.
X
X========================================================================
X
XExecution:
X
X 1. Prepare an input file that contains a name list of files you want
X to get from a remote host (cf. sample.dat). The file consists of
X two types of lines: device-directory line (DDL) and file-line (FL).
X
X a) Device-directory line (DDL):
X Format:
X -d|c|l device_directory_name [dir_file]
X where
X d,c,l are flags indicating a DDL line:
X "-d" :- the name on that line is a device_directory_name
X that defines the directory where a subsequently
X requested file resides, at the remote host.
X This flag requires one name after the option.
X "-c" :- a request to change the local directory so that
X requested files will be put into that directory.
X The name on that line is an existing local
X directory. This flag requires zero or one name
X after the option. If no name is followed, then
X a change to the home directory is performed.
X "-l" :- a request to obtain a directory listing for the
X remote directory named on that line. This flag
X requires two names after the option: the name
X of the remote directory, and the name of the
X file to which the listing is to be stored.
X Example:
X -d PD1:<MSDOS.DSKUTL>
X -l PD:<ANONYMOUS> root.dirlst
X -c download
X Function:
X A "-d" DDL line defines the directory from which all files
X on the subsequent file-lines, up to a new "-d" DDL line,
X are to be fetched.
X A "-l" DDL line gets a directory listing to aid the download.
X A "-c" DDL line changes the local directory PERMANENTLY upto
X the next "-c" DDL line to help organize the downloaded
X file.
X
X *NOTE*: PS:<ANONYMOUS> directory contains general information
X and many directory lists at SIMTEL20. New users are
X particularly encouraged to look into this directory.
X
X b) File lines (FL):
X Format:
X [-a|b|8|t] RemoteFile [LocalFile]
X where:
X a,b,8,t are flags:
X "-a" :- a file is to be transferred in ASCII mode
X "-b" :- a file is to be transferred in binary mode
X "-t" or "-8"
X :- a file is to be transferred in tenex mode
X (32->8 bits conversion, which is the mode
X you should use if you are ftp'ing into
X SIMTEL20 from a DEC VAX or a SUN)
X The option can be omitted (indicated by the bracket
X "[","]".) If it is omitted, the default is "-t"
X (identical to "-8").
X RemoteFile is the requested file's name at the remote host
X LocalFile (optional) is the file name under which the
X RemoteFile is to be received at the local machine.
X If it is omitted, the default is RemoteFile.
X Examples:
X -a 00-INDEX.TXT DSKUTL.IDX
X -8 BACKEZ.ARC
X DISCACHE.ARC CACHE.ARC
X TIMEPARK.ARC
X -a VDSK.ASM
X Functions:
X An FL line specifies the name of a requested file (whose
X directory is specified by a preceding DDL line), and the
X transfer mode for the file.
X
X *NOTE* 1) An option on an FL line must NOT be omitted if the
X RemoteFile starts with a "-". And only the first letter
X of an option is effective.
X 2) Options and names are separated by blanks or TABs.
X No other delimiters can be used.
X 3) There can be more than one blank or TAB between the
X options and names.
X 4) There can be blanks or TABs before an option. But
X nothing should be inserted between "-" and a flag.
X 5) A DDL or FL line can appear anywhere in an input file
X though some sequence may not be meaningful.
X 6) The input file may contain any number of blank line
X anywhere. They are simply ignored.
X 7) The file name on an FL line, and directory names on a
X "-d" or "-l" DDL line can be either in lower or upper
X case. This makes no difference as far as autoftp30.sh is
X concerned. However, all options must be in lower case.
X
X 2. Run the program:
X There are two ways:
X i) run as a background job (strongly recommended) by typing:
X sh autoftp30.sh in_file &
X ii) run as a foreground job (not recommended) by typing:
X sh autoftp30.sh in_file
X where in_file is the name of the input file prepared as above.
X
X If the program is run as a background job (indicated by "&" at the
X end of the line, do a "man sh" for more information), then the
X terminal on which this command is issued is freed right away. Thus
X the user can immediately issue whatever other commands he may want.
X Otherwise, the terminal is taken by the autoftp process, and the
X user has to wait until its completion (upto several hours) before
X he can issue any other command.
X
X While the program is running background, its status can be checked
X by issuing "ps -xg" (do a "man ps" for more information). It can
X be terminated, if the user wishes, by "kill -9 pid" where "pid" is
X the process id, shown by "ps", of the very process to be terminated
X (do a "man kill" for more information.)
X
X 3. The results are a number of files: the files received, and 6 working
X files created by the execution. Among the 6 files, 5 of them only
X exist during the execution.
X
X a) XXXXXmsg :- (XXXXX is a process ID number, as shown by a "ps"
X command in UNIX.)
X This is the only working file that is usually left after the
X execution and the only working file the user should be concerned
X with. It contains the history of the ftp attempts. Check this file
X to see if each requested file is successfully transferred. A file
X transfer fails only when it is too large or has a wrong name,
X which will be reported in this file. (If your local system goes
X down, or the process is killed by a "kill" command, the transfer
X will of course be interrupted and no message will be reported in
X these cases.)
X
X b) XXXXXstdout, XXXXXstderr, XXXXXftp.script, XXXXXtmp :-
X (XXXXX is again a process ID number, as shown by a "ps"
X command in UNIX.)
X These files are temporary working files. XXXXXtmp only exists
X momentarily. If the autoftp30.sh terminates gracefully, they will
X all be erased upon its completion. Otherwise, the user can always
X delete them manually (this happens if the autoftp30.sh is killed
X by a kill command of UNIX, the local machine went down in the
X middle of the execution, or due to a situation unanticipated by
X the AutoFtp.)
X
X========================================================================
X
XHistory:
X
X Version 2.1 (GET21), by Mingqi Deng, Jan. 12, 1989
X --------------------------------------------------
X
X 1. Unlike Get20, Get21 will not give up when connection is refused
X or disrupted. Therefore the users will be relieved from the
X frustration of running it over and over again for a good
X connection.
X 2. To get out from a silent connection, there is a time out for
X each connection. The default is one hour. For large files or
X slow communication lines, the user is advised to increase the
X value.
X 3. A separate shell program sample is included for transferring
X multiple files from SIMTEL20.
X
X-----------------------------------------------------------------------
X
XVersion 2.0 (GET20) by : Ferd Boundick
X---------------------------------------
X
X date written: some time in 1983
X modification: 22 March 84
X
X 1. ftp modes are referred to as "ascii, binary, and tenex"
X 2. The option -8 is identical to -t for tenex (36->8) transfers.
X 3. Remote host name now is stored in the variable "RemoteHost".
X 4. Local host name now is stored in the variable "LocalHost" for
X remote login usage.
SHAR_EOF
if test 13337 -ne "`wc -c < 'README'`"
then
echo shar: "error transmitting 'README'" '(should have been 13337 characters)'
fi
fi
echo shar: "extracting 'autoftp30.sh'" '(5769 characters)'
if test -f 'autoftp30.sh'
then
echo shar: "will not over-write existing file 'autoftp30.sh'"
else
sed 's/^ X//' << \SHAR_EOF > 'autoftp30.sh'
X#! /bin/sh
X#
X# AutoFtp Version 3.0, by Mingqi Deng, July 6, 1989
X# -------------------------------------------------
X#
X# Refer to file README for instructions to run the program
X
X# Set-up:
X#
X# 1. Set the following 3 parameters in this program on lines 23-62:
X#
X# ALARM, RemoteHost, FtpLibDir
X#
X# Instructions and examples are given as comments in the following.
X#
X# 2. Make sure that you do NOT have any executable files of the same
X# name as the following UNIX commands' names:
X#
X# cat chmod cp echo expr grep mv rm sh sleep sed test
X#
X# Otherwise, rename your files to different names.
X
X# An ftp attempt will be aborted after ALARM many seconds. It must at
X# least be equal to 300. The default # is 3600, eg., ALARM=3600 (do
X# not leave blanks between '=' and '3600'!)
X
XALARM=3600
X
X# Define host names:
X# Use one of the following addresses for simtel20 archive site for the
X# parameter RemoteHost below:
X# "26.2.0.74"
X# "WSMR-SIMTEL20.ARMY.MIL"
X# "SIMTEL20.ARPA"
X# The first one is highly recommended if it works, since it is the
X# most time-saving address to use. The second is the official name. The
X# third is an alias, thus least recommended. However, you may find only
X# one of them works for you, depending on how your UNIX installation
X# handles the addresses. One symptom is a quickly failed ftp (less than
X# 5 seconds), which can be noticed by the ps command of UNIX.
X#
X# Also note that it has been noticed that some system does not recognize
X# the address in upper case. Therefore, if none of the above three
X# works for you, change the names to lower case and try again.
X#
X# LocalHost is set to "guest". If you find it not working, replace
X# it with the host name of your machine on which this program is run.
X# eg., RemoteHost="26.2.0.74"
X# LocalHost="shire.cs.psu.edu"
X
XRemoteHost="26.2.0.74"
XLocalHost="guest"
X
X# Set the path name for the directory where three compiled C programs
X# ftpget.c, nextfile.c and checkout.c are. This program assumes as
X# default that the three compiled programs are in $HOME/bin (a directory
X# "bin" in your home directory). If they are to be put in a different
X# directory, say, lib in your home directory, you should set FtpLibDir
X# as:
X# FtpLibDir="$HOME/lib"
X# Otherwise, just leave 'FtpLibDir=""' on next line as it is.
XFtpLibDir=""
X
X#
X#-------AUTOFTP30.SH Set-up Stops Here: No further set-up needed------
X#
X
Xtest 1$FtpLibDir = 1 && FtpLibDir=$HOME/bin
X_ftpget="$FtpLibDir/ftpget"
X_checkout="$FtpLibDir/checkout"
X_nextfile="$FtpLibDir/nextfile"
X
Xtest -s "$_ftpget" ||
X { echo "***Cannot find file '$_ftpget'!"
X echo " Please compile 'ftpget.c', name the compiled program as"
X echo " 'ftpget' and place it in your '$FtpLibDir' directory." ;
X exit 2 ; }
Xtest -s "$_checkout" ||
X { echo "***Cannot find file '$_checkout'!"
X echo " Please compile 'checkout.c', name the compiled program as"
X echo " 'checkout' and place it in your '$FtpLibDir' directory." ;
X exit 2 ; }
Xtest -s "$_nextfile" ||
X { echo "***Cannot find file '$_nextfile'!"
X echo " Please compile 'nextfile.c', name the compiled program as"
X echo " 'nextfile' and place it in your '$FtpLibDir' directory." ;
X exit 2 ; }
X
Xtest $# != 1 &&
X { echo "***Usage: sh autoftp30.sh in_file" ; exit 2; }
X
Xexec 1>$$stdout 2>$$stderr
X
X# Try FTP into simtel20 SLEEP many seconds until being connected
X# SLEEP will be increased and decreased randomly for subsequent tries.
XSLEEP=60
X
X# save messages
Xcat $$stdout $$stderr > $$msg
X
X#initialize the loop
XWS=`expr \( $SLEEP \* 47 + 31 \) \% 89 + 50`
X
Xctr=1
Xcp $1 $$input
Xretry=no
X
X# Repeat if there is more request in the input file or if the last
X# attempt failed and a retry can be performed.
Xwhile { test -s $$input || test $retry = yes ; }
Xdo
X
X > $$stderr
X > $$stdout
X
X# If not a re-try for a requested file, then fetch next requested
X# file name. If the fetch fails, then quit autoftp30.sh.
X test $retry = no &&
X { echo "%%%%%%% Process File Request #$ctr %%%%%%%" >> $$msg
X ctr=`expr $ctr + 1`
X $_nextfile $$input $RemoteHost anonymous $LocalHost $$ftp.script >> $$msg ||
X { status=92; break;}
X }
X
X# Attempt to get the file. If not able to make an attempt, then quit.
X# Note that exit status=99 means there is no alarm call.
X chmod og-rx $$ftp.script
X $_ftpget $ALARM $$ftp.script ||
X { test $? = 99 && # alarm called, do not quit yet, $_checkout
X # will respond
X { status=93; break; } ; }
X
X# Check the result of the transfer. If a retry is not to be made, then
X# set "retry" to no, otherwise set it to yes.
X $_checkout $$stdout $$stderr $$ftp.script $$tmp >> $$msg
X status=$?
X { test $status = 99 && { status=94; break ; } ; } ||
X { test $status = 0 && retry=no ; } || retry=yes
X
X# if not the last request, i.e., $$input is not empty or retry=yes,
X# then wait for a while before next attempt. Otherwise done!!!
X test -s $$input || test $retry = yes || { status=95; break ; }
X
X# save the messages for only the last attempt on a request
X test $retry = no && cat $$tmp >> $$msg
X rm $$tmp
X
X sleep $WS
X WS=`expr \( $WS \* 13 \/ 10 \) \% 900 + 60`
X
Xdone
X
Xtest $status -ge 92 &&
X { test $status -le 93 && cat $$stderr >> $$msg ||
X { cat $$tmp >> $$msg ; rm $$tmp ; } # status=94,95
X }
X
Xcase $status in
X 92) echo "*******Fatal error: when preparing an ftp attempt!*******" >> $$msg;;
X 93) echo "*******Fatal error: during an ftp attempt!*******" >> $$msg;;
X 94) echo "*******Fatal error: when checking last ftp result!*******" >> $$msg;;
X 95) echo "###################Execution Completed###################" >> $$msg;;
X *) ;;
Xesac
X
X#remove ftp command and working files
Xrm $$ftp.script $$stderr $$stdout $$input
X
Xexit 0
SHAR_EOF
if test 5769 -ne "`wc -c < 'autoftp30.sh'`"
then
echo shar: "error transmitting 'autoftp30.sh'" '(should have been 5769 characters)'
fi
chmod +x 'autoftp30.sh'
fi
echo shar: "extracting 'checkout.c'" '(10184 characters)'
if test -f 'checkout.c'
then
echo shar: "will not over-write existing file 'checkout.c'"
else
sed 's/^ X//' << \SHAR_EOF > 'checkout.c'
X/*
X * checkout.c by Mingqi Deng, July 6, 1989
X *
X * checks the result of an ftp attempt made by autoftp30.sh (cf.
X * ftpget.c) to get a file from a remote host.
X *
X * Compile:
X * cc -o checkout checkout.c
X * Execute:
X * checkout f_stdout f_stderr ftp_script f_tmp
X * where:
X * f_stdout :- the standard output file used by ftpget.c
X * f_stderr :- the standard error-message file used by ftpget.c
X * ftp_script :- the ftp command script file created by nextfile(.c)
X * f_tmp :- a temporary file for deleting null chars in
X * f_stderr and f_stdout, also used as stderr by
X * checkout(.c) for most of its error messages.
X *
X * Exit status:
X * 99 : fatal error, quit this session of autoftp30.sh
X * 0 : finish an attempt, no further attempt should be made
X * on this requested file (either file successfully
X * received, ALARM in autoftp30.sh too small, or a wrong
X * file name)
X * 2 : a failed attempt that should be retried
X *
X * Example:
X * checkout 1234stdout 1234stderr 1234ftp.script 1234tmp
X *
X * Note :
X * Two constants max_line_length and max_line defined on the
X * "#define" lines below specify the maximum length of lines in
X * f_stderr and f_stdout, and the maximum number of lines in them
X * altogether.In case they are not large enough (your will get a
X * message saying so), increase them.
X */
X
X#include <stdio.h>
X#include <sys/types.h>
X#include <sys/stat.h>
X#include <sys/timeb.h>
X
X#define max_line_length 160
X#define max_line 400
X
Xchar hold[max_line][max_line_length+1];
Xint ctr, /* number of lines in f_stderr and f_stdout */
X letter; /* number of letters in f_stderr and f_stdout */
XFILE *f_tmp;
X
Xmain(argc, argv)
Xint argc;
Xchar *argv[];
X{
X int flag,ftp_get_file;
X char cmd[80],s[80],s1[80],s2[80],*rfile,*lfile,*sprintf(),*malloc();
X FILE *f_err, *f_out, *f_ftp;
X struct stat *buf;
X time_t tloc,timeofday;
X
X f_tmp = fopen(argv[4],"w");
X if (argc != 5) {
X fprintf(stderr,"***Usage: checkout stdout stderr ftp_script f_tmp\n");
X exit(99);
X }
X f_out = fopen(argv[1],"r");
X f_err = fopen(argv[2],"r");
X f_ftp = fopen(argv[3],"r");
X if (f_err == NULL || f_out == NULL || f_ftp == NULL)
X { fprintf(f_tmp,"***File(s) '%s', '%s' or '%s' do not exist\n",
X argv[1],argv[2],argv[3]);
X exit(99);}
X
X ctr=0; letter=0; /* read in the stdout file of the ftp session*/
X while ((ctr<max_line) && (getline(hold[ctr],f_out,f_tmp)!=0)) ctr++;
X if (ctr == max_line) {
X fprintf(f_tmp,"%s\n%s\n%s\n",
X "***Increase the constant 'max_line' on the '#define' line",
X " in file checkout.c, recompile it, then try again!");
X exit(99);
X }
X
X /* read in the stderr file of the ftp session*/
X while ((ctr<max_line) && (getline(hold[ctr],f_err,f_tmp)!=0)) ctr++;
X if (ctr == max_line) {
X fprintf(f_tmp,"%s\n%s\n%s\n",
X "***Increase the constant 'max_line' on the '#define' line",
X " in file checkout.c, recompile it, then try again!");
X exit(99);
X }
X if (letter==0) /* empty file: a silent connection, try again */
X { printf("A silent connection, will try again.\n"); exit(2);}
X
X flag = detect("unknown host");
X flag = (flag)? 1: detect("Unknown host");
X if (flag) {
X /* wrong remote host name, quit attempt for this run */
X fprintf(f_tmp,"***host unknown: check RemoteHost in autoftp30.sh!\n");
X exit(99);
X }
X
X /* get the requested file names from the ftp script file
X if a 'get' is performed. */
X ftp_get_file=0;
X while( fgets(s,max_line_length,f_ftp) != NULL)
X if (strncmp(s,"get",3) == 0) {
X extract3(s,s1,s1,s2);
X if (s1[0]!='\0') { rfile = s1; }
X else {
X fprintf(f_tmp,"***Invalid ftp_script file '%s'\n",argv[3]);
X exit(99);
X }
X if (s2[0]!='\0') lfile=s2;
X else lfile=s1;
X ftp_get_file=1;
X }
X
X flag = detect("Invalid use of terminal designator");
X flag = (flag)? 1:detect("File not accessible");
X flag = (flag)? 1:detect("File not accessable");
X flag = (flag)? 1:detect("file not found");
X flag = (flag)? 1:detect("File not found");
X flag = (flag)? 1:detect("not found");
X flag = (flag)? 1:detect("No such file");
X flag = (flag)? 1:detect("No such directory");
X
X if (flag) {
X /* wrong remote file name, quit attempt for this file */
X if (ftp_get_file)
X fprintf(f_tmp,
X "***Remote file/direcortory %s not found!\n",rfile);
X else
X fprintf(f_tmp, "***Remote direcortory not found!\n");
X exit(0); /* abort the current request */
X }
X
X flag = detect("refused");
X flag = (flag)? 1: detect("unreachable");
X flag = (flag)? 1: detect("failed");
X flag = (flag)? 1: detect("Connection timed out");
X flag = (flag)? 1: detect("timed out");
X flag = (flag)? 1: detect("Not connected");
X flag = (flag)? 1: detect("not connected");
X flag = (flag)? 1: detect("not accessable");
X flag = (flag)? 1: detect("not accessible");
X flag = (flag)? 1: detect("not available");
X flag = (flag)? 1: detect("time out");
X flag = (flag)? 1: detect("times out");
X
X if (flag) { /* a bad connection, try again */
X printf("A bad connection, will try again.\n");
X /* remove the incomplete file if it exists */
X sprintf(cmd,"test -f '%s' && rm '%s'",lfile,lfile);
X system(cmd);
X exit(2); /* try again */
X }
X
X flag = detect("Transfer complete");
X flag = (flag)? 1:detect("received");
X if (flag != 0) {
X if (ftp_get_file) {
X fprintf(f_tmp,"=======File '%s'\n",rfile);
X fprintf(f_tmp,
X " successfully received as '%s'.=======\n",lfile);
X } else
X fprintf(f_tmp,"=======Transfer successfully completed.\n");
X exit(0); /* done for this RemoteFile */
X } else {
X flag = detect("Alarm call");
X if (ftp_get_file==0) {
X printf(" A silented connection. Will try again.\n");
X exit(2);
X }
X
X /* then check if too large a requested file */
X buf=(struct stat *)malloc(sizeof(struct stat));
X stat(lfile,buf); /* get GMT time in seconds (from 12/31/1969
X 19:00:00) for the file being received
X since last modification. If the file
X does not exist, 0 is returned. */
X timeofday = time(&tloc); /* get current time */
X /* if the file was modified in last 5 minutes*/
X if (timeofday - buf->st_mtime < 300) {
X if (flag == 0) fprintf(f_tmp,
X "***I am confused. But most likely the chance is:\n");
X fprintf(f_tmp, "%s\n%s%s%s%s%s\n%s%s%s\n",
X "***'alarm' in autoftp30.sh appears too small for remote file",
X " '",rfile,"' (to be received as '",lfile,"').",
X " File '",lfile,"' removed, increase the 'alarm' and try again.");
X /* remove the incomplete file (it must exist
X since the difference is < 300) */
X sprintf(cmd,"rm '%s'",lfile);
X system(cmd);
X exit(0); /* abort this request, do not try any more. */
X } else {
X if (flag == 0)
X printf("***I am confused. But most likely the chance is:\n");
X printf(" A silented connection. Will try again.\n");
X /* remove the file if it exists. */
X sprintf(cmd,"test -f '%s' && rm '%s'",lfile,lfile);
X system(cmd);
X exit(2); /* do not abort this request, try again. */
X }
X }
X}
X
X/* detect(s)
X * returns 1 if string s is in the file f_err and f_out that have been
X * read into array hold.
X */
Xdetect(s)
Xchar *s;
X{
X int i,flag;
X
X for (i=0; i<ctr && ((flag=substring(hold[i],s))==0); i++);
X return(flag);
X}
X
X/* substring:
X * returns 1 if s2 is a substring of s1, 0 otherwise.
X */
Xsubstring(s1,s2)
Xchar *s1,*s2;
X{
X int i,l1,l2,found;
X
X l1 = strlen(s1);
X l2 = strlen(s2);
X
X found = 1;
X for (i=0; i<=l1-l2 && found!=0; i++)
X found = strncmp(s1+i,s2,l2);
X
X return(found==0);
X}
X
X/* getline(s,fin,fout)
X* reads an input line from file fin, and skips null chars, count
X* the number of letters in the input file (result kept in global var
X* letter). All non-null characters are written to fout to eliminate
X* numerous annoying null character (inserted by ftp?) that causes very
X* slow scrolling when using MORE of UNIX to display the file fin.
X* return 0 if eof.
X*/
Xgetline(s,fin,fout)
Xchar s[];
XFILE *fin,*fout;
X{
X char c;
X int i,cc; /* cc used to avoid machine dependent comparison
X of getc()'s return value to EOF */
X
X i = 0;
X while( ((cc=getc(fin)) != EOF) && i <= max_line_length) {
X c=cc;
X if (c=='\n')
X { s[i]='\0'; putc(c,fout); return(1); }
X else
X if (c != '\0') {
X putc(c,fout);
X if (c > 64 && c < 91 || c > 96 && c < 123 )
X { letter++; s[i++]=c; }
X else
X if (c==' ') s[i++]=c;
X }
X }
X
X if (i>max_line_length)
X { fprintf(f_tmp,"%s\n%s\n",
X "***'max_line_length' in checkout.c appears too small.",
X " Please increase it, recompile and try again!");
X exit(99);
X }
X
X s[i] = '\0';
X return(0);
X}
X
X/* extract3(s,s0,s1,s2)
X* extracts 3 substring from s to s0, s1 and s2, where
X* blanks, tabs are delimiters, new line character is ignored. S is
X* terminated by a null character as usual, so will s0, s1 and s3.
X*/
Xextract3(s,s0,s1,s2)
Xchar s[],s0[],s1[],s2[];
X{
X int i,head,tail,ptr,l;
X
X l = strlen(s); tail=0;
X for (i=0;i<3;i++) {
X ptr=0;
X head=tail;
X while(s[head]==' ' || /* skip blanks, tabs and new line */
X s[head]==9 ||
X s[head]=='\n') head++;
X tail=head;
X
X while(tail<l &&
X s[tail]!=' '&& /* stop if a blank, tab or NL is seen */
X s[tail]!=9 &&
X s[tail]!='\n')
X switch(i) {
X case 0: s0[ptr++]=s[tail++]; break;
X case 1: s1[ptr++]=s[tail++]; break;
X case 2: s2[ptr++]=s[tail++]; break;
X }
X switch(i) {
X case 0: s0[ptr]='\0'; break;
X case 1: s1[ptr]='\0'; break;
X case 2: s2[ptr]='\0'; break;
X }
X }
X}
X
SHAR_EOF
if test 10184 -ne "`wc -c < 'checkout.c'`"
then
echo shar: "error transmitting 'checkout.c'" '(should have been 10184 characters)'
fi
fi
echo shar: "extracting 'ftpget.c'" '(2525 characters)'
if test -f 'ftpget.c'
then
echo shar: "will not over-write existing file 'ftpget.c'"
else
sed 's/^ X//' << \SHAR_EOF > 'ftpget.c'
X/*
X * ftpget.c by Mingqi Deng, July 6, 1989
X *
X * makes one attempt to get a file from a remote host.
X *
X * Compile:
X * cc -o ftpget ftpget.c
X * Execute:
X * ftpget alarm remotehost ftp_script
X * where
X * alarm :- the number in seconds that an ftp attempt can last
X * ftp_script :- ftp command script created by nextfile.c
X *
X * Example:
X * ftpget 3600 wsmr-simtel20.army.mil 123ftp_script
X * Note :
X * 1. The maximum number of characters contained on ftpget's command
X * line is defined in the constant ftpget_cmd_line_length. The
X * default is 160.
X * 2. The host name is assumed to have no more than 80 characters.
X * Adjust the constant hostname_length if necessary.
X */
X
X#include <stdio.h>
X#include <signal.h>
X
Xint id,pgid,mask;
X
X#define ftpget_cmd_line_length 160
X#define hostname_length 80
X
Xmain(argc, argv)
Xint argc;
Xchar *argv[];
X{
X unsigned t_alarm;
X char cmd[ftpget_cmd_line_length+1];
X void handler();
X FILE *f;
X
X if (argc != 3) {
X fprintf(stderr,"***Type 'ftpget alarm ftp.script' to run\n");
X exit(99);
X }
X /* check if file ftp_script exists. */
X f = fopen(argv[2],"r");
X if (f == NULL) {
X fprintf(stderr,"***Ftp script file '%s' does not exist.\n",argv[2]);
X exit(99);
X }
X fclose(f);
X
X sscanf(argv[1],"%u",&t_alarm);
X if (t_alarm < 300) {
X fprintf(stderr,"***'alarm'(= %d < 300) in autoftp30.sh too small!\n",t_alarm);
X exit(99);
X }
X
X mask=sigsetmask(0); /* do not block any signals */
X id=getpid(); pgid=getpgrp(id); /* get process group id */
X setpgrp(id,pgid+1); /* modify process group id so that only this
X and all of its subprocesses (with this id)
X can be terminated by a signal */
X signal(SIGALRM,handler); /* catch the alarm signal and use procedure
X "handler" to process it */
X /* create a command "ftp remotehost < ftp_script" to
X be run in current shell (instead of a subshell)*/
X sprintf(cmd,"exec ftp -n < '%s'",argv[2]);
X
X alarm(t_alarm); /* timing the system call next: send a SIGALRM
X signal to the current process after t_alarm
X many seconds */
X system(cmd); /* execute "ftp remotehost < ftp_script" */
X alarm(0); /* stop the alarm if "cmd" ends before the alarm
X call*/
X}
X
X/* SIGALRM signal handling */
Xvoid handler()
X{
X fprintf(stderr,"Alarm call!\n");
X killpg(pgid+1,SIGHUP); /* kill the current process and its
X subprocess (ftp ....) */
X exit(5);
X}
SHAR_EOF
if test 2525 -ne "`wc -c < 'ftpget.c'`"
then
echo shar: "error transmitting 'ftpget.c'" '(should have been 2525 characters)'
fi
fi
echo shar: "extracting 'nextfile.c'" '(12936 characters)'
if test -f 'nextfile.c'
then
echo shar: "will not over-write existing file 'nextfile.c'"
else
sed 's/^ X//' << \SHAR_EOF > 'nextfile.c'
X/*
X * nextfile.c by Mingqi Deng, July 6, 1989
X *
X * get next requested file from an input file and prepare an ftp
X * script file for ftpget.c (cf. ftpget.c) The requested file
X * will be deleted from the input file.
X *
X * Compile:
X * cc -o nextfile nextfile.c
X * Execute:
X * nextfile in_file RemoteHost login password ftp_script
X * where
X * in_file :- input file to autoftp30.sh (cf. README) that consists
X * of two types of lines:
X * a) Device-directory line (DDL):
X * Format:
X * -d|c|l device_directory_name [dir_file]
X * where
X * "-d" :- the name on that line is a device_directory_name
X * that defines the directory where a subsequently
X * requested file resides, at the remote host.
X * This flag requires one name after the option.
X * "-c" :- a request to change the local directory so that
X * requested files will be put into that directory.
X * The name on that line is an existing local
X * directory. This flag requires one name after
X * the option, too.
X * "-l" :- a request to obtain a directory listing for the
X * remote directory named on that line. This flag
X * requires two names after the option: the name
X * of the remote directory, and the name of the
X * file to which the listing is to be stored.
X * Example:
X * -d PD1:<MSDOS.DSKUTL>
X * -l PD:<ANONYMOUS> root.dirlst
X * -c download
X * Function:
X * A "-d" DDL line defines the directory from which all
X * files on the subsequent file-lines, up to a new "-d"
X * DDL line, are to be fetched.
X * A "-l" DDL line gets a directory listing.
X * A "-c" DDL line changes the local directory PERMANANTLY
X * upto next "-c" DDL line.
X *
X * b) File lines (FL):
X * Format:
X * [-a|b|8|t] RemoteFile [LocalFile]
X * where:
X * a,b,8,t are flags of options:
X * "-a" :- a file is to be transferred in ASCII mode
X * "-b" :- a file is to be transferred in binary mode
X * "-t" or "-8"
X * :- a file is to be transferred in tenex mode
X * (32->8 bits conversion, which is the mode
X * you should use if you are ftp'ing into
X * SIMTEL20 from a DEC VAX or a SUN)
X * If the option is omitted, the default is "-t".
X * RemoteFile is the requested file's name at the remote host
X * LocalFile (optional) is the file name under which the
X * RemoteFile is to be received at the local machine.
X * If it is omitted, the default is RemoteFile.
X * Examples:
X * -a 00-INDEX.TXT DSKUTL.IDX
X * -8 BACKEZ.ARC
X * DISCACHE.ARC CACHE.ARC
X * TIMEPARK.ARC
X * -a VDSK.ASM
X * Functions:
X * An FL line specifies the name of a requested file
X * (whose directory is specified by a preceding DDL line),
X * and the transfer mode for the file.
X * *NOTE*
X * 1) An option on an FL line must NOT be omitted if the
X * RemoteFile starts with a "-". And only the first letter
X * of an option is effective.
X * 2) Options and names are separated by blanks or TABs.
X * No other delimiters can be used.
X * 3) There can be more than one blank or TAB between the
X * options and names.
X * 4) There can be blanks or TABs before an option. But
X * nothing should be inserted between "-" and a flag.
X * 5) A DDL or FL line can appear anywhere in an input file
X * though some sequence may not be meaningful.
X * 6) The input file may contain any number of blank line
X * anywhere. They are simply ignored.
X * 7) The file name on an FL line, and directory names on a
X * "-d" or "-l" DDL line can be either in lower or upper
X * case. This makes no difference as far as autoftp30.sh is
X * concerned. However, all options must be in lower case.
X *
X * RemoteHost:- the host name of the anonymous ftp session
X * login :- the login id for the anonymous ftp session
X * password :- the password for the anonymous ftp session
X * ftp_script:- the output file that consists of ftp commands
X *
X * Example:
X * nextfile 123input WSMR-SIMTEL20.ARMY.MIL anonymous guest 123ftp.script
X * Note :
X * 1. The maximum number of characters contained on each line in
X * file in_file (cf. sample.dat) is no more than max_line_length.
X * The default is 80. Adjust it if necessary.
X * 2. The constant TENEX in the second "#define" may need adjusting.
X * Instead of being '"tenex"', it may have to be '"type L 8"',
X * '"type local"' or '"type local byte"'. Do a "man ftp" to see
X * how your system wants it.
X */
X
X#include <stdio.h>
X#include <string.h>
X
X#define max_line_length 80
X#define TENEX "tenex"
X
Xmain(argc, argv)
Xint argc;
Xchar *argv[];
X{
X int no_more, /* 1 if end of file */
X dir_path, /* 1 if a DDL line of -d option seen */
X chdir_req, /* 1 if an lcd request on current DDL*/
X not_done, /* contol while loop */
X to_chdir, /* 1 if a pending lcd request */
X chdir_flg, /* 1 if an lcd request seen */
X action; /* 1 if usful request (dir, get) seen */
X char cmd[80],type[10],*dummy=NULL,
X op_flg, option(),
X s1[max_line_length+1],
X s2[max_line_length+1],
X chdir_name[max_line_length+1],/* local dir name to chage to */
X dir1[max_line_length+1], /* remote dir name to get dir list */
X dir2[max_line_length+1], /* file to get remote dir list */
X dpath[max_line_length+1]; /* the directory path in DDL line*/
X FILE *fin,*fftp;
X
X if (argc != 6) {
X fprintf(stderr,
X "***Usage: nextfile input RemoteHost login password ftp.script\n");
X exit(3);
X }
X if ( (fin = fopen(argv[1],"r")) == NULL) {
X fprintf(stderr,"***The input file does not exist!\n"); exit(3);
X }
X
X /* Create an ftp command file which will be executed once
X ftp starts up. This is true no matter whether a login
X failed or not. A quit command is always issued. */
X fftp = fopen(argv[5],"w");
X fprintf(fftp,"open %s\n",argv[2]);
X fprintf(fftp,"user %s %s\n",argv[3],argv[4]);
X fprintf(fftp,"type ascii\n");
X fprintf(fftp,"verbose\n");
X
X action=0; dir_path=0; to_chdir=0; chdir_flg=0; chdir_flg=0;
X not_done=1;
X while (not_done) {
X /* process a sequence of DDL lines with -c option */
X no_more=lcd(fin,chdir_name,&chdir_req,&op_flg,s1,s2);
X if (chdir_req) { to_chdir = 1; /* delay issuing lcd command, since
X only the last one is effective */
X chdir_flg = 1; /* neet to remember the lcd for
X subsequent file transfer */
X }
X
X if (no_more) {
X printf("=======Last request .......\n");
X if (action==0)
X printf( "***Warning: No files requested!\n");
X fprintf(fftp,"bye\n");
X fclose(fftp);
X update_fin(fin,argv[1],dummy,0,dummy);
X exit(0);
X }
X /* if not eof, is it a DDL or FL line? */
X if (op_flg == 'l') {
X if (s1[0] == '\0' || s2[0] == '\0') {
X fprintf(stderr,
X "***Invalid '-l' DDL line in the input file!\n");
X exit(3);
X }
X if (to_chdir)
X { fprintf(fftp,"lcd %s\n",chdir_name); to_chdir=0; }
X fprintf(fftp,"cd %s\n",s1); /* note that ascii mode was set */
X fprintf(fftp,"dir *.* %s\n",s2);
X action=1;
X } else
X if (op_flg == 'd') {
X if (s1[0]=='\0') {
X fprintf(stderr,
X "***Invalid device-directory-line(DDL) in the input file!\n");
X exit(3);
X }
X dir_path=1;
X strcpy(dpath,s1);
X } else { /* not a -c, -l, or -d line, must be an FL line */
X if (dir_path==0) { /* no -d DDL line seen yet */
X fprintf(stderr,
X "***Device-directory line missing in the input file!\n");
X exit(3);
X }
X not_done = 0;
X }
X } /* of while */
X if (to_chdir) /* delayed lcd: only the last lcd is effective*/
X fprintf(fftp,"lcd %s\n",chdir_name);
X
X /******* process an FL line *****/
X if (s1[0]=='\0') {
X fprintf(stderr,"***The requested file name is blank!\n");
X exit(3);
X }
X if (s2[0]=='\0') strcpy(s2,s1);
X
X /* set the file transfer mode */
X if (op_flg == 'b') strcpy(type,"binary");
X if (op_flg == 't') strcpy(type,TENEX);
X if (op_flg == '8') strcpy(type,TENEX);
X
X printf("=======Start requesting file %s .........\n",s1);
X /* type ascii has been set at the beginning */
X if (op_flg != 'a') fprintf(fftp,"type %s\n", type);
X fprintf(fftp,"get %s%s %s\nbye\n",dpath,s1,s2);
X fclose(fftp);
X
X update_fin(fin,argv[1],dpath,chdir_flg,chdir_name);
X}
X
X/* gets next non-blank line from file fin, return 1 if EOF */
Xnextline(s,f)
Xchar *s;
XFILE *f;
X{
X char *p;
X
X while( (p=fgets(s,max_line_length,f)) != NULL)
X if (nonblank(s)) break;
X return(p==NULL);
X}
X
X/* nonblank(s)
X* returns true (non-zero) if s contains non-blank chars.
X*/
Xnonblank(s)
Xchar *s;
X{
X int i,flag;
X
X if (s==NULL) return(0);
X i = 0; flag = 0;
X for (i=0; i<strlen(s) && flag==0; i++)
X flag = (s[i]==' ' || s[i]==9 || s[i]=='\n' )? 0:1; /* 9 is tab*/
X return(flag);
X}
X
X/* extract(s,num,s0,s1,s2)
X* extracts num (1-3) many substring from s to s0, s1 and s2, where
X* blanks, tabs are delimiters, new line character is ignored. S is
X* terminated by a null character as usual, so will s0, s1 and s3.
X* Depending on s, any of s0, s1 or s2 can be an empty string.
X*/
Xextract(s,num,s0,s1,s2)
Xchar s[],s0[],s1[],s2[];
Xint num;
X{
X int i,head,tail,ptr,l;
X
X l = strlen(s); tail=0;
X for (i=0;i<num;i++) {
X ptr=0;
X head=tail;
X while(s[head]==' ' || /* skip blanks, tabs and new line
X ('\0' is after '\n') */
X s[head]==9 ||
X s[head]=='\n') head++;
X tail=head;
X
X while(tail<l && /* stop if end of the string s */
X s[tail]!=' '&& /* stop if a blank, tab or NL is seen */
X s[tail]!=9 &&
X s[tail]!='\n')
X switch(i) {
X case 0: s0[ptr++]=s[tail++]; break;
X case 1: s1[ptr++]=s[tail++]; break;
X case 2: s2[ptr++]=s[tail++]; break;
X }
X switch(i) {
X case 0: s0[ptr]='\0'; break;
X case 1: s1[ptr]='\0'; break;
X case 2: s2[ptr]='\0'; break;
X }
X }
X}
X
X/*
X * extract options of a non-blank input line, detects invalid options,
X * and will "insert" '-t' option to a default FL line. When returning,
X * s2 and s3 are set to the 2nd and 3rd string on the line.
X */
Xchar option(s,n,s2,s3)
Xchar *s,*s2,*s3;
Xint n;
X{
X char s1[max_line_length+1];
X
X extract(s,n,s1,s2,s3);
X if (s1[0] != '-') { /* default FL line option (-t) */
X strcpy(s3,s2); /* re-set s2 and s3 */
X strcpy(s2,s1);
X return('t');
X }
X if (s1[1] == '8') return('8');
X if (s1[1] == 'a') return('a');
X if (s1[1] == 'b') return('b');
X if (s1[1] == 'c') return('c');
X if (s1[1] == 'd') return('d');
X if (s1[1] == 'l') return('l');
X if (s1[1] == 't') return('t');
X /* unrecognizable option */
X fprintf(stderr, "***Invalid option in the input file!\n");
X exit(3);
X}
X
X/*
X * process a sequence of DDL lines with -c flags. note that only
X * last -c line retains its effect.
X */
Xlcd(f,chdir_name,chdir_req,op_flg,s1,s2)
Xint *chdir_req;
Xchar *op_flg,*chdir_name,*s1,*s2;
XFILE *f;
X{
X int chdir_line,flg;
X char c,s0[max_line_length+1];
X
X *chdir_req=0;
X
X chdir_line = 1;
X while (chdir_line) {
X
X flg=nextline(s0,f);
X if (flg) return(1); /* eof encountered, s0 is NULL */
X
X c=option(s0,3,s1,s2);
X if (c=='c') { *chdir_req=1; strcpy(chdir_name,s1); }
X else chdir_line = 0;
X }
X *op_flg = c;
X return(0);
X}
X
X/*
X * update the input file to delete the processed requests
X */
Xupdate_fin(fin,nfin,dpath,chdir_flg,chdir_name)
Xint chdir_flg; /* 1 if an lcd opertion was performed. */
Xchar *dpath, /* directory path in the last DDL (-d) line */
X *nfin, /* name of the input file */
X *chdir_name; /* name of the local directory changed to */
XFILE *fin; /* file pointer for the input file */
X{
X char name[10],s[max_line_length+1];
X int pid;
X FILE *ftmp;
X
X pid=getpid();
X sprintf(name,"%d%tmp",pid);
X ftmp = fopen(name,"w");
X /* save the DDL line if there is more FL in the input*/
X if ( nextline(s,fin) == 0 ) { /* if more non-blank lines */
X if (chdir_flg)
X fprintf(ftmp,"-c %s\n",chdir_name);
X fprintf(ftmp, "-d %s\n",dpath);
X fputs(s,ftmp);
X while ( fgets(s,max_line_length,fin) != NULL) fputs(s,ftmp);
X }
X fclose(fin);
X fclose(ftmp);
X
X /* replace in_file by the temporary file (maybe empty) */
X sprintf(s,"rm '%s'",nfin);
X system(s);
X /* rename the tmp_file to in_file */
X sprintf(s,"mv '%s' '%s'",name,nfin);
X system(s);
X}
SHAR_EOF
if test 12936 -ne "`wc -c < 'nextfile.c'`"
then
echo shar: "error transmitting 'nextfile.c'" '(should have been 12936 characters)'
fi
fi
echo shar: "extracting 'sample.dat'" '(262 characters)'
if test -f 'sample.dat'
then
echo shar: "will not over-write existing file 'sample.dat'"
else
sed 's/^ X//' << \SHAR_EOF > 'sample.dat'
X-l PS:<ANONYMOUS> root.dirlst
X-d PD1:<MSDOS.DSKUTL>
X-a 00-INDEX.TXT DSKUTL.IDX
X-8 DISCACHE.ARC CACHE.ARC
X TIMEPARK.ARC
X-a VDSK.ASM
X-d PD1:<MSDOS.SYSUTL>
X-a 00-INDEX.TXT SYSUTL.IDX
X BENCH410.ARC
X-a BOOTCODE.ASM
X CNFGTXT.ARC
X DOS33HLP.ARC
X DOS33PAT.ARC
SHAR_EOF
if test 262 -ne "`wc -c < 'sample.dat'`"
then
echo shar: "error transmitting 'sample.dat'" '(should have been 262 characters)'
fi
fi
exit 0
# End of shell archive
O /
----------------X---------------- Cut Here
O \
--
_
Kevin D. Quitt demott!kdq kdq at demott.com
DeMott Electronics Co. 14707 Keswick St. Van Nuys, CA 91405-1266
VOICE (818) 988-4975 FAX (818) 997-1190 MODEM (818) 997-4496 PEP last
More information about the Alt.sources
mailing list