1 /* Scp.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 *          Scp command                                          *
23 *          pscp - Remote Shell Client for Windows system        *
24 *          scp  - Remote Shell Client using ssh system          *
25 *                command for a unix/Linux system                *
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 
36 #ifdef G_OS_WIN32
37 
38 #include <stdio.h>
39 #include <stdlib.h>
40 #include <string.h>
41 #include <winsock.h>
42 #include <fcntl.h>
43 #include <io.h>
44 
45 
46 static gchar*	cmdGlobal = NULL;
47 static gchar*	foutGlobal = NULL;
48 static gchar*	ferrGlobal = NULL;
49 
50 /********************************************************/
createUnixFile(gchar * winFile)51 static gchar* createUnixFile(gchar* winFile)
52 {
53 	gchar *unixFile =  g_strdup_printf("%s%stmp%sunix.txt",gabedit_directory(),G_DIR_SEPARATOR_S,G_DIR_SEPARATOR_S);
54 	FILE* FileUnix = NULL;
55 	FILE* FileWin = NULL;
56 	char c;
57 
58 	FileUnix = FOpen(unixFile,"wb");
59 	if(!FileUnix)
60 	{
61 		g_free(unixFile);
62 		return NULL;
63 	}
64 
65 	FileWin = FOpen(winFile,"r");
66 	if(!FileWin)
67 	{
68 		g_free(unixFile);
69 		return NULL;
70 	}
71 	while (!feof(FileWin) && (c = getc(FileWin)) != EOF)
72 	{
73 		if(c == '\r')
74 			continue;
75 		if(c == '\n')
76 		{
77 			/*putc('\r', FileUnix);*/
78 			putc('\n', FileUnix);
79 		}
80 		else
81 			putc(c, FileUnix);
82 	}
83 	fclose(FileWin);
84 	fclose(FileUnix);
85 
86 	return unixFile;
87 
88 }
89 /********************************************************/
clientThread()90 static long clientThread ()
91 {
92 	if(system(cmdGlobal)==0)
93 	{
94 		FILE* FileOut = FOpen(foutGlobal,"w");
95 		fprintf(FileOut,"Ok\n");
96 		fclose(FileOut);
97 		return 0;
98 	}
99 	else
100 	{
101 		FILE* FileErr = FOpen(ferrGlobal,"w");
102 		FILE* FileOut = FOpen(foutGlobal,"w");
103 		fprintf(FileErr,_("Sorry, I Cannot get file at remot host...\n"));
104 		fprintf(FileOut,_("Sorry, I Cannot get file at remot host...\n"));
105 		fclose(FileErr);
106 		fclose(FileOut);
107 		return 1;
108 	}
109 }
110 
111 /********************************************************
112 * scp : main processing routine; connect to server,		*
113 * pass command line and wait for results				*
114 *********************************************************/
run_scp(gchar * fout,gchar * ferr,char * cmd,gchar * message)115 int run_scp(gchar* fout,gchar* ferr,char* cmd, gchar* message)
116 {
117 	HANDLE threadHnd;
118 	DWORD threadID;
119 
120 	FILE* FileOut;
121 	FILE* FileErr;
122 
123 
124 	if(cmdGlobal)
125 		g_free(cmdGlobal);
126 
127 	cmdGlobal = g_strdup(cmd);
128 
129 	show_progress_connection();
130 	progress_connection(0,message,FALSE);
131 
132 	threadHnd=CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)clientThread,
133 			(LPVOID)0, 0, (LPDWORD)&threadID);
134 	if(!threadHnd)
135 	{
136 			FILE* FileErr = FOpen(ferr,"w");
137 			fprintf(FileErr,_("Cannot start client thread...\n"));
138 			fclose(FileErr);
139 			hide_progress_connection();
140 			progress_connection(0," ",TRUE);
141 			WSACleanup();
142 			return 1;
143 	}
144 	/*printf("End start client thread\n");*/
145 
146 	FileErr = FOpen(ferr,"w");
147 	FileOut = FOpen(fout,"w");
148 	if(threadHnd)
149 	{
150 		DWORD exitCode=0;
151 		GetExitCodeThread(threadHnd, &exitCode);
152 		while(exitCode==STILL_ACTIVE)
153 		{
154 			Sleep(50);
155 			GetExitCodeThread(threadHnd, &exitCode);
156         		while(gtk_events_pending())
157                 		gtk_main_iteration();
158 			if(stopDownLoad)
159 			{
160 				fprintf(FileOut,_("Download Stopped\n"));
161 				break;
162 			}
163 		}
164 		CloseHandle(threadHnd);
165 	}
166 
167 	fclose(FileErr);
168 	fclose(FileOut);
169 
170 	hide_progress_connection();
171 	progress_connection(0," ",TRUE);
172 
173 	Sleep(500);
174 
175 	WSACleanup();
176 
177 	return 0;
178 }
179 
180 /******************************************************/
scp_put_file(gchar * fout,gchar * ferr,char * filename,char * localdir,char * remotedir,char * hostname,char * username,char * password)181 int scp_put_file(gchar* fout,gchar* ferr,
182 			 char* filename,char* localdir,char* remotedir,
183 			 char *hostname,char *username,char* password)
184 {
185 	gchar* winFile = g_strdup_printf("%s\\%s",localdir,filename);
186 	gchar* unixFile = createUnixFile(winFile);
187 
188 
189 	if(!unixFile)
190 	{
191 			FILE* FileErr = FOpen(ferr,"w");
192 			fprintf(FileErr,_("Sorry, I Cannot put file at remot host...\n"));
193 			fclose(FileErr);
194 			g_free(winFile);
195 			return 1;
196 	}
197 
198 	cmdGlobal = g_strdup_printf(
199 		"%s -pw %s \"%s\" %s@%s:%s/%s",
200 		pscpCommand,
201 		password,
202 		unixFile,
203 		username,hostname,remotedir,filename);
204 
205 	g_free(winFile);
206 
207 	unlink(fout);
208 	unlink(ferr);
209 	if(system(cmdGlobal)!=0)
210 	{
211 			FILE* FileErr = FOpen(ferr,"w");
212 			fprintf(FileErr,_("Sorry, I Cannot put %s file at remot host...\n"),filename);
213 			fclose(FileErr);
214 			unlink(unixFile);
215 			g_free(unixFile);
216 			return 1;
217 	}
218 	/*
219 	return run_scp(fout,ferr,cmdGlobal);
220 	*/
221 	unlink(unixFile);
222 	g_free(unixFile);
223 	return 0;
224 }
225 /******************************************************/
scp_get_file(gchar * fout,gchar * ferr,char * filename,char * localdir,char * remotedir,char * hostname,char * username,char * password)226 int scp_get_file(gchar* fout,gchar* ferr,
227 			 char* filename,char* localdir,char* remotedir,
228 			 char *hostname,char *username,char* password)
229 {
230 	gchar* message;
231 	gchar* cmd = NULL;
232 
233 	foutGlobal = g_strdup(fout);
234 	ferrGlobal = g_strdup(ferr);
235 
236 	message = g_strdup_printf( _("Get \"%s/%s\" file from \"%s\" host..."),
237 					remotedir,filename,hostname
238 				);
239 
240 	cmd = g_strdup_printf(
241 		"%s -pw %s %s@%s:%s/%s \"%s\\%s\"",
242 		pscpCommand,
243 		password,
244 		username,hostname,
245 		remotedir,filename,
246 		localdir,filename
247 		);
248 
249 	unlink(fout);
250 	unlink(ferr);
251 
252 	return run_scp(fout,ferr,cmd,message);
253 
254 }
255 #else /* G_OS_WIN32 */
256 /********************************************************
257 * ssh : main processing routine; connect to server,	*
258 * pass command line and wait for results				*
259 *********************************************************/
260 #include <stdlib.h>
261 #include <unistd.h>
262 #include <sys/types.h>
263 #include <sys/wait.h>
264 #include <errno.h>
265 #include <glib.h>
266 #include <pthread.h>
267 
268 extern char **environ;
269 static int endchild = 0;
270 static pid_t pidchild = -1;
271 static pid_t pidparent = -1;
272 
273 /********************************************************/
clientThread(gpointer data)274 static void* clientThread (gpointer data)
275 {
276 	char* cmd = (char*)data;
277 	pidchild = getpid();
278 	pidparent = getppid();
279 
280 	pthread_setcancelstate(PTHREAD_CANCEL_ENABLE,NULL);
281 	pthread_setcancelstate(PTHREAD_CANCEL_ASYNCHRONOUS,NULL);
282 
283 	pthread_testcancel();
284 	{int ierr = system(cmd);}
285 	pthread_testcancel();
286 	endchild = 1;
287 	pthread_exit((void*)0);
288 	return (void*)0;
289 }
290 /********************************************************/
run_scp(gchar * fout,gchar * ferr,char * cmd,char * message)291 int run_scp(gchar* fout,gchar* ferr,char* cmd,char* message)
292 {
293 	pthread_attr_t attr;
294 	pthread_t threadId;
295 	int ret;
296 	FILE* FileOut;
297 	FILE* FileErr;
298 
299 	/*printf("cmd = %s\n",cmd);*/
300 
301 	show_progress_connection();
302 	progress_connection(0,message,FALSE);
303 
304         pthread_attr_init(&attr);
305 	pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
306 	pthread_attr_setstacksize(&attr,1000);
307 	endchild = 0;
308 	ret = pthread_create(&threadId, &attr, clientThread, cmd);
309 	pthread_detach(threadId);
310 	if(ret)
311 	{
312 		FILE* FileErr = FOpen(ferr,"w");
313 		fprintf(FileErr,_("Cannot start client thread...\n"));
314 		fclose(FileErr);
315 		return 0;
316 	}
317 	else
318 
319 	FileErr = FOpen(ferr,"w");
320 	FileOut = FOpen(fout,"w");
321 	while(endchild==0)
322 	{
323         	while(gtk_events_pending())
324                 	gtk_main_iteration();
325 		if(stopDownLoad)
326 		{
327 			if(pthread_cancel(threadId)!=0)
328 			{
329 				progress_connection(0,_("Sorry I can not stop download"),FALSE);
330 			}
331 			else
332 			{
333 				if(pidchild != -1)
334 				{
335 					/*
336 					char t[BSIZE];
337 					sprintf(t,"kill %d",pidchild);
338 					system(t);
339 					*/
340 					/*printf("pid child = %d\n",pidchild);*/
341 				}
342 				pidchild =-1;
343 				fprintf(FileOut,_("Download Stopped\n"));
344 				break;
345 			}
346 		}
347 
348 	}
349 	fclose(FileErr);
350 	fclose(FileOut);
351 
352 	hide_progress_connection();
353 	progress_connection(0," ",TRUE);
354 	if(pidparent!=-1)
355 	{
356 		/*
357 		char t[BSIZE];
358 		sprintf(t,"kill %d",pidparent);
359 		printf("pid parent = %d\n",pidparent);
360 		system(t);
361 		*/
362 		pidparent =-1;
363 	}
364 
365 
366 	return 0;
367 }
368 /********************************************************/
scp_put_file(char * fout,char * ferr,char * filename,char * localdir,char * remotedir,char * hostname,char * username,char * password)369 int scp_put_file(char* fout,char* ferr,
370 			 char* filename,char* localdir,char* remotedir,
371 			 char *hostname,char *username,char* password)
372 {
373 	gchar *command;
374 	gchar* message;
375 
376 	message = g_strdup_printf( _("Put %s/%s file at %s host..."),
377 					remotedir,filename,hostname
378 				);
379 
380 
381 	show_progress_connection();
382 	progress_connection(0,message,FALSE);
383 
384 	command = g_strdup_printf(
385 					"sh -c \"sh -c 'scp %s/%s %s@%s:%s/%s' >%s 2>%s\"",
386 					localdir,filename,username,hostname,remotedir,filename,
387 					fout,ferr);
388 	unlink(fout);
389 	unlink(ferr);
390 	if(system(command)==0)
391 	{
392 		g_free(command);
393 		hide_progress_connection();
394 		progress_connection(0," ",TRUE);
395 	}
396 	else
397 	{
398 		g_free(command);
399 		return 1;
400 	}
401 
402 	return 0;
403 }
404 /********************************************************/
scp_get_file(char * fout,char * ferr,char * filename,char * localdir,char * remotedir,char * hostname,char * username,char * password)405 int scp_get_file(char* fout,char* ferr,
406 			 char* filename,char* localdir,char* remotedir,
407 			 char *hostname,char *username,char* password)
408 {
409 	gchar *command;
410 	gchar* message;
411 
412 	message = g_strdup_printf( _("Get \"%s/%s\" file from \"%s\" host..."),
413 					remotedir,filename,hostname
414 				);
415 
416 	command = g_strdup_printf(
417 					"sh -c \"sh -c 'scp  %s@%s:%s/%s %s/%s' \"",
418 					username,hostname,
419 					remotedir,filename,
420 					localdir,"."
421 					);
422 	unlink(fout);
423 	unlink(ferr);
424 
425 	if(run_scp(ferr,fout,command,message)==0)
426 		g_free(command);
427 	else
428 	{
429 		g_free(command);
430 		return 1;
431 	}
432 	return 0;
433 }
434 #endif /* G_SO_WIN32 */
435 /*********************************************************/
436 
437