448
+ − 1 /*
+ − 2 * Copyright (c) 2000, Red Hat, Inc.
+ − 3 *
+ − 4 * This program is free software; you can redistribute it and/or modify
+ − 5 * it under the terms of the GNU General Public License as published by
+ − 6 * the Free Software Foundation; either version 2 of the License, or
+ − 7 * (at your option) any later version.
+ − 8 *
+ − 9 * A copy of the GNU General Public License can be found at
+ − 10 * http://www.gnu.org/
+ − 11 *
+ − 12 * Written by DJ Delorie <dj@cygnus.com>
+ − 13 *
+ − 14 */
+ − 15
+ − 16 /* This file is responsible for implementing all direct FTP protocol
+ − 17 channels. It is intentionally simplistic. */
+ − 18
+ − 19 #include "win32.h"
+ − 20 #include "winsock.h"
+ − 21 #include <stdio.h>
+ − 22 #include <stdlib.h>
+ − 23 #include <ctype.h>
+ − 24
+ − 25 #include "resource.h"
+ − 26 #include "state.h"
+ − 27 #include "simpsock.h"
+ − 28 #include "log.h"
+ − 29
+ − 30 #include "netio.h"
+ − 31 #include "nio-ftp.h"
+ − 32
+ − 33 static SimpleSocket *cmd = 0;
+ − 34 static char *cmd_host = 0;
+ − 35 static int cmd_port = 0;
+ − 36
+ − 37 static char *last_line;
+ − 38
+ − 39 static int
+ − 40 ftp_line (SimpleSocket *s)
+ − 41 {
+ − 42 do {
+ − 43 last_line = s->gets ();
+ − 44 log (LOG_BABBLE, "ftp > %s", last_line);
+ − 45 } while (last_line && (!isdigit (last_line[0]) || last_line[3] != ' '));
672
+ − 46 return atoi (last_line ?: "0");
448
+ − 47 }
+ − 48
+ − 49 NetIO_FTP::NetIO_FTP (char *Purl)
+ − 50 : NetIO (Purl)
+ − 51 {
+ − 52 s = 0;
+ − 53 int code;
+ − 54
+ − 55 if (port == 0)
+ − 56 port = 21;
+ − 57
+ − 58 if (cmd_host && strcmp (host, cmd_host) != 0 || port != cmd_port)
+ − 59 {
+ − 60 if (cmd)
+ − 61 cmd->printf ("QUIT\r\n");
+ − 62 delete cmd;
+ − 63 free (cmd_host);
+ − 64 cmd = 0;
+ − 65 cmd_host = 0;
+ − 66 }
+ − 67
+ − 68 if (cmd == 0)
+ − 69 {
+ − 70 SimpleSocket *c = new SimpleSocket (host, port);
+ − 71 code = ftp_line (c);
+ − 72 c->printf ("USER anonymous\r\n");
+ − 73 code = ftp_line (c);
+ − 74 if (code == 331)
+ − 75 {
672
+ − 76 c->printf ("PASS xemacs-setup@\r\n");
448
+ − 77 code = ftp_line (c);
+ − 78 }
+ − 79
+ − 80 if (code < 200 || code >= 300)
+ − 81 {
+ − 82 delete c;
+ − 83 return;
+ − 84 }
+ − 85
+ − 86 cmd = c;
+ − 87 cmd_host = _strdup (host);
+ − 88 cmd_port = port;
+ − 89
+ − 90 cmd->printf ("TYPE I\r\n");
+ − 91 code = ftp_line (cmd);
+ − 92 }
+ − 93
+ − 94 cmd->printf ("PASV\r\n");
+ − 95 do {
+ − 96 code = ftp_line (cmd);
+ − 97 } while (code == 226); /* previous RETR */
+ − 98 if (code != 227)
+ − 99 return;
+ − 100
+ − 101 char *paren = strchr (last_line, '(');
+ − 102 if (!paren)
+ − 103 return;
+ − 104
+ − 105 int i1, i2, i3, i4, p1, p2;
+ − 106 sscanf (paren+1, "%d,%d,%d,%d,%d,%d", &i1, &i2, &i3, &i4, &p1, &p2);
+ − 107 char tmp[20];
+ − 108 sprintf (tmp, "%d.%d.%d.%d", i1, i2, i3, i4);
+ − 109 s = new SimpleSocket (tmp, p1*256 + p2);
+ − 110
+ − 111 cmd->printf ("RETR %s\r\n", path);
+ − 112 code = ftp_line (cmd);
+ − 113 if (code != 150)
+ − 114 {
+ − 115 delete s;
+ − 116 s = 0;
+ − 117 return;
+ − 118 }
+ − 119 }
+ − 120
+ − 121 NetIO_FTP::~NetIO_FTP ()
+ − 122 {
+ − 123 if (s)
+ − 124 delete s;
+ − 125 }
+ − 126
+ − 127 int
+ − 128 NetIO_FTP::ok ()
+ − 129 {
+ − 130 if (s)
+ − 131 return 1;
+ − 132 return 0;
+ − 133 }
+ − 134
+ − 135 int
+ − 136 NetIO_FTP::read (char *buf, int nbytes)
+ − 137 {
+ − 138 if (!s)
+ − 139 return 0;
+ − 140 return s->read (buf, nbytes);
+ − 141 }