1 /*
2 * Some code in this file is derived from the public domain code in
3 * WWW/Library/Implementation/HTFTP.c distributed with lynx-2.2,
4 * whose original author is Tim Berners-lee <timbl@info.cern.ch>.
5 *
6 * Author: William Chia-Wei Cheng (bill.cheng@acm.org)
7 *
8 * Copyright (C) 2001-2009, William Chia-Wei Cheng.
9 *
10 * This file may be distributed under the terms of the Q Public License
11 * as defined by Trolltech AS of Norway and appearing in the file
12 * LICENSE.QPL included in the packaging of this file.
13 *
14 * THIS FILE IS PROVIDED AS IS WITH NO WARRANTY OF ANY KIND, INCLUDING
15 * THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL,
17 * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
18 * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
19 * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
20 * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
21 *
22 * @(#)$Header: /mm2/home/cvs/bc-src/tgif/ftp.c,v 1.10 2011/05/16 16:21:57 william Exp $
23 */
24
25 #define _INCLUDE_FROM_FTP_C_
26
27 #include "tgifdefs.h"
28
29 #include "dialog.e"
30 #include "file.e"
31 #include "ftp.e"
32 #include "msg.e"
33 #include "remote.e"
34 #include "strtbl.e"
35 #include "tcp.e"
36 #include "util.e"
37
38 int debugFtp=0;
39
40 static int gnReadyToReceiveData=FALSE;
41
FtpFreeBuf(buf)42 void FtpFreeBuf(buf)
43 char *buf;
44 {
45 free(buf);
46 }
47
FtpDebug(val)48 void FtpDebug(val)
49 int val;
50 {
51 debugFtp = val;
52 }
53
FtpDoConnect(psz_host,us_port,pn_socket)54 int FtpDoConnect(psz_host, us_port, pn_socket)
55 char *psz_host;
56 int us_port, *pn_socket;
57 {
58 int rc, len=strlen(psz_host)+80;
59 char *msg=(char*)malloc((len+1)*sizeof(char));
60
61 if (msg == NULL) {
62 FailAllocMessage();
63 return TG_REMOTE_STATUS_MEM;
64 }
65 sprintf(msg, TgLoadCachedString(CSTID_MAKING_CONN_TO_HOST), "FTP", psz_host);
66 ShowRemoteStatus(msg);
67
68 rc = TcpDoConnect(psz_host, us_port, pn_socket);
69
70 if (rc == TG_REMOTE_STATUS_OK) {
71 sprintf(msg, TgLoadCachedString(CSTID_CONN_TO_HOST_ESTABLISHED), "FTP",
72 psz_host);
73 } else {
74 sprintf(msg, TgLoadString(STID_FAIL_TO_CONN_TO_HOST), "FTP", psz_host);
75 }
76 ShowRemoteStatus(msg);
77 free(msg);
78
79 return rc;
80 }
81
82 static
AppendSimpleString(buf,value)83 char *AppendSimpleString(buf, value)
84 char *buf, *value;
85 {
86 int cur_len=(buf==NULL ? 0 : strlen(buf));
87
88 if (value == NULL) {
89 int new_len=cur_len+2;
90
91 if (buf == NULL) {
92 buf = (char*)malloc((new_len+1)*sizeof(char));
93 } else {
94 buf = (char*)realloc(buf, new_len+1);
95 }
96 if (buf == NULL) return NULL;
97 sprintf(&buf[cur_len], "\r\n");
98 } else {
99 int new_len=cur_len+strlen(value)+2;
100
101 if (buf == NULL) {
102 buf = (char*)malloc((new_len+1)*sizeof(char));
103 } else {
104 buf = (char*)realloc(buf, new_len+1);
105 }
106 if (buf == NULL) return NULL;
107 sprintf(&buf[cur_len], "%s\r\n", value);
108 }
109 return buf;
110 }
111
FtpDoWrite(n_socket,psz_path)112 int FtpDoWrite(n_socket, psz_path)
113 int n_socket;
114 char *psz_path;
115 {
116 int status=TG_REMOTE_STATUS_OK;
117
118 if (psz_path == NULL) return TG_REMOTE_STATUS_OK;
119
120 status = TcpDoWrite(n_socket, psz_path, (int)strlen(psz_path));
121 return status;
122 }
123
124 static
FtpDumpResponse(func_name,buf)125 void FtpDumpResponse(func_name, buf)
126 char *func_name, *buf;
127 {
128 char *c_ptr=strchr(buf, '\n'), *line_ptr=buf;
129 FILE *fp=stdout;
130
131 /* debug, do not translate */
132 if (debugFtp > 0) fprintf(fp, "In %s:\n", func_name);
133 while (c_ptr != NULL) {
134 char *prev_ptr=c_ptr;
135
136 if (prev_ptr != line_ptr && *(--prev_ptr) == '\r') {
137 *prev_ptr = '\0';
138 } else {
139 prev_ptr = NULL;
140 *c_ptr = '\0';
141 }
142 if (debugFtp > 0) fprintf(fp, " %s\n", line_ptr);
143 if (prev_ptr == NULL) {
144 *c_ptr = '\n';
145 } else {
146 *prev_ptr = '\r';
147 }
148 line_ptr = &c_ptr[1];
149 c_ptr = strchr(line_ptr, '\n');
150 }
151 if (line_ptr != NULL) {
152 int len=strlen(line_ptr);
153
154 if (len > 0 && line_ptr[len-1] == '\r') {
155 line_ptr[len-1] = '\0';
156 if (debugFtp > 0) fprintf(fp, " %s\n", line_ptr);
157 line_ptr[len-1] = '\r';
158 } else {
159 if (debugFtp > 0) fprintf(fp, " %s\n", line_ptr);
160 }
161 }
162 }
163
164 #define MIN_READ_SIZE 0x100
165
166 static int ftpReadData=FALSE;
167
FtpDoRead(n_socket,ppsz_buf,pn_buf_sz)168 int FtpDoRead(n_socket, ppsz_buf, pn_buf_sz)
169 int n_socket, *pn_buf_sz;
170 char **ppsz_buf;
171 {
172 int buf_sz=0x400, len=0, end_of_file=FALSE;
173 int rc=(-1);
174 char *buf=(char*)malloc(buf_sz*sizeof(char));
175
176 if (pn_buf_sz != NULL) *pn_buf_sz = 0;
177 *ppsz_buf = NULL;
178 if (buf == NULL) {
179 FailAllocMessage();
180 return TG_REMOTE_STATUS_MEM;
181 }
182 CleanUpDownloadStats();
183 do {
184 int bytes_read;
185 char progress_buf[MAXSTRING];
186
187 *progress_buf = '\0';
188 if (buf_sz - len < MIN_READ_SIZE) {
189 buf_sz += 0x400;
190 if ((buf=(char*)realloc(buf, buf_sz)) == NULL) {
191 FailAllocMessage();
192 if (PRTGIF && cmdLineDumpURL && cmdLineDumpURLShowStatus &&
193 pn_buf_sz != NULL) {
194 fprintf(stderr, "\n");
195 }
196 return TG_REMOTE_STATUS_MEM;
197 }
198 }
199 bytes_read = read(n_socket, &buf[len], buf_sz-len-1);
200 /* debug, do not translate */
201 if (debugFtp >= 3) fprintf(stderr, " read %1d bytes\n", bytes_read);
202 if (bytes_read <= 0) {
203 if (bytes_read < 0 && (errno == ENOTCONN || errno == ECONNRESET ||
204 errno == EPIPE)) {
205 free(buf);
206 fprintf(stderr, TgLoadString(STID_NETWORK_READ_ERROR), "FTP");
207 fprintf(stderr, "\n");
208 if (PRTGIF && cmdLineDumpURL && cmdLineDumpURLShowStatus &&
209 pn_buf_sz != NULL) {
210 fprintf(stderr, "\n");
211 }
212 return TG_REMOTE_STATUS_READ;
213 } else if (bytes_read < 0) {
214 free(buf);
215 fprintf(stderr, TgLoadString(STID_NETWORK_ERROR), "FTP");
216 fprintf(stderr, "\n");
217 if (PRTGIF && cmdLineDumpURL && cmdLineDumpURLShowStatus &&
218 pn_buf_sz != NULL) {
219 fprintf(stderr, "\n");
220 }
221 return TG_REMOTE_STATUS_NET;
222 }
223 if (!UpdateDownloadStats(0, progress_buf)) {
224 *progress_buf = '\0';
225 }
226 end_of_file = TRUE;
227 } else {
228 if (!UpdateDownloadStats(bytes_read, progress_buf)) {
229 *progress_buf = '\0';
230 }
231 len += bytes_read;
232 }
233 if (!end_of_file && UserAbortComm()) {
234 if (buf != NULL) free(buf);
235 sprintf(gszMsgBox, TgLoadString(STID_CONN_ABORT_BY_USER), "FTP");
236 ShowRemoteStatus(gszMsgBox);
237 if (PRTGIF && cmdLineDumpURL && cmdLineDumpURLShowStatus &&
238 pn_buf_sz != NULL) {
239 fprintf(stderr, "\n");
240 }
241 return TG_REMOTE_STATUS_INTR;
242 } else {
243 char msg[MAXSTRING], *c_ptr;
244 int cont_code=(-1);
245
246 /* do not translate -- program constants */
247 sprintf(msg, "FTP: %1d bytes %s...", len,
248 (*progress_buf=='\0' ? "" : progress_buf));
249 ShowRemoteStatus(msg);
250 if (PRTGIF && cmdLineDumpURL && cmdLineDumpURLShowStatus &&
251 pn_buf_sz != NULL) {
252 /* do not translate -- program constants */
253 fprintf(stderr, "FTP: %1d bytes %s...\r", len,
254 (*progress_buf=='\0' ? "" : progress_buf));
255 }
256 buf[len] = '\0';
257 if (!ftpReadData) {
258 for (c_ptr=buf; *c_ptr != '\0'; c_ptr++) {
259 char cont_ch;
260
261 if (sscanf(c_ptr, "%d%c", &rc, &cont_ch) == 2) {
262 if (cont_code == (-1)) {
263 if (cont_ch == '-') {
264 cont_code = rc;
265 } else {
266 end_of_file = TRUE;
267 break;
268 }
269 } else if (cont_code == rc && cont_ch == ' ') {
270 cont_code = (-1);
271 end_of_file = TRUE;
272 break;
273 }
274 }
275 c_ptr = strchr(c_ptr, '\n');
276 if (c_ptr == NULL) break;
277 }
278 }
279 }
280 } while (!end_of_file);
281 if (PRTGIF && cmdLineDumpURL && cmdLineDumpURLShowStatus &&
282 pn_buf_sz != NULL) {
283 fprintf(stderr, "\n");
284 }
285 /* debug, do not translate */
286 if (debugFtp >= 2) fprintf(stderr, " rc = %1d in FtpDoRead().\n", rc);
287 if (rc == 421) {
288 free(buf);
289 fprintf(stderr, TgLoadString(STID_CONN_TERM_BY_SERVER), "FTP");
290 fprintf(stderr, "\n");
291 return TG_REMOTE_STATUS_TERM;
292 } else {
293 buf[len] = '\0';
294 *ppsz_buf = buf;
295 if (pn_buf_sz != NULL) *pn_buf_sz = len;
296 return TG_REMOTE_STATUS_OK;
297 }
298 }
299
300 static
FtpSendSimpleCmd(n_socket,value)301 int FtpSendSimpleCmd(n_socket, value)
302 int n_socket;
303 char *value;
304 {
305 int status=TG_REMOTE_STATUS_OK;
306 char *cmd;
307
308 if ((cmd=AppendSimpleString(NULL, value)) == NULL) {
309 FailAllocMessage();
310 return TG_REMOTE_STATUS_MEM;
311 }
312 status = FtpDoWrite(n_socket, cmd);
313 free(cmd);
314 return status;
315 }
316
317 static
FtpSendUserName(n_socket,value)318 int FtpSendUserName(n_socket, value)
319 int n_socket;
320 char *value;
321 {
322 return FtpSendSimpleCmd(n_socket, value);
323 }
324
325 static
FtpSendPassword(n_socket,password)326 int FtpSendPassword(n_socket, password)
327 int n_socket;
328 char *password;
329 {
330 return FtpSendSimpleCmd(n_socket, password);
331 }
332
333 static
FtpSendType(n_socket,type_cmd)334 int FtpSendType(n_socket, type_cmd)
335 int n_socket;
336 char *type_cmd;
337 {
338 return FtpSendSimpleCmd(n_socket, type_cmd);
339 }
340
341 static
FtpSendRetrieveCmd(n_socket,psz_path)342 int FtpSendRetrieveCmd(n_socket, psz_path)
343 int n_socket;
344 char *psz_path;
345 {
346 int status=TG_REMOTE_STATUS_OK;
347 char *cmd;
348
349 /* do not translate -- program constants */
350 cmd = (char*)malloc((strlen("RETR")+1+strlen(psz_path)+2+1)*sizeof(char));
351 if (cmd == NULL) {
352 FailAllocMessage();
353 return TG_REMOTE_STATUS_MEM;
354 }
355 /* do not translate -- program constants */
356 sprintf(cmd, "RETR %s\r\n", psz_path);
357 status = FtpDoWrite(n_socket, cmd);
358 free(cmd);
359 return status;
360 }
361
362 static
FtpSendListCmd(n_socket)363 int FtpSendListCmd(n_socket)
364 int n_socket;
365 {
366 /* do not translate -- program constants */
367 return FtpSendSimpleCmd(n_socket, "NLST");
368 }
369
370 static
FtpSendCWDCmd(n_socket,psz_path)371 int FtpSendCWDCmd(n_socket, psz_path)
372 int n_socket;
373 char *psz_path;
374 {
375 int status=TG_REMOTE_STATUS_OK;
376 char *cmd;
377
378 /* do not translate -- program constants */
379 cmd = (char*)malloc((strlen("CWD")+1+strlen(psz_path)+2+1)*sizeof(char));
380 if (cmd == NULL) {
381 FailAllocMessage();
382 return TG_REMOTE_STATUS_MEM;
383 }
384 /* do not translate -- program constants */
385 sprintf(cmd, "CWD %s\r\n", psz_path);
386 status = FtpDoWrite(n_socket, cmd);
387 free(cmd);
388 return status;
389 }
390
391 static
FtpSendPortCmd(n_socket,pn_data_socket)392 int FtpSendPortCmd(n_socket, pn_data_socket)
393 int n_socket, *pn_data_socket;
394 {
395 struct sockaddr_in soc_address;
396 struct sockaddr_in *sin=(&soc_address);
397 char port_cmd[20];
398
399 *pn_data_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
400 if (*pn_data_socket < 0) {
401 fprintf(stderr, TgLoadString(STID_FAIL_TO_OPEN_DATA_SOCKET), "FTP");
402 fprintf(stderr, "\n");
403 return TG_REMOTE_STATUS_FILE;
404 }
405
406 sin->sin_family = AF_INET;
407 sin->sin_addr.s_addr = INADDR_ANY;
408 {
409 int rc, addr_sz;
410
411 addr_sz = sizeof(soc_address);
412 rc = getsockname(n_socket, (struct sockaddr *)&soc_address,
413 (void*)(&addr_sz));
414 if (rc < 0) {
415 close(*pn_data_socket);
416 *pn_data_socket = (-1);
417 return TG_REMOTE_STATUS_HOST;
418 }
419 soc_address.sin_port = 0;
420 rc = bind(*pn_data_socket, (struct sockaddr*)&soc_address,
421 sizeof(soc_address));
422 if (rc < 0) {
423 close(*pn_data_socket);
424 *pn_data_socket = (-1);
425 return TG_REMOTE_STATUS_HOST;
426 }
427 addr_sz = sizeof(soc_address);
428 rc = getsockname(*pn_data_socket, (struct sockaddr *)&soc_address,
429 (void*)(&addr_sz));
430 if (rc < 0) {
431 close(*pn_data_socket);
432 *pn_data_socket = (-1);
433 return TG_REMOTE_STATUS_HOST;
434 }
435 }
436 /* do not translate -- program constants */
437 sprintf(port_cmd, "PORT %d,%d,%d,%d,%d,%d",
438 (int)*((unsigned char *)(&sin->sin_addr)+0),
439 (int)*((unsigned char *)(&sin->sin_addr)+1),
440 (int)*((unsigned char *)(&sin->sin_addr)+2),
441 (int)*((unsigned char *)(&sin->sin_addr)+3),
442 (int)*((unsigned char *)(&sin->sin_port)+0),
443 (int)*((unsigned char *)(&sin->sin_port)+1));
444 if (listen(*pn_data_socket, 1) < 0) {
445 close(*pn_data_socket);
446 *pn_data_socket = (-1);
447 return TG_REMOTE_STATUS_HOST;
448 }
449 return FtpSendSimpleCmd(n_socket, port_cmd);
450 }
451
452 static
FtpReadCmd(n_socket,ppsz_buf,pn_cmd)453 int FtpReadCmd(n_socket, ppsz_buf, pn_cmd)
454 int n_socket, *pn_cmd;
455 char **ppsz_buf;
456 /* if returns TG_REMOTE_STATUS_OK, caller must call FtpFreeBuf(*ppsz_buf) */
457 {
458 int status;
459
460 if ((status=FtpDoRead(n_socket, ppsz_buf, NULL)) == TG_REMOTE_STATUS_OK) {
461 status = TG_REMOTE_STATUS_FORMAT;
462 if (*ppsz_buf != NULL) {
463 if (sscanf(*ppsz_buf, "%d", pn_cmd) == 1) {
464 *pn_cmd = (int)(*pn_cmd / 100);
465 status = TG_REMOTE_STATUS_OK;
466 }
467 }
468 }
469 if (status != TG_REMOTE_STATUS_OK && *ppsz_buf != NULL) {
470 FtpFreeBuf(*ppsz_buf);
471 *ppsz_buf = NULL;
472 }
473 return status;
474 }
475
476 static
FtpLogin(n_socket)477 int FtpLogin(n_socket)
478 int n_socket;
479 {
480 char *buf=NULL;
481 int status, ftp_cmd=(-1);
482
483 if ((status=FtpReadCmd(n_socket, &buf, &ftp_cmd)) == TG_REMOTE_STATUS_OK) {
484 /* debug, do not translate */
485 FtpDumpResponse("FtpLogin", buf);
486 status = TG_REMOTE_STATUS_FORMAT;
487 if (ftp_cmd == 2) {
488 /* do not translate -- program constants */
489 status = FtpSendUserName(n_socket, "USER anonymous");
490 }
491 FtpFreeBuf(buf);
492 }
493 return status;
494 }
495
496 static char SZ_PASSWORD[128];
497
498 static int gnPasswordInitialized=FALSE;
499
500 static
InitPassword()501 void InitPassword()
502 {
503 char user_name[128];
504
505 if (gnPasswordInitialized) return;
506 gnPasswordInitialized = TRUE;
507
508 GetUserID(user_name, sizeof(user_name));
509
510 /* do not translate -- program constants */
511 sprintf(SZ_PASSWORD, "PASS %s", user_name);
512 }
513
514 static
FtpPassword(n_socket)515 int FtpPassword(n_socket)
516 int n_socket;
517 {
518 char *buf=NULL;
519 int status, ftp_cmd=(-1);
520
521 if ((status=FtpReadCmd(n_socket, &buf, &ftp_cmd)) == TG_REMOTE_STATUS_OK) {
522 /* debug, do not translate */
523 FtpDumpResponse("FtpPassword", buf);
524 status = TG_REMOTE_STATUS_FORMAT;
525 if (ftp_cmd == 3) {
526 InitPassword();
527 status = FtpSendPassword(n_socket, SZ_PASSWORD);
528 }
529 FtpFreeBuf(buf);
530 }
531 return status;
532 }
533
534 static
FtpPort(n_socket,pn_data_socket)535 int FtpPort(n_socket, pn_data_socket)
536 int n_socket, *pn_data_socket;
537 {
538 char *buf=NULL;
539 int status, ftp_cmd=(-1);
540
541 if ((status=FtpReadCmd(n_socket, &buf, &ftp_cmd)) == TG_REMOTE_STATUS_OK) {
542 /* debug, do not translate */
543 FtpDumpResponse("FtpPort", buf);
544 status = TG_REMOTE_STATUS_FORMAT;
545 if (ftp_cmd == 2) {
546 status = FtpSendPortCmd(n_socket, pn_data_socket);
547 } else if (ftp_cmd == 3) {
548 FtpFreeBuf(buf);
549 /* do not translate -- program constants */
550 status = FtpSendPassword(n_socket, "ACCT noaccount");
551 if ((status=FtpReadCmd(n_socket, &buf, &ftp_cmd)) ==
552 TG_REMOTE_STATUS_OK) {
553 /* debug, do not translate */
554 FtpDumpResponse("FtpPort", buf);
555 status = TG_REMOTE_STATUS_FORMAT;
556 if (ftp_cmd == 2) {
557 status = FtpSendPortCmd(n_socket, pn_data_socket);
558 }
559 FtpFreeBuf(buf);
560 buf = NULL;
561 }
562 }
563 if (buf != NULL) FtpFreeBuf(buf);
564 }
565 return status;
566 }
567
568 static
FtpType(n_socket)569 int FtpType(n_socket)
570 int n_socket;
571 {
572 char *buf=NULL;
573 int status, ftp_cmd=(-1);
574
575 if ((status=FtpReadCmd(n_socket, &buf, &ftp_cmd)) == TG_REMOTE_STATUS_OK) {
576 /* debug, do not translate */
577 FtpDumpResponse("FtpType", buf);
578 status = TG_REMOTE_STATUS_FORMAT;
579 if (ftp_cmd == 2) {
580 /* do not translate -- program constants */
581 status = FtpSendType(n_socket, "TYPE I");
582 }
583 FtpFreeBuf(buf);
584 }
585 return status;
586 }
587
588 static
FtpRetr(n_socket,psz_path)589 int FtpRetr(n_socket, psz_path)
590 int n_socket;
591 char *psz_path;
592 {
593 char *buf=NULL;
594 int status, ftp_cmd=(-1);
595
596 if ((status=FtpReadCmd(n_socket, &buf, &ftp_cmd)) == TG_REMOTE_STATUS_OK) {
597 /* debug, do not translate */
598 FtpDumpResponse("FtpRetr", buf);
599 status = TG_REMOTE_STATUS_FORMAT;
600 if (ftp_cmd == 2) {
601 status = FtpSendRetrieveCmd(n_socket, psz_path);
602 }
603 FtpFreeBuf(buf);
604 }
605 return status;
606 }
607
608 static
FtpCwd(n_socket,psz_path,pn_is_dir)609 int FtpCwd(n_socket, psz_path, pn_is_dir)
610 int n_socket, *pn_is_dir;
611 char *psz_path;
612 {
613 char *buf=NULL;
614 int status, ftp_cmd=(-1);
615
616 *pn_is_dir = FALSE;
617 if ((status=FtpReadCmd(n_socket, &buf, &ftp_cmd)) == TG_REMOTE_STATUS_OK) {
618 /* debug, do not translate */
619 FtpDumpResponse("FtpCwd", buf);
620 status = TG_REMOTE_STATUS_FORMAT;
621 if (ftp_cmd != 1) {
622 FtpFreeBuf(buf);
623 status = FtpSendCWDCmd(n_socket, psz_path);
624 if ((status=FtpReadCmd(n_socket, &buf, &ftp_cmd)) ==
625 TG_REMOTE_STATUS_OK) {
626 /* debug, do not translate */
627 FtpDumpResponse("FtpCwd", buf);
628 if (ftp_cmd == 2) {
629 *pn_is_dir = TRUE;
630 gnReadyToReceiveData = TRUE;
631 status = FtpSendListCmd(n_socket);
632 }
633 FtpFreeBuf(buf);
634 buf = NULL;
635 }
636 } else {
637 gnReadyToReceiveData = TRUE;
638 status = TG_REMOTE_STATUS_OK;
639 }
640 if (buf != NULL) FtpFreeBuf(buf);
641 }
642 return status;
643 }
644
645 static
FtpGetContent(n_socket,data_socket,is_dir,ppsz_buf,pn_buf_sz)646 int FtpGetContent(n_socket, data_socket, is_dir, ppsz_buf, pn_buf_sz)
647 int n_socket, data_socket, is_dir, *pn_buf_sz;
648 char **ppsz_buf;
649 {
650 struct sockaddr_in soc_address;
651 int soc_addrlen=sizeof(soc_address), accepted_socket;
652 int status=TG_REMOTE_STATUS_OK;
653
654 if (pn_buf_sz != NULL) *pn_buf_sz = 0;
655 *ppsz_buf = NULL;
656 accepted_socket = accept(data_socket, (struct sockaddr *)&soc_address,
657 (void*)(&soc_addrlen));
658 if (accepted_socket < 0) return TG_REMOTE_STATUS_HOST;
659
660 ftpReadData = TRUE;
661 if (is_dir) {
662 /* a directory */
663 status = FtpDoRead(accepted_socket, ppsz_buf, pn_buf_sz);
664 } else {
665 /* a file */
666 status = FtpDoRead(accepted_socket, ppsz_buf, pn_buf_sz);
667 }
668 ftpReadData = FALSE;
669 close(accepted_socket);
670 return TG_REMOTE_STATUS_OK;
671 }
672
FtpDoTalk(n_socket,psz_path,ppsz_buf,pn_buf_sz)673 int FtpDoTalk(n_socket, psz_path, ppsz_buf, pn_buf_sz)
674 int n_socket, *pn_buf_sz;
675 char *psz_path, **ppsz_buf;
676 {
677 int status=TG_REMOTE_STATUS_OK, data_socket=(-1), is_dir=FALSE;
678 char msg[80];
679
680 *ppsz_buf = NULL;
681 if ((status=FtpLogin(n_socket)) != TG_REMOTE_STATUS_OK) return status;
682 if ((status=FtpPassword(n_socket)) != TG_REMOTE_STATUS_OK) return status;
683 if ((status=FtpPort(n_socket, &data_socket)) != TG_REMOTE_STATUS_OK) {
684 return status;
685 }
686 if ((status=FtpType(n_socket)) != TG_REMOTE_STATUS_OK) return status;
687 if ((status=FtpRetr(n_socket, psz_path)) != TG_REMOTE_STATUS_OK) {
688 if (data_socket != (-1)) close(data_socket);
689 return (FTP_LOGGED_IN|status);
690 }
691 gnReadyToReceiveData = FALSE;
692 if ((status=FtpCwd(n_socket, psz_path, &is_dir)) != TG_REMOTE_STATUS_OK) {
693 if (data_socket != (-1)) close(data_socket);
694 return (FTP_LOGGED_IN|status);
695 }
696 if (gnReadyToReceiveData) {
697 sprintf(msg, TgLoadCachedString(CSTID_LOGIN_SUCC_RETRIEVE_DATA), "FTP");
698 ShowRemoteStatus(msg);
699
700 status = FtpGetContent(n_socket, data_socket, is_dir, ppsz_buf,
701 pn_buf_sz);
702 }
703 if (data_socket != (-1)) close(data_socket);
704 return (FTP_LOGGED_IN|status);
705 }
706
707