home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / usenet / altsrcs / 1 / 1429 / xtp.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-12-28  |  29.9 KB  |  1,030 lines

  1. /*
  2. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  3. %                                                                             %
  4. %                                                                             %
  5. %                                                                             %
  6. %                            X   X  TTTTT PPPP                                %
  7. %                             X X     T   P   P                               %
  8. %                              X      T   PPPP                                %
  9. %                             X X     T   P                                   %
  10. %                            X   X    T   P                                   %
  11. %                                                                             %
  12. %                                                                             %
  13. %                         File transfer program.                              %
  14. %                                                                             %
  15. %                                                                             %
  16. %                                                                             %
  17. %                           Software Design                                   %
  18. %                             John Cristy                                     %
  19. %                            February 1989                                    %
  20. %                                                                             %
  21. %                                                                             %
  22. %  Copyright 1990 E. I. Dupont de Nemours & Company                           %
  23. %                                                                             %
  24. %  Permission to use, copy, modify, distribute, and sell this software and    %
  25. %  its documentation for any purpose is hereby granted without fee,           %
  26. %  provided that the above copyright notice appear in all copies and that     %
  27. %  both that copyright notice and this permission notice appear in            %
  28. %  supporting documentation, and that the name of E. I. Dupont de Nemours     %
  29. %  & Company not be used in advertising or publicity pertaining to            %
  30. %  distribution of the software without specific, written prior               %
  31. %  permission.  E. I. Dupont de Nemours & Company makes no representations    %
  32. %  about the suitability of this software for any purpose.  It is provided    %
  33. %  "as is" without express or implied warranty.                               %
  34. %                                                                             %
  35. %  E. I. Dupont de Nemours & Company disclaims all warranties with regard     %
  36. %  to this software, including all implied warranties of merchantability      %
  37. %  and fitness, in no event shall E. I. Dupont de Nemours & Company be        %
  38. %  liable for any special, indirect or consequential damages or any           %
  39. %  damages whatsoever resulting from loss of use, data or profits, whether    %
  40. %  in an action of contract, negligence or other tortious action, arising     %
  41. %  out of or in connection with the use or performance of this software.      %
  42. %                                                                             %
  43. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  44. %
  45. %  Xtp is a utility for retrieving, listing, or printing files from a remote
  46. %  network site.
  47. %
  48. %  This program was adapted from a similiar program written by Steve Singles,
  49. %  University of Delaware.
  50. %
  51. %  Command syntax:
  52. %
  53. %  Usage: xtp [-options ...] <host/ip address> [ <home directory> ]
  54. %  
  55. %  Where options include:
  56. %    -binary                retrieve files as binary
  57. %    -exclude expression    exclude files that match the expression
  58. %    -directory expression  list file names that match the expression
  59. %    -ident password        specifies password
  60. %    -print expression      print files that match the expression
  61. %    -retrieve expression   retrieve files that match the expression
  62. %    -timeout seconds       specifies maximum seconds to logon host
  63. %    -user name             identify yourself to the remote FTP server
  64. %
  65. %
  66. */
  67.  
  68. /*
  69.   Include declarations.
  70. */
  71. #include <stdio.h>
  72. #include <ctype.h>
  73. #include <signal.h>
  74. #include <strings.h>
  75. #include <sys/file.h>
  76. #include <sys/types.h>
  77. #include <sys/time.h>
  78. #include <sys/socket.h>
  79. #include <sys/wait.h>
  80. #include "regular.h"
  81. /*
  82.   Define declarations.
  83. */
  84. #define False  0
  85. #define True  1
  86. /*
  87.   Variable declarations.
  88. */
  89. char
  90.   *malloc(),
  91.   *program_name,
  92.   *sprintf(),
  93.   *slave_tty[16],
  94.   *Wait();
  95.  
  96. int
  97.   binary,
  98.   master;
  99.  
  100. RegularExpression
  101.   *directory_expression,
  102.   *exclude_expression,
  103.   *print_expression,
  104.   *retrieve_expression;
  105.  
  106. /*
  107. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  108. %                                                                             %
  109. %                                                                             %
  110. %                                                                             %
  111. %   D i r e c t o r y  R e q u e s t                                          %
  112. %                                                                             %
  113. %                                                                             %
  114. %                                                                             %
  115. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  116. %
  117. %
  118. */
  119. void DirectoryRequest(fileinfo,filename)
  120. char
  121.   *fileinfo,
  122.   *filename;
  123. {
  124.   (void) fprintf(stdout,"%s %s\n",fileinfo,filename);
  125. }
  126.  
  127. /*
  128. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  129. %                                                                             %
  130. %                                                                             %
  131. %                                                                             %
  132. %   E r r o r                                                                 %
  133. %                                                                             %
  134. %                                                                             %
  135. %                                                                             %
  136. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  137. %
  138. %
  139. */
  140. void Error(error)
  141. char
  142.   *error;
  143. {
  144.   char
  145.     message[80];
  146.  
  147.   (void) sprintf(message,"%s: %s",program_name,error);
  148.   perror(message);
  149.   exit(1);
  150. }
  151.  
  152. /*
  153. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  154. %                                                                             %
  155. %                                                                             %
  156. %                                                                             %
  157. %   E x e c u t e F t p                                                       %
  158. %                                                                             %
  159. %                                                                             %
  160. %                                                                             %
  161. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  162. %
  163. %
  164. */
  165. void ExecuteFtp(hostname)
  166. char
  167.   *hostname;
  168. {
  169. #include <sys/ioctl.h>
  170.  
  171.   int
  172.     slave;
  173.  
  174.   struct ltchars
  175.     lc;
  176.  
  177.   struct sgttyb
  178.     b;
  179.  
  180.   struct tchars
  181.     tc;
  182.  
  183.   (void) signal(SIGTSTP,SIG_IGN);
  184.   if (isatty(0))
  185.     {
  186.       int
  187.         tty;
  188.  
  189.       tty=open("/dev/tty",O_RDWR);
  190.       if (tty >= 0)
  191.         {
  192.           (void) ioctl(tty,TIOCNOTTY,(char *) 0);
  193.           (void) close(tty);
  194.         }
  195.     }
  196.   slave=open((char *) slave_tty,O_RDWR);
  197.   if (slave < 0)
  198.     Error((char *) slave_tty);
  199.   /*
  200.     Fix tty line.
  201.   */
  202.   (void) ioctl(slave,TIOCGETP,&b);
  203.   b.sg_flags&=~(ECHO | CRMOD);
  204.   b.sg_erase=(-1);
  205.   b.sg_kill=(-1);
  206.   (void) ioctl(slave,TIOCSETP,&b);
  207.   tc.t_intrc=(-1);
  208.   tc.t_quitc=(-1);
  209.   tc.t_startc=(-1);
  210.   tc.t_stopc=(-1);
  211.   tc.t_eofc=(-1);
  212.   tc.t_brkc=(-1);
  213.   (void) ioctl(slave,TIOCSETC,&tc);
  214.   lc.t_suspc=(-1);
  215.   lc.t_dsuspc=(-1);
  216.   lc.t_rprntc=(-1);
  217.   lc.t_flushc=(-1);
  218.   lc.t_werasc=(-1);
  219.   lc.t_lnextc=(-1);
  220.   (void) ioctl(slave,TIOCSLTC,&lc);
  221.   (void) close(master);
  222.   (void) dup2(slave,0);
  223.   (void) dup2(slave,1);
  224.   (void) dup2(slave,2);
  225.   (void) close(slave);
  226.   (void) execl("/usr/ucb/ftp","ftp","-n","-i","-g",hostname,(char *) 0);
  227.   perror("/usr/ucb/ftp");
  228.   (void) kill(0,SIGTERM);
  229. }
  230.  
  231. /*
  232. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  233. %                                                                             %
  234. %                                                                             %
  235. %                                                                             %
  236. %   F e t c h R e q u e s t                                                   %
  237. %                                                                             %
  238. %                                                                             %
  239. %                                                                             %
  240. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  241. %
  242. %
  243. */
  244. void FetchRequest(filename)
  245. char
  246.   *filename;
  247. {
  248.   char
  249.     command[256],
  250.     *p,
  251.     *response;
  252.  
  253.   /*
  254.     get remote-file local-file
  255.   */
  256.   p=filename+strlen(filename);
  257.   while ((p > filename) && (*--p != '/'));
  258.   if (*p == '/')
  259.     p++;
  260.   (void) sprintf(command,"get %s %s\n",filename,p);
  261.   (void) write(master,command,strlen(command));
  262.   (void) fprintf(stdout,"%s retrieved.\n",filename);
  263.   while (response=Wait())
  264.     (void) fprintf(stdout,"%s\n",response);
  265. }
  266.  
  267. /*
  268. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  269. %                                                                             %
  270. %                                                                             %
  271. %                                                                             %
  272. %   G e t H o s t I n f o                                                     %
  273. %                                                                             %
  274. %                                                                             %
  275. %                                                                             %
  276. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  277. %
  278. %
  279. */
  280. void GetHostInfo(host)
  281. char
  282.   *host;
  283. {
  284. #include <netinet/in.h>
  285. #include <netdb.h>
  286. #include <arpa/inet.h>
  287.  
  288.   char
  289.     *address,
  290.     *inet_ntoa(),
  291.     *p;
  292.  
  293.   struct in_addr
  294.     in;
  295.  
  296.   struct hostent
  297.     *hp;
  298.  
  299.   if (isdigit(*host))
  300.     {
  301.       /*
  302.          Internet address to name.
  303.       */
  304.       in.s_addr=inet_addr(host);
  305.       hp=gethostbyaddr(&in.s_addr,sizeof(in.s_addr),AF_INET);
  306.       if (hp != (struct hostent *) NULL)
  307.         {
  308.           hp=gethostbyname(hp->h_name);
  309.           if (hp != (struct hostent *) NULL)
  310.             {
  311.               in.s_addr= *(int *) hp->h_addr;
  312.               address=inet_ntoa(in);
  313.             }
  314.         }
  315.     }
  316.   else
  317.     {
  318.       /*
  319.          Internet name to address.
  320.       */
  321.       hp=gethostbyname(host);
  322.       if (hp != (struct hostent *) NULL)
  323.         {
  324.           in.s_addr= *(int *) hp->h_addr;
  325.           address=inet_ntoa(in);
  326.           hp=gethostbyaddr(&in.s_addr,sizeof(in.s_addr),AF_INET);
  327.         }
  328.     }
  329.   if (hp == (struct hostent *) NULL)
  330.     (void) fprintf(stdout,"%s: ",host);
  331.   else
  332.     {
  333.       p=hp->h_name;
  334.       while (*p)
  335.       {
  336.         if (isupper(*p))
  337.           *p=tolower(*p);
  338.         p++;
  339.       }
  340.       (void) fprintf(stdout,"%s [%s]: ",hp->h_name,address);
  341.     }
  342. }
  343.  
  344. /*
  345. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  346. %                                                                             %
  347. %                                                                             %
  348. %                                                                             %
  349. %   G e t P s e u d o T e r m i n a l                                         %
  350. %                                                                             %
  351. %                                                                             %
  352. %                                                                             %
  353. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  354. %
  355. %
  356. */
  357. void GetPseudoTerminal()
  358. {
  359. #include <sys/stat.h>
  360.  
  361.   char
  362.     *master_tty[16];
  363.  
  364.   register char
  365.     *bank,
  366.     *cp;
  367.  
  368.   struct stat
  369.     info;
  370.  
  371.   for (bank="pqrs"; *bank; bank++)
  372.   {
  373.     (void) sprintf((char *) master_tty,"/dev/pty%c0",*bank);
  374.     if (stat(master_tty,&info) < 0)
  375.       break;
  376.     for (cp="0123456789abcdef"; *cp; cp++)
  377.     {
  378.       (void) sprintf((char *) master_tty,"/dev/pty%c%c",*bank,*cp);
  379.       master=open((char *) master_tty,O_RDWR);
  380.       if (master >= 0)
  381.         {
  382.           /*
  383.             Verify slave side is usable.
  384.           */
  385.           (void) sprintf((char *) slave_tty,"/dev/tty%c%c",*bank,*cp);
  386.           if (access((char *) slave_tty,R_OK | W_OK) == 0)
  387.             return;
  388.           (void) close(master);
  389.         }
  390.     }
  391.   }
  392.   Error("All network ports in use.\n");
  393. }
  394.  
  395. /*
  396. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  397. %                                                                             %
  398. %                                                                             %
  399. %                                                                             %
  400. %   P r i n t R e q u e s t                                                   %
  401. %                                                                             %
  402. %                                                                             %
  403. %                                                                             %
  404. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  405. %
  406. %
  407. */
  408. void PrintRequest(filename)
  409. char
  410.   *filename;
  411. {
  412.   char
  413.     command[256],
  414.     *response;
  415.  
  416.   /*
  417.     get remote-file [ - | <| zcat> ].
  418.   */
  419.   (void) sprintf(command,"get %s",filename);
  420.   (void) write(master,command,strlen(command));
  421.   if (strcmp(filename+strlen(filename)-2,".Z"))
  422.     (void) sprintf(command," -\n");
  423.   else
  424.     (void) sprintf(command," | zcat\n");
  425.   (void) write(master,command,strlen(command));
  426.   (void) fprintf(stdout,"%s:\n",filename);
  427.   while (response=Wait())
  428.     (void) fprintf(stdout,"%s\n",response);
  429. }
  430.  
  431. /*
  432. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  433. %                                                                             %
  434. %                                                                             %
  435. %                                                                             %
  436. %   P r o c e s s R e q u e s t                                               %
  437. %                                                                             %
  438. %                                                                             %
  439. %                                                                             %
  440. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  441. %
  442. %
  443. */
  444. void ProcessRequest()
  445. {
  446.   typedef struct _DirectoryNode
  447.   {
  448.     char
  449.       *info,
  450.       *name;
  451.  
  452.     struct _DirectoryNode
  453.       *next;
  454.   } DirectoryNode;
  455.  
  456.   char
  457.     command[256],
  458.     directory[1024],
  459.     *info,
  460.     *name,
  461.     *response;
  462.  
  463.   DirectoryNode
  464.     *next,
  465.     *root;
  466.  
  467.   int
  468.     unix_filesystem;
  469.  
  470.   register char
  471.     *p;
  472.  
  473.   register DirectoryNode
  474.     **last,
  475.     *node;
  476.  
  477.   RegularExpression
  478.     *expression;
  479.  
  480.   /*
  481.     Initialize function variables.
  482.   */
  483.   root=(DirectoryNode *) NULL;
  484.   last=(&root);
  485.   *directory=(char) NULL;
  486.   unix_filesystem=False;
  487.   /*
  488.     Unix-style filesystem if the first character is a '-' or last is '/'.
  489.   */
  490.   (void) strcpy(command,"dir\n");
  491.   (void) write(master,command,strlen(command));
  492.   response=Wait();
  493.   if (response == (char *) NULL)
  494.     return;
  495.   expression=CompileRegularExpression("[dbclps-][rwx-][rwx-][rwx-]");
  496.   while (response=Wait())
  497.   {
  498.     if (*response == (char) NULL)
  499.       continue;
  500.     if (ExecuteRegularExpression(expression,response))
  501.       unix_filesystem=True; 
  502.   }
  503.   free((char *) expression);
  504.   /*
  505.     Issue directory command to ftp program.
  506.   */
  507.   if (unix_filesystem)
  508.     (void) strcpy(command,"dir -R\n");
  509.   else
  510.     (void) strcpy(command,"dir [...]\n");
  511.   (void) write(master,command,strlen(command));
  512.   response=Wait();
  513.   if (response == (char *) NULL)
  514.     return;
  515.   response=Wait();
  516.   if (response == (char *) NULL)
  517.     {
  518.       /*
  519.         Directory command has limited functionality.
  520.       */
  521.       (void) strcpy(command,"dir\n");
  522.       (void) write(master,command,strlen(command));
  523.       response=Wait();
  524.       if (response == (char *) NULL)
  525.         return;
  526.     }
  527.   expression=CompileRegularExpression("Permission denied|not found");
  528.   if (!unix_filesystem)
  529.     while (response=Wait())
  530.     {
  531.       /*
  532.         Link non unix-style file into file list.
  533.       */
  534.       while (*response == ' ')
  535.         response++;
  536.       if (*response == (char) NULL)
  537.         continue;
  538.       p=response;
  539.       while ((*p != ' ') && *p)
  540.         p++;
  541.       if (*p)
  542.         {
  543.           /*
  544.             Extract file info.
  545.           */
  546.           *p++=(char) NULL;
  547.           while (*p == ' ')
  548.             p++;
  549.         }
  550.       info=(char *) malloc((unsigned int) (strlen(p)+1));
  551.       name=(char *) malloc((unsigned int) (strlen(response)+1));
  552.       if ((info == (char *) NULL) || (name == (char *) NULL))
  553.         {
  554.           (void) fprintf(stderr,"Can't continue, not enough memory\n");
  555.           exit(1);
  556.         }
  557.       (void) strcpy(info,p);
  558.       (void) strcpy(name,response);
  559.       if (exclude_expression)
  560.         if (ExecuteRegularExpression(exclude_expression,name))
  561.           {
  562.             (void) free(name);
  563.             (void) free(info);
  564.             continue;
  565.           }
  566.       node=(DirectoryNode *) malloc(sizeof(DirectoryNode));
  567.       if (node == (DirectoryNode *) NULL)
  568.         {
  569.           (void) fprintf(stderr,"Can't continue, not enough memory\n");
  570.           exit(1);
  571.         }
  572.       node->name=name;
  573.       node->info=info;
  574.       node->next=(DirectoryNode *) NULL;
  575.       *last=node;
  576.       last=(&node->next);
  577.     }
  578.   else
  579.     while (response=Wait())
  580.     {
  581.       /*
  582.          Link unix-style file into file list.
  583.       */
  584.       while (*response == ' ')
  585.         response++;
  586.       if (*response == (char) NULL)
  587.         continue;
  588.       p=response+strlen(response)-1;
  589.       if (*response == '-')
  590.         {
  591.           if (ExecuteRegularExpression(expression,response))
  592.             continue;
  593.           /*
  594.              Extract file name;  assume date followed by file name.
  595.           */
  596.           response++;
  597.           while (p > response)
  598.             if (*p-- == ' ')
  599.               if (isdigit(*p))
  600.                 break;
  601.           while (*++p == ' ');
  602.           p--;
  603.           *p++=(char) NULL;
  604.           info=(char *) malloc((unsigned int) (strlen(response)+1));
  605.           name=(char *) malloc((unsigned int) (strlen(directory)+strlen(p)+1));
  606.           if ((info == (char *) NULL) || (name == (char *) NULL))
  607.             {
  608.               (void) fprintf(stderr,"Can't continue, not enough memory\n");
  609.               exit(1);
  610.             }
  611.           (void) strcpy(info,response);
  612.           (void) strcpy(name,directory);
  613.           (void) strcat(name,p);
  614.           if (exclude_expression)
  615.             if (ExecuteRegularExpression(exclude_expression,name))
  616.               {
  617.                 (void) free(name);
  618.                 (void) free(info);
  619.                 continue;
  620.               }
  621.           node=(DirectoryNode *) malloc(sizeof(DirectoryNode));
  622.           if (node == (DirectoryNode *) NULL)
  623.             {
  624.               (void) fprintf(stderr,"Can't continue, not enough memory\n");
  625.               exit(1);
  626.             }
  627.           node->name=name;
  628.           node->info=info;
  629.           node->next=(DirectoryNode *) NULL;
  630.           *last=node;
  631.           last=(&node->next);
  632.         }
  633.       else
  634.         if (*p == ':')
  635.           {
  636.             /*
  637.               File is a directory.
  638.             */
  639.             *p='/';
  640.             (void) strcpy(directory,response);
  641.           }
  642.       }
  643.   free((char *) expression);
  644.   /*
  645.     Traverse file list.
  646.   */
  647.   node=root;
  648.   while (node)
  649.   {
  650.     if (directory_expression)
  651.       if (ExecuteRegularExpression(directory_expression,node->name))
  652.         (void) DirectoryRequest(node->info,node->name);
  653.     if (retrieve_expression)
  654.       if (ExecuteRegularExpression(retrieve_expression,node->name))
  655.         (void) FetchRequest(node->name);
  656.     if (print_expression)
  657.       if (ExecuteRegularExpression(print_expression,node->name))
  658.         (void) PrintRequest(node->name);
  659.     /*
  660.       Free allocated memory for this node.
  661.     */
  662.     (void) free(node->info);
  663.     (void) free(node->name);
  664.     next=node->next;
  665.     (void) free((char *) node);
  666.     node=next;
  667.   }
  668. }
  669.  
  670. /*
  671. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  672. %                                                                             %
  673. %                                                                             %
  674. %                                                                             %
  675. %   S i g n a l C h i l d                                                     %
  676. %                                                                             %
  677. %                                                                             %
  678. %                                                                             %
  679. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  680. %
  681. %
  682. */
  683. void SignalChild()
  684. {
  685.   char
  686.     message[256];
  687.  
  688.   int
  689.     status;
  690.  
  691.   (void) sprintf(message,"child died, status %x",wait(&status));
  692.   Error(message);
  693. }
  694.  
  695. /*
  696. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  697. %                                                                             %
  698. %                                                                             %
  699. %                                                                             %
  700. %   U s a g e                                                                 %
  701. %                                                                             %
  702. %                                                                             %
  703. %                                                                             %
  704. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  705. %
  706. %  Procedure Usage displays the program usage;
  707. %
  708. %  The format of the Usage routine is:
  709. %
  710. %      Usage(message)
  711. %
  712. %  A description of each parameter follows:
  713. %
  714. %    o message:  Specifies a specific message to display to the user.
  715. %
  716. %
  717. */
  718. void Usage(message)
  719. char
  720.   *message;
  721. {
  722.   char
  723.     **p;
  724.  
  725.   static char
  726.     *options[]=
  727.     {
  728.       "-binary                retrieve files as binary",
  729.       "-exclude expression    exclude files that match the expression",
  730.       "-directory expression  list file names that match the expression",
  731.       "-ident password        specifies password",
  732.       "-print expression      print files that match the expression",
  733.       "-retrieve expression   retrieve files that match the expression",
  734.       "-timeout seconds       specifies maximum seconds to logon host",
  735.       "-user name             identify yourself to the remote FTP server",
  736.       "-verbose               show all responses from the remote server",
  737.       NULL
  738.     };
  739.   if (message)
  740.     (void) fprintf(stderr,"Can't continue, %s\n\n",message);
  741.   (void) fprintf(stderr,
  742.     "Usage: %s [-options ...] <host/ip address> [ <home directory> ]\n",
  743.     program_name);
  744.   (void) fprintf(stderr,"\nWhere options include:\n");
  745.   for (p=options; *p; *p++)
  746.     (void) fprintf(stderr,"  %s\n",*p);
  747.   exit(1);
  748. }
  749.  
  750. /*
  751. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  752. %                                                                             %
  753. %                                                                             %
  754. %                                                                             %
  755. %   W a i t                                                                   %
  756. %                                                                             %
  757. %                                                                             %
  758. %                                                                             %
  759. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  760. %
  761. %
  762. */
  763. char *Wait()
  764. {
  765.   register char
  766.     *p;
  767.  
  768.   static char
  769.     buffer[1024],
  770.     *q;
  771.  
  772.   static char
  773.     line[1024];
  774.  
  775.   static int
  776.     count=0;
  777.  
  778.   p=line;
  779.   do
  780.   {
  781.     if (count <= 0) 
  782.       {
  783.         count=read(master,buffer,sizeof(buffer));
  784.         q=buffer;
  785.         if (count <= 0)
  786.           {
  787.             if (p == line)
  788.               return((char *) NULL);
  789.             break;
  790.           }
  791.       }
  792.     count--;
  793.     *p=(*q++);
  794.     if (*p == '\n')
  795.       break;
  796.     p++;
  797.     if ((p-line) >= 5)
  798.       if (!strncmp(p-5,"ftp> ",5))
  799.         if (count == 0)
  800.           return((char *) NULL);
  801.   } while (p < (line+sizeof(line)));
  802.   *p=(char) NULL;
  803.   return(line);
  804. }
  805.  
  806. /*
  807. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  808. %                                                                             %
  809. %                                                                             %
  810. %                                                                             %
  811. %   m a i n                                                                   %
  812. %                                                                             %
  813. %                                                                             %
  814. %                                                                             %
  815. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  816. %
  817. %
  818. */
  819. main(argc,argv)
  820. int
  821.   argc;
  822.  
  823. register char
  824.   **argv;
  825. {
  826.   char
  827.     command[256],
  828.     *ident,
  829.     *home_directory,
  830.     *hostname,
  831.     *user;
  832.  
  833.   int
  834.     child,
  835.     status;
  836.  
  837.   register char
  838.     *p;
  839.  
  840.   unsigned int
  841.     timeout,
  842.     verbose;
  843.  
  844.   /*
  845.     Initialize program variables.
  846.   */
  847.   binary=False;
  848.   directory_expression=(RegularExpression *) NULL;
  849.   exclude_expression=(RegularExpression *) NULL;
  850.   ident=(char *) NULL;
  851.   print_expression=(RegularExpression *) NULL;
  852.   retrieve_expression=(RegularExpression *) NULL;
  853.   timeout=0;
  854.   user=(char *) NULL;
  855.   program_name=argv[0];
  856.   verbose=False;
  857.   /*
  858.     Parse command line arguments.
  859.   */
  860.   for (p=(*argv++); *argv && (**argv == '-'); argv++)
  861.     switch (argv[0][1])
  862.     {
  863.       case 'b':
  864.       {
  865.         binary++;
  866.         break;
  867.       }
  868.       case 'd':
  869.       {
  870.         directory_expression=CompileRegularExpression(*++argv);
  871.         if (!directory_expression)
  872.           exit(1);
  873.         break;
  874.       }
  875.       case 'e':
  876.       {
  877.         exclude_expression=CompileRegularExpression(*++argv);
  878.         if (!exclude_expression)
  879.           exit(1);
  880.         break;
  881.       }
  882.       case 'i':
  883.       {
  884.         ident=(*++argv);
  885.         break;
  886.       }
  887.       case 'p':
  888.       {
  889.         print_expression=CompileRegularExpression(*++argv);
  890.         if (!print_expression)
  891.           exit(1);
  892.         break;
  893.       }
  894.       case 'r':
  895.       {
  896.         retrieve_expression=CompileRegularExpression(*++argv);
  897.         if (!retrieve_expression)
  898.           exit(1);
  899.         break;
  900.       }
  901.       case 't':
  902.       {
  903.         timeout=atoi(*++argv);
  904.         break;
  905.       }
  906.       case 'u':
  907.       {
  908.         user=(*++argv);
  909.         break;
  910.       }
  911.       case 'v':
  912.       {
  913.         verbose++;
  914.         break;
  915.       }
  916.       default:
  917.       {
  918.         Usage((char *) NULL);
  919.         break;
  920.       }
  921.     }
  922.   if ((argc < 2) || (*argv == (char *) NULL))
  923.     Usage((char *) NULL);
  924.   hostname=argv[0];
  925.   home_directory=argv[1];
  926.   if (!directory_expression && !retrieve_expression && !print_expression)
  927.     directory_expression=CompileRegularExpression("");
  928.   if ((ident == (char *) NULL) && (user == (char *) NULL))
  929.     {
  930.       static char
  931.         name[256];
  932.  
  933.       /*
  934.         Identify user as user@host.domain.
  935.       */
  936.       if (getlogin())
  937.         (void) strcpy(name,getlogin());
  938.       else
  939.         (void) strcpy(name,getpwuid(getuid()));
  940.       p=name+strlen(name);
  941.       *p++='@';
  942.       (void) gethostname(p,64);
  943.       while (*p)
  944.       p++;
  945.       (void) getdomainname(p,64);
  946.       user="anonymous";
  947.       ident=name;
  948.     }
  949.   else
  950.     if (ident == (char *) NULL)
  951.       ident=(char *) getpass("Password: ");
  952.     else
  953.       user="anonymous";
  954.   (void) GetHostInfo(hostname);
  955.   if (!home_directory)
  956.     (void) fprintf(stdout,"\n");
  957.   else
  958.     (void) fprintf(stdout,"%s\n",home_directory);
  959.   (void) GetPseudoTerminal();
  960.   /*
  961.     Connect and logon to host.
  962.   */
  963.   (void) signal(SIGCHLD,SignalChild);
  964.   if (timeout > 0)
  965.     (void) alarm(timeout);  /* enable timer. */
  966.   child=fork();
  967.   if (child < 0)
  968.     Error("fork");
  969.   if (child == 0)
  970.     ExecuteFtp(hostname);
  971.   while (p=Wait())
  972.     (void) fprintf(stderr,"%s\n",p);
  973.   (void) sprintf(command,"user %s %s\n",user,ident);
  974.   (void) write(master,command,strlen(command));
  975.   while (p=Wait())
  976.     (void) fprintf(stderr,"%s\n",p);
  977.   if (timeout > 0)
  978.     (void) alarm(0);  /* disable timer. */
  979.   (void) fprintf(stderr,"\n");
  980.   if (!verbose)
  981.     {
  982.       (void) strcpy(command,"verbose off\n");
  983.       (void) write(master,command,strlen(command));
  984.       while (Wait()); 
  985.     }
  986.   if (home_directory)
  987.     {
  988.       /*
  989.         Change remote working directory.
  990.       */
  991.       (void) sprintf(command,"cd %s\n",home_directory);
  992.       (void) write(master,command,strlen(command));
  993.       while (Wait()); 
  994.       (void) strcpy(command,"pwd\n");
  995.       (void) write(master,command,strlen(command));
  996.       while (p=Wait())
  997.         (void) fprintf(stderr,"%s\n",p);
  998.     }
  999.   if (binary)
  1000.     {
  1001.       /*
  1002.         Set file transfer type.
  1003.       */
  1004.       (void) strcpy(command,"type binary\n");
  1005.       (void) write(master,command,strlen(command));
  1006.       while (Wait()); 
  1007.       (void) write(master,command,strlen(command));
  1008.       (void) strcpy(command,"type\n");
  1009.       while (p=Wait())
  1010.         (void) fprintf(stderr,"%s\n",p);
  1011.     }
  1012.   (void) strcpy(command,"runique\n");
  1013.   (void) write(master,command,strlen(command));
  1014.   while (Wait()); 
  1015.   ProcessRequest();
  1016.   (void) strcpy(command,"quit\n");
  1017.   (void) write(master,command,strlen(command));
  1018.   (void) signal(SIGCHLD,SIG_DFL);
  1019.   /*
  1020.     Wait for child to finish.
  1021.   */
  1022.   while (child != wait(&status));
  1023.   (void) close(master);
  1024.   free((char *) directory_expression);
  1025.   free((char *) exclude_expression);
  1026.   free((char *) print_expression);
  1027.   free((char *) retrieve_expression);
  1028.   return(0);
  1029. }
  1030.