]>
Commit | Line | Data |
---|---|---|
4a83b7b0 | 1 | /* |
85553593 | 2 | * Copyright (c) 2000, 2001, Red Hat, Inc. |
4a83b7b0 DD |
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 | ||
5898e300 | 19 | #if 0 |
b24c88b3 RC |
20 | static const char *cvsid = |
21 | "\n%%% $Id$\n"; | |
5898e300 | 22 | #endif |
946fc045 | 23 | |
4a83b7b0 DD |
24 | #include "win32.h" |
25 | #include "winsock.h" | |
26 | #include <stdio.h> | |
27 | #include <stdlib.h> | |
a03db251 | 28 | #include <ctype.h> |
4a83b7b0 DD |
29 | |
30 | #include "resource.h" | |
31 | #include "state.h" | |
32 | #include "simpsock.h" | |
a03db251 | 33 | #include "log.h" |
4a83b7b0 DD |
34 | |
35 | #include "netio.h" | |
36 | #include "nio-ftp.h" | |
37 | ||
38 | static SimpleSocket *cmd = 0; | |
39 | static char *cmd_host = 0; | |
40 | static int cmd_port = 0; | |
41 | ||
42 | static char *last_line; | |
43 | ||
44 | static int | |
b24c88b3 | 45 | ftp_line (SimpleSocket * s) |
4a83b7b0 | 46 | { |
b24c88b3 RC |
47 | do |
48 | { | |
49 | last_line = s->gets (); | |
1ac649ed | 50 | log (LOG_BABBLE, String ("ftp > ") + (last_line ? last_line : "error")); |
b24c88b3 RC |
51 | } |
52 | while (last_line && (!isdigit (last_line[0]) || last_line[3] != ' ')); | |
53 | return atoi (last_line ? : "0"); | |
4a83b7b0 DD |
54 | } |
55 | ||
341988b9 | 56 | NetIO_FTP::NetIO_FTP (char const *Purl, BOOL allow_ftp_auth):NetIO (Purl, allow_ftp_auth) |
4a83b7b0 DD |
57 | { |
58 | s = 0; | |
b24c88b3 RC |
59 | int |
60 | code; | |
4a83b7b0 DD |
61 | |
62 | if (port == 0) | |
63 | port = 21; | |
64 | ||
65 | if (cmd_host && strcmp (host, cmd_host) != 0 || port != cmd_port) | |
66 | { | |
67 | if (cmd) | |
68 | cmd->printf ("QUIT\r\n"); | |
5e0464a1 RC |
69 | delete cmd; |
70 | delete [] cmd_host; | |
4a83b7b0 DD |
71 | cmd = 0; |
72 | cmd_host = 0; | |
73 | } | |
74 | ||
75 | if (cmd == 0) | |
76 | { | |
b24c88b3 RC |
77 | SimpleSocket * |
78 | c = new SimpleSocket (host, port); | |
4a83b7b0 | 79 | code = ftp_line (c); |
85553593 | 80 | |
b24c88b3 | 81 | auth_retry: |
85553593 | 82 | if (net_ftp_user) |
b24c88b3 | 83 | c->printf ("USER %s\r\n", net_ftp_user); |
85553593 | 84 | else |
b24c88b3 | 85 | c->printf ("USER anonymous\r\n"); |
4a83b7b0 DD |
86 | code = ftp_line (c); |
87 | if (code == 331) | |
88 | { | |
85553593 CV |
89 | if (net_ftp_passwd) |
90 | c->printf ("PASS %s\r\n", net_ftp_passwd); | |
91 | else | |
92 | c->printf ("PASS cygwin-setup@\r\n"); | |
4a83b7b0 DD |
93 | code = ftp_line (c); |
94 | } | |
b24c88b3 RC |
95 | if (code == 530) /* Authentication failed, retry */ |
96 | { | |
ab57ceaa | 97 | get_ftp_auth (NULL); |
85553593 CV |
98 | if (net_ftp_user && net_ftp_passwd) |
99 | goto auth_retry; | |
100 | } | |
4a83b7b0 DD |
101 | |
102 | if (code < 200 || code >= 300) | |
103 | { | |
b24c88b3 RC |
104 | delete |
105 | c; | |
4a83b7b0 DD |
106 | return; |
107 | } | |
108 | ||
109 | cmd = c; | |
5e0464a1 RC |
110 | cmd_host = new char [strlen (host) + 1]; |
111 | strcpy (cmd_host, host); | |
4a83b7b0 DD |
112 | cmd_port = port; |
113 | ||
114 | cmd->printf ("TYPE I\r\n"); | |
115 | code = ftp_line (cmd); | |
116 | } | |
117 | ||
118 | cmd->printf ("PASV\r\n"); | |
b24c88b3 RC |
119 | do |
120 | { | |
121 | code = ftp_line (cmd); | |
122 | } | |
123 | while (code == 226); /* previous RETR */ | |
4a83b7b0 DD |
124 | if (code != 227) |
125 | return; | |
126 | ||
b24c88b3 RC |
127 | char * |
128 | paren = strchr (last_line, '('); | |
4a83b7b0 DD |
129 | if (!paren) |
130 | return; | |
131 | ||
b24c88b3 RC |
132 | int |
133 | i1, i2, i3, i4, p1, p2; | |
134 | sscanf (paren + 1, "%d,%d,%d,%d,%d,%d", &i1, &i2, &i3, &i4, &p1, &p2); | |
135 | char | |
136 | tmp[20]; | |
4a83b7b0 | 137 | sprintf (tmp, "%d.%d.%d.%d", i1, i2, i3, i4); |
b24c88b3 | 138 | s = new SimpleSocket (tmp, p1 * 256 + p2); |
4a83b7b0 DD |
139 | |
140 | cmd->printf ("RETR %s\r\n", path); | |
141 | code = ftp_line (cmd); | |
67a55ad9 | 142 | if (code != 150 && code != 125) |
4a83b7b0 | 143 | { |
b24c88b3 RC |
144 | delete |
145 | s; | |
4a83b7b0 DD |
146 | s = 0; |
147 | return; | |
148 | } | |
149 | } | |
150 | ||
151 | NetIO_FTP::~NetIO_FTP () | |
152 | { | |
153 | if (s) | |
154 | delete s; | |
155 | } | |
156 | ||
157 | int | |
158 | NetIO_FTP::ok () | |
159 | { | |
67a55ad9 | 160 | if (s && s->ok ()) |
4a83b7b0 DD |
161 | return 1; |
162 | return 0; | |
163 | } | |
164 | ||
165 | int | |
166 | NetIO_FTP::read (char *buf, int nbytes) | |
167 | { | |
67a55ad9 | 168 | if (!ok ()) |
4a83b7b0 DD |
169 | return 0; |
170 | return s->read (buf, nbytes); | |
171 | } |