summaryrefslogtreecommitdiffabout
path: root/src/eyefiservice.cc
authorMichael Krelin <hacker@klever.net>2009-04-04 23:51:03 (UTC)
committer Michael Krelin <hacker@klever.net>2009-04-05 00:41:00 (UTC)
commit01eedb36de69f92fc896c525047df78b34f87324 (patch) (unidiff)
tree05320addd7a51652d3f3ff34cfe17e81cf1b8889 /src/eyefiservice.cc
parent6b71fd1e4edd46b7caf47135740c961d5d4f051c (diff)
downloadiii-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>
Diffstat (limited to 'src/eyefiservice.cc') (more/less context) (ignore whitespace changes)
-rw-r--r--src/eyefiservice.cc4
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
13static bool detached_child() { 13static 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
39int eyefiService::StartSession( 39int 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
71int eyefiService::GetPhotoStatus( 71int 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
84int eyefiService::MarkLastPhotoInRoll( 84int 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
106int eyefiService::UploadPhoto( 106int 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}