1 /*Ftp.c */
2 /**********************************************************************************************************
3 Copyright (c) 2002-2013 Abdul-Rahman Allouche. All rights reserved
4
5 Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
6 documentation files (the Gabedit), to deal in the Software without restriction, including without limitation
7 the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
8 and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
9
10 The above copyright notice and this permission notice shall be included in all copies or substantial portions
11 of the Software.
12
13 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
14 TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
15 THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
16 CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
17 DEALINGS IN THE SOFTWARE.
18 ************************************************************************************************************/
19
20 /****************************************************************
21 * *
22 * Files Transfer between local host and a remote host *
23 * ftp Client for a local Windows 95/98 system *
24 * rcp Client for a local unix/Linux system *
25 * *
26 ****************************************************************/
27
28 #include "../../Config.h"
29 #include <glib.h> /* definition of G_OS_WIN32 if windows */
30 #include "../Common/Global.h"
31 #include "../Utils/UtilsInterface.h"
32 #include "../Utils/Utils.h"
33 #include "../Common/Status.h"
34
35 #ifndef BUFSIZ
36 #define BUFSIZ 8192
37 #endif
38 #ifdef G_OS_WIN32
39
40 #include <stdio.h>
41 #include <stdlib.h>
42 #include <string.h>
43 #include <winsock.h>
44 #include <fcntl.h>
45 #include <io.h>
46 #include <direct.h>
47 #else /* G_OS_WIN32 */
48
49 #include <stdio.h>
50 #include <string.h>
51 #include <pwd.h>
52 #include <sys/types.h>
53 #include <unistd.h>
54 #include <fcntl.h>
55 #include <sys/socket.h>
56 #include <netinet/in.h>
57 #include <arpa/inet.h>
58 #include <netdb.h>
59 #include <errno.h>
60
61 #endif /* G_OS_WIN32 */
62
63
64 /*****************************************/
65 char *HostName = NULL;
66 char *UserName = NULL;
67 char *PassWord = NULL;
68 char *home;
69 static int data = -1;
70 static struct sockaddr_in remote_addr;
71 static int cinput = -1;
72 static int coutput = -1;
73 static FILE* FileErr = NULL;
74 static FILE* FileOut = NULL;
75 static long FileSize = 0;
76
77 /*********************************************************************/
CloseSocket(int s)78 static void CloseSocket(int s)
79 {
80 #ifndef G_OS_WIN32
81 close(s);
82 #else
83 closesocket(s);
84 #endif
85
86 }
87 /*********************************************************************/
ReadMsg(int cin,char * szBuffer,int len)88 int ReadMsg(int cin, char *szBuffer, int len)
89 {
90 int ret;
91
92 if( (ret=recv(cin,szBuffer,len,0)) <= 0)
93 return 0;
94
95 if(szBuffer[strlen(szBuffer)-2]=='\r')
96 szBuffer[strlen(szBuffer)-2]=' ';
97 return ret;
98 }
99 /*********************************************************************/
SendMsg(int cout,char * szBuffer,int len)100 int SendMsg(int cout, char *szBuffer, int len)
101 {
102 if( send(cout,szBuffer,len,0) <= 0)
103 return 0;
104 return 1;
105 }
106 /************************************************
107 * put_file_to_data : put file in data socket *
108 *************************************************/
put_file_to_data(int fout,char * filename)109 long put_file_to_data(int fout,char* filename)
110 {
111 FILE *fin = NULL;
112 long bytes = 0;
113 char c;
114 char buf[2];
115
116 buf[1] = '\0';
117
118 if( (fin = FOpen(filename,"r")) != NULL)
119 {
120 while (!feof(fin) && (c = getc(fin)) != EOF)
121 {
122 if(c == '\n')
123 {
124 buf[0] ='\r';
125 SendMsg(fout,buf,1);
126 }
127 buf[0] =c;
128 SendMsg(fout,buf,1);
129 bytes++;
130 }
131 fclose(fin);
132
133 return bytes;
134 }
135 return 0;
136 }
137 /****************************************************
138 * get_file_from_data : get file from data socket *
139 ****************************************************/
get_file_from_data(int din,char * filename)140 long get_file_from_data(int din,char* filename)
141 {
142 FILE *fout = NULL;
143 long bytes = 0;
144 char buf[2];
145 long step = FileSize/100;
146 gchar* str = g_strdup_printf(_("Get \"%s\" File from \"%s\" host : %%p%%%%"),filename,HostName);
147 buf[1] = '\0';
148
149 if( (fout = FOpen(filename,"w")) != NULL && !stopDownLoad)
150 {
151 while (ReadMsg(din,buf, 1)>0 && buf[0] != EOF && !stopDownLoad)
152 {
153 if(buf[0] != '\r')
154 putc(buf[0], fout);
155 bytes++;
156 if(bytes%step == 0)
157 {
158 progress_connection((gdouble)0.01,str,FALSE);
159 }
160 }
161 fclose(fout);
162 g_free(str);
163 return bytes;
164 }
165 return 0;
166 }
167 /****************************************
168 * get_reply : get replay of ftp server *
169 ****************************************/
get_reply()170 int get_reply()
171 {
172 char reply_string[BUFSIZ];
173
174
175 memset (reply_string, 0, BUFSIZ);
176 #ifdef G_OS_WIN32
177 Sleep(50);
178 #endif
179 for (;;)
180 {
181 if(ReadMsg(cinput,reply_string, sizeof(reply_string))<=0)
182 {
183 fprintf(FileErr,_("Error in get_reply\n"));
184 fflush(FileErr);
185 return 1;
186 };
187 fprintf(FileOut,"%s",reply_string);
188 fflush(FileOut);
189 if(strstr(reply_string,"incorrect") || strstr(reply_string,"failed"))
190 {
191 fprintf(FileErr, "Login failed.\n");
192 return 1;
193 }
194 if(strstr(reply_string,"No such file or directory"))
195 {
196 fprintf(FileErr, "No such file or directory\n");
197 return 2;
198 }
199 if(strstr(reply_string,"command not understood"))
200 {
201 fprintf(FileErr, "command not understood\n");
202 return 3;
203 }
204
205 return 0;
206 }
207 }
208 /************************************************
209 * ftp_command : execute command in ftp connection *
210 ************************************************/
ftp_command(char * fmt,...)211 int ftp_command(char *fmt,...)
212 {
213 va_list ap ;
214 char cmd_string[BUFSIZ];
215
216 memset (cmd_string, 0, BUFSIZ);
217 if (coutput<0)
218 {
219 fprintf (FileErr,"No control connection for command\n");
220 return -1;
221 }
222
223 va_start(ap,fmt);
224 vsprintf(cmd_string, fmt, ap);
225 va_end(ap);
226 strcat(cmd_string,"\r\n");
227 SendMsg(cinput,cmd_string,strlen(cmd_string));
228 return get_reply() ;
229 }
230 /************************************************************
231 * data_connection : new socket for data *
232 ************************************************************/
data_connection(char * mode,char * cmd,char * filename)233 int data_connection(char *mode,char *cmd,char *filename)
234 {
235 struct sockaddr_in data_addr;
236 struct sockaddr_in from_addr;
237 int s;
238 char *pos;
239 char *pos1;
240 int datain = -1;
241 #ifdef G_OS_WIN32
242 gint len = sizeof (data_addr);
243 #else
244 socklen_t len = sizeof (data_addr);
245 #endif
246
247 memset((char *)&data_addr,0, sizeof (data_addr));
248 data_addr.sin_addr.s_addr = INADDR_ANY;;
249 data_addr.sin_family = AF_INET;
250
251 if (data != -1)
252 close (data);
253 data = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
254 if (getsockname(cinput, (struct sockaddr *)&data_addr, &len) < 0)
255 {
256 fprintf(FileErr,"ftp: getsockname");
257 return -1;
258 }
259
260 data_addr.sin_port = 0;
261
262 if (bind(data, (struct sockaddr *)&data_addr, sizeof (data_addr)) < 0)
263 {
264 fprintf(FileErr,"ftp: bind");
265 return -1;
266 }
267 if (getsockname(data, (struct sockaddr *)&data_addr, &len) < 0)
268 {
269 fprintf(FileErr,"ftp: getsockname");
270 return -1;
271 }
272
273 if (listen(data, 1) < 0)
274 {
275 fprintf(FileErr,"ftp: listen");
276 return -1;
277 }
278
279 pos = (char *) &data_addr.sin_addr;
280 pos1 = (char *) &data_addr.sin_port;
281 /*
282 printf ("PORT %d,%d,%d,%d,%d,%d\r\n",
283 pos[0] & 0xff, pos[1] & 0xff, pos[2] & 0xff,
284 pos[3] & 0xff, pos1[0] & 0xff,
285 pos1[1] & 0xff);
286 */
287 if( ftp_command ( "PORT %d,%d,%d,%d,%d,%d",
288 pos[0] & 0xff, pos[1] & 0xff, pos[2] & 0xff,
289 pos[3] & 0xff, pos1[0] & 0xff,
290 pos1[1] & 0xff
291 )
292 != 0)
293 return -1;
294
295 if(ftp_command(cmd,filename) != 0)
296 return -1;
297
298 if( (datain = data)<0)
299 {
300 fprintf(FileErr,"ftp: fdopen");
301 return -1;
302 }
303
304 s = accept(datain, (struct sockaddr *) &from_addr, &len);
305
306 if (s < 0)
307 {
308 fprintf(FileErr,"ftp: accept");
309 CloseSocket(data);
310 data = -1;
311 return -1;
312 }
313
314 CloseSocket(data);
315 data = s;
316 return data;
317 }
318
319 /********************************************
320 * login : put user name and password name *
321 ********************************************/
login(char * host,char * user,char * pass)322 int login(char* host,char *user,char *pass)
323 {
324 int n = 0;
325
326
327 n = ftp_command("USER %s", user);
328
329 if (n == 0)
330 {
331 n = ftp_command("PASS %s", pass);
332 }
333 else
334 return -1;
335
336 if (n != 0)
337 {
338 fflush(FileErr);
339 return -1;
340 }
341 return 0;
342 }
343 #ifdef G_OS_WIN32
344 /************************************************
345 * hostCheck : check the remote host name and *
346 * fill the server address structure *
347 * Window version *
348 *************************************************/
hostCheck(const char * hostname)349 static gboolean hostCheck (const char* hostname)
350 {
351 HostName = NULL;
352 memset(&remote_addr, 0, sizeof(remote_addr));
353 remote_addr.sin_addr.s_addr=inet_addr(hostname);
354 remote_addr.sin_family = AF_INET;
355 if(remote_addr.sin_addr.s_addr==(u_long)INADDR_NONE)
356 {
357 /*
358 we must have gotten a host name instead
359 of an IP address; resolve!
360 */
361 struct hostent* hostInfo=gethostbyname(hostname);
362 if(!hostInfo)
363 {
364 fprintf(FileErr,"Invalid hostname!");
365 return FALSE;
366 }
367 remote_addr.sin_family = hostInfo->h_addrtype;
368 memcpy((void*)&remote_addr.sin_addr.s_addr, hostInfo->h_addr, hostInfo->h_length);
369 }
370 HostName = g_strdup(hostname);
371
372 return TRUE;
373 }
374 /************************************************************************
375 * rresvport : the windows hack of rresvport; *
376 * bind a socket to a reserved port using the given protocol, if any *
377 * Window version *
378 ************************************************************************/
rresvport(u_short * alport,int sProto)379 static int rresvport (u_short* alport, int sProto)
380 {
381 struct sockaddr_in sin;
382 int s;
383
384 sin.sin_family=AF_INET;
385 sin.sin_addr.s_addr=INADDR_ANY;
386 s=socket(AF_INET, SOCK_STREAM, sProto);
387 if(s<0)
388 return -1;
389
390 for((*alport)=IPPORT_RESERVED-1; (*alport)>IPPORT_RESERVED/2; (*alport)--)
391 {
392 sin.sin_port=htons((u_short)(*alport));
393 if(bind(s, (struct sockaddr*)&sin, sizeof(sin))==0)
394 return s;
395 if(WSAGetLastError()!=WSAEADDRINUSE)
396 break;
397 }
398 /* ran out of available ports or weird error; shouldn't happen too often...*/
399 closesocket(s);
400 return -1;
401 }
402 /********************************************************
403 * initSocket : standard socket initialization procedure *
404 * Window version *
405 *********************************************************/
initSocket()406 static int initSocket ()
407 {
408 /* get port number for ftp */
409 struct servent FAR* sp=getservbyname("ftp", "tcp");
410 LPPROTOENT lpProto;
411 SOCKET ftpClient;
412 /* the local rsh port; determined dynamically */
413 u_short ftpPort;
414
415 /* the rsh protocol ("tcp") */
416 u_short ftpProto;
417 int on=1;
418
419 struct linger linger;
420 /* struct hostent *hp = NULL;*/
421
422 if(sp==NULL)
423 {
424 fprintf(FileErr, "Cannot determine port number for the ftp client.");
425 return INVALID_SOCKET;
426 }
427 remote_addr.sin_port = sp->s_port;
428
429 /* get protocol number for tcp */
430 lpProto=getprotobyname("tcp");
431 if(!lpProto)
432 ftpProto = IPPROTO_TCP;
433 else
434 ftpProto = lpProto->p_proto;
435
436 /* create socket */
437 ftpClient=rresvport(&ftpPort, ftpProto);
438 if(ftpClient==INVALID_SOCKET)
439 {
440 fprintf(FileErr, "Cannot allocate socket for the ftp client.");
441 return INVALID_SOCKET;
442 }
443 if(setsockopt(ftpClient, SOL_SOCKET, SO_KEEPALIVE, (char*)&on, sizeof(on))<0)
444 {
445 fprintf(FileErr, "Cannot set SO_KEEPALIVE!\n");
446 return INVALID_SOCKET;
447 }
448 linger.l_onoff=1;
449 linger.l_linger=60;
450 if(setsockopt(ftpClient, SOL_SOCKET, SO_LINGER, (char*)&linger, sizeof(linger))<0)
451 {
452 fprintf(FileErr,"Cannot set SO_LINGER!\n");
453 return INVALID_SOCKET;
454 }
455 return ftpClient;
456 }
457 #else
458 /************************************************
459 * hostCheck : check the remote host name and *
460 * fill the server address structure *
461 * Unix version *
462 *************************************************/
hostCheck(const char * hostname)463 static gboolean hostCheck (const char* hostname)
464 {
465 struct hostent *hp = NULL;
466 memset((char *)&remote_addr, 0,sizeof (remote_addr));
467 remote_addr.sin_addr.s_addr = inet_addr(hostname);
468
469 if (remote_addr.sin_addr.s_addr != (u_long)INADDR_NONE)
470 {
471 remote_addr.sin_family = AF_INET;
472 HostName = g_strdup(hostname);
473 }
474 else
475 {
476 hp = gethostbyname(hostname);
477 if (!hp)
478 {
479 fprintf(FileErr, "ftp: unknown host %s ", hostname);
480 return FALSE;
481 }
482 remote_addr.sin_family = hp->h_addrtype;
483 memcpy(&remote_addr.sin_addr,hp->h_addr_list[0],hp->h_length);
484 HostName = g_strdup(hp->h_name);
485 }
486 return TRUE;
487 }
488 /********************************************************
489 * initSocket : standard socket initialization procedure *
490 * Unix version *
491 *********************************************************/
initSocket()492 static int initSocket ()
493 {
494 struct servent *sp;
495 int s;
496
497 s = socket(remote_addr.sin_family, SOCK_STREAM, 0);
498
499 if (s < 0) {
500 fprintf(FileErr,"ftp: socket");
501 return -1;
502 }
503 sp = getservbyname("ftp", "tcp");
504
505 remote_addr.sin_port = sp->s_port;
506
507 return s;
508 }
509 #endif /*G_OS_WIN32*/
510 /********************************************
511 * tcpopen : open tcp connection *
512 ********************************************/
tcpopen(char * host)513 int tcpopen(char *host)
514 {
515
516 int s;
517 #ifdef G_OS_WIN32
518 gint len;
519 #else
520 socklen_t len;
521 #endif
522
523 #ifdef G_OS_WIN32
524 if( !winsockCheck(FileErr) )
525 return -1;
526 #endif
527 if( !hostCheck(host) )
528 return -1;
529 if((s = initSocket())<0)
530 return -1;
531
532 while (connect(s, (struct sockaddr *)&remote_addr, sizeof (remote_addr)) < 0)
533 {
534 fprintf(FileErr,"ftp: connection impossible");
535 return -1;
536 }
537 len = sizeof (remote_addr);
538 if (getsockname(s, (struct sockaddr *)&remote_addr, &len) < 0)
539 {
540 fprintf(FileErr,"ftp: getsockname");
541 CloseSocket(s);
542 return -1;
543 }
544
545 cinput = s;
546 coutput = s;
547 if (cinput<0 || coutput <0)
548 {
549 if(s>=0)
550 CloseSocket(s);
551 return -1;
552 }
553 return get_reply();
554 }
555 /********************************************************************************/
ftp_disconnect()556 void ftp_disconnect()
557 {
558 if (data != -1)
559 CloseSocket(data);
560 data = -1;
561 if(coutput)
562 #ifndef G_OS_WIN32
563 ftp_command("QUIT");
564 #endif
565 if(FileOut)
566 fclose(FileOut);
567 FileOut = NULL;
568 if(FileErr)
569 fclose(FileErr);
570 FileErr = NULL;
571 if(HostName)
572 g_free(HostName);
573 HostName = NULL;
574 if(UserName)
575 g_free(UserName);
576 UserName = NULL;
577 if(PassWord)
578 g_free(PassWord);
579 PassWord = NULL;
580 #ifdef G_OS_WIN32
581 if(cinput)
582 CloseSocket(cinput);
583 if(coutput)
584 CloseSocket(coutput);
585 shutdown(coutput, 2);
586
587 #else
588 if(cinput)
589 CloseSocket(cinput);
590 #endif
591
592 cinput = -1;
593 coutput = -1;
594 #ifdef G_OS_WIN32
595 WSACleanup();
596 #endif
597 }
598 /********************************************************************************/
ftp_connection(char * hostname,char * username,char * password)599 int ftp_connection(char *hostname,char *username,char* password)
600 {
601 int code = 0;
602 if(tcpopen(hostname) == 0)
603 {
604 if((code = login(hostname,username,password))!=0)
605 {
606 return code;
607 }
608 UserName = g_strdup(username);
609 PassWord = g_strdup(password);
610 code = ftp_command("PWD");
611 if(code != 0)
612 return code;
613 code = ftp_command("TYPE %s", "A");
614 if(code != 0)
615 return code;
616 return 0;
617 }
618 return -1;
619
620
621 }
622 /*********************************************************************/
get_file_size(char * filename)623 static long get_file_size(char* filename)
624 {
625 char cmd_string[BUFSIZ];
626 char reply_string[BUFSIZ];
627 long size;
628 int i;
629
630 memset (cmd_string, 0, BUFSIZ);
631 if (coutput<0)
632 {
633 fprintf (FileErr,"No control connection for command\n");
634 return -1;
635 }
636
637 sprintf(cmd_string,"SIZE %s\r\n",filename);
638 ftp_command("TYPE %s", "A");
639 SendMsg(cinput,cmd_string,strlen(cmd_string));
640
641
642
643 memset (reply_string, 0, BUFSIZ);
644 #ifdef G_OS_WIN32
645 Sleep(50);
646 #endif
647 if(ReadMsg(cinput,reply_string, sizeof(reply_string))<=0)
648 {
649 fprintf(FileErr,"Error in get_file_size\n");
650 fflush(FileErr);
651 return -1;
652 }
653 if(strstr(reply_string,"No such file or directory"))
654 {
655 fprintf(FileErr, "No such file or directory\n");
656 return -1;
657 }
658 if(strstr(reply_string,"command not understood"))
659 {
660 fprintf(FileErr, "command not understood\n");
661 return -1;
662 }
663 if(strstr(reply_string,":"))
664 {
665 sscanf(strstr(reply_string,":")+1,"%ld",&size);
666
667 }
668 else
669 sscanf(reply_string,"%d %ld",&i,&size);
670 return size;
671 }
672 /*********************************************************************/
ftp_get_file(char * fout,char * ferr,char * filename,char * localdir,char * remotedir,char * hostname,char * username,char * password)673 int ftp_get_file(char* fout,char* ferr,char* filename,char* localdir,char* remotedir,
674 char *hostname,char *username,char* password)
675 {
676 int finput = -1;
677 int code = 0;
678 long bytes = 0;
679 gchar* str = g_strdup_printf(_("Get \"%s\" File from remote host : %%p%%"),filename);
680
681 FileOut = FOpen(fout,"w");
682 FileErr = FOpen(ferr,"w");
683
684 if( !FileOut || !FileErr)
685 {
686 return -1;
687 }
688
689 show_progress_connection();
690 progress_connection(0,_("Connecting...."),FALSE);
691 if( !cinput || !coutput || !HostName || strcmp(HostName,hostname) || !UserName || strcmp(UserName,username) )
692 {
693 if( (code = ftp_connection(hostname,username,password)) != 0)
694 goto closeall;
695 }
696
697 if( (code = chdir(localdir)) != 0)
698 goto closeall;
699 if( (code = ftp_command("CWD %s",remotedir)) != 0)
700 goto closeall;
701
702 progress_connection(0,"Get File size ",FALSE);
703 FileSize = get_file_size(filename);
704 /*
705 if( (code = ftp_command("SIZE %s",filename)) != 0)
706 goto closeall;
707 */
708 progress_connection(0,"Data connecting....",FALSE);
709 if( (finput = data_connection("r","RETR %s",filename))<0)
710 {
711 code = -1;
712 goto closeall;
713 }
714 progress_connection(0,str,FALSE);
715 if( (bytes = get_file_from_data(finput,filename)) == 0)
716 {
717 code = -1;
718 goto closeall;
719 }
720
721 if (data != -1)
722 {
723 CloseSocket(data);
724 #ifdef G_OS_WIN32
725 shutdown(data, 2);
726 #endif
727 }
728
729 data = -1;
730 finput = -1;
731 get_reply();
732 fprintf (FileOut," %ld bytes received.\n",bytes);
733
734 closeall :
735 g_free(str);
736 FileSize = 0;
737 hide_progress_connection();
738 progress_connection(0," ",TRUE);
739 if(finput>=0)
740 CloseSocket(finput);
741 finput = -1;
742 ftp_disconnect();
743 return code;
744 }
745 /******************************************************/
ftp_put_file(char * fout,char * ferr,char * filename,char * localdir,char * remotedir,char * hostname,char * username,char * password)746 int ftp_put_file(char* fout,char* ferr,char* filename,char* localdir,char* remotedir,
747 char *hostname,char *username,char* password)
748 {
749 int foutput = -1;
750 int code = 0;
751 long bytes = 0;
752
753 stopDownLoad = FALSE;
754 FileOut = FOpen(fout,"w");
755 FileErr = FOpen(ferr,"w");
756 if( !FileOut || !FileErr)
757 {
758 return -1;
759 }
760
761 if( !cinput || !coutput || !HostName || strcmp(HostName,hostname) || !UserName || strcmp(UserName,username) )
762 {
763 if( (code = ftp_connection(hostname,username,password)) != 0)
764 goto closeall;
765 }
766
767 if( (code = chdir(localdir)) != 0)
768 goto closeall;
769 if( (code = ftp_command("CWD %s",remotedir)) != 0)
770 goto closeall;
771 if( (foutput = data_connection("w","STOR %s",filename))<0)
772 {
773 code = -1;
774 goto closeall;
775 }
776 if( (bytes = put_file_to_data(foutput,filename))<0)
777 {
778 code = -1;
779 goto closeall;
780 }
781
782 if(foutput>=0)
783 CloseSocket(foutput);
784
785 foutput = -1;
786 get_reply();
787 fprintf (FileOut," %ld bytes sent.\n",bytes);
788
789 closeall :
790 if(foutput>=0)
791 CloseSocket(foutput);
792 ftp_disconnect();
793 return code;
794
795 }
796 /******************************************************/
797