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

  1. /*
  2.  * checkout.c by Mingqi Deng, July 6, 1989
  3.  *
  4.  *    checks the result of an ftp attempt made by autoftp30.sh (cf. 
  5.  *    ftpget.c) to get a file from a remote host.
  6.  *
  7.  *  Compile:  
  8.  *             cc -o checkout checkout.c
  9.  *  Execute:
  10.  *             checkout f_stdout f_stderr ftp_script f_tmp
  11.  *    where:
  12.  *      f_stdout   :- the standard output file used by ftpget.c
  13.  *      f_stderr   :- the standard error-message file used by ftpget.c
  14.  *      ftp_script :- the ftp command script file created by nextfile(.c)
  15.  *      f_tmp      :- a temporary file for deleting null chars in
  16.  *              f_stderr and f_stdout, also used as stderr by
  17.  *                    checkout(.c) for most of its error messages.
  18.  *
  19.  *  Exit status:
  20.  *         99  : fatal error, quit this session of autoftp30.sh
  21.  *          0  : finish an attempt, no further attempt should be made
  22.  *         on this requested file (either file successfully 
  23.  *          received, ALARM in autoftp30.sh too small, or a wrong 
  24.  *         file name)
  25.  *        2  : a failed attempt that should be retried
  26.  *
  27.  *  Example:   
  28.  *            checkout 1234stdout 1234stderr 1234ftp.script 1234tmp
  29.  *
  30.  *  Note   :
  31.  *     Two constants max_line_length and max_line defined on the
  32.  *     "#define" lines below specify the maximum length of lines in
  33.  *     f_stderr and f_stdout, and the maximum number of lines in them
  34.  *     altogether.In case they are not large enough (your will get a 
  35.  *     message saying so), increase them.
  36.  */
  37.  
  38. #include <stdio.h>
  39. #include <sys/types.h>
  40. #include <sys/stat.h>
  41. #include <sys/timeb.h>
  42.  
  43. #define max_line_length    160
  44. #define max_line           400
  45.  
  46. char hold[max_line][max_line_length+1];
  47. int  ctr,     /* number of lines in f_stderr and f_stdout */
  48.      letter;  /* number of letters in f_stderr and f_stdout */
  49. FILE *f_tmp;
  50.  
  51. main(argc, argv)
  52. int argc;
  53. char *argv[];
  54. {
  55.   int flag,ftp_get_file;
  56.   char cmd[80],s[80],s1[80],s2[80],*rfile,*lfile,*sprintf(),*malloc();
  57.   FILE *f_err, *f_out, *f_ftp;
  58.   struct stat *buf;
  59.   time_t tloc,timeofday;
  60.  
  61.   f_tmp = fopen(argv[4],"w");
  62.   if (argc != 5) {
  63.      fprintf(stderr,"***Usage: checkout stdout stderr ftp_script f_tmp\n");
  64.      exit(99);
  65.   }
  66.   f_out = fopen(argv[1],"r");
  67.   f_err = fopen(argv[2],"r");
  68.   f_ftp = fopen(argv[3],"r");
  69.   if (f_err == NULL || f_out == NULL || f_ftp == NULL) 
  70.      { fprintf(f_tmp,"***File(s) '%s', '%s' or '%s' do not exist\n",
  71.            argv[1],argv[2],argv[3]);
  72.        exit(99);}
  73.  
  74.   ctr=0; letter=0;      /* read in the stdout file of the ftp session*/
  75.   while ((ctr<max_line) && (getline(hold[ctr],f_out,f_tmp)!=0)) ctr++;
  76.   if (ctr == max_line) {
  77.      fprintf(f_tmp,"%s\n%s\n%s\n",
  78.       "***Increase the constant 'max_line' on the '#define' line",
  79.       "   in file checkout.c, recompile it, then try again!");
  80.      exit(99);
  81.   }
  82.  
  83.                         /* read in the stderr file of the ftp session*/
  84.   while ((ctr<max_line) && (getline(hold[ctr],f_err,f_tmp)!=0)) ctr++;
  85.   if (ctr == max_line) {
  86.      fprintf(f_tmp,"%s\n%s\n%s\n",
  87.       "***Increase the constant 'max_line' on the '#define' line",
  88.       "   in file checkout.c, recompile it, then try again!");
  89.      exit(99);
  90.   }
  91.   if (letter==0)     /* empty file: a silent connection, try again */
  92.       { printf("A silent connection, will try again.\n"); exit(2);} 
  93.    
  94.   flag  = detect("unknown host");
  95.   flag  = (flag)? 1: detect("Unknown host");
  96.   if (flag) {
  97.          /* wrong remote host name, quit attempt for this run */
  98.      fprintf(f_tmp,"***host unknown: check RemoteHost in autoftp30.sh!\n"); 
  99.      exit(99);   
  100.   }
  101.  
  102.            /* get the requested file names from the ftp script file 
  103.         if a 'get' is performed. */
  104.   ftp_get_file=0;
  105.   while( fgets(s,max_line_length,f_ftp) != NULL)
  106.      if (strncmp(s,"get",3) == 0) {
  107.            extract3(s,s1,s1,s2);
  108.            if (s1[0]!='\0') { rfile = s1; }
  109.            else {
  110.          fprintf(f_tmp,"***Invalid ftp_script file '%s'\n",argv[3]);
  111.               exit(99);
  112.            }
  113.        if (s2[0]!='\0') lfile=s2;
  114.            else             lfile=s1;
  115.        ftp_get_file=1;
  116.      }
  117.  
  118.   flag = detect("Invalid use of terminal designator"); 
  119.   flag = (flag)? 1:detect("File not accessible");
  120.   flag = (flag)? 1:detect("File not accessable");
  121.   flag = (flag)? 1:detect("file not found");
  122.   flag = (flag)? 1:detect("File not found");
  123.   flag = (flag)? 1:detect("not found");
  124.   flag = (flag)? 1:detect("No such file");
  125.   flag = (flag)? 1:detect("No such directory");
  126.  
  127.   if (flag) {
  128.          /* wrong remote file name, quit attempt for this file */
  129.      if (ftp_get_file) 
  130.         fprintf(f_tmp,
  131.         "***Remote file/direcortory %s not found!\n",rfile); 
  132.      else 
  133.         fprintf(f_tmp, "***Remote direcortory not found!\n"); 
  134.      exit(0);    /* abort the current request */
  135.   }
  136.   
  137.   flag = detect("refused");
  138.   flag = (flag)? 1: detect("unreachable");
  139.   flag = (flag)? 1: detect("failed");
  140.   flag = (flag)? 1: detect("Connection timed out");
  141.   flag = (flag)? 1: detect("timed out");
  142.   flag = (flag)? 1: detect("Not connected");
  143.   flag = (flag)? 1: detect("not connected");
  144.   flag = (flag)? 1: detect("not accessable");
  145.   flag = (flag)? 1: detect("not accessible");
  146.   flag = (flag)? 1: detect("not available");
  147.   flag = (flag)? 1: detect("time out");
  148.   flag = (flag)? 1: detect("times out");
  149.  
  150.   if (flag) {        /* a bad connection, try again */
  151.       printf("A bad connection, will try again.\n"); 
  152.             /* remove the incomplete file if it exists */
  153.       sprintf(cmd,"test -f '%s' && rm '%s'",lfile,lfile);
  154.       system(cmd);
  155.       exit(2);   /* try again */
  156.   }
  157.  
  158.   flag  = detect("Transfer complete");
  159.   flag  = (flag)? 1:detect("received");
  160.   if (flag != 0)  {
  161.       if (ftp_get_file) {
  162.          fprintf(f_tmp,"=======File '%s'\n",rfile);
  163.          fprintf(f_tmp,
  164.         "       successfully received as '%s'.=======\n",lfile);
  165.       } else
  166.          fprintf(f_tmp,"=======Transfer successfully completed.\n");
  167.       exit(0);  /* done for this RemoteFile */
  168.   } else {
  169.       flag = detect("Alarm call");
  170.       if (ftp_get_file==0) {
  171.          printf("   A silented connection. Will try again.\n");
  172.          exit(2);
  173.       }
  174.  
  175.          /* then check if too large a requested file */
  176.       buf=(struct stat *)malloc(sizeof(struct stat));
  177.       stat(lfile,buf);    /* get GMT time in seconds (from 12/31/1969
  178.                 19:00:00) for the file being received 
  179.                 since last modification. If the file 
  180.                 does not exist, 0 is returned. */
  181.       timeofday = time(&tloc);   /* get current time */
  182.         /* if the file was modified in last 5 minutes*/
  183.       if (timeofday - buf->st_mtime < 300)  {
  184.          if (flag == 0) fprintf(f_tmp, 
  185.         "***I am confused. But most likely the chance is:\n");
  186.          fprintf(f_tmp, "%s\n%s%s%s%s%s\n%s%s%s\n",
  187.           "***'alarm' in autoftp30.sh appears too small for remote file",
  188.           "   '",rfile,"' (to be received as '",lfile,"').",
  189.           "   File '",lfile,"' removed, increase the 'alarm' and try again.");
  190.          /* remove the incomplete file (it must exist
  191.                since the difference is < 300)  */
  192.           sprintf(cmd,"rm '%s'",lfile);
  193.           system(cmd);
  194.       exit(0);   /* abort this request, do not try any more. */
  195.       } else {
  196.          if (flag == 0) 
  197.         printf("***I am confused. But most likely the chance is:\n");
  198.          printf("   A silented connection. Will try again.\n");
  199.             /* remove the file if it exists. */
  200.      sprintf(cmd,"test -f '%s' && rm '%s'",lfile,lfile);
  201.          system(cmd);
  202.      exit(2);   /* do not abort this request, try again. */
  203.       } 
  204.   } 
  205. }
  206.  
  207. /* detect(s)
  208.  *   returns 1 if string s is in the file f_err and f_out that have been
  209.  * read into array hold.
  210.  */
  211. detect(s)
  212. char *s;
  213. {
  214.   int i,flag;
  215.  
  216.   for (i=0; i<ctr && ((flag=substring(hold[i],s))==0); i++);
  217.   return(flag);
  218. }
  219.  
  220. /* substring:
  221.  *   returns 1 if s2 is a substring of s1, 0 otherwise.
  222.  */
  223. substring(s1,s2)
  224. char *s1,*s2;
  225. {
  226.    int i,l1,l2,found;
  227.  
  228.    l1 = strlen(s1); 
  229.    l2 = strlen(s2); 
  230.   
  231.    found = 1; 
  232.    for (i=0; i<=l1-l2 && found!=0; i++) 
  233.        found = strncmp(s1+i,s2,l2);
  234.  
  235.    return(found==0);
  236. }
  237.  
  238. /* getline(s,fin,fout)
  239. *      reads an input line from file fin, and skips null chars, count 
  240. *  the number of letters in the input file (result kept in global var
  241. *  letter). All non-null characters are written to fout to eliminate
  242. *  numerous annoying null character (inserted by ftp?) that causes very
  243. *  slow scrolling when using MORE of UNIX to display the file fin.
  244. *      return 0 if eof.
  245. */
  246. getline(s,fin,fout)
  247. char s[];
  248. FILE *fin,*fout;
  249. {
  250.    char c;
  251.    int  i,cc;  /* cc used to avoid machine dependent comparison
  252.                   of getc()'s return value to EOF */
  253.  
  254.    i = 0; 
  255.    while( ((cc=getc(fin)) != EOF) && i <= max_line_length) {
  256.       c=cc;
  257.       if (c=='\n') 
  258.            { s[i]='\0'; putc(c,fout); return(1); }
  259.       else 
  260.            if (c != '\0') { 
  261.            putc(c,fout);
  262.                 if (c > 64 && c < 91 || c > 96 && c < 123 ) 
  263.              { letter++; s[i++]=c; }
  264.                 else 
  265.              if (c==' ')  s[i++]=c;
  266.        }
  267.    }
  268.  
  269.    if (i>max_line_length) 
  270.        { fprintf(f_tmp,"%s\n%s\n",
  271.            "***'max_line_length' in checkout.c appears too small.",
  272.            "   Please increase it, recompile and try again!");
  273.          exit(99);
  274.        }
  275.   
  276.    s[i] = '\0';
  277.    return(0);
  278. }
  279.  
  280. /* extract3(s,s0,s1,s2)
  281. *     extracts 3 substring from s to s0, s1 and s2, where 
  282. *   blanks, tabs are delimiters, new line character is ignored. S is 
  283. *   terminated by a null character as usual, so will s0, s1 and s3.
  284. */
  285. extract3(s,s0,s1,s2)
  286. char s[],s0[],s1[],s2[];
  287. {
  288.    int i,head,tail,ptr,l;
  289.  
  290.    l = strlen(s); tail=0;
  291.    for (i=0;i<3;i++) {
  292.        ptr=0;
  293.        head=tail;
  294.        while(s[head]==' ' ||  /* skip blanks, tabs and new line */
  295.          s[head]==9   ||
  296.          s[head]=='\n') head++;
  297.        tail=head;
  298.  
  299.        while(tail<l      &&  
  300.          s[tail]!=' '&&   /* stop if a blank, tab or NL is seen */
  301.          s[tail]!=9  &&
  302.          s[tail]!='\n')  
  303.           switch(i) {
  304.               case 0:  s0[ptr++]=s[tail++]; break;
  305.               case 1:  s1[ptr++]=s[tail++]; break;
  306.               case 2:  s2[ptr++]=s[tail++]; break;
  307.           }
  308.         switch(i) {
  309.               case 0:  s0[ptr]='\0'; break;
  310.               case 1:  s1[ptr]='\0'; break;
  311.               case 2:  s2[ptr]='\0'; break;
  312.         }
  313.    }
  314. }
  315.  
  316.