author | Michael Krelin <hacker@klever.net> | 2009-04-04 23:51:03 (UTC) |
---|---|---|
committer | Michael Krelin <hacker@klever.net> | 2009-04-05 00:41:00 (UTC) |
commit | 01eedb36de69f92fc896c525047df78b34f87324 (patch) (unidiff) | |
tree | 05320addd7a51652d3f3ff34cfe17e81cf1b8889 /src/eyefiservice.cc | |
parent | 6b71fd1e4edd46b7caf47135740c961d5d4f051c (diff) | |
download | iii-01eedb36de69f92fc896c525047df78b34f87324.zip iii-01eedb36de69f92fc896c525047df78b34f87324.tar.gz iii-01eedb36de69f92fc896c525047df78b34f87324.tar.bz2 |
send back original transfer mode and timestamp
in an attempt to make it send more than one photo per session,
but it doesn't seem to help. Well, it doesn't hurt either.
Signed-off-by: Michael Krelin <hacker@klever.net>
-rw-r--r-- | src/eyefiservice.cc | 4 |
1 files changed, 2 insertions, 2 deletions
diff --git a/src/eyefiservice.cc b/src/eyefiservice.cc index 97cb33b..153a7c4 100644 --- a/src/eyefiservice.cc +++ b/src/eyefiservice.cc | |||
@@ -1,185 +1,185 @@ | |||
1 | #include <cassert> | 1 | #include <cassert> |
2 | #include <iostream> | 2 | #include <iostream> |
3 | #include <fstream> | 3 | #include <fstream> |
4 | #include <stdexcept> | 4 | #include <stdexcept> |
5 | #include <iterator> | 5 | #include <iterator> |
6 | #include <syslog.h> | 6 | #include <syslog.h> |
7 | #include <sys/wait.h> | 7 | #include <sys/wait.h> |
8 | #include <autosprintf.h> | 8 | #include <autosprintf.h> |
9 | #include "eyekinfig.h" | 9 | #include "eyekinfig.h" |
10 | #include "eyetil.h" | 10 | #include "eyetil.h" |
11 | #include "soapeyefiService.h" | 11 | #include "soapeyefiService.h" |
12 | 12 | ||
13 | static bool detached_child() { | 13 | static bool detached_child() { |
14 | pid_t p = fork(); | 14 | pid_t p = fork(); |
15 | if(p<0) throw std::runtime_error("failed to fork()"); | 15 | if(p<0) throw std::runtime_error("failed to fork()"); |
16 | if(!p) { | 16 | if(!p) { |
17 | p = fork(); | 17 | p = fork(); |
18 | if(p<0) { | 18 | if(p<0) { |
19 | syslog(LOG_ERR,"Failed to re-fork child process"); | 19 | syslog(LOG_ERR,"Failed to re-fork child process"); |
20 | _exit(-1); | 20 | _exit(-1); |
21 | } | 21 | } |
22 | if(!p) { | 22 | if(!p) { |
23 | setsid(); | 23 | setsid(); |
24 | for(int i=getdtablesize();i>=0;--i) close(i); | 24 | for(int i=getdtablesize();i>=0;--i) close(i); |
25 | int i=open("/dev/null",O_RDWR); assert(i==0); | 25 | int i=open("/dev/null",O_RDWR); assert(i==0); |
26 | i = dup(i); assert(i==1); | 26 | i = dup(i); assert(i==1); |
27 | i = dup(i); assert(i==2); | 27 | i = dup(i); assert(i==2); |
28 | return true; | 28 | return true; |
29 | } | 29 | } |
30 | _exit(0); | 30 | _exit(0); |
31 | } | 31 | } |
32 | int rc; | 32 | int rc; |
33 | if(waitpid(p,&rc,0)<0) throw std::runtime_error("failed to waitpid()"); | 33 | if(waitpid(p,&rc,0)<0) throw std::runtime_error("failed to waitpid()"); |
34 | if(!WIFEXITED(rc)) throw std::runtime_error("error in forked process"); | 34 | if(!WIFEXITED(rc)) throw std::runtime_error("error in forked process"); |
35 | if(WEXITSTATUS(rc)) throw std::runtime_error("forked process signalled error"); | 35 | if(WEXITSTATUS(rc)) throw std::runtime_error("forked process signalled error"); |
36 | return false; | 36 | return false; |
37 | } | 37 | } |
38 | 38 | ||
39 | int eyefiService::StartSession( | 39 | int eyefiService::StartSession( |
40 | std::string macaddress,std::string cnonce, | 40 | std::string macaddress,std::string cnonce, |
41 | int transfermode,long transfermodetimestamp, | 41 | int transfermode,long transfermodetimestamp, |
42 | struct rns__StartSessionResponse &r ) { | 42 | struct rns__StartSessionResponse &r ) { |
43 | #ifndef NDEBUG | 43 | #ifndef NDEBUG |
44 | syslog(LOG_DEBUG, | 44 | syslog(LOG_DEBUG, |
45 | "StartSession request from %s with cnonce=%s, transfermode=%d, transfermodetimestamp=%ld", | 45 | "StartSession request from %s with cnonce=%s, transfermode=%d, transfermodetimestamp=%ld", |
46 | macaddress.c_str(), cnonce.c_str(), transfermode, transfermodetimestamp ); | 46 | macaddress.c_str(), cnonce.c_str(), transfermode, transfermodetimestamp ); |
47 | #endif | 47 | #endif |
48 | r.credential = binary_t(macaddress+cnonce+eyekinfig_t(macaddress).get_upload_key()).md5().hex(); | 48 | r.credential = binary_t(macaddress+cnonce+eyekinfig_t(macaddress).get_upload_key()).md5().hex(); |
49 | /* TODO: better nonce generator */ | 49 | /* TODO: better nonce generator */ |
50 | time_t t = time(0); | 50 | time_t t = time(0); |
51 | r.snonce = binary_t(&t,sizeof(t)).md5().hex(); | 51 | r.snonce = binary_t(&t,sizeof(t)).md5().hex(); |
52 | r.transfermode=2; | 52 | r.transfermode=transfermode; |
53 | r.transfermodetimestamp=t; | 53 | r.transfermodetimestamp=transfermodetimestamp; |
54 | r.upsyncallowed=false; | 54 | r.upsyncallowed=false; |
55 | 55 | ||
56 | std::string cmd = eyekinfig_t(macaddress).get_on_start_session(); | 56 | std::string cmd = eyekinfig_t(macaddress).get_on_start_session(); |
57 | if(!cmd.empty()) { | 57 | if(!cmd.empty()) { |
58 | if(detached_child()) { | 58 | if(detached_child()) { |
59 | putenv( gnu::autosprintf("EYEFI_MACADDRESS=%s",macaddress.c_str()) ); | 59 | putenv( gnu::autosprintf("EYEFI_MACADDRESS=%s",macaddress.c_str()) ); |
60 | putenv( gnu::autosprintf("EYEFI_TRANSFERMODE=%d",transfermode) ); | 60 | putenv( gnu::autosprintf("EYEFI_TRANSFERMODE=%d",transfermode) ); |
61 | putenv( gnu::autosprintf("EYEFI_TRANSFERMODETIMESTAMP=%ld",transfermodetimestamp) ); | 61 | putenv( gnu::autosprintf("EYEFI_TRANSFERMODETIMESTAMP=%ld",transfermodetimestamp) ); |
62 | char *argv[] = { (char*)"/bin/sh", (char*)"-c", (char*)cmd.c_str(), 0 }; | 62 | char *argv[] = { (char*)"/bin/sh", (char*)"-c", (char*)cmd.c_str(), 0 }; |
63 | execv("/bin/sh",argv); | 63 | execv("/bin/sh",argv); |
64 | syslog(LOG_ERR,"Failed to execute '%s'",cmd.c_str()); | 64 | syslog(LOG_ERR,"Failed to execute '%s'",cmd.c_str()); |
65 | _exit(-1); | 65 | _exit(-1); |
66 | } | 66 | } |
67 | } | 67 | } |
68 | return SOAP_OK; | 68 | return SOAP_OK; |
69 | } | 69 | } |
70 | 70 | ||
71 | int eyefiService::GetPhotoStatus( | 71 | int eyefiService::GetPhotoStatus( |
72 | std::string credential, std::string macaddress, | 72 | std::string credential, std::string macaddress, |
73 | std::string filename, long filesize, std::string filesignature, | 73 | std::string filename, long filesize, std::string filesignature, |
74 | struct rns__GetPhotoStatusResponse &r ) { | 74 | struct rns__GetPhotoStatusResponse &r ) { |
75 | #ifndef NDEBUG | 75 | #ifndef NDEBUG |
76 | syslog(LOG_DEBUG, | 76 | syslog(LOG_DEBUG, |
77 | "GetPhotoStatus request from %s with credential=%s, filename=%s, filesize=%ld, filesignature=%s", | 77 | "GetPhotoStatus request from %s with credential=%s, filename=%s, filesize=%ld, filesignature=%s", |
78 | macaddress.c_str(), credential.c_str(), filename.c_str(), filesize, filesignature.c_str() ); | 78 | macaddress.c_str(), credential.c_str(), filename.c_str(), filesize, filesignature.c_str() ); |
79 | #endif | 79 | #endif |
80 | r.fileid = 1; r.offset = 0; | 80 | r.fileid = 1; r.offset = 0; |
81 | return SOAP_OK; | 81 | return SOAP_OK; |
82 | } | 82 | } |
83 | 83 | ||
84 | int eyefiService::MarkLastPhotoInRoll( | 84 | int eyefiService::MarkLastPhotoInRoll( |
85 | std::string macaddress, int mergedelta, | 85 | std::string macaddress, int mergedelta, |
86 | struct rns__MarkLastPhotoInRollResponse &r ) { | 86 | struct rns__MarkLastPhotoInRollResponse &r ) { |
87 | #ifndef NDEBUG | 87 | #ifndef NDEBUG |
88 | syslog(LOG_DEBUG, | 88 | syslog(LOG_DEBUG, |
89 | "MarkLastPhotoInRoll request from %s with mergedelta=%d", | 89 | "MarkLastPhotoInRoll request from %s with mergedelta=%d", |
90 | macaddress.c_str(), mergedelta ); | 90 | macaddress.c_str(), mergedelta ); |
91 | #endif | 91 | #endif |
92 | std::string cmd = eyekinfig_t(macaddress).get_on_mark_last_photo_in_roll(); | 92 | std::string cmd = eyekinfig_t(macaddress).get_on_mark_last_photo_in_roll(); |
93 | if(!cmd.empty()) { | 93 | if(!cmd.empty()) { |
94 | if(detached_child()) { | 94 | if(detached_child()) { |
95 | putenv( gnu::autosprintf("EYEFI_MACADDRESS=%s",macaddress.c_str()) ); | 95 | putenv( gnu::autosprintf("EYEFI_MACADDRESS=%s",macaddress.c_str()) ); |
96 | putenv( gnu::autosprintf("EYEFI_MERGEDELTA=%d",mergedelta) ); | 96 | putenv( gnu::autosprintf("EYEFI_MERGEDELTA=%d",mergedelta) ); |
97 | char *argv[] = { (char*)"/bin/sh", (char*)"-c", (char*)cmd.c_str(), 0 }; | 97 | char *argv[] = { (char*)"/bin/sh", (char*)"-c", (char*)cmd.c_str(), 0 }; |
98 | execv("/bin/sh",argv); | 98 | execv("/bin/sh",argv); |
99 | syslog(LOG_ERR,"Failed to execute '%s'",cmd.c_str()); | 99 | syslog(LOG_ERR,"Failed to execute '%s'",cmd.c_str()); |
100 | _exit(-1); | 100 | _exit(-1); |
101 | } | 101 | } |
102 | } | 102 | } |
103 | return SOAP_OK; | 103 | return SOAP_OK; |
104 | } | 104 | } |
105 | 105 | ||
106 | int eyefiService::UploadPhoto( | 106 | int eyefiService::UploadPhoto( |
107 | int fileid, std::string macaddress, | 107 | int fileid, std::string macaddress, |
108 | std::string filename, long filesize, std::string filesignature, | 108 | std::string filename, long filesize, std::string filesignature, |
109 | std::string encryption, int flags, | 109 | std::string encryption, int flags, |
110 | struct rns__UploadPhotoResponse& r ) { | 110 | struct rns__UploadPhotoResponse& r ) { |
111 | #ifndef NDEBUG | 111 | #ifndef NDEBUG |
112 | syslog(LOG_DEBUG, | 112 | syslog(LOG_DEBUG, |
113 | "UploadPhoto request from %s with fileid=%d, filename=%s, filesize=%ld," | 113 | "UploadPhoto request from %s with fileid=%d, filename=%s, filesize=%ld," |
114 | " filesignature=%s, encryption=%s, flags=%04X", | 114 | " filesignature=%s, encryption=%s, flags=%04X", |
115 | macaddress.c_str(), fileid, filename.c_str(), filesize, | 115 | macaddress.c_str(), fileid, filename.c_str(), filesize, |
116 | filesignature.c_str(), encryption.c_str(), flags ); | 116 | filesignature.c_str(), encryption.c_str(), flags ); |
117 | #endif | 117 | #endif |
118 | eyekinfig_t eyekinfig(macaddress); | 118 | eyekinfig_t eyekinfig(macaddress); |
119 | 119 | ||
120 | umask(eyekinfig.get_umask()); | 120 | umask(eyekinfig.get_umask()); |
121 | 121 | ||
122 | std::string td = eyekinfig.get_targetdir(); | 122 | std::string td = eyekinfig.get_targetdir(); |
123 | tmpdir_t indir(td+"/.incoming.XXXXXX"); | 123 | tmpdir_t indir(td+"/.incoming.XXXXXX"); |
124 | 124 | ||
125 | for(soap_multipart::iterator i=mime.begin(),ie=mime.end();i!=ie;++i) { | 125 | for(soap_multipart::iterator i=mime.begin(),ie=mime.end();i!=ie;++i) { |
126 | #ifndef NDEBUG | 126 | #ifndef NDEBUG |
127 | syslog(LOG_DEBUG, | 127 | syslog(LOG_DEBUG, |
128 | " MIME attachment with id=%s, type=%s, size=%ld", | 128 | " MIME attachment with id=%s, type=%s, size=%ld", |
129 | (*i).id, (*i).type, (long)(*i).size ); | 129 | (*i).id, (*i).type, (long)(*i).size ); |
130 | #endif | 130 | #endif |
131 | 131 | ||
132 | #ifndef NDEBUG | 132 | #ifndef NDEBUG |
133 | if((*i).id && !strcmp((*i).id,"INTEGRITYDIGEST")) { | 133 | if((*i).id && !strcmp((*i).id,"INTEGRITYDIGEST")) { |
134 | std::string idigest((*i).ptr,(*i).size); | 134 | std::string idigest((*i).ptr,(*i).size); |
135 | syslog(LOG_DEBUG, " INTEGRITYDIGEST=%s", idigest.c_str()); | 135 | syslog(LOG_DEBUG, " INTEGRITYDIGEST=%s", idigest.c_str()); |
136 | } | 136 | } |
137 | #endif | 137 | #endif |
138 | if( (*i).id && !strcmp((*i).id,"FILENAME") ) { | 138 | if( (*i).id && !strcmp((*i).id,"FILENAME") ) { |
139 | assert( (*i).type && !strcmp((*i).type,"application/x-tar") ); | 139 | assert( (*i).type && !strcmp((*i).type,"application/x-tar") ); |
140 | #ifdef III_SAVE_TARS | 140 | #ifdef III_SAVE_TARS |
141 | std::string tarfile = indir.get_file(filename); | 141 | std::string tarfile = indir.get_file(filename); |
142 | { | 142 | { |
143 | std::ofstream(tarfile.c_str(),std::ios::out|std::ios::binary).write((*i).ptr,(*i).size); | 143 | std::ofstream(tarfile.c_str(),std::ios::out|std::ios::binary).write((*i).ptr,(*i).size); |
144 | } | 144 | } |
145 | #endif | 145 | #endif |
146 | tarchive_t a((*i).ptr,(*i).size); | 146 | tarchive_t a((*i).ptr,(*i).size); |
147 | if(!a.read_next_header()) | 147 | if(!a.read_next_header()) |
148 | throw std::runtime_error("failed to tarchive_t::read_next_header())"); | 148 | throw std::runtime_error("failed to tarchive_t::read_next_header())"); |
149 | std::string jf = indir.get_file(a.entry_pathname()); | 149 | std::string jf = indir.get_file(a.entry_pathname()); |
150 | std::string::size_type ls = jf.rfind('/'); | 150 | std::string::size_type ls = jf.rfind('/'); |
151 | std::string jbn = (ls==std::string::npos)?jf:jf.substr(ls+1); | 151 | std::string jbn = (ls==std::string::npos)?jf:jf.substr(ls+1); |
152 | int fd=open(jf.c_str(),O_CREAT|O_WRONLY,0666); | 152 | int fd=open(jf.c_str(),O_CREAT|O_WRONLY,0666); |
153 | assert(fd>0); | 153 | assert(fd>0); |
154 | a.read_data_into_fd(fd); | 154 | a.read_data_into_fd(fd); |
155 | close(fd); | 155 | close(fd); |
156 | std::string tf = td+'/'+jbn; | 156 | std::string tf = td+'/'+jbn; |
157 | bool success = false; | 157 | bool success = false; |
158 | if(!link(jf.c_str(), tf.c_str())) { | 158 | if(!link(jf.c_str(), tf.c_str())) { |
159 | unlink(jf.c_str()); success = true; | 159 | unlink(jf.c_str()); success = true; |
160 | }else{ | 160 | }else{ |
161 | for(int i=1;i<32767;++i) { | 161 | for(int i=1;i<32767;++i) { |
162 | tf = (const char*)gnu::autosprintf( "%s/(%05d)%s", | 162 | tf = (const char*)gnu::autosprintf( "%s/(%05d)%s", |
163 | td.c_str(), i, jbn.c_str() ); | 163 | td.c_str(), i, jbn.c_str() ); |
164 | if(!link(jf.c_str(), tf.c_str())) { | 164 | if(!link(jf.c_str(), tf.c_str())) { |
165 | unlink(jf.c_str()); success = true; | 165 | unlink(jf.c_str()); success = true; |
166 | break; | 166 | break; |
167 | } | 167 | } |
168 | } | 168 | } |
169 | } | 169 | } |
170 | std::string cmd = eyekinfig.get_on_upload_photo(); | 170 | std::string cmd = eyekinfig.get_on_upload_photo(); |
171 | if(success && !cmd.empty()) { | 171 | if(success && !cmd.empty()) { |
172 | if(detached_child()) { | 172 | if(detached_child()) { |
173 | putenv( gnu::autosprintf("EYEFI_MACADDRESS=%s",macaddress.c_str()) ); | 173 | putenv( gnu::autosprintf("EYEFI_MACADDRESS=%s",macaddress.c_str()) ); |
174 | putenv( gnu::autosprintf("EYEFI_UPLOADED=%s",tf.c_str()) ); | 174 | putenv( gnu::autosprintf("EYEFI_UPLOADED=%s",tf.c_str()) ); |
175 | char *argv[] = { (char*)"/bin/sh", (char*)"-c", (char*)cmd.c_str(), 0 }; | 175 | char *argv[] = { (char*)"/bin/sh", (char*)"-c", (char*)cmd.c_str(), 0 }; |
176 | execv("/bin/sh",argv); | 176 | execv("/bin/sh",argv); |
177 | syslog(LOG_ERR,"Failed to execute '%s'",cmd.c_str()); | 177 | syslog(LOG_ERR,"Failed to execute '%s'",cmd.c_str()); |
178 | _exit(-1); | 178 | _exit(-1); |
179 | } | 179 | } |
180 | } | 180 | } |
181 | } | 181 | } |
182 | } | 182 | } |
183 | r.success = true; | 183 | r.success = true; |
184 | return SOAP_OK; | 184 | return SOAP_OK; |
185 | } | 185 | } |