home *** CD-ROM | disk | FTP | other *** search
/ The Datafile PD-CD 3 / PDCD_3.iso / internet / tcpipsrc / FTP / c / ftpcli < prev    next >
Text File  |  1995-02-02  |  38KB  |  1,625 lines

  1. /* FTP client (interactive user) code */
  2. #define LINELEN         128     /* Length of command buffer */
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #include <string.h>
  6. #include <time.h>
  7. #include <stdarg.h>
  8. #include <ctype.h>
  9. #include "alarm.h"
  10. #include "global.h"
  11. #include "mbuf.h"
  12. #include "domain.h"
  13. #include "netuser.h"
  14. #include "icmp.h"
  15. #include "timer.h"
  16. #include "tcp.h"
  17. #include "ftp.h"
  18. #include "session.h"
  19. #include "cmdparse.h"
  20. #include "misc.h"
  21. #include "Terminal.h"
  22. #include "vterm.h"
  23. #include "bbc.h"
  24. #include "files.h"
  25. #include "pathent.h"
  26. #include "var.h"
  27.  
  28. extern varlist global_vars;
  29.  
  30. extern os_error *create_path(char *path, int size, int type);
  31. extern char *fttoa(int t);
  32.  
  33. extern struct session *current;
  34. struct session *current_ftp;
  35. extern char nospace[];
  36. extern char badhost[];
  37. static char notsess[]   = "Not an FTP session!\r\n";
  38. static char cantwrite[] = "Can't write %s\r\n";
  39. static char cantread[]  = "Can't read %s\r\n";
  40. static char nomemforop[] = "Insufficient memory for this operation\r\n";
  41.  
  42. static int  donothing(int, char **);
  43. static int  doftpquit(int, char **);
  44. static int  dowinclose(int, char **);
  45. static int  dowinopen(int, char **);
  46. static int  doftpcd(int, char **);
  47. static int  domkdir(int, char **);
  48. static int  dormdir(int, char **);
  49. static int  doascii(int, char **);
  50. static int  dobinary(int, char **);
  51. static int  dotype(int, char **);
  52. static int  doget(int, char **);
  53. static int  doreget(int, char **);
  54. static int  domget(int, char **);
  55. static int  dobatch(int, char **);
  56. static int  dopath(int, char **);
  57. static int  doquote(int, char **);
  58. static int  doview(int, char **);
  59. static int  dohash(int, char **);
  60. static int  dolist(int, char **);
  61. static int  dols(int, char **);
  62. static int  doput(int, char **);
  63. static void doreply(struct ftp *);
  64. static void ftpsetup(struct ftp *, void (*)(), void (*)(), void (*)());
  65. static void ftpccs(struct tcb *, char, char);
  66. static void ftpcds(struct tcb *, char, char);
  67. static int  sndftpmsg(struct ftp *, char *, ...);
  68. static void prompt(struct ftp *ftp);
  69. static int batch_ftp(struct ftp *ftp);
  70. static int mprocess(struct ftp *ftp);
  71.  
  72. void ftp_mpcleanup(struct ftp *ftp);
  73.  
  74.  
  75. struct cmds ftpabort[] = {
  76.   "",             donothing,    0,    NULLCHAR,               NULLCHAR,
  77.   "abort",        doabort,      0,    NULLCHAR,               NULLCHAR,
  78.   "hash",         dohash,       2,    "hash lumpsize",        NULLCHAR,
  79.   NULLCHAR,       NULLFP,       0,    "Only valid command is \"abort\"", NULLCHAR,
  80. };
  81.  
  82. struct cmds ftpcmds[] = {
  83.   "",             donothing,    0,    NULLCHAR,               NULLCHAR,
  84.   "ascii",        doascii,      0,    NULLCHAR,               NULLCHAR,
  85.   "abort",        doabort,      0,    NULLCHAR,               NULLCHAR,
  86.   "binary",       dobinary,     0,    NULLCHAR,               NULLCHAR,
  87.   "cd",           doftpcd,      2,    "cd <directory>",       NULLCHAR,
  88.   "dir",          dolist,       0,    NULLCHAR,               NULLCHAR,
  89.   "list",         dolist,       0,    NULLCHAR,               NULLCHAR,
  90.   "get",          doget,        2,    "get remotefile <localfile>",  NULLCHAR,
  91.   "hash",         dohash,       2,    "hash lumpsize",        NULLCHAR,
  92.   "image",        dobinary,     0,    NULLCHAR,               NULLCHAR,
  93.   "ls",           dols,         0,    NULLCHAR,               NULLCHAR,
  94.   "mget",         domget,       2,    "mget <filelist>",      NULLCHAR,
  95.   "mkdir",        domkdir,      2,    "mkdir <directory>",    NULLCHAR,
  96.   "nlst",         dols,         0,    NULLCHAR,               NULLCHAR,
  97.   "path",         dopath,       0,    "path [<path process options>|off|default]", NULLCHAR,
  98.   "put",          doput,        2,    "put localfile <remotefile>",  NULLCHAR,
  99.   "quote",        doquote,      0,    "quote <command>", NULLCHAR,
  100.   "reget",        doreget,      2,    "reget remotefile <localfile>",  NULLCHAR,
  101.   "rmdir",        dormdir,      2,    "rmdir <directory>",    NULLCHAR,
  102.   "source",       dobatch,      0,    "source <ftp command file>", NULLCHAR,
  103.   "type",         dotype,       0,    NULLCHAR,               NULLCHAR,
  104.   "view",         doview,       1,    "view remotefile",      NULLCHAR,
  105.   "winclose",     dowinclose,   0,    "winclose",             NULLCHAR,
  106.   "winopen",      dowinopen,    0,    "winopen",              NULLCHAR,
  107.   "quit",         doftpquit,    0,    "quit",                 NULLCHAR,
  108.   "bye",          doftpquit,    0,    "bye",                  NULLCHAR,
  109.   NULLCHAR,       NULLFP,       0,    NULLCHAR,               NULLCHAR,
  110. };
  111.  
  112. /* Handle top-level FTP command */
  113. int doftp(int argc, char **argv)
  114. {
  115.   int used_args;
  116.   struct session *s;
  117.   struct ftp *ftp;
  118.   struct tcb *tcb;
  119.   struct socket lsocket,fsocket;
  120.  
  121.   lsocket.address = ip_addr;
  122.   lsocket.port = lport++;
  123.   if ((fsocket.address = resolve(argv[1])) == 0)
  124.   {
  125.     cwprintf(NULL, badhost,argv[1]);
  126.     return 1;
  127.   }
  128.  
  129.   if (argc<3)
  130.   {
  131.     fsocket.port = FTP_PORT;
  132.     used_args = 2;
  133.   }
  134.   else
  135.   {
  136.     if (*argv[2]!='\\')
  137.     {
  138.       fsocket.port = atoi(argv[2]);
  139.       used_args = 3;
  140.     }
  141.     else
  142.     {
  143.       fsocket.port = FTP_PORT;
  144.       used_args = 2;
  145.     }
  146.   }
  147.   /* Allocate a session control block */
  148.   if ((s = newsession()) == NULLSESSION)
  149.   {
  150.     cwprintf(NULL, "Too many sessions\r\n");
  151.     return 1;
  152.   }
  153.   if ((s->name = malloc((unsigned)strlen(argv[1])+1)) != NULLCHAR)
  154.     strcpy(s->name,argv[1]);
  155.   s->type = FTP;
  156.   s->parse = (void(*)())ftpparse;
  157.  
  158.   /* Allocate an FTP control block */
  159.   if ((ftp = ftp_create(LINELEN)) == NULLFTP)
  160.   {
  161.     s->type = FREE;
  162.     cwprintf(NULL, nospace);
  163.     return 1;
  164.   }
  165.   ftp->window = Window_Open(s, "FTP", term_SIXTEEN | term_CARET);
  166.   vterm_parse(ftp->window->vt, argc-used_args, &argv[used_args]);
  167.   current = s;
  168.   ftp->state   = STARTUP_STATE;
  169.   s->cb.ftp    = ftp;     /* Downward link */
  170.   ftp->session = s;       /* Upward link */
  171.   s->window    = ftp->window;
  172.   ftp->session->echo = TRUE;
  173.  
  174.   /* Now open the control connection */
  175.   tcb = open_tcp(&lsocket, &fsocket, TCP_ACTIVE, 0, (void(*)())ftpccr, NULLVFP, (void(*)())ftpccs, 0,( char *)ftp);
  176.   ftp->control = tcb;
  177.   go(s);
  178.   return 0;
  179. }
  180.  
  181. /* Parse user FTP commands */
  182. void ftpparse(struct session *active, char *line, int16 len)
  183. {
  184.   struct mbuf *bp;
  185.   extern struct cmds cmds[];
  186.   if (active == NULL)
  187.     active = current;
  188.   current_ftp = active;
  189.  
  190.   /* direct '*' prefixed commands to main command window */
  191.   if (*line=='*')
  192.   {
  193.     cmdparse(cmds, line+1, NULL);
  194.     prompt(active->cb.ftp);
  195.     return;
  196.   }
  197.  
  198.   switch(active->cb.ftp->state)
  199.   {
  200.   case RECEIVING_STATE:
  201.   case SENDING_FILE_STATE:
  202.     /* The only command allowed in data transfer state is ABORT */
  203.     if (cmdparse(ftpabort, line, active->window) == -1)
  204.     {
  205.       cwprintf(active->window, "Transfer in progress; only ABORT is acceptable\r\n");
  206.     }
  207.     break;
  208.   case COMMAND_STATE:
  209.     /* Save it now because cmdparse modifies the original */
  210.     bp = qdata(line,len);
  211.     if (cmdparse(ftpcmds, line, active->window) == -1)
  212.     {
  213.       /* Send it direct */
  214.       if (bp != NULLBUF)
  215.         send_tcp(active->cb.ftp->control,bp);
  216.       else
  217.         cwprintf(active->window, nospace);
  218.     }
  219.     else
  220.     {
  221.       free_p(bp);
  222.     }
  223.     break;
  224.   case STARTUP_STATE:             /* Startup up autologin */
  225.     cwprintf(active->window, "Not connected yet, ignoring %s\r\n",line);
  226.     break;
  227.   case USER_STATE:                /* Got the user name */
  228.     line[len] = '\0';
  229.     sndftpmsg(active->cb.ftp,"USER %s",line);
  230.     break;
  231.   case PASS_STATE:                /* Got the password */
  232.     cooked();
  233.     active->raw = FALSE;
  234.         vterm_setflags(active->window->vt,
  235.            /* Clear */ VTSW_CHAT|VTSW_LINE|VTSW_NEWLINE|VTSW_WRAP|VTSW_ECHO,
  236.            /* Set */   VTSW_LINE|VTSW_NEWLINE|VTSW_WRAP|VTSW_ECHO );
  237.     line[len] = '\0';
  238.     sndftpmsg(active->cb.ftp,"PASS %s",line);
  239.     break;
  240.   }
  241. }
  242.  
  243. /* Handle null line to avoid trapping on first command in table */
  244. static int donothing(int argc, char **argv)
  245. {
  246.   argc = argc;
  247.   argv = argv;
  248.   return 0;
  249. }
  250.  
  251. static int dowinclose(int argc, char **argv)
  252. {
  253.   register struct ftp *ftp;
  254.  
  255.   argc = argc;
  256.   argv = argv;
  257.  
  258.   ftp = current_ftp->cb.ftp;
  259.   vterm_close(current_ftp->window->vt);
  260.   current_ftp->window->Flags.flags.closing = 1;
  261.   prompt(ftp);