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