*/
+#define ATS_PRAHA 1
+
#include <string.h>
#include <glib.h>
-#include <libpq-fe.h>
+#include <pgsql/libpq-fe.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <errno.h>
+
#include "db.h"
#include "smsd.h"
#include "gsm-common.h"
+#include "gsm-ringtones.h"
+#include "gsm-filetypes.h"
static PGconn *connIn = NULL;
static PGconn *connOut = NULL;
buf = g_string_sized_new (128);
g_string_sprintf (buf, "INSERT INTO inbox VALUES ('%s',
'%02d-%02d-%02d %02d:%02d:%02d+01', 'now', '%s', 'f')",
- data->RemoteNumber.number, data->Time.Year + 2000, data->Time.Month,
+ data->Sender, data->Time.Year + 2000, data->Time.Month,
data->Time.Day, data->Time.Hour, data->Time.Minute,
data->Time.Second, data->MessageText);
res = PQexec(connIn, buf->str);
return (0);
}
+#define DBL_FieldString "id, number, text, hexencode, type, fromfile, netcode, udhpresent, longuseudh, eightbit, smsc"
+enum DBL_Field {
+ DBLF_id,
+ DBLF_number,
+ DBLF_text,
+ DBLF_hexencode,
+ DBLF_type,
+ DBLF_fromfile,
+ DBLF_netcode,
+ DBLF_udhpresent,
+ DBLF_longuseudh,
+ DBLF_eightbit,
+ DBLF_smsc,
+ };
+
+#define DBL_true "t"
+#define DBL_false "f"
+
+static int DBL_safestrcasecmp(const char *s1,const char *s2)
+{
+ if (!s1 || !s2)
+ return((!!s1)-(!!s2));
+ return(strcasecmp(s1,s2));
+}
void DB_Look (void)
{
buf = g_string_sized_new (128);
+#ifndef ATS_PRAHA
g_string_sprintf (buf, "BEGIN");
-
res1 = PQexec(connOut, buf->str);
PQclear (res1);
+#endif
- g_string_sprintf (buf, "SELECT id, number, text FROM outbox \
+ g_string_sprintf (buf, "SELECT " DBL_FieldString " FROM outbox \
WHERE processed='f' FOR UPDATE");
res1 = PQexec(connOut, buf->str);
for (i = 0; i < PQntuples (res1); i++)
{
GSM_SMSMessage sms;
+ char *type = PQgetvalue (res1, i, DBLF_type);
+ bool fromfile = !DBL_safestrcasecmp(DBL_true, PQgetvalue (res1, i, DBLF_fromfile));
+ char *smsc = PQgetvalue (res1, i, DBLF_smsc);
+ char *smsbuf = PQgetvalue (res1, i, DBLF_text);
+ size_t smsbuflen = strlen(smsbuf);
+ bool sendlogo;
- sms.MessageCenter.No = 1;
- sms.Type = SMS_Submit;
- sms.DCS.Type = SMS_GeneralDataCoding;
- sms.DCS.u.General.Compressed = false;
- sms.DCS.u.General.Alphabet = SMS_DefaultAlphabet;
- sms.DCS.u.General.Class = 0;
- sms.Validity.VPF = SMS_RelativeFormat;
- sms.Validity.u.Relative = 4320; /* 4320 minutes == 72 hours */
- sms.UDH_No = 0;
- sms.Report = false;
-
- strncpy (sms.RemoteNumber.number, PQgetvalue (res1, i, 1), GSM_MAX_DESTINATION_LENGTH + 1);
- sms.RemoteNumber.number[GSM_MAX_DESTINATION_LENGTH] = '\0';
- if (sms.RemoteNumber.number[0] == '+') sms.RemoteNumber.type = SMS_International;
- else sms.RemoteNumber.type = SMS_Unknown;
-
- strncpy (sms.MessageText, PQgetvalue (res1, i, 2), GSM_MAX_SMS_LENGTH + 1);
- sms.MessageText[GSM_MAX_SMS_LENGTH] = '\0';
+ if (!smsc)
+ sms.MessageCenter.No = 1;
+ else {
+ sms.MessageCenter.No = 0;
+ if (strlen(smsc)+1 > sizeof(sms.MessageCenter.Number))
+ continue; /* error */
+ strcpy(sms.MessageCenter.Number, smsc);
+ }
+
+ sms.Type = GST_MO;
+ sms.Class = -1;
+ sms.Compression = false;
+ sms.EightBit = !DBL_safestrcasecmp(DBL_true, PQgetvalue (res1, i, DBLF_eightbit));
+ sms.Validity = 4320;
+ sms.UDHPresent = !DBL_safestrcasecmp(DBL_true, PQgetvalue (res1, i, DBLF_udhpresent));
+
+ if (!DBL_safestrcasecmp(DBL_true, PQgetvalue (res1, i, DBLF_hexencode))) {
+char *d_end = (char *)SMS_BlockFromHex(smsbuf/*d*/, smsbuf/*s*/, smsbuflen);
+
+ if (!d_end)
+ continue;
+ smsbuflen = d_end - smsbuf;
+ }
+ sendlogo=false;
+ if (!DBL_safestrcasecmp("ringtone" ,type)) {
+ SMS_SetupUDH(&sms, GSM_RingtoneUDH);
+ if (fromfile) {
+GSM_Ringtone ringtone;
+static char ringbuf[GSM_MAX_RINGTONE_PACKAGE_LENGTH];
+int ringbuflen=GSM_MAX_RINGTONE_PACKAGE_LENGTH;
+
+ if (GSM_ReadRingtoneFile(smsbuf, &ringtone))
+ continue; /* error */
+ GSM_PackRingtone(&ringtone, ringbuf, &ringbuflen);
+ smsbuf=ringbuf;
+ smsbuflen=ringbuflen;
+ }
+ }
+ else if (!DBL_safestrcasecmp("oplogo" ,type)) {
+ SMS_SetupUDH(&sms, GSM_OpLogo);
+ sendlogo=true;
+ }
+ else if (!DBL_safestrcasecmp("calleridlogo",type)) {
+ SMS_SetupUDH(&sms, GSM_CallerIDLogo);
+ sendlogo=true;
+ }
+ else { /* "text" */
+ if (fromfile) {
+static char textbuf[GSM_MAX_CONCATENATED_SMS_LENGTH];
+int textbuflen;
+int fd;
+
+ if (-1==(fd=open(smsbuf,O_RDONLY)))
+ continue; /* error */
+ if (-1==(textbuflen=read(fd,textbuf,sizeof(textbuf))))
+ continue; /* error */
+ close(fd);
+ smsbuf=textbuf;
+ smsbuflen=textbuflen;
+ }
+ if (sms.UDHPresent) {
+u8 len=1+(*(u8 *)smsbuf);
+
+ if (len>smsbuflen || len>sizeof(sms.UDH))
+ g_print ("%d: UDH too long: UDHlen=%d, smsbuflen=%d, sizeof(sms.UDH)=%d !!!\n", __LINE__,
+ len, smsbuflen,sizeof(sms.UDH));
+ else {
+ memcpy(sms.UDH,smsbuf,len);
+ memmove(smsbuf,smsbuf+len,smsbuflen-len);
+ smsbuflen-=len;
+ }
+ }
+ }
+
+ if (sendlogo) {
+GSM_Bitmap bitmap;
+static u8 bin[sizeof(bitmap.bitmap) +64/*headers safety*/];
+u8 *d;
+char *usernetcode=PQgetvalue (res1, i, DBLF_netcode);
+
+ if (GE_NONE!=GSM_ReadBitmapFile(smsbuf, &bitmap))
+ continue; /* error */
+
+ d=bin;
+ if (!DBL_safestrcasecmp("oplogo" ,type)) {
+ if (usernetcode) {
+ if (strlen(usernetcode)+1 > sizeof(bitmap.netcode))
+ continue; /* error */
+ strcpy(bitmap.netcode, usernetcode);
+ }
+ *d++ = ((bitmap.netcode[1] & 0x0f) << 4) | (bitmap.netcode[0] & 0xf);
+ *d++ = 0xf0 | (bitmap.netcode[2] & 0x0f);
+ *d++ = ((bitmap.netcode[5] & 0x0f) << 4) | (bitmap.netcode[4] & 0xf);
+ }
+ /* Set the logo size */
+ *d++ = 0x00; /* RFU by Nokia */
+ *d++ = bitmap.width;
+ *d++ = bitmap.height;
+ *d++ = 0x01; /* depth=number of grayscales */
+
+ memcpy(d,bitmap.bitmap,bitmap.size);
+ d+=bitmap.size;
+
+ smsbuf=bin;
+ smsbuflen=d-bin;
+ }
+
+ strncpy (sms.Destination, PQgetvalue (res1, i, DBLF_number), GSM_MAX_DESTINATION_LENGTH + 1);
+ sms.Destination[GSM_MAX_DESTINATION_LENGTH] = '\0';
+
#ifdef XDEBUG
- g_print ("%s, %s\n", sms.Destination, sms.MessageText);
+ g_print ("To: %s\n", sms.Destination);
#endif
- if (WriteSMS (&sms) != 0)
+ if (GE_SMSSENDOK == WriteSMS_deconcatenated (&sms, smsbuf, smsbuflen,
+ !DBL_safestrcasecmp(DBL_true, PQgetvalue (res1, i, DBLF_longuseudh))))
{
g_string_sprintf (buf, "UPDATE outbox SET processed='t' WHERE id='%s'",
- PQgetvalue (res1, i, 0));
+ PQgetvalue (res1, i, DBLF_id));
res2 = PQexec(connOut, buf->str);
if (!res2 || PQresultStatus (res2) != PGRES_COMMAND_OK)
{
PQclear (res1);
+#ifndef ATS_PRAHA
g_string_sprintf (buf, "COMMIT");
res1 = PQexec(connOut, buf->str);
+ PQclear (res1);
+#endif
g_string_free(buf, TRUE);
- PQclear (res1);
+
+#ifdef ATS_PRAHA
+ if (!access("/tmp/smsd-exit",F_OK)) {
+ g_print("/tmp/smsd-exit exists, terminating\n");
+ if (unlink("/tmp/smsd-exit"))
+ g_print("/tmp/smsd-exit unlink failed: %s\n",strerror(errno));
+ exit(0);
+ }
+#endif
}