| | 85 | } |
|---|
| | 86 | |
|---|
| | 87 | |
|---|
| | 88 | TempFile *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 | |
|---|
| | 106 | void 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); |
|---|
| 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); |
|---|
| 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 | |
|---|
| | 924 | error: |
|---|
| | 925 | |
|---|
| | 926 | if(tmpfile) |
|---|
| | 927 | cleanup_temp_file(tmpfile); |
|---|
| | 928 | if(scpcommand); |
|---|
| 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 */ |
|---|
| 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)) { |
|---|
| 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 | |
|---|
| | 1021 | error: |
|---|
| | 1022 | |
|---|
| | 1023 | if(tmpfile) |
|---|
| | 1024 | cleanup_temp_file(tmpfile); |
|---|