Changeset 2467

Show
Ignore:
Timestamp:
08/18/07 13:06:08 (1 year ago)
Author:
paule
Message:

Fix scp support and make it actually use scp instead of sftp, so you don't have to have an sftp server installed on the device

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • plugins/opie-sync/src/opie_comms.c

    r2463 r2467  
    6262 
    6363 
     64typedef struct { 
     65        char *filename; /* use fd instead where possible */ 
     66        int fd; 
     67} TempFile; 
     68 
     69 
    6470/* 
    6571 * comms_init 
     
    7783{ 
    7884        curl_global_cleanup(); 
     85} 
     86 
     87 
     88TempFile *create_temp_file(void) { 
     89        osync_trace(TRACE_ENTRY, "%s", __func__); 
     90         
     91        TempFile *tmpfile = g_malloc(sizeof(TempFile)); 
     92        char *template = g_strdup("/tmp/opie-sync.XXXXXX"); 
     93        tmpfile->fd = mkstemp(template); 
     94        if(tmpfile->fd == -1) { 
     95                osync_trace( TRACE_EXIT_ERROR, "failed to create temporary file" ); 
     96                g_free(template); 
     97                return NULL; 
     98        } 
     99        tmpfile->filename = template; 
     100         
     101        osync_trace(TRACE_EXIT, "%s(%p)", __func__, tmpfile); 
     102        return tmpfile; 
     103} 
     104 
     105 
     106void cleanup_temp_file(TempFile *tempfile) { 
     107        if(tempfile->fd > -1) 
     108                close(tempfile->fd); 
     109        unlink(tempfile->filename); /* FIXME check the result of this */ 
     110        g_free(tempfile->filename); 
     111        g_free(tempfile); 
    79112} 
    80113 
     
    111144                } 
    112145                 
    113                 pos += bufsize
     146                pos += wbytes
    114147                if(pos == len)  { 
    115148                        /* finished */ 
     
    220253                        } 
    221254                        else { 
    222 //                              rc = scp_fetch_file(env, data); 
    223                                 osync_trace( TRACE_INTERNAL, "SCP currently not supported." ); 
    224                                 rc = FALSE; 
     255                                rc = scp_fetch_file(env, remotefile, &data); 
    225256                        } 
    226257                        break; 
     
    697728                                } 
    698729                                else { 
    699 //                                      rc = scp_put_file(env, data); 
    700                                         osync_trace( TRACE_INTERNAL, "SCP currently not supported." ); 
    701                                         rc = FALSE; 
     730                                        rc = scp_put_file(env, remotefile, data); 
    702731                                } 
    703732                                break; 
     
    722751                                fprintf(stderr, "Error during upload to device, writing file to %s", backupfile);  
    723752                                osync_trace( TRACE_INTERNAL, "Error during upload to device, writing file to %s", backupfile ); 
    724 //X                            rc = backup_file(backupfile, data->str, data->len); 
     753                               rc = backup_file(backupfile, data, strlen(data)); 
    725754                                g_free(backupfile); 
    726755                                g_free(basename); 
     
    831860gboolean scp_fetch_file(OpiePluginEnv* env, const char *remotefile, GString **data) 
    832861{ 
    833         osync_trace(TRACE_ENTRY, "%s(%p, %p)", __func__, env, data); 
     862        osync_trace(TRACE_ENTRY, "%s(%p, %s, %p)", __func__, env, remotefile, data); 
    834863         
    835864        gboolean rc = TRUE; 
    836865        char* scpcommand = NULL; 
    837  
    838         int scpretval; 
    839          
    840         if(env->url && env->device_port && env->username)  
    841         { 
    842                 /* fetch each of the requested files */ 
     866        int scpretval, scpexitstatus; 
     867        TempFile *tmpfile = NULL; 
     868         
     869        if(env->url && env->device_port && env->username) { 
    843870                /* We have to close the temp file, because we want  
    844                                 sftp to be able to write to it */ 
    845 //             close(data->local_fd); 
    846                  
    847                 /* not keeping it quiet for the moment */ 
    848                 char *localfile = NULL; 
    849                  
    850                 scpcommand = g_strdup_printf("sftp -o Port=%d -o BatchMode=yes %s@%s:%s %s", 
    851                                             env->device_port, 
    852                                             env->username
    853                                             env->url
    854                                             remotefile
    855                                             localfile); 
     871                                scp to be able to write to it */ 
     872               tmpfile = create_temp_file(); 
     873                close(tmpfile->fd); 
     874                tmpfile->fd = -1; 
     875                 
     876                /* A crude test to see if the file exists. You can't combine  
     877                  this with scp unfortunately because scp seems to return 1  
     878                  on any error */ 
     879                scpcommand = g_strdup_printf("ssh -o BatchMode=yes %s@%s \"ls %s > /dev/null\""
     880                                                                                                                               env->username
     881                                                                                                                               env->url
     882                                                                                                                               remotefile); 
    856883                 
    857884                scpretval = pclose(popen(scpcommand,"w")); 
    858                  
    859                 if((scpretval == -1) || (WEXITSTATUS(scpretval) != 0)) 
    860                 { 
    861                         osync_trace( TRACE_INTERNAL, "SFTP failed" ); 
    862                         rc = FALSE; 
    863                 } 
    864                 else  
    865                 { 
    866                         osync_trace( TRACE_INTERNAL, "SFTP ok" ); 
    867                 } 
    868                  
     885                scpexitstatus = WEXITSTATUS(scpretval); 
     886                 
     887                if(scpexitstatus != 1) { 
     888                        if((scpretval == -1) || (scpexitstatus != 0)) { 
     889                                rc = FALSE; 
     890                                osync_trace( TRACE_INTERNAL, "ssh login failed" ); 
     891                                goto error; 
     892                        } 
     893                        g_free(scpcommand); 
     894                         
     895                        /* Fetch the file */ 
     896                        scpcommand = g_strdup_printf("scp -q -B %s@%s:%s %s", 
     897                                                                                                                                        env->username, 
     898                                                                                                                                        env->url, 
     899                                                                                                                                        remotefile, 
     900                                                                                                                                        tmpfile->filename); 
     901                         
     902                        scpretval = pclose(popen(scpcommand,"w")); 
     903                        scpexitstatus = WEXITSTATUS(scpretval); 
     904                         
     905                        if((scpretval == -1) || (scpexitstatus != 0)) { 
     906                                osync_trace( TRACE_INTERNAL, "scp transfer failed" ); 
     907                                rc = FALSE; 
     908                                goto error; 
     909                        } 
     910                        else { 
     911                                osync_trace( TRACE_INTERNAL, "scp ok" ); 
     912                        } 
     913                         
     914                        /* read the temp file */  
     915                        OSyncError *error = NULL; 
     916                        int len = 0; 
     917                        char *str = NULL;  
     918                        rc = osync_file_read(tmpfile->filename, &str, &len, &error); 
     919                        *data = g_string_new_len(str, len); 
     920                        free(str); 
     921                } 
     922        } 
     923         
     924error:   
     925         
     926        if(tmpfile) 
     927                cleanup_temp_file(tmpfile); 
     928        if(scpcommand); 
    869929                g_free(scpcommand); 
    870                 /* reopen the temp file */  
    871 //              data->local_fd = open(data->local_filename, O_RDWR | O_EXCL); 
    872         } 
    873930         
    874931        osync_trace(TRACE_EXIT, "%s(%i)", __func__, rc ); 
     
    882939gboolean scp_put_file(OpiePluginEnv* env, const char *remotefile, char *data) 
    883940{ 
    884         osync_trace(TRACE_ENTRY, "%s(%p, %p)", __func__, env, data); 
     941        osync_trace(TRACE_ENTRY, "%s(%p, %s, %p)", __func__, env, remotefile, data); 
    885942         
    886943        gboolean rc = TRUE; 
    887944        char* scpcommand = NULL; 
    888945        int scpretval = 0; 
    889         char batchfile[] = "/tmp/opie_syncXXXXXX"; 
    890         int batchfd = 0; 
    891  
    892         /* to use SFTP to upload we'll have to create a batch file with all of 
    893                 the commands we want to execute */ 
    894         if((batchfd = mkstemp(batchfile)) < 0)    
    895         { 
    896                 /* could not create temp batch file */ 
    897                 char* errmsg = g_strdup_printf("SFTP could not create batch file: %s\n", 
    898                                                                                                                                         strerror(errno)); 
    899                 osync_trace( TRACE_INTERNAL, "%s", errmsg ); 
    900                 g_free(errmsg); 
     946        int scpexitstatus = 0; 
     947 
     948        TempFile *tmpfile = create_temp_file(); 
     949        if(!tmpfile) { 
     950                /* could not create temp file - error message has already been sent to trace */ 
    901951                rc = FALSE; 
    902                                                                                                                                          
    903         } 
    904         else 
    905         { 
    906                 /* ok - print the commands to the file */ 
    907                 GString *batchbuf = g_string_new(""); 
    908                  
    909                 char *localfile = NULL; // FIXME 
    910                  
    911                 g_string_append_printf(batchbuf, "put %s %s\n", localfile, remotefile); 
    912                 g_string_append_printf(batchbuf, "bye\n"); 
    913                  
    914                 if(write(batchfd, (void *)batchbuf->str, batchbuf->len) < 0) 
    915                 { 
    916                         /* could not write to temp file */ 
    917                         char* errmsg = g_strdup_printf("SFTP could not write to batch file: %s\n", 
    918                                                                                                                                                 strerror(errno)); 
    919                         osync_trace( TRACE_INTERNAL, "%s", errmsg ); 
    920                         g_free(errmsg); 
     952        } 
     953        else { 
     954                int bufsize = 1024; 
     955                int wbytes; 
     956                int pos = 0; 
     957                int len = strlen(data); 
     958                 
     959                while(TRUE) { 
     960                        if(len - pos < bufsize) 
     961                                bufsize = len - pos; 
     962                         
     963                        wbytes = write(tmpfile->fd, data + pos, bufsize); 
     964                        if(wbytes == -1) { 
     965                                osync_trace( TRACE_INTERNAL, "error writing to backup file" ); 
     966                                perror("error writing to backup file"); 
     967                                rc = FALSE; 
     968                                goto error; 
     969                        } 
     970                         
     971                        pos += wbytes; 
     972                        if(pos == len)  { 
     973                                /* finished */ 
     974                                break; 
     975                        } 
     976                } 
     977                 
     978                /* We have to close now */ 
     979                close(tmpfile->fd); 
     980                tmpfile->fd = -1; 
     981                 
     982                /* create path */ 
     983                char *dirname = g_path_get_dirname(remotefile); 
     984                scpcommand = g_strdup_printf("ssh -o BatchMode=yes %s@%s \"mkdir -p %s\"", 
     985                                                                                                                                env->username, 
     986                                                                                                                                env->url, 
     987                                                                                                                                dirname); 
     988                g_free(dirname); 
     989                 
     990                scpretval = pclose(popen(scpcommand,"w")); 
     991                scpexitstatus = WEXITSTATUS(scpretval); 
     992                 
     993                if((scpretval == -1) || (scpexitstatus != 0)) { 
    921994                        rc = FALSE; 
    922                         close(batchfd); 
    923                 } 
    924                 else 
    925                 {  
    926                         fsync(batchfd); 
    927                         close(batchfd); 
    928                          
    929                         /* transfer the file */  
    930                         scpcommand = g_strdup_printf("sftp -o Port=%d -o BatchMode=yes -b %s %s@%s", 
    931                                                     env->device_port, 
    932                                                     batchfile, 
    933                                                     env->username, 
    934                                                     env->url); 
    935                          
    936                         scpretval = pclose(popen(scpcommand,"w")); 
    937  
    938                         if((scpretval == -1) || (WEXITSTATUS(scpretval) != 0)) 
    939                         { 
    940                                 rc = FALSE; 
    941                                 osync_trace( TRACE_INTERNAL, "SFTP upload failed" ); 
    942                         } 
    943                         else 
    944                         { 
    945                                 rc = TRUE; 
    946                                 osync_trace( TRACE_INTERNAL, "SFTP upload ok" ); 
    947                         } 
    948  
    949                         /* remove the temporary file we created */ 
    950                         if(unlink(batchfile) < 0) 
    951                         { 
    952                                 char* errmsg = g_strdup_printf("SFTP could not remove batch file: %s\n", 
    953                                                                strerror(errno)); 
    954                                 osync_trace( TRACE_INTERNAL, "%s", errmsg ); 
    955                                 g_free(errmsg); 
    956                         } 
    957  
    958                         g_free(scpcommand); 
    959                 } 
    960                  
    961                 g_string_free(batchbuf, TRUE); 
    962         } 
     995                        osync_trace( TRACE_INTERNAL, "ssh create path failed" ); 
     996                } 
     997                g_free(scpcommand); 
     998                 
     999                /* transfer the file */  
     1000                scpcommand = g_strdup_printf("scp -q -B %s %s@%s:%s", 
     1001                                                                                                                                tmpfile->filename, 
     1002                                                                                                                                env->username, 
     1003                                                                                                                                env->url, 
     1004                                                                                                                                remotefile); 
     1005                 
     1006                scpretval = pclose(popen(scpcommand,"w")); 
     1007                scpexitstatus = WEXITSTATUS(scpretval); 
     1008 
     1009                if((scpretval == -1) || (scpexitstatus != 0)) { 
     1010                        rc = FALSE; 
     1011                        osync_trace( TRACE_INTERNAL, "scp upload failed" ); 
     1012                } 
     1013                else { 
     1014                        rc = TRUE; 
     1015                        osync_trace( TRACE_INTERNAL, "scp upload ok" ); 
     1016                } 
     1017 
     1018                g_free(scpcommand); 
     1019        } 
     1020         
     1021error: 
     1022 
     1023        if(tmpfile) 
     1024                cleanup_temp_file(tmpfile); 
    9631025         
    9641026        osync_trace(TRACE_EXIT, "%s(%d)", __func__, rc );