Changeset 2461
- Timestamp:
- 08/17/07 15:46:49 (1 year ago)
- Files:
-
- plugins/opie-sync/src/opie_comms.c (modified) (30 diffs)
- plugins/opie-sync/src/opie_xml.c (modified) (1 diff)
- plugins/opie-sync/src/opie_xml.h (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
plugins/opie-sync/src/opie_comms.c
r2446 r2461 38 38 #include <opensync/opensync.h> 39 39 #include <opensync/opensync-plugin.h> 40 #include <opensync/opensync_xml.h> 40 41 41 42 #include "opie_comms.h" 42 43 #include "opie_xml.h" 43 44 #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 = 456 };57 45 58 46 int opie_curl_fwrite(void* buffer, size_t size, size_t nmemb, void* stream); … … 60 48 int opie_curl_nullwrite(void *buffer, size_t size, size_t nmemb, void *stream); 61 49 int 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);50 gboolean ftp_fetch_file(OpiePluginEnv* env, const char *remotefile, GString **data); 51 gboolean scp_fetch_file(OpiePluginEnv* env, const char *remotefile, GString **data); 52 gboolean ftp_put_file(OpiePluginEnv* env, const char *remotefile, char *data); 53 gboolean scp_put_file(OpiePluginEnv* env, const char *remotefile, char *data); 66 54 gboolean ftp_fetch_notes(OpiePluginEnv* env, xmlDoc *doc); 67 55 … … 88 76 89 77 /* 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 */ 80 int backup_file(const char *backupfile, const char *str, int len) { 81 osync_trace(TRACE_ENTRY, "%s(%s, %p, %i)", __func__, backupfile, str, len); 157 82 158 83 int destfd = 0; 159 84 int rc = FALSE; 160 85 int bufsize = 1024; 161 int rbytes,wbytes;162 char *buf = NULL;86 int wbytes; 87 int pos = 0; 163 88 164 89 destfd = open(backupfile, O_CREAT | O_WRONLY | O_EXCL, 0600); … … 169 94 } 170 95 171 /* Rewind to start */172 lseek(fd, 0, SEEK_SET);173 174 buf = g_malloc0(bufsize);175 96 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"); 180 104 close(destfd); 181 105 goto error; 182 106 } 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) { 193 110 /* finished */ 194 111 close(destfd); … … 197 114 } 198 115 199 /* Rewind to start */200 lseek(fd, 0, SEEK_SET);201 202 116 rc = TRUE; 203 117 204 118 error: 205 g_free(buf);206 119 207 120 osync_trace(TRACE_EXIT, "%s(%i)", __func__, rc); … … 261 174 262 175 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; 278 178 279 179 /* check which connection method was requested */ … … 297 197 } 298 198 else 299 rc = ftp_fetch_file(env, data);199 rc = ftp_fetch_file(env, remotefile, &data); 300 200 break; 301 201 … … 308 208 rc = FALSE; 309 209 } 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 } 312 215 break; 313 216 … … 320 223 if(rc && (objtype != OPIE_OBJECT_TYPE_NOTE)) 321 224 { 322 if(env->backupdir )225 if(env->backupdir && data) 323 226 { 324 227 if(env->backuppath == NULL) … … 327 230 if(env->backuppath) { 328 231 /* Build full path to file */ 329 char *basename = g_path_get_basename( data->remote_filename);232 char *basename = g_path_get_basename(remotefile); 330 233 char *backupfile = g_build_filename(env->backuppath, basename, NULL); 331 234 /* Run the backup */ 332 rc = backup_file(backupfile, data-> local_fd);235 rc = backup_file(backupfile, data->str, data->len); 333 236 g_free(backupfile); 334 237 g_free(basename); … … 338 241 if(rc) 339 242 { 340 if( data->local_fd <= 0) {243 if(!data) { 341 244 /* File didn't exist on the handheld (ie, clean device) */ 342 245 if(sink) … … 347 250 } 348 251 else { 349 *doc = opie_xml_ fd_open(data->local_fd);252 *doc = opie_xml_string_read(data->str, data->len); 350 253 /* Flag document as unchanged */ 351 254 (*doc)->_private = (void *)1; 352 close(data->local_fd);353 data->local_fd = -1;354 255 } 355 256 } … … 357 258 358 259 if(data) 359 cleanup_temp_file(data, tmpfilemode);260 g_string_free(data, TRUE); 360 261 361 262 osync_trace(TRACE_EXIT, "%s(%i)", __func__, rc ); … … 367 268 * ftp_fetch_file 368 269 */ 369 gboolean ftp_fetch_file(OpiePluginEnv* env, RemoteData*data)270 gboolean ftp_fetch_file(OpiePluginEnv* env, const char *remotefile, GString **data) 370 271 { 371 272 osync_trace(TRACE_ENTRY, "%s(%p, %p)", __func__, env, data); … … 375 276 CURL *curl = NULL; 376 277 CURLcode res; 377 FILE* fd;378 278 379 279 if (env->url && env->username && env->password ) … … 402 302 env->device_port, 403 303 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); 413 305 414 306 /* curl init */ 415 307 curl = curl_easy_init(); 416 308 309 *data = g_string_new(""); 417 310 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); 420 313 421 314 #ifdef _OPIE_PRINT_DEBUG … … 433 326 server returns "access denied" on non-existent directory. */ 434 327 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; 437 331 } 438 332 else if(res != CURLE_OK) … … 446 340 { 447 341 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);457 342 } 458 343 … … 712 597 713 598 gboolean rc = TRUE; 714 int tmpfilemode;715 599 716 600 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; 728 602 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) 732 605 goto error; 733 }734 fsync(data->local_fd);735 lseek(data->local_fd, 0, SEEK_SET);736 606 } 737 607 … … 751 621 } 752 622 else { 753 rc = ftp_put_file(env, data);623 rc = ftp_put_file(env, remotefile, data); 754 624 } 755 625 break; … … 763 633 rc = FALSE; 764 634 } 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 } 767 640 break; 768 641 … … 781 654 if(env->backuppath) { 782 655 /* Build full path to file */ 783 char *basename = g_path_get_basename( data->remote_filename);656 char *basename = g_path_get_basename(remotefile); 784 657 char *backupfile = g_build_filename(env->backuppath, "upload_failures", basename, NULL); 785 658 /* Run the backup */ 786 659 fprintf(stderr, "Error during upload to device, writing file to %s", backupfile); 787 660 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); 789 662 g_free(backupfile); 790 663 g_free(basename); … … 793 666 794 667 if(data) 795 cleanup_temp_file(data, tmpfilemode);668 free(data); 796 669 } 797 670 else { … … 810 683 * ftp_put_file 811 684 */ 812 gboolean ftp_put_file(OpiePluginEnv* env, RemoteData*data)685 gboolean ftp_put_file(OpiePluginEnv* env, const char *remotefile, char *data) 813 686 { 814 687 osync_trace(TRACE_ENTRY, "%s(%p, %p)", __func__, env, data); 815 688 816 689 gboolean rc = TRUE; 817 struct stat file_info;818 690 CURL *curl; 819 691 CURLcode res; 820 FILE *hd_src;821 692 char* separator_path; 822 693 … … 844 715 env->device_port, 845 716 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 852 719 curl = curl_easy_init(); 853 720 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 862 729 #ifdef _OPIE_PRINT_DEBUG 863 curl_easy_setopt(curl, CURLOPT_VERBOSE, TRUE);730 curl_easy_setopt(curl, CURLOPT_VERBOSE, TRUE); 864 731 #endif 865 732 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 } 884 741 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); 889 749 890 750 g_free(ftpurl); … … 906 766 * scp_fetch_file 907 767 */ 908 gboolean scp_fetch_file(OpiePluginEnv* env, RemoteData*data)768 gboolean scp_fetch_file(OpiePluginEnv* env, const char *remotefile, GString **data) 909 769 { 910 770 osync_trace(TRACE_ENTRY, "%s(%p, %p)", __func__, env, data); … … 920 780 /* We have to close the temp file, because we want 921 781 sftp to be able to write to it */ 922 close(data->local_fd);782 // close(data->local_fd); 923 783 924 784 /* not keeping it quiet for the moment */ 785 char *localfile = NULL; 786 925 787 scpcommand = g_strdup_printf("sftp -o Port=%d -o BatchMode=yes %s@%s:%s %s", 926 788 env->device_port, 927 789 env->username, 928 790 env->url, 929 data->remote_filename,930 data->local_filename);791 remotefile, 792 localfile); 931 793 932 794 scpretval = pclose(popen(scpcommand,"w")); … … 944 806 g_free(scpcommand); 945 807 /* 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); 947 809 } 948 810 … … 955 817 * scp_put_file 956 818 */ 957 gboolean scp_put_file(OpiePluginEnv* env, RemoteData*data)819 gboolean scp_put_file(OpiePluginEnv* env, const char *remotefile, char *data) 958 820 { 959 821 osync_trace(TRACE_ENTRY, "%s(%p, %p)", __func__, env, data); … … 981 843 /* ok - print the commands to the file */ 982 844 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); 984 849 g_string_append_printf(batchbuf, "bye\n"); 985 850 plugins/opie-sync/src/opie_xml.c
r2449 r2461 45 45 46 46 47 xmlDoc *opie_xml_ fd_open(int fd) {48 xmlDoc *doc = xmlRead Fd(fd, "/", NULL, 0);47 xmlDoc *opie_xml_string_read(const char *str, int len) { 48 xmlDoc *doc = xmlReadMemory(str, len, "/", NULL, 0); 49 49 if (!doc) { 50 50 osync_trace(TRACE_INTERNAL, "Unable to parse XML data"); plugins/opie-sync/src/opie_xml.h
r2448 r2461 29 29 #include "opie_sync.h" 30 30 31 xmlDoc *opie_xml_ fd_open(int fd);31 xmlDoc *opie_xml_string_read(const char *str, int len); 32 32 xmlDoc *opie_xml_file_open(const gchar *xml_file); 33 33 xmlNode *opie_xml_get_collection(xmlDoc *doc, const char *listelement);
