summaryrefslogtreecommitdiffabout
path: root/gammu/emb/gammu/smsd/s_files.c
Unidiff
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.c313
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 */
21static 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 */
110static 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. */
248static 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
295static 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
302GSM_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 */