home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / usenet / altsrcs / 2 / 2317 / nextfile.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-12-28  |  12.6 KB  |  385 lines

  1. /*
  2.  * nextfile.c by Mingqi Deng, July 6, 1989
  3.  *
  4.  *     get next requested file from an input file and prepare an ftp
  5.  *     script file for ftpget.c (cf. ftpget.c) The requested file
  6.  *     will be deleted from the input file.
  7.  *
  8.  *  Compile:  
  9.  *           cc -o nextfile nextfile.c
  10.  *  Execute:
  11.  *           nextfile in_file RemoteHost login password ftp_script
  12.  *    where
  13.  *      in_file   :- input file to autoftp30.sh (cf. README) that consists
  14.  *             of two types of lines:
  15.  *       a) Device-directory line (DDL):
  16.  *               Format:   
  17.  *              -d|c|l  device_directory_name [dir_file]
  18.  *          where 
  19.  *            "-d" :- the name on that line is a device_directory_name
  20.  *            that defines the directory where a subsequently
  21.  *            requested file resides, at the remote host.
  22.  *            This flag requires one name after the option.
  23.  *            "-c" :- a request to change the local directory so that
  24.  *            requested files will be put into that directory.
  25.  *            The name on that line is an existing local
  26.  *            directory. This flag requires one name after
  27.  *            the option, too.
  28.  *            "-l" :- a request to obtain a directory listing for the
  29.  *            remote directory named on that line. This flag
  30.  *            requires two names after the option: the name
  31.  *            of the remote directory, and the name of the
  32.  *            file to which the listing is to be stored.
  33.  *            Example:
  34.  *            -d PD1:<MSDOS.DSKUTL>
  35.  *            -l PD:<ANONYMOUS> root.dirlst
  36.  *             -c download
  37.  *           Function:
  38.  *                 A "-d" DDL line defines the directory from which all
  39.  *           files on the subsequent file-lines, up to a new "-d"
  40.  *           DDL line, are to be fetched.
  41.  *                    A "-l" DDL line gets a directory listing.
  42.  *           A "-c" DDL line changes the local directory PERMANANTLY
  43.  *           upto next "-c" DDL line.
  44.  * 
  45.  *            b) File lines (FL):
  46.  *             Format:
  47.  *               [-a|b|8|t] RemoteFile [LocalFile]
  48.  *             where:
  49.  *                a,b,8,t are flags of options:
  50.  *                "-a" :- a file is to be transferred in ASCII mode 
  51.  *              "-b" :- a file is to be transferred in binary mode 
  52.  *              "-t" or "-8" 
  53.  *                :- a file is to be transferred in tenex mode
  54.  *                (32->8 bits conversion, which is the mode
  55.  *                you should use if you are ftp'ing into
  56.  *                SIMTEL20 from a DEC VAX or a SUN)
  57.  *           If the option is omitted, the default is "-t".
  58.  *             RemoteFile is the requested file's name at the remote host
  59.  *             LocalFile (optional) is the file name under which the 
  60.  *           RemoteFile is to be received at the local machine.
  61.  *                   If it is omitted, the default is RemoteFile.
  62.  *            Examples:
  63.  *            -a     00-INDEX.TXT  DSKUTL.IDX
  64.  *            -8     BACKEZ.ARC
  65.  *            DISCACHE.ARC    CACHE.ARC
  66.  *            TIMEPARK.ARC
  67.  *            -a    VDSK.ASM
  68.  *        Functions:
  69.  *                An FL line specifies the name of a requested file 
  70.  *          (whose directory is specified by a preceding DDL line),
  71.  *           and the transfer mode for the file.
  72.  *         *NOTE*
  73.  *          1) An option on an FL line must NOT be omitted if the 
  74.  *        RemoteFile starts with a "-". And only the first letter
  75.  *        of an option is effective.
  76.  *            2) Options and names are separated by blanks or TABs.
  77.  *          No other delimiters can be used. 
  78.  *          3) There can be more than one blank or TAB between the 
  79.  *        options and names. 
  80.  *          4) There can be blanks or TABs before an option. But 
  81.  *        nothing should be inserted between "-" and a flag.
  82.  *          5) A DDL or FL line can appear anywhere in an input file
  83.  *        though some sequence may not be meaningful.
  84.  *          6) The input file may contain any number of blank line
  85.  *        anywhere. They are simply ignored.
  86.  *          7) The file name on an FL line, and directory names on a 
  87.  *        "-d" or "-l" DDL line can be either in lower or upper 
  88.  *        case. This makes no difference as far as autoftp30.sh is
  89.  *        concerned. However, all options must be in lower case.
  90.  *
  91.  *      RemoteHost:- the host name of the anonymous ftp session
  92.  *      login     :- the login id for the anonymous ftp session
  93.  *      password  :- the password for the anonymous ftp session
  94.  *      ftp_script:- the output file that consists of ftp commands
  95.  *
  96.  *  Example:   
  97.  *      nextfile 123input WSMR-SIMTEL20.ARMY.MIL anonymous guest 123ftp.script
  98.  *  Note   : 
  99.  *    1. The maximum number of characters contained on each line in
  100.  *       file in_file (cf. sample.dat) is no more than max_line_length. 
  101.  *       The default is 80. Adjust it if necessary.
  102.  *    2. The constant TENEX in the second "#define" may need adjusting.
  103.  *       Instead of being '"tenex"', it may have to be '"type L 8"', 
  104.  *       '"type local"' or '"type local byte"'.  Do a "man ftp" to see 
  105.  *       how your system wants it.
  106.  */
  107.  
  108. #include <stdio.h>
  109. #include <string.h>
  110.  
  111. #define max_line_length              80
  112. #define TENEX                       "tenex"
  113.  
  114. main(argc, argv)
  115. int argc;
  116. char *argv[];
  117. {
  118.   int  no_more,          /* 1 if end of file */
  119.        dir_path,          /* 1 if a DDL line of -d option seen */
  120.        chdir_req,          /* 1 if an lcd request on current DDL*/
  121.        not_done,         /* contol while loop */ 
  122.        to_chdir,          /* 1 if a pending lcd request */
  123.        chdir_flg,          /* 1 if an lcd request seen */
  124.        action;             /* 1 if usful request (dir, get) seen */
  125.   char cmd[80],type[10],*dummy=NULL,
  126.        op_flg, option(), 
  127.        s1[max_line_length+1],        
  128.        s2[max_line_length+1],       
  129.        chdir_name[max_line_length+1],/* local dir name to chage to */
  130.        dir1[max_line_length+1],      /* remote dir name to get dir list */
  131.        dir2[max_line_length+1],      /* file to get remote dir list */
  132.        dpath[max_line_length+1];     /* the directory path in DDL line*/
  133.   FILE *fin,*fftp;
  134.  
  135.   if (argc != 6) {
  136.      fprintf(stderr,
  137.      "***Usage: nextfile input RemoteHost login password ftp.script\n");
  138.      exit(3);
  139.   }
  140.   if ( (fin = fopen(argv[1],"r")) == NULL) {
  141.      fprintf(stderr,"***The input file does not exist!\n"); exit(3);
  142.   }
  143.  
  144.             /* Create an ftp command file which will be executed once 
  145.            ftp starts up. This is true no matter whether a login 
  146.            failed or not. A quit command is always issued. */
  147.   fftp = fopen(argv[5],"w");   
  148.   fprintf(fftp,"open %s\n",argv[2]);
  149.   fprintf(fftp,"user %s %s\n",argv[3],argv[4]);
  150.   fprintf(fftp,"type ascii\n");
  151.   fprintf(fftp,"verbose\n");
  152.  
  153.   action=0; dir_path=0; to_chdir=0; chdir_flg=0; chdir_flg=0;
  154.   not_done=1;
  155.   while (not_done) {
  156.         /* process a sequence of DDL lines with -c option */
  157.      no_more=lcd(fin,chdir_name,&chdir_req,&op_flg,s1,s2);
  158.      if (chdir_req) { to_chdir = 1; /* delay issuing lcd command, since 
  159.                       only the last one is effective */
  160.               chdir_flg = 1; /* neet to remember the lcd for
  161.                         subsequent file transfer */
  162.             }
  163.  
  164.      if (no_more) {
  165.         printf("=======Last request .......\n");
  166.         if (action==0)
  167.             printf( "***Warning: No files requested!\n"); 
  168.         fprintf(fftp,"bye\n");
  169.       fclose(fftp);
  170.     update_fin(fin,argv[1],dummy,0,dummy);
  171.         exit(0);
  172.      }
  173.            /* if not eof, is it a DDL or FL line? */
  174.      if (op_flg == 'l') {
  175.         if (s1[0] == '\0' || s2[0] == '\0') {
  176.            fprintf(stderr,
  177.          "***Invalid '-l' DDL line in the input file!\n");
  178.            exit(3); 
  179.         }
  180.         if (to_chdir)  
  181.        { fprintf(fftp,"lcd %s\n",chdir_name); to_chdir=0; }
  182.         fprintf(fftp,"cd %s\n",s1);   /* note that ascii mode was set */
  183.         fprintf(fftp,"dir *.* %s\n",s2);
  184.     action=1;
  185.   } else 
  186.      if (op_flg == 'd') {
  187.         if (s1[0]=='\0') {
  188.            fprintf(stderr,
  189.          "***Invalid device-directory-line(DDL) in the input file!\n");
  190.            exit(3); 
  191.         } 
  192.         dir_path=1;
  193.         strcpy(dpath,s1); 
  194.   } else {    /* not a -c, -l, or -d line, must be an FL line */
  195.       if (dir_path==0) {  /* no -d DDL line seen yet */
  196.          fprintf(stderr,
  197.         "***Device-directory line missing in the input file!\n");
  198.          exit(3); 
  199.       } 
  200.       not_done = 0;
  201.   }
  202.   }  /* of while */
  203.   if (to_chdir)     /* delayed lcd: only the last lcd is effective*/
  204.      fprintf(fftp,"lcd %s\n",chdir_name); 
  205.  
  206.    /*******  process an FL line *****/
  207.   if (s1[0]=='\0') {
  208.       fprintf(stderr,"***The requested file name is blank!\n");
  209.       exit(3); 
  210.   }
  211.   if (s2[0]=='\0') strcpy(s2,s1);
  212.  
  213.             /* set the file transfer mode */
  214.   if (op_flg == 'b')  strcpy(type,"binary");
  215.   if (op_flg == 't')  strcpy(type,TENEX);
  216.   if (op_flg == '8')  strcpy(type,TENEX);
  217.  
  218.   printf("=======Start requesting file %s .........\n",s1);
  219.     /* type ascii has been set at the beginning */
  220.   if (op_flg != 'a') fprintf(fftp,"type %s\n", type); 
  221.   fprintf(fftp,"get %s%s %s\nbye\n",dpath,s1,s2);
  222.   fclose(fftp);
  223.  
  224.   update_fin(fin,argv[1],dpath,chdir_flg,chdir_name);
  225. }
  226.  
  227. /* gets next non-blank line from file fin, return 1 if EOF  */
  228. nextline(s,f)
  229. char *s;
  230. FILE *f;
  231. {
  232.   char *p;
  233.  
  234.   while( (p=fgets(s,max_line_length,f)) != NULL) 
  235.        if (nonblank(s)) break; 
  236.   return(p==NULL);  
  237. }
  238.  
  239. /* nonblank(s)
  240. *      returns true (non-zero) if s contains non-blank chars.
  241. */
  242. nonblank(s)
  243. char *s;
  244. {
  245.   int i,flag;
  246.   
  247.   if (s==NULL) return(0);
  248.   i = 0; flag = 0;
  249.   for (i=0; i<strlen(s) && flag==0; i++) 
  250.     flag = (s[i]==' ' || s[i]==9 || s[i]=='\n' )? 0:1; /* 9 is tab*/
  251.   return(flag);
  252. }
  253.  
  254. /* extract(s,num,s0,s1,s2)
  255. *     extracts num (1-3) many substring from s to s0, s1 and s2, where 
  256. *   blanks, tabs are delimiters, new line character is ignored. S is 
  257. *   terminated by a null character as usual, so will s0, s1 and s3.
  258. *   Depending on s, any of s0, s1 or s2 can be an empty string.
  259. */
  260. extract(s,num,s0,s1,s2)
  261. char s[],s0[],s1[],s2[];
  262. int num;
  263. {
  264.    int i,head,tail,ptr,l;
  265.  
  266.    l = strlen(s); tail=0;
  267.    for (i=0;i<num;i++) {
  268.        ptr=0;
  269.        head=tail;
  270.        while(s[head]==' ' ||  /* skip blanks, tabs and new line 
  271.                  ('\0' is after '\n') */
  272.          s[head]==9   ||
  273.          s[head]=='\n') head++;
  274.        tail=head;
  275.  
  276.        while(tail<l      &&   /* stop if end of the string s */
  277.          s[tail]!=' '&&   /* stop if a blank, tab or NL is seen */
  278.          s[tail]!=9  &&
  279.          s[tail]!='\n')  
  280.           switch(i) {
  281.               case 0:  s0[ptr++]=s[tail++]; break;
  282.               case 1:  s1[ptr++]=s[tail++]; break;
  283.               case 2:  s2[ptr++]=s[tail++]; break;
  284.           }
  285.         switch(i) {
  286.               case 0:  s0[ptr]='\0'; break;
  287.               case 1:  s1[ptr]='\0'; break;
  288.               case 2:  s2[ptr]='\0'; break;
  289.         }
  290.    }
  291. }
  292.  
  293. /*
  294.  * extract options of a non-blank input line, detects invalid options,
  295.  * and will "insert" '-t' option to a default FL line. When returning,
  296.  * s2 and s3 are set to the 2nd and 3rd string on the line.
  297.  */
  298. char option(s,n,s2,s3)
  299. char *s,*s2,*s3;
  300. int n;
  301. {
  302.    char s1[max_line_length+1];
  303.  
  304.    extract(s,n,s1,s2,s3);
  305.    if (s1[0] != '-') {    /* default FL line option (-t) */
  306.       strcpy(s3,s2);      /* re-set s2 and s3 */
  307.       strcpy(s2,s1);
  308.       return('t');     
  309.    }
  310.    if (s1[1] == '8') return('8');
  311.    if (s1[1] == 'a') return('a');
  312.    if (s1[1] == 'b') return('b');
  313.    if (s1[1] == 'c') return('c');
  314.    if (s1[1] == 'd') return('d');
  315.    if (s1[1] == 'l') return('l');
  316.    if (s1[1] == 't') return('t');
  317.         /* unrecognizable option */
  318.    fprintf(stderr, "***Invalid option in the input file!\n");
  319.    exit(3); 
  320. }
  321.  
  322. /*
  323.  * process a sequence of DDL lines with -c flags. note that only
  324.  * last -c line retains its effect.
  325.  */
  326. lcd(f,chdir_name,chdir_req,op_flg,s1,s2)
  327. int  *chdir_req;
  328. char *op_flg,*chdir_name,*s1,*s2;
  329. FILE *f;
  330. {
  331.    int  chdir_line,flg;
  332.    char c,s0[max_line_length+1];
  333.  
  334.    *chdir_req=0;
  335.  
  336.    chdir_line = 1;
  337.    while (chdir_line) {
  338.  
  339.       flg=nextline(s0,f);
  340.       if (flg) return(1);  /* eof encountered, s0 is NULL */
  341.  
  342.       c=option(s0,3,s1,s2);
  343.       if (c=='c')   { *chdir_req=1; strcpy(chdir_name,s1); }
  344.       else            chdir_line = 0;
  345.    }
  346.    *op_flg = c;
  347.    return(0);
  348. }
  349.  
  350. /* 
  351.  * update the input file to delete the processed requests
  352.  */
  353. update_fin(fin,nfin,dpath,chdir_flg,chdir_name)
  354. int  chdir_flg;      /* 1 if an lcd opertion was performed. */
  355. char *dpath,         /* directory path in the last DDL (-d) line */
  356.      *nfin,             /* name of the input file */
  357.      *chdir_name;    /* name of the local directory changed to */
  358. FILE *fin;              /* file pointer for the input file */
  359.   char name[10],s[max_line_length+1];
  360.   int  pid;
  361.   FILE *ftmp;
  362.   
  363.   pid=getpid(); 
  364.   sprintf(name,"%d%tmp",pid);
  365.   ftmp = fopen(name,"w");
  366.             /* save the DDL line if there is more FL in the input*/
  367.   if ( nextline(s,fin) == 0 ) {   /* if more non-blank lines */
  368.       if (chdir_flg)
  369.     fprintf(ftmp,"-c %s\n",chdir_name);
  370.       fprintf(ftmp, "-d %s\n",dpath);
  371.       fputs(s,ftmp);
  372.       while ( fgets(s,max_line_length,fin) != NULL) fputs(s,ftmp); 
  373.   }
  374.   fclose(fin);
  375.   fclose(ftmp);
  376.  
  377.         /* replace in_file by the temporary file (maybe empty) */ 
  378.   sprintf(s,"rm '%s'",nfin);  
  379.   system(s);
  380.              /* rename the tmp_file to in_file */
  381.   sprintf(s,"mv '%s' '%s'",name,nfin);  
  382.   system(s);
  383. }
  384.