]> cygwin.com Git - cygwin-apps/setup.git/blob - nio-ftp.cc
Use solver to check for problems and produce a list of package transactions
[cygwin-apps/setup.git] / nio-ftp.cc
1 /*
2 * Copyright (c) 2000, 2001, 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 "nio-ftp.h"
20
21 #include "LogSingleton.h"
22
23 #include "win32.h"
24 #include <winsock2.h>
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <ctype.h>
28
29 #include "resource.h"
30 #include "state.h"
31 #include "simpsock.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 {
44 last_line = s->gets ();
45 Log (LOG_BABBLE) << "ftp > " << (last_line ? last_line : "error")
46 << endLog;
47 }
48 while (last_line && (!isdigit (last_line[0]) || last_line[3] != ' '));
49 return atoi (last_line ? : "0");
50 }
51
52 NetIO_FTP::NetIO_FTP (char const *Purl):NetIO (Purl)
53 {
54 s = 0;
55 int
56 code;
57
58 if (port == 0)
59 port = 21;
60
61 control_reconnect:
62 if ((cmd_host && strcmp (host, cmd_host) != 0) || port != cmd_port)
63 {
64 if (cmd)
65 cmd->printf ("QUIT\r\n");
66 delete cmd;
67 delete [] cmd_host;
68 cmd = 0;
69 cmd_host = 0;
70 }
71
72 if (cmd == 0)
73 {
74 SimpleSocket *
75 c = new SimpleSocket (host, port);
76 code = ftp_line (c);
77
78 auth_retry:
79 if (net_ftp_user)
80 c->printf ("USER %s\r\n", net_ftp_user);
81 else
82 c->printf ("USER anonymous\r\n");
83 code = ftp_line (c);
84 if (code == 331)
85 {
86 if (net_ftp_passwd)
87 c->printf ("PASS %s\r\n", net_ftp_passwd);
88 else
89 c->printf ("PASS cygwin-setup@\r\n");
90 code = ftp_line (c);
91 }
92 if (code == 530) /* Authentication failed, retry */
93 {
94 get_ftp_auth (NULL);
95 if (net_ftp_user && net_ftp_passwd)
96 goto auth_retry;
97 }
98
99 if (code < 200 || code >= 300)
100 {
101 delete
102 c;
103 return;
104 }
105
106 cmd = c;
107 cmd_host = new char [strlen (host) + 1];
108 strcpy (cmd_host, host);
109 cmd_port = port;
110
111 cmd->printf ("TYPE I\r\n");
112 code = ftp_line (cmd);
113 }
114
115 cmd->printf ("PASV\r\n");
116 do
117 {
118 code = ftp_line (cmd);
119 }
120 while (code == 226); /* previous RETR */
121 if (code == 421) /* Timeout, retry */
122 {
123 Log (LOG_BABBLE) << "FTP timeout -- reconnecting" << endLog;
124 delete [] cmd_host;
125 cmd_host = new char[1]; cmd_host[0] = '\0';
126 goto control_reconnect;
127 }
128 if (code != 227)
129 return;
130
131 char *
132 digit = strpbrk (last_line + 3, "0123456789");
133 if (!digit)
134 return;
135
136 int
137 i1, i2, i3, i4, p1, p2;
138 sscanf (digit, "%d,%d,%d,%d,%d,%d", &i1, &i2, &i3, &i4, &p1, &p2);
139 char
140 tmp[20];
141 sprintf (tmp, "%d.%d.%d.%d", i1, i2, i3, i4);
142 s = new SimpleSocket (tmp, p1 * 256 + p2);
143
144 cmd->printf ("RETR %s\r\n", path);
145 code = ftp_line (cmd);
146 if (code != 150 && code != 125)
147 {
148 delete
149 s;
150 s = 0;
151 return;
152 }
153 }
154
155 NetIO_FTP::~NetIO_FTP ()
156 {
157 if (s)
158 delete s;
159 }
160
161 int
162 NetIO_FTP::ok ()
163 {
164 if (s && s->ok ())
165 return 1;
166 return 0;
167 }
168
169 int
170 NetIO_FTP::read (char *buf, int nbytes)
171 {
172 int rv;
173 if (!ok ())
174 return 0;
175 rv = s->read (buf, nbytes);
176 if (rv == 0)
177 ftp_line (cmd);
178 return rv;
179 }
This page took 0.044781 seconds and 5 git commands to generate.