source: trunk/zoo-project/zoo-kernel/sshapi.c @ 968

Last change on this file since 968 was 939, checked in by djay, 6 years ago

Fix const decelaration to build on windows, pass full children content for text/* ComplexData?.

  • Property svn:keywords set to Id
File size: 21.7 KB
RevLine 
[822]1/*
2 *
3 * Author : Gérald FENOY
4 *
[897]5 * Copyright 2017-2019 GeoLabs SARL. All rights reserved.
[822]6 *
7 * This work was supported by public funds received in the framework of GEOSUD,
8 * a project (ANR-10-EQPX-20) of the program "Investissements d'Avenir" managed
9 * by the French National Research Agency
10 *
[839]11 * Permission is hereby granted, free of charge, to any person obtaining a copy
[822]12 * of this software and associated documentation files (the "Software"), to deal
13 * in the Software without restriction, including without limitation the rights
14 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15 * copies of the Software, and to permit persons to whom the Software is
16 * furnished to do so, subject to the following conditions:
17 *
18 * The above copyright notice and this permission notice shall be included in
19 * all copies or substantial portions of the Software.
20 *
21 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
27 * THE SOFTWARE.
28 */
29
30#include "sshapi.h"
[854]31#include "service_internal.h"
[822]32
33SSHCON *sessions[MAX_PARALLEL_SSH_CON];
34
35/**
36 * Wait until one or more file descriptor has been changed for the socket for a
37 * time defined by timeout
38 * @param socket_fd int defining the sockket file descriptor
39 * @param session an exeisting LIBSSH2_SESSION
40 */ 
41int waitsocket(int socket_fd, LIBSSH2_SESSION *session)
42{
43    struct timeval timeout;
44    int rc;
45    fd_set fd;
46    fd_set *writefd = NULL;
47    fd_set *readfd = NULL;
48    int dir;
49 
50    timeout.tv_sec = 10;
51    timeout.tv_usec = 0;
52 
53    FD_ZERO(&fd);
54 
55    FD_SET(socket_fd, &fd);
56 
57    /* now make sure we wait in the correct direction */ 
58    dir = libssh2_session_block_directions(session);
59
60 
61    if(dir & LIBSSH2_SESSION_BLOCK_INBOUND)
62        readfd = &fd;
63 
64    if(dir & LIBSSH2_SESSION_BLOCK_OUTBOUND)
65        writefd = &fd;
66 
67    rc = select(socket_fd + 1, readfd, writefd, NULL, &timeout);
68 
69    return rc;
70}
71
72/**
73 * Connect to a remote host using SSH protocol
74 * @param conf maps The main configuration maps
75 * @return the libssh2 sessions pointer or NULL in case any failure occured.
76 */
77SSHCON *ssh_connect(maps* conf){
78  unsigned long hostaddr;
79  int i, use_pw = 1;
80  struct sockaddr_in sin;
81  const char *fingerprint;
82  SSHCON *result=(SSHCON*)malloc((2*sizeof(int))+sizeof(LIBSSH2_SESSION*)+sizeof(LIBSSH2_SFTP*));
83  result->sock_id=NULL;
84  result->index=NULL;
85  result->session=NULL;
86  result->sftp_session=NULL;
87  const char *user;
88  const char *password=NULL;
89  const char *public_key;
90  char *private_key;
91  int rc;
92  FILE *local;
93  char mem[1024 * 1000];
94  char error[1024];
95  int port=22;
96
[854]97  map* hpc_config=getMapFromMaps(conf,"lenv","configId");
98  map* hpc_host=getMapFromMaps(conf,hpc_config->value,"ssh_host");
99  map* hpc_port=getMapFromMaps(conf,hpc_config->value,"ssh_port");
100  map* hpc_user=getMapFromMaps(conf,hpc_config->value,"ssh_user");
101  map* hpc_password=getMapFromMaps(conf,hpc_config->value,"ssh_password");
102  map* hpc_public_key=getMapFromMaps(conf,hpc_config->value,"ssh_key");
[877]103 
[854]104  char ip[100];
105  struct hostent *my_hostent;
106  struct in_addr **addrs;
107 
108  if (hpc_host != NULL) {
109    // Fetch ip address for the hostname
110    if ( (my_hostent = gethostbyname( hpc_host->value ) ) == NULL){
111      herror("gethostbyname");
112      setMapInMaps(conf,"lenv","message",_("Issue when invoking gethostbyname!"));
113      return NULL;
114    }
115 
116    addrs = (struct in_addr **) my_hostent->h_addr_list;
117 
118    for(i = 0; addrs[i] != NULL; i++) {
119      strcpy(ip , inet_ntoa(*addrs[i]) );
120      break;
121    }
122  }
[822]123
124#ifdef WIN32
125  WSADATA wsadata;
126  int err;
127  err = WSAStartup(MAKEWORD(2,0), &wsadata);
128  if (err != 0) {
129    sprintf(error, "WSAStartup failed with error: %d\n", err);
130    setMapInMaps(conf,"lenv","message",error);
131    return NULL;
132  }
133#endif
134
135  if (hpc_host != NULL) {
[854]136    hostaddr = inet_addr(ip);
[822]137  } else {
138    setMapInMaps(conf,"lenv","message","No host parameter found in your main.cfg file!\n");
139    return NULL;
140  }
141
142  // Default port is 22
143  if(hpc_port!=NULL){
144    port=atoi(hpc_port->value);
145  }
146
147  // In case there is no HPC > user the it must failed
148  if (hpc_user != NULL) {
149    user = hpc_user->value;
150  }else{
151    setMapInMaps(conf,"lenv","message","No user parameter found in your main.cfg file!");
152    return NULL;
153  }
154
155  // TODO: in case password is available but there is also the public key
156  // defined, then we can consider this password as the pass phrase.
157  if (hpc_password != NULL) {
158    password = hpc_password->value;
159  }else{
160    use_pw=-1;
161    if (hpc_public_key != NULL) {
162      public_key = hpc_public_key->value;
[890]163      private_key = zStrdup(hpc_public_key->value);
[822]164      private_key[strlen(public_key)-4]=0;
165    }else{
166      setMapInMaps(conf,"lenv","message","No method found to authenticate!");
167      return NULL;
168    }
169  }
170
171  rc = libssh2_init (0);
172  if (rc != 0) {
173    sprintf (error, "libssh2 initialization failed (%d)\n", rc);
174    setMapInMaps(conf,"lenv","message",error);
175    return NULL;
176  }
177
178  result->sock_id = socket(AF_INET, SOCK_STREAM, 0);
179  sin.sin_family = AF_INET;
180  sin.sin_port = htons(port);
181  sin.sin_addr.s_addr = hostaddr;
182  if (connect(result->sock_id, (struct sockaddr*)(&sin),sizeof(struct sockaddr_in)) != 0) {
183    setMapInMaps(conf,"lenv","message","Failed to connect to remote host!");
184    return NULL;
185  }
186
187  result->session = libssh2_session_init();
188  result->sftp_session = NULL;
189  map* tmp=getMapFromMaps(conf,"lenv","nb_sessions");
190  if(tmp!=NULL){
191    char nb_sessions[10];
192    int nb_sess=atoi(tmp->value);
193    sprintf(nb_sessions,"%d",nb_sess+1);
194    setMapInMaps(conf,"lenv","nb_sessions",nb_sessions);
195    result->index=nb_sess+1;
196    sessions[nb_sess+1]=result;
197  }else{
198    setMapInMaps(conf,"lenv","nb_sessions","0");
199    sessions[0]=result;
200    result->index=0;
201  }
202
203  if (!result->session)
204    return NULL;
205
[862]206  libssh2_session_set_blocking(result->session, 1);
[822]207
208  while ((rc = libssh2_session_handshake(result->session, result->sock_id))
209         == LIBSSH2_ERROR_EAGAIN);
210
211  if (rc) {
212    sprintf(error, "Failure establishing SSH session: %d\n", rc);
213    setMapInMaps(conf,"lenv","message",error);
214    return NULL;
215  }
216
217  fingerprint = libssh2_hostkey_hash(result->session, LIBSSH2_HOSTKEY_HASH_SHA1);
218 
219  if (use_pw>0) {
220    while ((rc = libssh2_userauth_password(result->session, user, password)) ==
221           LIBSSH2_ERROR_EAGAIN);
222    if (rc) {
223      setMapInMaps(conf,"lenv","message","Authentication by password failed.");
224      ssh_close(conf);
225      return NULL;
226    }
227  } else {
228    while ((rc = libssh2_userauth_publickey_fromfile(result->session, user,
229                                                     public_key,
230                                                     private_key,
231                                                     password)) ==
232           LIBSSH2_ERROR_EAGAIN);
233    if (rc) {
234      setMapInMaps(conf,"lenv","message","Authentication by public key failed");
235      ssh_close(conf);
236      return NULL;
237    }
238    free(private_key);
239  }
240
241  return result;
242
243}
244
245/**
246 * Get the number of opened SSH connections
247 * @param conf maps pointer to the main configuration maps
248 * @return the number of opened SSH connections
249 */
250int ssh_get_cnt(maps* conf){
251  int result=0;
[854]252  map* myMap=getMapFromMaps(conf,"lenv","nb_sessions");
[822]253  if(myMap!=NULL){
254    result=atoi(myMap->value);
255  }
256  return result;
257}
258
259/**
260 * Verify if a file exists on the remote host
261 * @param conf maps pointer to the main configuration maps
262 * @param targetPath const char* defining the path for storing the file on the
263 * remote host
264 * @return true in case of success, false if failure occured
265 */
[839]266size_t ssh_file_exists(maps* conf,const char* targetPath,int cnt){
[822]267  size_t result=-1;
268  if(cnt>0)
269    cnt-=1;
270  int rc;
271  LIBSSH2_SFTP_ATTRIBUTES attrs;
272  LIBSSH2_SFTP_HANDLE *sftp_handle;
273  do{
274    sftp_handle =
275      libssh2_sftp_open(sessions[cnt]->sftp_session, targetPath, LIBSSH2_FXF_READ,
276                        LIBSSH2_SFTP_S_IRUSR|LIBSSH2_SFTP_S_IWUSR|
277                        LIBSSH2_SFTP_S_IRGRP|LIBSSH2_SFTP_S_IROTH);
278    if (!sftp_handle) {
279      fprintf(stderr, "Unable to open file with SFTP: %d %ld\n",__LINE__,
280              libssh2_sftp_last_error(sessions[cnt]->sftp_session));
281      return 0;
282    }
283  }while(!sftp_handle);
[860]284#ifdef SSH_DEBUG
[822]285  fprintf(stderr, "libssh2_sftp_open() is done, get file information\n");
[860]286#endif
[822]287  do {
288  rc = libssh2_sftp_stat_ex(sessions[cnt]->sftp_session, targetPath, strlen(targetPath),
289                            LIBSSH2_SFTP_LSTAT, &attrs );
290  if (rc<0 &&
291      (libssh2_session_last_errno(sessions[cnt]->session) != LIBSSH2_ERROR_EAGAIN))
292    {
293      fprintf(stderr, "error trying to fstat_ex, returned %d\n", rc);
294      break;
295    }
296  else
297    {
[860]298#ifdef SSH_DEBUG
[822]299      fprintf(stderr, "Stat Data: RetCode=%d\n", rc);
300      fprintf(stderr, "Stat Data: Size=%llu\n", attrs.filesize);
301      fprintf(stderr, "Stat Data: Perm=%lx\n",  attrs.permissions);
302      fprintf(stderr, "Stat Data: mtime=%lu\n",  attrs.mtime);
[860]303#endif
[822]304      if(rc==0)
305        break;
306      result=attrs.filesize;
307    }
308  } while (true);
309  libssh2_sftp_close(sftp_handle);
310  //libssh2_sftp_shutdown(sessions[cnt]->sftp_session);
311
312  return result;
313}
314
315/**
316 * Upload a file over an opened SSH connection
317 * @param conf maps pointer to the main configuration maps
318 * @param localPath const char* defining the local path for accessing the file
319 * @param targetPath const char* defining the path for storing the file on the
320 * remote host
321 * @return true in case of success, false if failure occured
322 */
[839]323bool ssh_copy(maps* conf,const char* localPath,const char* targetPath,int cnt){
[897]324  char mem[1024 * 16];
[822]325  size_t nread;
326  size_t memuse=0;
327  time_t start;
328  long total = 0;
[897]329  int counter=0;
[822]330  int duration;
331  int rc;
332  LIBSSH2_SFTP_HANDLE *sftp_handle;
333  //map* myMap=getMapFromMaps(conf,"lenv","cnt_session");
334  if(getMapFromMaps(conf,"lenv","cnt_session")!=NULL){
335    char tmp[10];
336    sprintf(tmp,"%d",cnt+1);
337    setMapInMaps(conf,"lenv","cnt_session",tmp);
338  }else
339    setMapInMaps(conf,"lenv","cnt_session","0");
340  FILE *local = fopen(localPath, "rb");
341  if (!local) {
342    fprintf(stderr, "Can't open local file %s\n", localPath);
[839]343    return false;
[822]344  }
[854]345 
[822]346  do {
347    sessions[cnt]->sftp_session = libssh2_sftp_init(sessions[cnt]->session);
348    if (!sessions[cnt]->sftp_session &&
349        (libssh2_session_last_errno(sessions[cnt]->session) != LIBSSH2_ERROR_EAGAIN)) {
350     
351      fprintf(stderr, "Unable to init SFTP session\n");
352      return false;
353    }
[860]354    if(!sessions[cnt]->sftp_session)
355      zSleep(10);
[822]356  } while (!sessions[cnt]->sftp_session);
357
358  do {
359    sftp_handle =
360      libssh2_sftp_open(sessions[cnt]->sftp_session, targetPath,
361                        LIBSSH2_FXF_WRITE|LIBSSH2_FXF_CREAT|LIBSSH2_FXF_TRUNC,
362                        LIBSSH2_SFTP_S_IRUSR|LIBSSH2_SFTP_S_IWUSR|
363                        LIBSSH2_SFTP_S_IRGRP|LIBSSH2_SFTP_S_IROTH);
364
365    if (!sftp_handle &&
366        (libssh2_session_last_errno(sessions[cnt]->session) != LIBSSH2_ERROR_EAGAIN)) {
367     
368      fprintf(stderr, "Unable to open file with SFTP\n");
369      return false;
370    }
[860]371    if(!sftp_handle)
372      zSleep(10);
[822]373  } while (!sftp_handle);
374  start = time(NULL);
375 
376  do {
377    nread = fread(&mem[memuse], 1, sizeof(mem)-memuse, local);
378    if (nread <= 0) {
379      if (memuse > 0)
380        nread = 0;
381      else
382        break;
383    }
384    memuse += nread;
385    total += nread;
386   
387    while ((rc = libssh2_sftp_write(sftp_handle, mem, memuse)) ==
388           LIBSSH2_ERROR_EAGAIN) {
389      waitsocket(sessions[cnt]->sock_id, sessions[cnt]->session);
390    }
391    if(rc < 0)
392      break;
393   
[897]394    memuse = 0;
[822]395   
396  } while (rc > 0);
397 
398  duration = (int)(time(NULL)-start);
399  fclose(local);
[839]400  libssh2_sftp_close_handle(sftp_handle);
[822]401
402  libssh2_sftp_shutdown(sessions[cnt]->sftp_session);
403  return true;
404}
405
406/**
407 * Download a file over an opened SSH connection
408 * @param conf maps pointer to the main configuration maps
409 * @param localPath const char* defining the local path for storing the file
410 * @param targetPath const char* defining the path for accessing the file on the
411 * remote host
[854]412 * @return 0 in case of success, -1 if failure occured
[822]413 */
[839]414int ssh_fetch(maps* conf,const char* localPath,const char* targetPath,int cnt){
[822]415  size_t nread;
416  size_t memuse=0;
417  time_t start;
418  long total = 0;
419  int duration;
420  int rc;
421  LIBSSH2_SFTP_HANDLE *sftp_handle;
422  FILE *local = fopen(localPath, "wb");
423  if (!local) {
424    fprintf(stderr, "Can't open local file %s\n", localPath);
425    return -1;
426  }
427
428  do {
429    sessions[cnt]->sftp_session = libssh2_sftp_init(sessions[cnt]->session);
430    if (!sessions[cnt]->sftp_session &&
431        (libssh2_session_last_errno(sessions[cnt]->session) != LIBSSH2_ERROR_EAGAIN)) {
432      fprintf(stderr, "Unable to init SFTP session\n");
[854]433      return -1;
[822]434    }
[860]435    if(!sessions[cnt]->sftp_session)
[897]436      zSleep(10);
[822]437  } while (!sessions[cnt]->sftp_session);
[854]438  do {
439    sftp_handle = libssh2_sftp_open(sessions[cnt]->sftp_session, targetPath,   
440                                    LIBSSH2_FXF_READ, 0);
441    if (!sftp_handle) {
442      if (libssh2_session_last_errno(sessions[cnt]->session) != LIBSSH2_ERROR_EAGAIN) {
443        fprintf(stderr, " ** Unable to open file with SFTP\n");
444        return -1;
445      }
446      else {
447        waitsocket(sessions[cnt]->sock_id, sessions[cnt]->session); 
448      }
449    }
[862]450    if(!sftp_handle)
[897]451      zSleep(10);
[854]452  } while (!sftp_handle);
[897]453
[854]454  int result=0;
[897]455  int counter=0;
[854]456  do {
[822]457    do {
[897]458      char* mem=(char*)malloc(16*1024);
459      rc = libssh2_sftp_read(sftp_handle, mem,16*1024);
[854]460      if(rc > 0) {
461        fwrite(mem, rc, 1, local);
462      }
[862]463      free(mem);
[897]464      if(counter%25==0)
465        zSleep(10);
[854]466    } while (rc > 0);
[897]467
[854]468    if(rc != LIBSSH2_ERROR_EAGAIN) {
469      result=-1;
470      break;
471    }
[897]472
[854]473    struct timeval timeout;
474    fd_set fd;
475    timeout.tv_sec = 10;
476    timeout.tv_usec = 0;
[897]477
[854]478    FD_ZERO(&fd);
[897]479
[854]480    FD_SET(sessions[cnt]->sock_id, &fd);
[897]481
[854]482    rc = select(sessions[cnt]->sock_id+1, &fd, &fd, NULL, &timeout);
483    if(rc <= 0) {
484      if(rc==0)
485        fprintf(stderr, "SFTP download timed out: %d\n", rc);
486      else
487        fprintf(stderr, "SFTP download error: %d\n", rc);
488      return -1;
489    }
[897]490
491    if(counter%50==0)
492       zSleep(10);
493    counter++;
494
[854]495  } while (1);
[822]496  duration = (int)(time(NULL)-start);
497  fclose(local);
[839]498  libssh2_sftp_close_handle(sftp_handle);
[822]499  libssh2_sftp_shutdown(sessions[cnt]->sftp_session);
500  return 0;
501}
502
503/**
504 * Execute a command over an opened SSH connection
505 * @param conf maps pointer to the main configuration maps
506 * @param command const char pointer to the command to be executed
507 * @return bytecount resulting from the execution of the command
508 */
[839]509int ssh_exec(maps* conf,const char* command,int cnt){
[822]510  LIBSSH2_CHANNEL *channel;
511  int rc;
512  int bytecount = 0;
513  int exitcode;
514  char *exitsignal=(char *)"none";
515  while( (channel = libssh2_channel_open_session(sessions[cnt]->session)) == NULL &&
516         libssh2_session_last_error(sessions[cnt]->session,NULL,NULL,0) == LIBSSH2_ERROR_EAGAIN ) {
[860]517    waitsocket(sessions[cnt]->sock_id, sessions[cnt]->session);
[822]518  }
519  if( channel == NULL ){
520    fprintf(stderr,"Error\n");
[854]521    return -1;
[822]522  }
523  while( (rc = libssh2_channel_exec(channel, command)) == LIBSSH2_ERROR_EAGAIN ) {
524    waitsocket(sessions[cnt]->sock_id, sessions[cnt]->session);
525  }
526  if( rc != 0 ) {
527    fprintf(stderr,"Error\n");
528    return -1;
529  }
530
531  map* tmpPath=getMapFromMaps(conf,"main","tmpPath");
532  map* uuid=getMapFromMaps(conf,"lenv","usid");
533  char *logPath=(char*)malloc((strlen(tmpPath->value)+strlen(uuid->value)+11)*sizeof(char));
534  sprintf(logPath,"%s/exec_out_%s",tmpPath->value,uuid->value);
[886]535 
[822]536  FILE* logFile=fopen(logPath,"wb");
[851]537  free(logPath);
[822]538  while(true){
539    int rc;
540    do {
541      char buffer[0x4000];
542      rc = libssh2_channel_read( channel, buffer, sizeof(buffer) );
543     
544      if( rc > 0 ){
545        int i;
546        bytecount += rc;
547        buffer[rc]=0;
[886]548       
[822]549        fprintf(logFile,"%s",buffer);
550        fflush(logFile);
551      }
552    }
553    while( rc > 0 );
554   
555    if( rc == LIBSSH2_ERROR_EAGAIN ) {
556      waitsocket(sessions[cnt]->sock_id, sessions[cnt]->session);
557    }
558    else
559      break;
560  }
561  fclose(logFile);
562  exitcode = 127;
563  while( (rc = libssh2_channel_close(channel)) == LIBSSH2_ERROR_EAGAIN )
564    waitsocket(sessions[cnt]->sock_id, sessions[cnt]->session);
565 
566  if( rc == 0 ) {
567    exitcode = libssh2_channel_get_exit_status( channel );
568    libssh2_channel_get_exit_signal(channel, &exitsignal,
569                                    NULL, NULL, NULL, NULL, NULL);
570  }
571 
572  if (exitsignal)
573    fprintf(stderr, "\nGot signal: %s\n", exitsignal);
574  else
575    fprintf(stderr, "\nEXIT: %d bytecount: %d\n", exitcode, bytecount);
576 
577  libssh2_channel_free(channel);
578
579  return bytecount;
580}
581
582/**
583 * Close an opened SSH connection
584 * @param conf maps pointer to the main configuration maps
585 * @param con SSHCON pointer to the SSH connection
586 * @return true in case of success, false if failure occured
587 */
588bool ssh_close_session(maps* conf,SSHCON* con){
[862]589  if(con==NULL)
590    return true;
[822]591  while (libssh2_session_disconnect(con->session, "Normal Shutdown, Thank you for using the ZOO-Project sshapi")
592         == LIBSSH2_ERROR_EAGAIN);
593#ifdef WIN32
594  closesocket(con->sock_id);
595#else
596  close(con->sock_id);
597#endif
[839]598  libssh2_session_free(con->session);
[862]599  con=NULL;
[822]600  return true;
601}
602
603/**
604 * Close all the opened SSH connections
605 * @param conf maps pointer to the main configuration maps
606 * @return true in case of success, false if failure occured
607 */
608bool ssh_close(maps* conf){
609  int i,nb_sessions;
610  map* tmp=getMapFromMaps(conf,"lenv","nb_sessions");
611  if(tmp!=NULL){
612    nb_sessions=atoi(tmp->value);
613    for(i=0;i<nb_sessions;i++)
614      ssh_close_session(conf,sessions[i]);
615  }
616  libssh2_exit();
617  return true;
618}
[839]619
620bool addToUploadQueue(maps** conf,maps* input){
621  map* queueMap=getMapFromMaps(*conf,"uploadQueue","length");
622  if(queueMap==NULL){
623    maps* queueMaps=createMaps("uploadQueue");
624    queueMaps->content=createMap("length","0");
625    addMapsToMaps(conf,queueMaps);
626    freeMaps(&queueMaps);
627    free(queueMaps);
628    queueMap=getMapFromMaps(*conf,"uploadQueue","length");
629  }
630  maps* queueMaps=getMaps(*conf,"uploadQueue");
631  int queueIndex=atoi(queueMap->value);
632  if(input!=NULL){
633    if(getMap(input->content,"cache_file")!=NULL){
634      map* length=getMap(input->content,"length");
635      if(length==NULL){
636        addToMap(input->content,"length","1");
637        length=getMap(input->content,"length");
638      }
639      int len=atoi(length->value);
640      int i=0;
641      for(i=0;i<len;i++){
642       
643        map* tmp[2]={getMapArray(input->content,"localPath",i),
644                     getMapArray(input->content,"targetPath",i)};
645
[862]646        setMapArray(queueMaps->content,"input",queueIndex+i,input->name);
647        setMapArray(queueMaps->content,"localPath",queueIndex+i,tmp[0]->value);
648        setMapArray(queueMaps->content,"targetPath",queueIndex+i,tmp[1]->value);
649
[839]650      }
651    }
652  }
653  return true;
654}
655
[886]656int fileMd5Check(maps** conf,const char* localPath,const char* targetPath){
657  if(strstr(localPath,".zca")!=NULL){
[888]658    char *logPath=NULL;   
659    char *command=(char*)malloc(((2*strlen(targetPath))+42)*sizeof(char));
660    sprintf(command,"(md5sum %s | awk {'print $1'}) && touch %s",targetPath,targetPath);
[886]661    if(ssh_exec(*conf,command,ssh_get_cnt(*conf))<=0){
662      return -1;
663    }else{
664      struct stat f_status={};
665      map* usid=getMapFromMaps(*conf,"lenv","usid");
666      map* tmpMap=getMapFromMaps(*conf,"main","tmpPath");
667      char* tmpPath=zStrdup(localPath);
668      tmpPath[strlen(tmpPath)-2]='m';
669      tmpPath[strlen(tmpPath)-1]='d';
670      free(command);
671      logPath=(char*)malloc((strlen(tmpMap->value)+strlen(usid->value)+11)*sizeof(char));
672      sprintf(logPath,"%s/exec_out_%s",tmpMap->value,usid->value);
673      int ts=stat(logPath, &f_status);
674      if(ts==0) {
675        char* fcontent=(char*)malloc(sizeof(char)*(f_status.st_size+1));
676        FILE* f=fopen(logPath,"rb");
677        fread(fcontent,f_status.st_size,1,f);
678        fcontent[f_status.st_size-1]=0;
679        fclose(f);
680        free(logPath);
681        struct stat f_status1={};
682        int ts1=stat(tmpPath, &f_status1);
683        if(ts1==0) {
684          char* fcontent1=(char*)malloc(sizeof(char)*(f_status.st_size+1));
685          FILE* f1=fopen(tmpPath,"rb");
686          fread(fcontent1,f_status1.st_size,1,f1);
687          fcontent1[f_status1.st_size]=0;
688          fclose(f1);
689          free(tmpPath);
690          if(strcmp(fcontent,fcontent1)==0){
691            free(fcontent);
692            free(fcontent1);
693            return 0;
694          }else{
695            free(fcontent);
696            free(fcontent1);
697            return -1;
698          }
699        }else{
700          free(tmpPath);
701          free(fcontent);
702          return -1;
703        }       
704      }
705      free(logPath);
706      free(tmpPath);
707    }
708  }
709  return -1;
710}
711
[839]712bool runUpload(maps** conf){
713  SSHCON *test=ssh_connect(*conf);
714  if(test==NULL){
715    return false;
716  }
717  map* queueLengthMap=getMapFromMaps(*conf,"uploadQueue","length");
718  maps* queueMaps=getMaps(*conf,"uploadQueue");
719  if(queueLengthMap!=NULL){
720    int cnt=atoi(queueLengthMap->value);
721    int i=0;
722    for(i=0;i<cnt;i++){
723      map* argv[3]={
724        getMapArray(queueMaps->content,"input",i),
725        getMapArray(queueMaps->content,"localPath",i),
726        getMapArray(queueMaps->content,"targetPath",i)
727      };
[886]728      if(fileMd5Check(conf,argv[1]->value,argv[2]->value)<0){
729        /**/zooLock* lck;
730        if((lck=lockFile(*conf,argv[1]->value,'w'))!=NULL){/**/
731          if(ssh_copy(*conf,argv[1]->value,argv[2]->value,ssh_get_cnt(*conf))!=true){
[939]732            const char* templateStr=_("Unable to copy over SSH the file requested for setting the value of %s.");
[886]733            char *tmpMessage=(char*)malloc((strlen(templateStr)+strlen(argv[0]->value)+1)*sizeof(char));
734            sprintf(tmpMessage,templateStr,argv[0]->value);
735            setMapInMaps(*conf,"lenv","message",tmpMessage);
736            free(tmpMessage);
737            unlockFile(*conf,lck);
738            return false;
739          }
740          /**/unlockFile(*conf,lck);
741        }else{
742          setMapInMaps(*conf,"lenv","message",_("Unable to lock the file for upload!"));
[854]743          return false;
[886]744        }/**/
745      }
[839]746    }   
747  }
[862]748  while (libssh2_session_disconnect(test->session, "Normal Shutdown, Thank you for using the ZOO-Project sshapi")
749         == LIBSSH2_ERROR_EAGAIN);
750#ifdef WIN32
751  closesocket(test->sock_id);
752#else
753  close(test->sock_id);
754#endif
755  libssh2_session_free(test->session);
756  free(test);
757  test=NULL;
758  sessions[ssh_get_cnt(*conf)-1]=NULL;
759  maps* tmp=getMaps(*conf,"lenv");
760  addIntToMap(tmp->content,"nb_sessions",ssh_get_cnt(*conf)-1); 
761
[839]762  return true; 
763}
Note: See TracBrowser for help on using the repository browser.

Search

Context Navigation

ZOO Sponsors

http://www.zoo-project.org/trac/chrome/site/img/geolabs-logo.pnghttp://www.zoo-project.org/trac/chrome/site/img/neogeo-logo.png http://www.zoo-project.org/trac/chrome/site/img/apptech-logo.png http://www.zoo-project.org/trac/chrome/site/img/3liz-logo.png http://www.zoo-project.org/trac/chrome/site/img/gateway-logo.png

Become a sponsor !

Knowledge partners

http://www.zoo-project.org/trac/chrome/site/img/ocu-logo.png http://www.zoo-project.org/trac/chrome/site/img/gucas-logo.png http://www.zoo-project.org/trac/chrome/site/img/polimi-logo.png http://www.zoo-project.org/trac/chrome/site/img/fem-logo.png http://www.zoo-project.org/trac/chrome/site/img/supsi-logo.png http://www.zoo-project.org/trac/chrome/site/img/cumtb-logo.png

Become a knowledge partner

Related links

http://zoo-project.org/img/ogclogo.png http://zoo-project.org/img/osgeologo.png