Diffstat (limited to 'gammu/emb/gammu/smsd/s_files.c') (more/less context) (show whitespace changes)
-rw-r--r-- | gammu/emb/gammu/smsd/s_files.c | 313 |
1 files changed, 313 insertions, 0 deletions
diff --git a/gammu/emb/gammu/smsd/s_files.c b/gammu/emb/gammu/smsd/s_files.c new file mode 100644 index 0000000..dac8d9c --- a/dev/null +++ b/gammu/emb/gammu/smsd/s_files.c | |||
@@ -0,0 +1,313 @@ | |||
1 | /* (c) 2002-2003 by Joergen Thomsen */ | ||
2 | |||
3 | #include "../../cfg/config.h" | ||
4 | |||
5 | #include <string.h> | ||
6 | #include <stdio.h> | ||
7 | #include <errno.h> | ||
8 | #include <time.h> | ||
9 | #ifdef WIN32 | ||
10 | # include <io.h> | ||
11 | #endif | ||
12 | #if defined HAVE_DIRENT_H && defined HAVE_SCANDIR && defined HAVE_ALPHASORT | ||
13 | # include <dirent.h> | ||
14 | #endif | ||
15 | |||
16 | #include "../../common/misc/coding/coding.h" | ||
17 | #include "../../common/service/backup/gsmback.h" | ||
18 | #include "smsdcore.h" | ||
19 | |||
20 | /* Save SMS from phone (called Inbox sms - it's in phone Inbox) somewhere */ | ||
21 | static GSM_Error SMSDFiles_SaveInboxSMS(GSM_MultiSMSMessage sms, GSM_SMSDConfig *Config) | ||
22 | { | ||
23 | GSM_Errorerror = ERR_NONE; | ||
24 | int i,j; | ||
25 | unsigned char FileName[100], FullName[400], ext[4], buffer[64],buffer2[400]; | ||
26 | bool done; | ||
27 | FILE *file; | ||
28 | #ifdef GSM_ENABLE_BACKUP | ||
29 | GSM_SMS_Backup backup; | ||
30 | #endif | ||
31 | |||
32 | j = 0; | ||
33 | done = false; | ||
34 | for (i=0;i<sms.Number && !done;i++) { | ||
35 | strcpy(ext, "txt"); | ||
36 | if (sms.SMS[i].Coding == SMS_Coding_8bit) strcpy(ext, "bin"); | ||
37 | DecodeUnicode(sms.SMS[i].Number,buffer2); | ||
38 | /* we loop on yy for the first SMS assuming that if xxxx_yy_00.ext is absent, | ||
39 | any xxxx_yy_01,02, must be garbage, that can be overwritten */ | ||
40 | file = NULL; | ||
41 | do { | ||
42 | sprintf(FileName, | ||
43 | "IN%02d%02d%02d_%02d%02d%02d_%02i_%s_%02i.%s", | ||
44 | sms.SMS[i].DateTime.Year, sms.SMS[i].DateTime.Month, sms.SMS[i].DateTime.Day, | ||
45 | sms.SMS[i].DateTime.Hour, sms.SMS[i].DateTime.Minute, sms.SMS[i].DateTime.Second, | ||
46 | j, buffer2, i, ext); | ||
47 | strcpy(FullName, Config->inboxpath); | ||
48 | strcat(FullName, FileName); | ||
49 | if (file) fclose(file); | ||
50 | file = fopen(FullName, "r"); | ||
51 | } while ((i == 0) && (file && (++j < 100))); | ||
52 | if (file) { | ||
53 | fclose(file); | ||
54 | if (i == 0) { | ||
55 | WriteSMSDLog("Cannot save %s. No available file names", FileName); | ||
56 | return ERR_CANTOPENFILE; | ||
57 | } | ||
58 | } | ||
59 | errno = 0; | ||
60 | |||
61 | if ((sms.SMS[i].PDU == SMS_Status_Report) && mystrncasecmp(Config->deliveryreport, "log", 3)) { | ||
62 | strcpy(buffer, DecodeUnicodeString(sms.SMS[i].Number)); | ||
63 | WriteSMSDLog("Delivery report: %s to %s", DecodeUnicodeString(sms.SMS[i].Text), buffer); | ||
64 | } else { | ||
65 | #ifdef GSM_ENABLE_BACKUP | ||
66 | if (mystrncasecmp(Config->inboxformat, "detail", 0)) { | ||
67 | for (j=0;j<sms.Number;j++) backup.SMS[j] = &sms.SMS[j]; | ||
68 | backup.SMS[sms.Number] = NULL; | ||
69 | error = GSM_SaveSMSBackupFile(FullName, &backup); | ||
70 | done = true; | ||
71 | } | ||
72 | #endif | ||
73 | if (!mystrncasecmp(Config->inboxformat, "detail", 0)) { | ||
74 | file = fopen(FullName, "wb"); | ||
75 | if (file) { | ||
76 | switch (sms.SMS[i].Coding) { | ||
77 | case SMS_Coding_Unicode: | ||
78 | case SMS_Coding_Default: | ||
79 | |||
80 | DecodeUnicode(sms.SMS[i].Text,buffer2); | ||
81 | if (mystrncasecmp(Config->inboxformat, "unicode", 0)) { | ||
82 | buffer[0] = 0xFE; | ||
83 | buffer[1] = 0xFF; | ||
84 | fwrite(buffer,1,2,file); | ||
85 | fwrite(sms.SMS[i].Text,1,strlen(buffer2)*2,file); | ||
86 | } else { | ||
87 | fwrite(buffer2,1,strlen(buffer2),file); | ||
88 | } | ||
89 | break; | ||
90 | case SMS_Coding_8bit: | ||
91 | fwrite(sms.SMS[i].Text,1,sms.SMS[i].Length,file); | ||
92 | } | ||
93 | fclose(file); | ||
94 | } else error = ERR_CANTOPENFILE; | ||
95 | } | ||
96 | if (error == ERR_NONE) { | ||
97 | WriteSMSDLog("%s %s", (sms.SMS[i].PDU == SMS_Status_Report?"Delivery report":"Received"), FileName); | ||
98 | } else { | ||
99 | WriteSMSDLog("Cannot save %s (%i)", FileName, errno); | ||
100 | return ERR_CANTOPENFILE; | ||
101 | } | ||
102 | } | ||
103 | } | ||
104 | return ERR_NONE; | ||
105 | } | ||
106 | |||
107 | /* Find one multi SMS to sending and return it (or return ERR_EMPTY) | ||
108 | * There is also set ID for SMS | ||
109 | */ | ||
110 | static GSM_Error SMSDFiles_FindOutboxSMS(GSM_MultiSMSMessage *sms, GSM_SMSDConfig *Config, unsigned char *ID) | ||
111 | { | ||
112 | GSM_Error error = ERR_NOTSUPPORTED; | ||
113 | GSM_MultiPartSMSInfo SMSInfo; | ||
114 | unsigned char FileName[100],FullName[400]; | ||
115 | unsigned char Buffer[(GSM_MAX_SMS_LENGTH*MAX_MULTI_SMS+1)*2]; | ||
116 | unsigned char Buffer2[(GSM_MAX_SMS_LENGTH*MAX_MULTI_SMS+1)*2]; | ||
117 | FILE *File; | ||
118 | int i, len, phlen; | ||
119 | char *pos1, *pos2; | ||
120 | #if defined HAVE_DIRENT_H && defined HAVE_SCANDIR & defined HAVE_ALPHASORT | ||
121 | struct dirent **namelist = NULL; | ||
122 | int l, m ,n; | ||
123 | |||
124 | strcpy(FullName, Config->outboxpath); | ||
125 | FullName[strlen(Config->outboxpath)-1] = '\0'; | ||
126 | n = scandir(FullName, &namelist, 0, alphasort); | ||
127 | m = 0; | ||
128 | while ((m < n) && ((*(namelist[m]->d_name) == '.') || | ||
129 | !mystrncasecmp(namelist[m]->d_name,"out", 3) || | ||
130 | ((strlen(namelist[m]->d_name) >= 4) && | ||
131 | !mystrncasecmp(&namelist[m]->d_name[strlen(namelist[m]->d_name)-4],".txt",4) | ||
132 | ) | ||
133 | ) | ||
134 | ) m++; | ||
135 | if (m < n) strcpy(FileName,namelist[m]->d_name); | ||
136 | for (l=0; l < n; l++) free(namelist[l]); | ||
137 | free(namelist); | ||
138 | namelist = NULL; | ||
139 | if (m >= n) return ERR_EMPTY; | ||
140 | error = ERR_NONE; | ||
141 | #else | ||
142 | #ifdef WIN32 | ||
143 | struct _finddata_t c_file; | ||
144 | long hFile; | ||
145 | |||
146 | strcpy(FullName, Config->outboxpath); | ||
147 | strcat(FullName, "OUT*.txt"); | ||
148 | if((hFile = _findfirst( FullName, &c_file )) == -1L ) { | ||
149 | return ERR_EMPTY; | ||
150 | } else { | ||
151 | strcpy(FileName,c_file.name); | ||
152 | } | ||
153 | _findclose( hFile ); | ||
154 | error = ERR_NONE; | ||
155 | #endif | ||
156 | #endif | ||
157 | if (error != ERR_NONE) return error; | ||
158 | |||
159 | strcpy(FullName, Config->outboxpath); | ||
160 | strcat(FullName, FileName); | ||
161 | |||
162 | File = fopen(FullName, "rb"); | ||
163 | len = fread(Buffer, 1, sizeof(Buffer)-2, File); | ||
164 | fclose(File); | ||
165 | if (len<2) return ERR_EMPTY; | ||
166 | |||
167 | if ((Buffer[0] != 0xFF || Buffer[1] != 0xFE) && | ||
168 | (Buffer[0] != 0xFE || Buffer[1] != 0xFF)) { | ||
169 | if (len > GSM_MAX_SMS_LENGTH*MAX_MULTI_SMS) len = GSM_MAX_SMS_LENGTH*MAX_MULTI_SMS; | ||
170 | EncodeUnicode(Buffer2, Buffer, len); | ||
171 | len = len*2; | ||
172 | memmove(Buffer, Buffer2, len); | ||
173 | } | ||
174 | |||
175 | Buffer[len] = 0; | ||
176 | Buffer[len+1] = 0; | ||
177 | ReadUnicodeFile(Buffer2,Buffer); | ||
178 | |||
179 | SMSInfo.ReplaceMessage = 0; | ||
180 | SMSInfo.Entries[0].Buffer= Buffer2; | ||
181 | SMSInfo.Class = -1; | ||
182 | SMSInfo.EntriesNum = 1; | ||
183 | if (mystrncasecmp(Config->transmitformat, "unicode", 0)) { | ||
184 | SMSInfo.Entries[0].ID = SMS_ConcatenatedTextLong; | ||
185 | SMSInfo.UnicodeCoding = true; | ||
186 | } else if (mystrncasecmp(Config->transmitformat, "7bit", 0)) { | ||
187 | SMSInfo.Entries[0].ID = SMS_ConcatenatedTextLong; | ||
188 | SMSInfo.UnicodeCoding = false; | ||
189 | } else { | ||
190 | /* auto */ | ||
191 | SMSInfo.Entries[0].ID = SMS_ConcatenatedAutoTextLong; | ||
192 | } | ||
193 | GSM_EncodeMultiPartSMS(&SMSInfo,sms); | ||
194 | |||
195 | pos1 = FileName; | ||
196 | strcpy(ID,FileName); | ||
197 | for (i = 1; i <= 3 && pos1 != NULL ; i++) pos1 = strchr(++pos1, '_'); | ||
198 | if (pos1 != NULL) { | ||
199 | /* OUT<priority><date>_<time>_<serialno>_<phone number>_<anything>.txt */ | ||
200 | pos2 = strchr(++pos1, '_'); | ||
201 | if (pos2 != NULL) { | ||
202 | phlen = strlen(pos1) - strlen(pos2); | ||
203 | } else { | ||
204 | /* something wrong */ | ||
205 | return ERR_UNKNOWN; | ||
206 | } | ||
207 | } else if (i == 2) { | ||
208 | /* OUTxxxxxxx.txt or OUTxxxxxxx */ | ||
209 | pos1 = &FileName[3]; | ||
210 | pos2 = strchr(pos1, '.'); | ||
211 | if (pos2 == NULL) { | ||
212 | phlen = strlen(pos1); | ||
213 | } else { | ||
214 | phlen = strlen(pos1) - strlen(pos2); | ||
215 | } | ||
216 | } else if (i == 4) { | ||
217 | /* OUT<priority>_<phone number>_<serialno>.txt */ | ||
218 | pos1 = strchr(FileName, '_'); | ||
219 | pos2 = strchr(++pos1, '_'); | ||
220 | phlen = strlen(pos1) - strlen(pos2); | ||
221 | } else { | ||
222 | /* something wrong */ | ||
223 | return ERR_UNKNOWN; | ||
224 | } | ||
225 | |||
226 | for (len=0;len<sms->Number;len++) { | ||
227 | EncodeUnicode(sms->SMS[len].Number, pos1, phlen); | ||
228 | } | ||
229 | |||
230 | #ifdef DEBUG | ||
231 | if (sms->Number != 0) { | ||
232 | DecodeUnicode(sms->SMS[0].Number,Buffer); | ||
233 | dbgprintf("Found %i sms to \"%s\" with text \"%s\" cod %i lgt %i udh: t %i l %i\n", | ||
234 | sms->Number, | ||
235 | Buffer, | ||
236 | DecodeUnicodeString(sms->SMS[0].Text), | ||
237 | sms->SMS[0].Coding, | ||
238 | sms->SMS[0].Length, | ||
239 | sms->SMS[0].UDH.Type, | ||
240 | sms->SMS[0].UDH.Length); | ||
241 | } else dbgprintf("error\n"); | ||
242 | #endif | ||
243 | |||
244 | return ERR_NONE; | ||
245 | } | ||
246 | |||
247 | /* After sending SMS is moved to Sent Items or Error Items. */ | ||
248 | static GSM_Error SMSDFiles_MoveSMS(GSM_MultiSMSMessage *sms, GSM_SMSDConfig *Config, unsigned char *ID, bool alwaysDelete, bool sent) | ||
249 | { | ||
250 | FILE *oFile,*iFile; | ||
251 | int ilen = 0, olen = 0; | ||
252 | char Buffer[(GSM_MAX_SMS_LENGTH*MAX_MULTI_SMS+1)*2],ifilename[400],ofilename[400]; | ||
253 | char*sourcepath, *destpath; | ||
254 | |||
255 | sourcepath = Config->outboxpath; | ||
256 | if (sent) { | ||
257 | destpath = Config->sentsmspath; | ||
258 | } else { | ||
259 | destpath = Config->errorsmspath; | ||
260 | } | ||
261 | |||
262 | strcpy(ifilename, sourcepath); | ||
263 | strcat(ifilename, ID); | ||
264 | strcpy(ofilename, destpath); | ||
265 | strcat(ofilename, ID); | ||
266 | |||
267 | #ifdef WIN32 | ||
268 | if (!mystrncasecmp(ifilename, ofilename, strlen(ofilename))) { | ||
269 | #else | ||
270 | if (strcmp(ifilename, ofilename) != 0) { | ||
271 | #endif | ||
272 | iFile = fopen(ifilename, "r"); | ||
273 | ilen = fread(Buffer, 1, sizeof(Buffer), iFile); | ||
274 | fclose(iFile); | ||
275 | oFile = fopen(ofilename, "w"); | ||
276 | olen = fwrite(Buffer, 1, ilen, oFile); | ||
277 | fclose(oFile); | ||
278 | } | ||
279 | if (ilen == olen) { | ||
280 | if ((strcmp(ifilename, "/") == 0) || (remove(ifilename) != 0)) { | ||
281 | WriteSMSDLog("Could not delete %s (%i)", ifilename, errno); | ||
282 | return ERR_UNKNOWN; | ||
283 | } | ||
284 | return ERR_NONE; | ||
285 | } else { | ||
286 | WriteSMSDLog("Error copying SMS %s -> %s", ifilename, ofilename); | ||
287 | if (alwaysDelete) { | ||
288 | if ((strcmp(ifilename, "/") == 0) || (remove(ifilename) != 0)) | ||
289 | WriteSMSDLog("Could not delete %s (%i)", ifilename, errno); | ||
290 | } | ||
291 | return ERR_UNKNOWN; | ||
292 | } | ||
293 | } | ||
294 | |||
295 | static GSM_Error SMSDFiles_AddSentSMSInfo(GSM_MultiSMSMessage *sms, GSM_SMSDConfig *Config, unsigned char *ID, int Part, bool OK) | ||
296 | { | ||
297 | if (OK) WriteSMSDLog("Transmitted %s (%s: %i) to %s", Config->SMSID, (Part == sms->Number?"total":"part"),Part,DecodeUnicodeString(sms->SMS[0].Number)); | ||
298 | |||
299 | return ERR_NONE; | ||
300 | } | ||
301 | |||
302 | GSM_SMSDService SMSDFiles = { | ||
303 | NONEFUNCTION, /* Init */ | ||
304 | SMSDFiles_SaveInboxSMS, | ||
305 | SMSDFiles_FindOutboxSMS, | ||
306 | SMSDFiles_MoveSMS, | ||
307 | NOTSUPPORTED, /* CreateOutboxSMS*/ | ||
308 | SMSDFiles_AddSentSMSInfo | ||
309 | }; | ||
310 | |||
311 | /* How should editor hadle tabs in this file? Add editor commands here. | ||
312 | * vim: noexpandtab sw=8 ts=8 sts=8: | ||
313 | */ | ||