summaryrefslogtreecommitdiffabout
path: root/gammu/emb/gammu/smsd/s_files.c
Side-by-side diff
Diffstat (limited to 'gammu/emb/gammu/smsd/s_files.c') (more/less context) (ignore 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 @@
+/* (c) 2002-2003 by Joergen Thomsen */
+
+#include "../../cfg/config.h"
+
+#include <string.h>
+#include <stdio.h>
+#include <errno.h>
+#include <time.h>
+#ifdef WIN32
+# include <io.h>
+#endif
+#if defined HAVE_DIRENT_H && defined HAVE_SCANDIR && defined HAVE_ALPHASORT
+# include <dirent.h>
+#endif
+
+#include "../../common/misc/coding/coding.h"
+#include "../../common/service/backup/gsmback.h"
+#include "smsdcore.h"
+
+/* Save SMS from phone (called Inbox sms - it's in phone Inbox) somewhere */
+static GSM_Error SMSDFiles_SaveInboxSMS(GSM_MultiSMSMessage sms, GSM_SMSDConfig *Config)
+{
+ GSM_Error error = ERR_NONE;
+ int i,j;
+ unsigned char FileName[100], FullName[400], ext[4], buffer[64],buffer2[400];
+ bool done;
+ FILE *file;
+#ifdef GSM_ENABLE_BACKUP
+ GSM_SMS_Backup backup;
+#endif
+
+ j = 0;
+ done = false;
+ for (i=0;i<sms.Number && !done;i++) {
+ strcpy(ext, "txt");
+ if (sms.SMS[i].Coding == SMS_Coding_8bit) strcpy(ext, "bin");
+ DecodeUnicode(sms.SMS[i].Number,buffer2);
+ /* we loop on yy for the first SMS assuming that if xxxx_yy_00.ext is absent,
+ any xxxx_yy_01,02, must be garbage, that can be overwritten */
+ file = NULL;
+ do {
+ sprintf(FileName,
+ "IN%02d%02d%02d_%02d%02d%02d_%02i_%s_%02i.%s",
+ sms.SMS[i].DateTime.Year, sms.SMS[i].DateTime.Month, sms.SMS[i].DateTime.Day,
+ sms.SMS[i].DateTime.Hour, sms.SMS[i].DateTime.Minute, sms.SMS[i].DateTime.Second,
+ j, buffer2, i, ext);
+ strcpy(FullName, Config->inboxpath);
+ strcat(FullName, FileName);
+ if (file) fclose(file);
+ file = fopen(FullName, "r");
+ } while ((i == 0) && (file && (++j < 100)));
+ if (file) {
+ fclose(file);
+ if (i == 0) {
+ WriteSMSDLog("Cannot save %s. No available file names", FileName);
+ return ERR_CANTOPENFILE;
+ }
+ }
+ errno = 0;
+
+ if ((sms.SMS[i].PDU == SMS_Status_Report) && mystrncasecmp(Config->deliveryreport, "log", 3)) {
+ strcpy(buffer, DecodeUnicodeString(sms.SMS[i].Number));
+ WriteSMSDLog("Delivery report: %s to %s", DecodeUnicodeString(sms.SMS[i].Text), buffer);
+ } else {
+#ifdef GSM_ENABLE_BACKUP
+ if (mystrncasecmp(Config->inboxformat, "detail", 0)) {
+ for (j=0;j<sms.Number;j++) backup.SMS[j] = &sms.SMS[j];
+ backup.SMS[sms.Number] = NULL;
+ error = GSM_SaveSMSBackupFile(FullName, &backup);
+ done = true;
+ }
+#endif
+ if (!mystrncasecmp(Config->inboxformat, "detail", 0)) {
+ file = fopen(FullName, "wb");
+ if (file) {
+ switch (sms.SMS[i].Coding) {
+ case SMS_Coding_Unicode:
+ case SMS_Coding_Default:
+
+ DecodeUnicode(sms.SMS[i].Text,buffer2);
+ if (mystrncasecmp(Config->inboxformat, "unicode", 0)) {
+ buffer[0] = 0xFE;
+ buffer[1] = 0xFF;
+ fwrite(buffer,1,2,file);
+ fwrite(sms.SMS[i].Text,1,strlen(buffer2)*2,file);
+ } else {
+ fwrite(buffer2,1,strlen(buffer2),file);
+ }
+ break;
+ case SMS_Coding_8bit:
+ fwrite(sms.SMS[i].Text,1,sms.SMS[i].Length,file);
+ }
+ fclose(file);
+ } else error = ERR_CANTOPENFILE;
+ }
+ if (error == ERR_NONE) {
+ WriteSMSDLog("%s %s", (sms.SMS[i].PDU == SMS_Status_Report?"Delivery report":"Received"), FileName);
+ } else {
+ WriteSMSDLog("Cannot save %s (%i)", FileName, errno);
+ return ERR_CANTOPENFILE;
+ }
+ }
+ }
+ return ERR_NONE;
+}
+
+/* Find one multi SMS to sending and return it (or return ERR_EMPTY)
+ * There is also set ID for SMS
+ */
+static GSM_Error SMSDFiles_FindOutboxSMS(GSM_MultiSMSMessage *sms, GSM_SMSDConfig *Config, unsigned char *ID)
+{
+ GSM_Error error = ERR_NOTSUPPORTED;
+ GSM_MultiPartSMSInfo SMSInfo;
+ unsigned char FileName[100],FullName[400];
+ unsigned char Buffer[(GSM_MAX_SMS_LENGTH*MAX_MULTI_SMS+1)*2];
+ unsigned char Buffer2[(GSM_MAX_SMS_LENGTH*MAX_MULTI_SMS+1)*2];
+ FILE *File;
+ int i, len, phlen;
+ char *pos1, *pos2;
+#if defined HAVE_DIRENT_H && defined HAVE_SCANDIR & defined HAVE_ALPHASORT
+ struct dirent **namelist = NULL;
+ int l, m ,n;
+
+ strcpy(FullName, Config->outboxpath);
+ FullName[strlen(Config->outboxpath)-1] = '\0';
+ n = scandir(FullName, &namelist, 0, alphasort);
+ m = 0;
+ while ((m < n) && ((*(namelist[m]->d_name) == '.') ||
+ !mystrncasecmp(namelist[m]->d_name,"out", 3) ||
+ ((strlen(namelist[m]->d_name) >= 4) &&
+ !mystrncasecmp(&namelist[m]->d_name[strlen(namelist[m]->d_name)-4],".txt",4)
+ )
+ )
+ ) m++;
+ if (m < n) strcpy(FileName,namelist[m]->d_name);
+ for (l=0; l < n; l++) free(namelist[l]);
+ free(namelist);
+ namelist = NULL;
+ if (m >= n) return ERR_EMPTY;
+ error = ERR_NONE;
+#else
+#ifdef WIN32
+ struct _finddata_t c_file;
+ long hFile;
+
+ strcpy(FullName, Config->outboxpath);
+ strcat(FullName, "OUT*.txt");
+ if((hFile = _findfirst( FullName, &c_file )) == -1L ) {
+ return ERR_EMPTY;
+ } else {
+ strcpy(FileName,c_file.name);
+ }
+ _findclose( hFile );
+ error = ERR_NONE;
+#endif
+#endif
+ if (error != ERR_NONE) return error;
+
+ strcpy(FullName, Config->outboxpath);
+ strcat(FullName, FileName);
+
+ File = fopen(FullName, "rb");
+ len = fread(Buffer, 1, sizeof(Buffer)-2, File);
+ fclose(File);
+ if (len<2) return ERR_EMPTY;
+
+ if ((Buffer[0] != 0xFF || Buffer[1] != 0xFE) &&
+ (Buffer[0] != 0xFE || Buffer[1] != 0xFF)) {
+ if (len > GSM_MAX_SMS_LENGTH*MAX_MULTI_SMS) len = GSM_MAX_SMS_LENGTH*MAX_MULTI_SMS;
+ EncodeUnicode(Buffer2, Buffer, len);
+ len = len*2;
+ memmove(Buffer, Buffer2, len);
+ }
+
+ Buffer[len] = 0;
+ Buffer[len+1] = 0;
+ ReadUnicodeFile(Buffer2,Buffer);
+
+ SMSInfo.ReplaceMessage = 0;
+ SMSInfo.Entries[0].Buffer = Buffer2;
+ SMSInfo.Class = -1;
+ SMSInfo.EntriesNum = 1;
+ if (mystrncasecmp(Config->transmitformat, "unicode", 0)) {
+ SMSInfo.Entries[0].ID = SMS_ConcatenatedTextLong;
+ SMSInfo.UnicodeCoding = true;
+ } else if (mystrncasecmp(Config->transmitformat, "7bit", 0)) {
+ SMSInfo.Entries[0].ID = SMS_ConcatenatedTextLong;
+ SMSInfo.UnicodeCoding = false;
+ } else {
+ /* auto */
+ SMSInfo.Entries[0].ID = SMS_ConcatenatedAutoTextLong;
+ }
+ GSM_EncodeMultiPartSMS(&SMSInfo,sms);
+
+ pos1 = FileName;
+ strcpy(ID,FileName);
+ for (i = 1; i <= 3 && pos1 != NULL ; i++) pos1 = strchr(++pos1, '_');
+ if (pos1 != NULL) {
+ /* OUT<priority><date>_<time>_<serialno>_<phone number>_<anything>.txt */
+ pos2 = strchr(++pos1, '_');
+ if (pos2 != NULL) {
+ phlen = strlen(pos1) - strlen(pos2);
+ } else {
+ /* something wrong */
+ return ERR_UNKNOWN;
+ }
+ } else if (i == 2) {
+ /* OUTxxxxxxx.txt or OUTxxxxxxx */
+ pos1 = &FileName[3];
+ pos2 = strchr(pos1, '.');
+ if (pos2 == NULL) {
+ phlen = strlen(pos1);
+ } else {
+ phlen = strlen(pos1) - strlen(pos2);
+ }
+ } else if (i == 4) {
+ /* OUT<priority>_<phone number>_<serialno>.txt */
+ pos1 = strchr(FileName, '_');
+ pos2 = strchr(++pos1, '_');
+ phlen = strlen(pos1) - strlen(pos2);
+ } else {
+ /* something wrong */
+ return ERR_UNKNOWN;
+ }
+
+ for (len=0;len<sms->Number;len++) {
+ EncodeUnicode(sms->SMS[len].Number, pos1, phlen);
+ }
+
+#ifdef DEBUG
+ if (sms->Number != 0) {
+ DecodeUnicode(sms->SMS[0].Number,Buffer);
+ dbgprintf("Found %i sms to \"%s\" with text \"%s\" cod %i lgt %i udh: t %i l %i\n",
+ sms->Number,
+ Buffer,
+ DecodeUnicodeString(sms->SMS[0].Text),
+ sms->SMS[0].Coding,
+ sms->SMS[0].Length,
+ sms->SMS[0].UDH.Type,
+ sms->SMS[0].UDH.Length);
+ } else dbgprintf("error\n");
+#endif
+
+ return ERR_NONE;
+}
+
+/* After sending SMS is moved to Sent Items or Error Items. */
+static GSM_Error SMSDFiles_MoveSMS(GSM_MultiSMSMessage *sms, GSM_SMSDConfig *Config, unsigned char *ID, bool alwaysDelete, bool sent)
+{
+ FILE *oFile,*iFile;
+ int ilen = 0, olen = 0;
+ char Buffer[(GSM_MAX_SMS_LENGTH*MAX_MULTI_SMS+1)*2],ifilename[400],ofilename[400];
+ char *sourcepath, *destpath;
+
+ sourcepath = Config->outboxpath;
+ if (sent) {
+ destpath = Config->sentsmspath;
+ } else {
+ destpath = Config->errorsmspath;
+ }
+
+ strcpy(ifilename, sourcepath);
+ strcat(ifilename, ID);
+ strcpy(ofilename, destpath);
+ strcat(ofilename, ID);
+
+#ifdef WIN32
+ if (!mystrncasecmp(ifilename, ofilename, strlen(ofilename))) {
+#else
+ if (strcmp(ifilename, ofilename) != 0) {
+#endif
+ iFile = fopen(ifilename, "r");
+ ilen = fread(Buffer, 1, sizeof(Buffer), iFile);
+ fclose(iFile);
+ oFile = fopen(ofilename, "w");
+ olen = fwrite(Buffer, 1, ilen, oFile);
+ fclose(oFile);
+ }
+ if (ilen == olen) {
+ if ((strcmp(ifilename, "/") == 0) || (remove(ifilename) != 0)) {
+ WriteSMSDLog("Could not delete %s (%i)", ifilename, errno);
+ return ERR_UNKNOWN;
+ }
+ return ERR_NONE;
+ } else {
+ WriteSMSDLog("Error copying SMS %s -> %s", ifilename, ofilename);
+ if (alwaysDelete) {
+ if ((strcmp(ifilename, "/") == 0) || (remove(ifilename) != 0))
+ WriteSMSDLog("Could not delete %s (%i)", ifilename, errno);
+ }
+ return ERR_UNKNOWN;
+ }
+}
+
+static GSM_Error SMSDFiles_AddSentSMSInfo(GSM_MultiSMSMessage *sms, GSM_SMSDConfig *Config, unsigned char *ID, int Part, bool OK)
+{
+ if (OK) WriteSMSDLog("Transmitted %s (%s: %i) to %s", Config->SMSID, (Part == sms->Number?"total":"part"),Part,DecodeUnicodeString(sms->SMS[0].Number));
+
+ return ERR_NONE;
+}
+
+GSM_SMSDService SMSDFiles = {
+ NONEFUNCTION, /* Init */
+ SMSDFiles_SaveInboxSMS,
+ SMSDFiles_FindOutboxSMS,
+ SMSDFiles_MoveSMS,
+ NOTSUPPORTED, /* CreateOutboxSMS */
+ SMSDFiles_AddSentSMSInfo
+};
+
+/* How should editor hadle tabs in this file? Add editor commands here.
+ * vim: noexpandtab sw=8 ts=8 sts=8:
+ */