Changeset 2461

Show
Ignore:
Timestamp:
08/17/07 15:46:49 (1 year ago)
Author:
paule
Message:

Rip out code that messed around with temporary files and fds, and instead read data directly to and from strings in memory. This breaks scp conntype support (will be fixed later).

Files:

Legend:

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

    r2446 r2461  
    3838#include <opensync/opensync.h> 
    3939#include <opensync/opensync-plugin.h> 
     40#include <opensync/opensync_xml.h> 
    4041 
    4142#include "opie_comms.h" 
    4243#include "opie_xml.h" 
    4344#include "opie_qcop.h" 
    44  
    45 typedef struct { 
    46         char *remote_filename; 
    47         char *local_filename; /* use fd instead where possible */ 
    48         int local_fd; 
    49 } RemoteData; 
    50  
    51 enum temp_file_type { 
    52         TT_STANDARD = 1, 
    53         TT_VISIBLE = 2, 
    54         TT_DEBUG = 3, 
    55         TT_DEBUG_CREATE = 4 
    56 }; 
    5745 
    5846int opie_curl_fwrite(void* buffer, size_t size, size_t nmemb, void* stream); 
     
    6048int opie_curl_nullwrite(void *buffer, size_t size, size_t nmemb, void *stream); 
    6149int opie_curl_strread(void *buffer, size_t size, size_t nmemb, void *stream); 
    62 gboolean ftp_fetch_file(OpiePluginEnv* env, RemoteData *data); 
    63 gboolean scp_fetch_file(OpiePluginEnv* env, RemoteData *data); 
    64 gboolean ftp_put_file(OpiePluginEnv* env, RemoteData *data); 
    65 gboolean scp_put_file(OpiePluginEnv* env, RemoteData *data); 
     50gboolean ftp_fetch_file(OpiePluginEnv* env, const char *remotefile, GString **data); 
     51gboolean scp_fetch_file(OpiePluginEnv* env, const char *remotefile, GString **data); 
     52gboolean ftp_put_file(OpiePluginEnv* env, const char *remotefile, char *data); 
     53gboolean scp_put_file(OpiePluginEnv* env, const char *remotefile, char *data); 
    6654gboolean ftp_fetch_notes(OpiePluginEnv* env, xmlDoc *doc); 
    6755 
     
    8876 
    8977/* 
    90  * Set up a temporary file 
    91  */ 
    92 RemoteData *create_temp_file(const char *remote_file, int tmpfilemode) { 
    93         osync_trace(TRACE_ENTRY, "%s(%s, %i)", __func__, remote_file, tmpfilemode); 
    94          
    95         RemoteData *pair = g_malloc(sizeof(RemoteData)); 
    96         pair->remote_filename = g_strdup(remote_file); 
    97         if(tmpfilemode == TT_DEBUG || tmpfilemode == TT_DEBUG_CREATE) { 
    98                 /* Bypass normal temporary file handling (for debugging purposes) */ 
    99                 char *basename = g_path_get_basename(remote_file); 
    100                 pair->local_filename = g_strdup_printf("/tmp/%s", basename); 
    101                 g_free(basename); 
    102                 if(tmpfilemode == TT_DEBUG_CREATE) 
    103                         pair->local_fd = open(pair->local_filename, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR); 
    104                 else 
    105                         pair->local_fd = open(pair->local_filename, O_RDWR | O_EXCL); 
    106                 if(pair->local_fd == -1) { 
    107                         osync_trace( TRACE_INTERNAL, "failed to open local file %s", pair->local_filename ); 
    108                 } 
    109         } 
    110         else { 
    111                 char *template = g_strdup("/tmp/opie-sync.XXXXXX"); 
    112                 pair->local_fd = mkstemp(template); 
    113                 if(pair->local_fd == -1) { 
    114                         osync_trace( TRACE_INTERNAL, "failed to create temporary file" ); 
    115                         g_free(template); 
    116                         return NULL; 
    117                 } 
    118                 pair->local_filename = template; 
    119                 if(tmpfilemode != TT_VISIBLE) { 
    120                         if(unlink(template) == -1) { 
    121                                 osync_trace( TRACE_INTERNAL, "failed to unlink temporary file" ); 
    122                         } 
    123                 } 
    124         } 
    125          
    126         osync_trace(TRACE_EXIT, "%s(%p)", __func__, pair); 
    127         return pair; 
    128 
    129  
    130  
    131 /* 
    132  * Clean up and free a RemoteData temp file as built by create_temp_file  
    133  */ 
    134 void cleanup_temp_file(RemoteData *data, int tmpfilemode) { 
    135         osync_trace(TRACE_ENTRY, "%s(%p, %i)", __func__, data, tmpfilemode); 
    136          
    137         if(tmpfilemode == TT_VISIBLE) { 
    138                 if(unlink(data->local_filename) == -1) { 
    139                         osync_trace( TRACE_INTERNAL, "failed to unlink temporary file" ); 
    140                 } 
    141         } 
    142         if(data->local_fd > 0) 
    143                 close(data->local_fd); 
    144          
    145         g_free(data->local_filename); 
    146         g_free(data); 
    147  
    148         osync_trace(TRACE_EXIT, "%s", __func__); 
    149 
    150  
    151  
    152 /* 
    153  * backup data from an fd to a file 
    154  */ 
    155 int backup_file(const char *backupfile, int fd) { 
    156         osync_trace(TRACE_ENTRY, "%s(%s, %i)", __func__, backupfile, fd); 
     78 * create a backup file from a string 
     79 */ 
     80int backup_file(const char *backupfile, const char *str, int len) { 
     81        osync_trace(TRACE_ENTRY, "%s(%s, %p, %i)", __func__, backupfile, str, len); 
    15782         
    15883        int destfd = 0; 
    15984        int rc = FALSE; 
    16085        int bufsize = 1024; 
    161         int rbytes, wbytes; 
    162         char *buf = NULL
     86        int wbytes; 
     87        int pos = 0
    16388         
    16489        destfd = open(backupfile, O_CREAT | O_WRONLY | O_EXCL, 0600); 
     
    16994        } 
    17095         
    171         /* Rewind to start */ 
    172         lseek(fd, 0, SEEK_SET); 
    173          
    174         buf = g_malloc0(bufsize); 
    17596        while(TRUE) { 
    176                 rbytes = read(fd, buf, bufsize); 
    177                 if(rbytes == -1) { 
    178                         osync_trace( TRACE_INTERNAL, "error reading during backup" ); 
    179                         perror("error reading during backup"); 
     97                if(len - pos < bufsize) 
     98                        bufsize = len - pos; 
     99                 
     100                wbytes = write(destfd, str + pos, bufsize); 
     101                if(wbytes == -1) { 
     102                        osync_trace( TRACE_INTERNAL, "error writing to backup file" ); 
     103                        perror("error writing to backup file"); 
    180104                        close(destfd); 
    181105                        goto error; 
    182106                } 
    183                 else if(rbytes > 0) { 
    184                         wbytes = write(destfd, buf, rbytes); 
    185                         if(wbytes == -1) { 
    186                                 osync_trace( TRACE_INTERNAL, "error writing to backup file" ); 
    187                                 perror("error writing to backup file"); 
    188                                 close(destfd); 
    189                                 goto error; 
    190                         } 
    191                 } 
    192                 else  { 
     107                 
     108                pos += bufsize; 
     109                if(pos == len)  { 
    193110                        /* finished */ 
    194111                        close(destfd); 
     
    197114        } 
    198115         
    199         /* Rewind to start */ 
    200         lseek(fd, 0, SEEK_SET); 
    201          
    202116        rc = TRUE; 
    203117 
    204118error: 
    205         g_free(buf); 
    206119         
    207120        osync_trace(TRACE_EXIT, "%s(%i)", __func__, rc); 
     
    261174         
    262175        gboolean rc = TRUE; 
    263         int tmpfilemode; 
    264          
    265         if(env->conn_type == OPIE_CONN_NONE) { 
    266                 tmpfilemode = TT_DEBUG; 
    267         } 
    268         else if (env->conn_type == OPIE_CONN_SCP) { 
    269                 tmpfilemode = TT_VISIBLE; 
    270         } 
    271         else { 
    272                 tmpfilemode = TT_STANDARD; 
    273         } 
    274          
    275         RemoteData *data = NULL; 
    276         if(objtype != OPIE_OBJECT_TYPE_NOTE) 
    277                 data = create_temp_file(remotefile, tmpfilemode); 
     176         
     177        GString *data = NULL; 
    278178         
    279179        /* check which connection method was requested */ 
     
    297197                        } 
    298198                        else 
    299                                 rc = ftp_fetch_file(env, data); 
     199                                rc = ftp_fetch_file(env, remotefile, &data); 
    300200                        break; 
    301201                         
     
    308208                                rc = FALSE; 
    309209                        } 
    310                         else 
    311                                 rc = scp_fetch_file(env, data); 
     210                        else { 
     211//                              rc = scp_fetch_file(env, data); 
     212                                osync_trace( TRACE_INTERNAL, "SCP currently not supported." ); 
     213                                rc = FALSE; 
     214                        } 
    312215                        break; 
    313216                         
     
    320223        if(rc && (objtype != OPIE_OBJECT_TYPE_NOTE)) 
    321224        { 
    322                 if(env->backupdir)  
     225                if(env->backupdir && data)  
    323226                { 
    324227                        if(env->backuppath == NULL) 
     
    327230                        if(env->backuppath) { 
    328231                                /* Build full path to file */ 
    329                                 char *basename = g_path_get_basename(data->remote_filename); 
     232                                char *basename = g_path_get_basename(remotefile); 
    330233                                char *backupfile = g_build_filename(env->backuppath, basename, NULL); 
    331234                                /* Run the backup */ 
    332                                 rc = backup_file(backupfile, data->local_fd); 
     235                                rc = backup_file(backupfile, data->str, data->len); 
    333236                                g_free(backupfile); 
    334237                                g_free(basename); 
     
    338241                if(rc) 
    339242                { 
    340                         if(data->local_fd <= 0) { 
     243                        if(!data) { 
    341244                                /* File didn't exist on the handheld (ie, clean device) */ 
    342245                                if(sink) 
     
    347250                        } 
    348251                        else { 
    349                                 *doc = opie_xml_fd_open(data->local_fd); 
     252                                *doc = opie_xml_string_read(data->str, data->len); 
    350253                                /* Flag document as unchanged */ 
    351254                                (*doc)->_private = (void *)1; 
    352                                 close(data->local_fd); 
    353                                 data->local_fd = -1; 
    354255                        } 
    355256                } 
     
    357258         
    358259        if(data) 
    359                 cleanup_temp_file(data, tmpfilemode); 
     260                g_string_free(data, TRUE); 
    360261         
    361262        osync_trace(TRACE_EXIT, "%s(%i)", __func__, rc ); 
     
    367268 * ftp_fetch_file 
    368269 */ 
    369 gboolean ftp_fetch_file(OpiePluginEnv* env, RemoteData *data) 
     270gboolean ftp_fetch_file(OpiePluginEnv* env, const char *remotefile, GString **data) 
    370271{ 
    371272        osync_trace(TRACE_ENTRY, "%s(%p, %p)", __func__, env, data); 
     
    375276        CURL *curl = NULL; 
    376277        CURLcode res; 
    377         FILE* fd; 
    378278 
    379279        if (env->url && env->username && env->password ) 
     
    402302                                          env->device_port, 
    403303                                          separator_path, 
    404                                           data->remote_filename); 
    405                  
    406                 fd = fdopen(data->local_fd, "w+");  
    407                 if(!fd) 
    408                 { 
    409                         osync_trace(TRACE_EXIT_ERROR, "failed to open temporary file"); 
    410                         g_free(ftpurl); 
    411                         return FALSE; 
    412                 } 
     304                                          remotefile); 
    413305 
    414306                /* curl init */ 
    415307                curl = curl_easy_init(); 
    416308                 
     309                *data = g_string_new(""); 
    417310                curl_easy_setopt(curl, CURLOPT_URL, ftpurl); 
    418                 curl_easy_setopt(curl, CURLOPT_WRITEDATA, fd); 
    419                 curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, opie_curl_fwrite); 
     311                curl_easy_setopt(curl, CURLOPT_WRITEDATA, *data); 
     312                curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, opie_curl_strwrite); 
    420313                 
    421314#ifdef _OPIE_PRINT_DEBUG 
     
    433326                                server returns "access denied" on non-existent directory. */ 
    434327                        osync_trace( TRACE_INTERNAL, "FTP file doesn't exist, ignoring" ); 
    435                         /* Close the fd and set it to -1 to indicate the file wasn't there */ 
    436                         data->local_fd = -1; 
     328                        /* Free and null the string to indicate the file wasn't there */ 
     329                        g_string_free(*data, TRUE); 
     330                        *data = NULL; 
    437331                } 
    438332                else if(res != CURLE_OK)  
     
    446340                { 
    447341                        osync_trace( TRACE_INTERNAL, "FTP ok" ); 
    448                 } 
    449  
    450                 fflush(fd); 
    451                 if(data->local_fd > 0) { 
    452                         free(fd);   /* don't fclose, we still need it */ 
    453                         lseek(data->local_fd, 0, SEEK_SET); 
    454                 } 
    455                 else { 
    456                         fclose(fd); 
    457342                } 
    458343 
     
    712597         
    713598        gboolean rc = TRUE; 
    714         int tmpfilemode; 
    715599 
    716600        if(doc && doc->_private == 0) { 
    717                 if(env->conn_type == OPIE_CONN_NONE) { 
    718                         tmpfilemode = TT_DEBUG_CREATE; 
    719                 } 
    720                 else if (env->conn_type == OPIE_CONN_SCP) { 
    721                         tmpfilemode = TT_VISIBLE; 
    722                 } 
    723                 else { 
    724                         tmpfilemode = TT_STANDARD; 
    725                 } 
    726          
    727                 RemoteData *data = NULL; 
     601                char *data = NULL; 
    728602                if(objtype != OPIE_OBJECT_TYPE_NOTE) { 
    729                         data = create_temp_file(remotefile, tmpfilemode); 
    730                         if(opie_xml_save_to_fd(doc, data->local_fd) == -1) { 
    731                                 osync_trace(TRACE_EXIT_ERROR, "failed to write data to temporary file"); /* FIXME actually say what data we failed to write */ 
     603                        data = osxml_write_to_string(doc); 
     604                        if(!data) 
    732605                                goto error; 
    733                         } 
    734                         fsync(data->local_fd); 
    735                         lseek(data->local_fd, 0, SEEK_SET); 
    736606                } 
    737607 
     
    751621                                } 
    752622                                else { 
    753                                         rc = ftp_put_file(env, data); 
     623                                        rc = ftp_put_file(env, remotefile, data); 
    754624                                } 
    755625                                break; 
     
    763633                                        rc = FALSE; 
    764634                                } 
    765                                 else 
    766                                         rc = scp_put_file(env, data); 
     635                                else { 
     636//                                      rc = scp_put_file(env, data); 
     637                                        osync_trace( TRACE_INTERNAL, "SCP currently not supported." ); 
     638                                        rc = FALSE; 
     639                                } 
    767640                                break; 
    768641                                 
     
    781654                        if(env->backuppath) { 
    782655                                /* Build full path to file */ 
    783                                 char *basename = g_path_get_basename(data->remote_filename); 
     656                                char *basename = g_path_get_basename(remotefile); 
    784657                                char *backupfile = g_build_filename(env->backuppath, "upload_failures", basename, NULL); 
    785658                                /* Run the backup */ 
    786659                                fprintf(stderr, "Error during upload to device, writing file to %s", backupfile);  
    787660                                osync_trace( TRACE_INTERNAL, "Error during upload to device, writing file to %s", backupfile ); 
    788                                rc = backup_file(backupfile, data->local_fd); 
     661//X                            rc = backup_file(backupfile, data->str, data->len); 
    789662                                g_free(backupfile); 
    790663                                g_free(basename); 
     
    793666                 
    794667                if(data) 
    795                         cleanup_temp_file(data, tmpfilemode); 
     668                        free(data); 
    796669        } 
    797670        else { 
     
    810683 * ftp_put_file 
    811684 */ 
    812 gboolean ftp_put_file(OpiePluginEnv* env, RemoteData *data)  
     685gboolean ftp_put_file(OpiePluginEnv* env, const char *remotefile, char *data)  
    813686{ 
    814687        osync_trace(TRACE_ENTRY, "%s(%p, %p)", __func__, env, data); 
    815688         
    816689        gboolean rc = TRUE; 
    817         struct stat file_info; 
    818690        CURL *curl; 
    819691        CURLcode res; 
    820         FILE *hd_src; 
    821692        char* separator_path; 
    822693         
     
    844715                                          env->device_port, 
    845716                                          separator_path, 
    846                                           data->remote_filename); 
    847  
    848                 /* get the file size of the local file */ 
    849                 fstat(data->local_fd, &file_info); 
    850          
    851                 hd_src = fdopen(data->local_fd, "rb+"); 
     717                                          remotefile); 
     718 
    852719                curl = curl_easy_init(); 
    853720                 
    854                 if(hd_src) 
    855                 { 
    856                        curl_easy_setopt(curl, CURLOPT_UPLOAD, TRUE)
    857                        curl_easy_setopt(curl, CURLOPT_URL, ftpurl); 
    858                        curl_easy_setopt(curl, CURLOPT_INFILE, hd_src); 
    859                        curl_easy_setopt(curl, CURLOPT_INFILESIZE, file_info.st_size); 
    860                        curl_easy_setopt(curl, CURLOPT_FTP_CREATE_MISSING_DIRS, 1); 
    861                         
     721                curl_easy_setopt(curl, CURLOPT_UPLOAD, TRUE) ; 
     722                curl_easy_setopt(curl, CURLOPT_URL, ftpurl); 
     723                curl_easy_setopt(curl, CURLOPT_READDATA, data)
     724                curl_easy_setopt(curl, CURLOPT_READFUNCTION, opie_curl_strread); 
     725                 
     726                 
     727                curl_easy_setopt(curl, CURLOPT_FTP_CREATE_MISSING_DIRS, 1); 
     728                 
    862729#ifdef _OPIE_PRINT_DEBUG 
    863                        curl_easy_setopt(curl, CURLOPT_VERBOSE, TRUE); 
     730                curl_easy_setopt(curl, CURLOPT_VERBOSE, TRUE); 
    864731#endif 
    865732                                 
    866                         res = curl_easy_perform(curl); 
    867                          
    868                         if(res != CURLE_OK)  
    869                         { 
    870                                 fprintf(stderr, "FTP upload failed (error %d)\n", res); 
    871                                 osync_trace( TRACE_INTERNAL, "FTP upload failed (error %d)", res ); 
    872                                 rc = FALSE; 
    873                         }  
    874                         else 
    875                         { 
    876                                 osync_trace( TRACE_INTERNAL, "FTP upload ok" ); 
    877                                 rc = TRUE; 
    878                         } 
    879                          
    880                         /* cleanup */ 
    881                         free(hd_src);   /* don't fclose, we still need it */ 
    882                         curl_easy_cleanup(curl); 
    883                 } 
     733                res = curl_easy_perform(curl); 
     734                 
     735                if(res != CURLE_OK)  
     736                { 
     737                        fprintf(stderr, "FTP upload failed (error %d)\n", res); 
     738                        osync_trace( TRACE_INTERNAL, "FTP upload failed (error %d)", res ); 
     739                        rc = FALSE; 
     740                }  
    884741                else 
    885                 {  
    886                         /* fopen of local file failed */ 
    887                         rc = FALSE; 
    888                 } 
     742                { 
     743                        osync_trace( TRACE_INTERNAL, "FTP upload ok" ); 
     744                        rc = TRUE; 
     745                } 
     746                 
     747                /* cleanup */ 
     748                curl_easy_cleanup(curl); 
    889749                 
    890750                g_free(ftpurl); 
     
    906766 * scp_fetch_file 
    907767 */ 
    908 gboolean scp_fetch_file(OpiePluginEnv* env, RemoteData *data) 
     768gboolean scp_fetch_file(OpiePluginEnv* env, const char *remotefile, GString **data) 
    909769{ 
    910770        osync_trace(TRACE_ENTRY, "%s(%p, %p)", __func__, env, data); 
     
    920780                /* We have to close the temp file, because we want  
    921781                                sftp to be able to write to it */ 
    922               close(data->local_fd); 
     782//            close(data->local_fd); 
    923783                 
    924784                /* not keeping it quiet for the moment */ 
     785                char *localfile = NULL; 
     786                 
    925787                scpcommand = g_strdup_printf("sftp -o Port=%d -o BatchMode=yes %s@%s:%s %s", 
    926788                                            env->device_port, 
    927789                                            env->username, 
    928790                                            env->url, 
    929                                             data->remote_filename, 
    930                                             data->local_filename); 
     791                                            remotefile, 
     792                                            localfile); 
    931793                 
    932794                scpretval = pclose(popen(scpcommand,"w")); 
     
    944806                g_free(scpcommand); 
    945807                /* reopen the temp file */  
    946               data->local_fd = open(data->local_filename, O_RDWR | O_EXCL); 
     808//            data->local_fd = open(data->local_filename, O_RDWR | O_EXCL); 
    947809        } 
    948810         
     
    955817 * scp_put_file 
    956818 */ 
    957 gboolean scp_put_file(OpiePluginEnv* env, RemoteData *data) 
     819gboolean scp_put_file(OpiePluginEnv* env, const char *remotefile, char *data) 
    958820{ 
    959821        osync_trace(TRACE_ENTRY, "%s(%p, %p)", __func__, env, data); 
     
    981843                /* ok - print the commands to the file */ 
    982844                GString *batchbuf = g_string_new(""); 
    983                 g_string_append_printf(batchbuf, "put %s %s\n", data->local_filename, data->remote_filename); 
     845                 
     846                char *localfile = NULL; // FIXME 
     847                 
     848                g_string_append_printf(batchbuf, "put %s %s\n", localfile, remotefile); 
    984849                g_string_append_printf(batchbuf, "bye\n"); 
    985850                 
  • plugins/opie-sync/src/opie_xml.c

    r2449 r2461  
    4545 
    4646 
    47 xmlDoc *opie_xml_fd_open(int fd) { 
    48         xmlDoc *doc = xmlReadFd(fd, "/", NULL, 0); 
     47xmlDoc *opie_xml_string_read(const char *str, int len) { 
     48        xmlDoc *doc = xmlReadMemory(str, len, "/", NULL, 0); 
    4949        if (!doc) { 
    5050                osync_trace(TRACE_INTERNAL, "Unable to parse XML data"); 
  • plugins/opie-sync/src/opie_xml.h

    r2448 r2461  
    2929#include "opie_sync.h" 
    3030 
    31 xmlDoc *opie_xml_fd_open(int fd); 
     31xmlDoc *opie_xml_string_read(const char *str, int len); 
    3232xmlDoc *opie_xml_file_open(const gchar *xml_file); 
    3333xmlNode *opie_xml_get_collection(xmlDoc *doc, const char *listelement);