· 7 years ago · Nov 15, 2018, 02:16 PM
1/**
2 * @file sms_queue.pc
3 * @copyright CODIX Jsc.
4 * @author Stoyan Denev <sdenev@imx.fr>
5 * @date 14 Sep 2004
6 * @brief Traitement du SMS flux, part of iMX SMS project
7 *
8 * $Id: sms_queue.pc,v 1.24 2016/09/30 14:45:19 ninikolov Exp $
9 *
10 * \defgroup smsq SMS Queue processing.
11 * \ingroup mod_sms
12 *
13 * VERSION HISTORY:
14 * 1.00.01 14.09.2004 Program Startup
15 * 1.00.02 CVS TESTS
16 */
17
18
19#include <stdio.h>
20#include <stdlib.h>
21#include <unistd.h>
22#include <errno.h>
23#include <fcntl.h>
24#include <signal.h>
25#include <string.h>
26#include <termio.h>
27#include <dirent.h>
28#include <time.h>
29#include <sys/time.h>
30#include <sys/types.h>
31#include <sys/dir.h>
32#include <stdarg.h>
33#include <assert.h>
34
35#define VERSION "$Revision: 1.24 $"
36
37/* CVS name and revision */
38#ifdef __GNUC__
39static const char texte_rcs_id[] __attribute__ ((unused)) = "$Revision: 1.24 $";
40static const char texte_source[] __attribute__ ((unused)) = "$Source: /app/cvs/repo/prog/sms_queue.pc,v $";
41#else /* __GNUC__ */
42static const char texte_rcs_id[] = "$Revision: 1.24 $";
43static const char texte_source[] = "$Source: /app/cvs/repo/prog/sms_queue.pc,v $";
44#endif /* __GNUC__ */
45
46/**\ingroup smsq*/
47/*@{*/
48
49#define FALSE 0 /*for HPUX*/
50#define TRUE 1 /*for HPUX*/
51
52/* logmsg file - $IMX_TMP/sms/LOG_FILE_NAME */
53#define LOG_FILE_NAME "sms_queue"
54
55/* return status */
56enum {
57 SUCCESS = 0,
58 EFAIL,
59 NOT_FOUND
60};
61#define STAT_OK SUCCESS /* must not change value 0 */
62#define STAT_ERROR -EFAIL
63#define STAT_NOTFOUND -NOT_FOUND
64
65#define NO_LINE -EFAIL
66
67/* sleep and timeouts */
68#define SLEEP_ON_PASS 10
69#define SLEEP_ON_WAIT 3
70#define WAIT_TIMEOUT 2000
71
72/* v_domaine params */
73#define VD_TYPE_SMS_TYPE_SMS "SMS_TYPE_SMS" /* TYPE SMS */
74#define VD_ABREV_ENT "ENT" /* SMS entrant */
75#define VD_ABREV_SRT "SRT" /* SMS sortant */
76
77#define VD_TYPE_SMS_PRTY "SMS_PRTY" /* SMS PRIORITY */
78#define VD_ABREV_10 "10" /* La plus haute priorite */
79#define VD_ABREV_20 "20" /* Haute priorite */
80#define VD_ABREV_30 "30" /* Priorite normale */
81#define VD_ABREV_40 "40" /* Priorite basse */
82#define VD_ABREV_50 "50" /* La priorite la plus basse */
83
84#define VD_TYPE_SMS_TYPE_NUM "SMS_TYPE_NUM" /* TYPE NUMBER */
85#define VD_ABREV_GSM "GSM" /* SMS vers GSM */
86#define VD_ABREV_DFT "DFT" /* SMS vers telephone domicile de France Telecom */
87
88#define VD_TYPE_SMS_ETAT "SMS_ETAT"
89#define VD_ABREV_NTR "NTR" /* SMS Ã traiter */
90#define VD_ABREV_ENC "ENC" /* SMS en cours de traitement */
91#define VD_ABREV_ATR "ATR" /* Attente reponse */
92#define VD_ABREV_TRT "TRT" /* SMS traite */
93#define VD_ABREV_ECI "ECI" /* Echec envoi SMS: caracteres invalides */
94#define VD_ABREV_ESI "ESI" /* Echec envoi SMS: contenu SMS invalide */
95#define VD_ABREV_EPL "EPL" /* Echec envoi SMS: probleme liaison GSM */
96#define VD_ABREV_ENI "ENI" /* Echec envoi SMS: numero incorrect */
97#define VD_ABREV_EPR "EPR" /* Echec envoi SMS: probleme reseau */
98
99#define VD_TYPE_SMS_TYPE_LIGNE "SMS_TYPE_LIGNE"
100#define VD_ABREV_ST1 "ST1" /* Siemens MC35i/TC35i compatible */
101#define VD_ABREV_NK1 "NK1" /* Nokia 6310i compatible */
102#define VD_ABREV_GW1 "GW1" /* Gateway */
103
104/* smsd dirs */
105#define PREF_DIR_OUTGOING "outgoing"
106#define PREF_DIR_TMP "tmp"
107#define PREF_DIR_STAT "stat"
108#define PREF_DIR_DONE "done"
109#define PREF_DIR_INCOMING "incoming"
110#define PREF_DIR_FAILED "failed"
111
112/* SMS status */
113#define SMS_STAT_SENT "SENT"
114#define SMS_STAT_SEND_FAILED "SNDFAILED"
115#define SMS_STAT_SEND_FAILED_OPEN "SNDFAILED-FILE"
116#define SMS_STAT_SEND_FAILED_FORMAT "SNDFAILED-FORMAT"
117#define SMS_STAT_SEND_FAILED_MESSAGE "SNDFAILED-MESSAGE"
118#define SMS_STAT_SEND_FAILED_DEVICE "SNDFAILED-DEVICE"
119#define SMS_STAT_DELIVER_FAILED_FILE "DLVFAILED-FILE"
120#define SMS_STAT_DELIVER_FAILED_FORMAT "DLVFAILED-FORMAT"
121#define SMS_STAT_DELIVERED "DELIVERED"
122#define SMS_STAT_NOT_DELIVERED "NOTDELIVERED-"
123#define SMS_STAT_RECEIVED "RECEIVED"
124
125#define MAX_SMS_DATA 1024
126
127enum {
128 LOG_NONE = 0,
129 LOG_ERR,
130 LOG_INFO
131};
132
133EXEC SQL INCLUDE sqlca;
134
135/* SQL types */
136typedef char SQL40[41];
137typedef char SQL120[120];
138typedef char SQL300[301];
139typedef char SQL1024[1025];
140typedef char SQL80[81];
141
142EXEC SQL BEGIN DECLARE SECTION;
143 EXEC SQL TYPE SQL40 IS STRING(41);
144 EXEC SQL TYPE SQL120 IS STRING(121);
145 EXEC SQL TYPE SQL300 IS STRING(301);
146 EXEC SQL TYPE SQL1024 IS STRING(1025);
147 EXEC SQL TYPE SQL80 IS STRING(81);
148EXEC SQL END DECLARE SECTION;
149
150static char log_file_name[PATH_MAX + 1]; /* logmsg file name */
151
152static char
153 dir_outgoing[PATH_MAX + 1], /* outgoing SMS */
154 dir_tmp[PATH_MAX + 1], /* tmp DIR */
155 dir_done[PATH_MAX + 1], /* done DIR */
156 dir_stat[PATH_MAX + 1], /* stat SMS */
157 dir_failed[PATH_MAX + 1], /* failed SMS */
158 dir_incoming[PATH_MAX + 1]; /* incoming SMS */
159
160/**This is a list of international dialing codes. The last element of the array should always be:"000",
161 it's used to idicate the end of the array.*/
162static char phone_prefix[][8] = {
163 "+93", "+355", "+213", "+1684", "+376", "+244", "+1264", "+672", "+1268", "+54",
164 "+374", "+297", "+247", "+61", "+672", "+43", "+994", "+1242", "+973", "+880",
165 "+1246", "+1268", "+375", "+32", "+501", "+229", "+1441", "+975", "+591", "+387",
166 "+267", "+55", "+1284", "+673", "+359", "+226", "+257", "+855", "+237", "+1", "+238",
167 "+1345", "+236", "+235", "+64", "+56", "+86", "+6108", "+6118", "+6128", "+6138",
168 "+6148", "+615", "+6168", "+6178", "+6188", "+6198", "+57", "+269", "+242", "+243",
169 "+682", "+506", "+225", "+385", "+53", "+5399", "+599", "+357", "+420", "+45", "+246",
170 "+253", "+1767", "+1809", "+1829", "+670", "+56", "+593", "+20", "+503", "+8812", "+8813",
171 "+88213", "+240", "+291", "+372", "+251", "+500", "+298", "+679", "+358", "+33", "+596",
172 "+594", "+689", "+241", "+220", "+995", "+49", "+233", "+350", "+881", "+8810", "+8811",
173 "+8812", "+8813", "+8816", "+8817", "+8818", "+8819", "+8818", "+8819", "+30", "+299",
174 "+1473", "+590", "+1671", "+5399", "+502", "+245", "+224", "+592", "+509", "+504", "+852",
175 "+36", "+8810", "+8811", "+354", "+91", "+62", "+871", "+874", "+873", "+872", "+870",
176 "+800", "+808", "+98", "+964", "+353", "+8816", "+8817", "+972", "+39", "+1876", "+81",
177 "+962", "+7", "+254", "+686", "+850", "+82", "+965", "+996", "+856", "+371", "+961",
178 "+266", "+231", "+218", "+423", "+370", "+352", "+853", "+389", "+261", "+265", "+60",
179 "+960", "+223", "+356", "+692", "+596", "+222", "+230", "+269", "+52", "+691", "+1808",
180 "+373", "+377", "+976", "+382", "+1664", "+212", "+258", "+95", "+264", "+674", "+977",
181 "+31", "+599", "+1869", "+687", "+64", "+505", "+227", "+234", "+683", "+672", "+1670",
182 "+47", "+968", "+92", "+680", "+970", "+507", "+675", "+595", "+51", "+63", "+48", "+351",
183 "+1787", "+1939", "+974", "+262", "+40", "+7", "+250", "+290", "+1869", "+1758", "+508",
184 "+1784", "+685", "+378", "+239", "+966", "+221", "+381", "+248", "+232", "+65", "+421",
185 "+386", "+677", "+252", "+27", "+34", "+94", "+249", "+597", "+268", "+46", "+41", "+963",
186 "+886", "+992", "+255", "+66", "+88216", "+670", "+228", "+690", "+676", "+1868", "+216",
187 "+90", "+993", "+1649", "+688", "+256", "+380", "+971", "+44", "+1", "+1340", "+878", "+598",
188 "+998", "+678", "+39", "+379", "+58", "+84", "+808", "+681", "+967", "+260", "+255", "+263",
189 "000"
190};
191
192EXEC SQL BEGIN DECLARE SECTION;
193 static int max_tests = 0; /* number of max send tests */
194 static int sms_line = -1;
195 static int sms_default_line = -1;
196 static char impr_sms_ligne[16];
197EXEC SQL END DECLARE SECTION;
198
199
200static int do_rollback(void);
201static int set_sms_stat (char *ref_sms, char *etat);
202static int archive_flux(char *ref_sms);
203static int get_mail_addr(char *tel, char *mail_addr, char *RefDoss);
204static int check_phone_prefix(char *tel, char *tel1, char *tel2);
205
206static void log_msg(int type, char *message, ...);
207
208/*#define do_log_info(fm, ...) log_msg(LOG_INFO, __VA_ARGS__)*/
209
210
211/********************************************************************************
212 Function: get_str_time
213 In: (no arguments)
214 Out: current date and time
215Description: Returns date and time in format YYYY-MM-DD hh:mi:ss.mmmm
216********************************************************************************/
217static char *get_str_time (void)
218{
219 static char result[64];
220 struct timeval tv;
221 struct timezone tz;
222 struct tm *t_time;
223
224 result[0] = '\0';
225
226 gettimeofday(&tv, &tz);
227 t_time = localtime (&tv.tv_sec);
228
229 sprintf (result, "%04d-%02d-%02d %02d:%02d:%02d",
230 (t_time->tm_year + 1900), (t_time->tm_mon + 1), t_time->tm_mday, t_time->tm_hour,
231 t_time->tm_min, t_time->tm_sec);
232
233 return result;
234}
235/********************************************************************************
236 Function: set_log_file_name
237 In: (no arguments)
238 Out: (no return)
239Description: Sets the logmsg file name in format:
240 $IMX_TMP/sms/LOG_FILE_NAME_YYYYMMDDhhmiss_line
241********************************************************************************/
242static void set_log_file_name (void)
243{
244 time_t l_time;
245 struct tm *t_time;
246
247 time (&l_time);
248 t_time = localtime (&l_time);
249
250 sprintf(log_file_name, "%s/sms/log/queue/%s_%04d%02d%02d%02d%02d%02d_%d.logmsg",
251 getenv("IMX_TRACE"), LOG_FILE_NAME,
252 (t_time->tm_year + 1900), (t_time->tm_mon + 1), t_time->tm_mday,
253 t_time->tm_hour, t_time->tm_min, t_time->tm_sec, sms_line == -1 ? 0 : sms_line);
254}
255/********************************************************************************
256 Function: logmsg
257 In: message
258 Out: (no return)
259Description: Write the message in the logmsg file
260********************************************************************************/
261static void logmsg(char *message, ...)
262{
263 FILE *fp = NULL;
264 va_list args;
265
266 if (!(fp = fopen (log_file_name, "a+"))) {
267 fprintf(stderr, "Cannot open log file : %s", strerror(errno));
268 }
269
270 if (fp == NULL) {
271 fp = stdout;
272 }
273
274 fprintf (fp, "%s: ", get_str_time ());
275
276 va_start (args, message);
277 vfprintf (fp, message, args);
278 va_end (args);
279
280 fflush (fp);
281 if (fp != stdout) {
282 fclose (fp);
283 }
284}
285
286/********************************************************************************
287 Function: only_digits
288 In: phone number
289 Out: (no return)
290Description: Leaves only the digits in the phone number
291********************************************************************************/
292static void only_digits (char *str)
293{
294 char result[256];
295 int i = 0, j = 0, len = strlen (str);
296
297 /* Trim garbage left */
298 for (; i < len; i++) {
299 if (str[i] >= '0' && str[i] <= '9' || str[i] == '+') {
300 break;
301 }
302 }
303
304 if (str[i] == '+') {
305 result[j++] = str[i++];
306 }
307
308 for (; i < len && j < 256; i++) {
309 if (str[i] >= '0' && str[i] <= '9') {
310 result[j++] = str[i];
311 }
312 }
313
314 result[j] = '\0';
315 strcpy (str, result);
316}
317
318/********************************************************************************
319 Function: sql_log_error
320 In: return code,
321 message
322 Out: return code (first arg)
323Description: SQL error - write date/time, message, the SQL error in the logmsg file
324********************************************************************************/
325static int sql_log_error (int code, char *message, ...)
326{
327 char v_buffer[4096], err_msg[4096];
328 size_t buff_len, msg_len;
329
330 va_list args;
331
332 va_start (args, message);
333 vsprintf (v_buffer, message, args);
334 va_end (args);
335
336 buff_len = sizeof (err_msg);
337 sqlglm (err_msg, &buff_len, &msg_len);
338
339 logmsg("sql error: %s sql: %.*s\n", v_buffer, msg_len, err_msg);
340 do_rollback ();
341
342 return code;
343}
344
345/** \brief Output Log message.
346 * \param [in] message - Message to print.
347 * \return none
348 */
349static void log_msg(int type, char *message, ...) {
350 char v_buffer[4096];
351 va_list args;
352
353 va_start (args, message);
354 vsprintf (v_buffer, message, args);
355 va_end (args);
356
357 switch(type) {
358 case LOG_ERR:
359 logmsg("ERR: %s\n", v_buffer); break;
360 case LOG_INFO:
361 logmsg("INFO: %s\n", v_buffer); break;
362 default:
363 logmsg("%s\n", v_buffer);
364 }
365}
366
367/********************************************************************************
368 Function: connect_db - This Function is NOT USE!
369 In: (no arguments)
370 Out: STAT_OK on success
371 STAT_ERROR on fail
372Description: Establish connection to the base
373********************************************************************************/
374static int connect_db (void)
375{
376 EXEC SQL BEGIN DECLARE SECTION;
377 SQL40 uname, upwd;
378 EXEC SQL END DECLARE SECTION;
379
380 get_user_pass (uname, upwd);
381
382 logmsg("UN: [%s], PW: [%s]\n", uname, upwd);
383
384 EXEC SQL WHENEVER SQLERROR DO return (sql_log_error (STAT_ERROR, "cannot connect to oracle"));
385 EXEC SQL CONNECT :uname IDENTIFIED BY :upwd;
386
387 return STAT_OK;
388}
389/********************************************************************************
390 Function: disconnect_db - This Function is NOT USE!
391 In: (no arguments)
392 Out: STAT_OK on success
393 STAT_ERROR on fail
394Description: Drop connection to the database
395********************************************************************************/
396static int disconnect_db (void)
397{
398 EXEC SQL WHENEVER SQLERROR DO return (sql_log_error (STAT_ERROR, "cannot connect to oracle"));
399 EXEC SQL COMMIT WORK RELEASE;
400
401 return STAT_OK;
402}
403/********************************************************************************
404 Function: do_quiet_commit
405 In: (no arguments)
406 Out: STAT_OK on success
407 STAT_ERROR on fail
408Description: Commit the transaction - no logmsg appied
409********************************************************************************/
410static int do_quiet_commit (void)
411{
412 EXEC SQL WHENEVER SQLERROR DO return (sql_log_error (STAT_ERROR, "cannot commit"));
413 EXEC SQL COMMIT;
414
415 return STAT_OK;
416}
417/********************************************************************************
418 Function: do_commit
419 In: (no arguments)
420 Out: STAT_OK on success
421 STAT_ERROR on fail
422Description: Commit the transaction
423********************************************************************************/
424static int do_commit (void)
425{
426 logmsg("COMMIT\n");
427 return do_quiet_commit ();
428}
429/********************************************************************************
430 Function: do_rollback
431 In: (no arguments)
432 Out: STAT_OK on success
433 STAT_ERROR on fail
434Description: Rollback the transaction
435********************************************************************************/
436static int do_rollback(void)
437{
438 EXEC SQL WHENEVER SQLERROR DO return (sql_log_error (STAT_ERROR, "cannot rollback"));
439 EXEC SQL ROLLBACK;
440
441 logmsg("ROLLBACK\n");
442 return STAT_OK;
443}
444/********************************************************************************
445 Function: on_extit
446 In: signal info
447 Out: (no result)
448Description: Overrided signals SIGQUIT, SIGINT, SIGKILL
449 Note SIGKILL may not be overrided on AIX machines
450********************************************************************************/
451static void on_extit (int siginf)
452{
453 logmsg ("TERM signal [%d] received\n", siginf);
454
455 DisconnectOracle();
456
457 signal(SIGQUIT, SIG_DFL);
458 signal(SIGINT , SIG_DFL);
459 signal(SIGKILL, SIG_DFL);
460
461 exit (0);
462}
463/********************************************************************************
464 Function: init_env
465 In: (no arguments)
466 Out: STAT_OK on success
467 STAT_NOTFOUND on not found
468 STAT_ERROR on fail
469Description: Init the environment variables
470********************************************************************************/
471static int init_env(void)
472{
473 logmsg("init the sms queue for line [%d]...\n", sms_line);
474
475 /* Load the default line only if we are not given parameter */
476
477 EXEC SQL WHENEVER SQLERROR DO return (sql_log_error (STAT_ERROR, "cannot init default lines for SMS"));
478 EXEC SQL WHENEVER NOT FOUND DO log_msg (LOG_INFO, "No default lines for SMS");
479 EXEC SQL SELECT nbjour INTO :sms_default_line
480 FROM v_domaine
481 WHERE type = 'SMS_PREFIX'
482 AND UPPER(valeur) = 'DEFAULT';
483
484 if(sms_default_line != -1) {
485 logmsg("SMS queue default line is [%d]\n", sms_default_line);
486 if (sms_line == -1) {
487 sms_line = sms_default_line;
488 logmsg("setting sms queue line to default : [%d]", sms_line);
489 }
490 } else {
491 log_msg (LOG_INFO, "SMS queue line: [%d]", sms_line);
492 }
493
494 /* Setup printer */
495 sprintf(impr_sms_ligne, "M%u", sms_line + 79);
496 log_msg (LOG_INFO, "SMS Printer: %s", impr_sms_ligne);
497
498 sprintf(dir_outgoing, "%s/sms/spool/%d/%s", getenv("IMX_TMP"), sms_line, PREF_DIR_OUTGOING);
499 sprintf(dir_tmp, "%s/sms/spool/%d/%s", getenv("IMX_TMP"), sms_line, PREF_DIR_TMP);
500 sprintf(dir_done, "%s/sms/spool/%d/%s", getenv("IMX_TMP"), sms_line, PREF_DIR_DONE);
501 sprintf(dir_stat, "%s/sms/spool/%d/%s", getenv("IMX_TMP"), sms_line, PREF_DIR_STAT);
502 sprintf(dir_incoming, "%s/sms/spool/%d/%s", getenv("IMX_TMP"), sms_line, PREF_DIR_INCOMING);
503 sprintf(dir_failed, "%s/sms/spool/%d/%s", getenv("IMX_TMP"), sms_line, PREF_DIR_FAILED);
504
505 logmsg("dir_outgoing: [%s]\n", dir_outgoing);
506 logmsg("dir_tmp: [%s]\n", dir_tmp);
507 logmsg("dir_done: [%s]\n", dir_done);
508 logmsg("dir_stat: [%s]\n", dir_stat);
509 logmsg("dir_incoming: [%s]\n", dir_incoming);
510 logmsg("dir_failed: [%s]\n", dir_failed);
511
512 if (access (dir_outgoing, F_OK | R_OK | W_OK) ||
513 access (dir_done, F_OK | R_OK | W_OK) ||
514 access (dir_tmp, F_OK | R_OK | W_OK) ||
515 access (dir_stat, F_OK | R_OK | W_OK) ||
516 access (dir_failed, F_OK | R_OK | W_OK) ||
517 access (dir_incoming, F_OK | R_OK | W_OK)) {
518 logmsg("error: spool directory list incomplete\n");
519 return STAT_ERROR;
520 }
521
522 /* get max tests for sending */
523 EXEC SQL WHENEVER SQLERROR DO return (sql_log_error (STAT_ERROR, "cannot init environment max_tests"));
524 EXEC SQL WHENEVER NOT FOUND DO return (sql_log_error (STAT_NOTFOUND, "not found error when init environment max_tests"));
525 EXEC SQL SELECT COUNT (*)
526 INTO :max_tests
527 FROM t_sms_tentative;
528
529 logmsg("max_tests: [%d]\n", max_tests);
530
531 /* get max tests for sending */
532
533 return STAT_OK;
534}
535
536/********************************************************************************
537 Function: get_status
538 In: result
539 Out: STAT_OK on success
540 STAT_NOTFOUND on not found
541 STAT_ERROR on fail
542Description: Read for protected number and copy it to result
543********************************************************************************/
544static int protect_number (char *pnumber)
545{
546 EXEC SQL BEGIN DECLARE SECTION;
547 SQL80 number;
548 EXEC SQL END DECLARE SECTION;
549
550 number[0] = '\0';
551
552 EXEC SQL WHENEVER SQLERROR DO return (STAT_ERROR);
553 EXEC SQL WHENEVER NOT FOUND DO return (STAT_NOTFOUND);
554 EXEC SQL SELECT valeur
555 INTO :number
556 FROM v_domaine
557 WHERE type = 'TEST_MSF'
558 AND abrev = 'SMS'
559 AND ROWNUM = 1;
560
561 logmsg("get protected number: [%s]\n", number);
562
563 strcpy (pnumber, number);
564 return STAT_OK;
565}
566
567/** \brief Count Pending SMSes
568 * \return Count Of Pending SMSs
569 * \retval STAT_ERROR - On SQL Error.
570 */
571static int count_pending_smses(void)
572{
573 EXEC SQL BEGIN DECLARE SECTION;
574 int sql_count = -1024;
575 EXEC SQL END DECLARE SECTION;
576
577 sql_count = STAT_NOTFOUND;
578
579 EXEC SQL WHENEVER SQLERROR DO return (sql_log_error (STAT_ERROR, "cannot count NTR items"));
580 EXEC SQL WHENEVER NOT FOUND DO return (STAT_NOTFOUND);
581
582 if(sms_default_line == -EFAIL) {
583 EXEC SQL SELECT count(*) INTO :sql_count
584 FROM t_sms_flux tf, g_texte gt
585 WHERE tf.etat = 'NTR'
586 AND tf.typenum = 'GSM'
587 AND tf.reftexte = gt.reftexte
588 AND gt.imprimante = :impr_sms_ligne;
589 } else if (sms_line != sms_default_line) {
590 EXEC SQL SELECT count(*) INTO :sql_count
591 FROM t_sms_flux tf, v_domaine vd
592 WHERE tf.etat = 'NTR'
593 AND tf.typenum = 'GSM'
594 AND vd.nbjour = :sms_line
595 AND vd.type = 'SMS_PREFIX'
596 AND substr(ltrim(tf.numero, '0+'), 0, length(vd.abrev)) = vd.abrev
597 AND length(vd.abrev) =
598 (select max(length(abrev))
599 from v_domaine
600 where type = 'SMS_PREFIX'
601 and substr(ltrim(tf.numero, '0+'), 0, length(abrev)) = abrev);
602 } else {
603 EXEC SQL SELECT count(*) INTO :sql_count
604 FROM t_sms_flux tf
605 WHERE tf.etat = 'NTR'
606 AND tf.typenum = 'GSM'
607 AND NOT EXISTS (SELECT 1
608 FROM v_domaine
609 WHERE type='SMS_PREFIX'
610 AND valeur != 'DEFAULT'
611 AND substr( ltrim(tf.numero, '0+'), 0, length(abrev)) = abrev);
612 }
613
614 return sql_count;
615}
616
617/** \brief Process sms flux.
618 \retval SUCCESS - On successful processing all pending sms's or no pending sms's
619 \retval STAT_NOTFOUND - On not found
620 \retval STAT_ERROR - On error.
621
622 Export all sms's from t_sms_queue with etat 'NTR' to file for smsd.
623 In normal case every printer is differnt queue.
624 For some clients sms's are routed to different queues, depend on phone number prefix.
625 ETAT in t_sms_flux become 'ENC'.
626*/
627static int process_flux (void)
628{
629 char file_name[PATH_MAX + 1], tmp_file[PATH_MAX + 1];
630 FILE *fp;
631
632 EXEC SQL BEGIN DECLARE SECTION;
633 SQL40 sql_refsms, sql_numero, sql_tm1, sql_startdt, sql_stopdt, sql_refgrp;
634 SQL1024 sql_texte;
635 int sql_count, sql_seqgrp;
636 EXEC SQL END DECLARE SECTION;
637
638 /* NIGHT/DAY MODE CHNG */
639 EXEC SQL WHENEVER SQLERROR DO return (sql_log_error (STAT_ERROR, "cannot select from t_sms_ligne"));
640 EXEC SQL WHENEVER NOT FOUND DO strcpy(sql_tm1,"");
641 EXEC SQL SELECT TO_CHAR(SYSDATE, 'HH24:MI'), start_dt, stop_dt
642 INTO :sql_tm1, :sql_startdt, :sql_stopdt
643 FROM t_sms_ligne
644 WHERE ligne = :sms_line
645 AND TO_CHAR (SYSDATE, 'HH24MI') >= start_dt
646 AND TO_CHAR (SYSDATE, 'HH24MI') < stop_dt;
647
648 if (sql_tm1[0] == 0) {
649 logmsg("NIGHT MODE\n");
650 return STAT_OK;
651 }
652
653 /* logmsg("DAY MODE it is %s o'clock START=%s STOP=%s\n", sql_tm1, sql_startdt, sql_stopdt);
654 END NIGHT/DAY MODE CHNG */
655
656 sql_count = count_pending_smses();
657 logmsg("process_flux: [%d] items 2do\n", sql_count);
658 if (sql_count <= 0) {
659 return STAT_OK;
660 }
661
662 /* get max tests for sending */
663 EXEC SQL WHENEVER SQLERROR DO return (sql_log_error (STAT_ERROR, "cannot declare t_sms_flux_cursor cursor"));
664 EXEC SQL WHENEVER NOT FOUND DO return (sql_log_error (STAT_NOTFOUND, "not found error when declare t_sms_flux_cursor cursor"));
665
666 if(sms_default_line == NO_LINE) {
667 EXEC SQL DECLARE t_sms_flux_cursor_1 CURSOR FOR
668 SELECT tf.refsms, tf.numero, tf.texte, tf.refgroupe, tf.seqgroupe
669 FROM t_sms_flux tf, g_texte gt
670 WHERE tf.etat = 'NTR'
671 AND tf.typenum = 'GSM'
672 AND tf.reftexte = gt.reftexte
673 AND gt.imprimante = :impr_sms_ligne
674 ORDER BY tf.prty, tf.refgroupe, tf.seqgroupe
675 FOR UPDATE OF tf.etat;
676 } else if (sms_line != sms_default_line) {
677 EXEC SQL DECLARE t_sms_flux_cursor_2 CURSOR FOR
678 SELECT tf.refsms, tf.numero, tf.texte, tf.refgroupe, tf.seqgroupe
679 FROM t_sms_flux tf, v_domaine vd
680 WHERE tf.etat = 'NTR'
681 AND tf.typenum = 'GSM'
682 AND vd.nbjour = :sms_line
683 AND vd.type = 'SMS_PREFIX'
684 AND substr(ltrim(tf.numero, '0+'), 0, length(vd.abrev)) = vd.abrev
685 AND length(vd.abrev) =
686 (select max(length(abrev))
687 FROM v_domaine
688 WHERE type = 'SMS_PREFIX'
689 AND substr(ltrim(tf.numero, '0+'), 0, length(abrev)) = abrev)
690 ORDER BY tf.prty, tf.refgroupe, tf.seqgroupe
691 FOR UPDATE OF etat;
692 } else {
693 EXEC SQL DECLARE t_sms_flux_cursor_3 CURSOR FOR
694 SELECT tf.refsms, tf.numero, tf.texte, tf.refgroupe, tf.seqgroupe
695 FROM t_sms_flux tf
696 WHERE tf.etat = 'NTR'
697 AND tf.typenum = 'GSM'
698 AND NOT EXISTS (SELECT 1
699 FROM v_domaine
700 WHERE type='SMS_PREFIX'
701 AND valeur != 'DEFAULT'
702 AND substr( ltrim(tf.numero, '0+'), 0, length(abrev)) = abrev)
703 ORDER BY tf.prty, tf.refgroupe, tf.seqgroupe
704 FOR UPDATE OF etat;
705 }
706
707 EXEC SQL WHENEVER SQLERROR DO return (sql_log_error (STAT_ERROR, "cannot open t_sms_flux_cursor cursor"));
708 EXEC SQL WHENEVER NOT FOUND DO return (sql_log_error (STAT_NOTFOUND, "not found error when open t_sms_flux_cursor cursor"));
709 if(sms_default_line == NO_LINE) {
710 EXEC SQL OPEN t_sms_flux_cursor_1;
711 } else if (sms_line != sms_default_line) {
712 EXEC SQL OPEN t_sms_flux_cursor_2;
713 } else {
714 EXEC SQL OPEN t_sms_flux_cursor_3;
715 }
716
717 EXEC SQL WHENEVER SQLERROR DO return (sql_log_error (STAT_ERROR, "cannot fetch t_sms_flux_cursor cursor"));
718 EXEC SQL WHENEVER NOT FOUND DO break;
719
720 for (;;) {
721 memset (sql_refsms, '\0', sizeof (sql_refsms));
722 memset (sql_numero, '\0', sizeof (sql_numero));
723 memset (sql_texte, '\0', sizeof (sql_texte));
724 memset (file_name, '\0', sizeof (file_name));
725 memset (sql_refgrp, '\0', sizeof (sql_refgrp));
726
727 EXEC SQL WHENEVER SQLERROR DO return (sql_log_error (STAT_ERROR, "cannot fetch t_sms_flux_cursor cursor"));
728 EXEC SQL WHENEVER NOT FOUND DO break;
729 if(sms_default_line == NO_LINE) {
730 EXEC SQL FETCH t_sms_flux_cursor_1
731 INTO :sql_refsms, :sql_numero, :sql_texte, :sql_refgrp, :sql_seqgrp;
732 } else if (sms_line != sms_default_line) {
733 EXEC SQL FETCH t_sms_flux_cursor_2
734 INTO :sql_refsms, :sql_numero, :sql_texte, :sql_refgrp, :sql_seqgrp;
735 } else {
736 EXEC SQL FETCH t_sms_flux_cursor_3
737 INTO :sql_refsms, :sql_numero, :sql_texte, :sql_refgrp, :sql_seqgrp;
738 }
739
740 logmsg("refsms: [%s]\n", sql_refsms);
741 logmsg("numero: [%s]\n", sql_numero);
742 logmsg("texte: [%s]\n", sql_texte);
743
744 if (!sql_numero[0]) {
745 set_sms_stat (sql_refsms, VD_ABREV_ENI);
746 utlUpdateLog (0, 1); /* fail */
747 continue;
748 } else {
749 EXEC SQL WHENEVER SQLERROR DO return (sql_log_error (STAT_ERROR, "cannot update t_sms_flux table"));
750 EXEC SQL WHENEVER NOT FOUND DO break;
751 EXEC SQL UPDATE t_sms_flux SET dttrait = SYSDATE WHERE refsms = :sql_refsms;
752 }
753
754 logmsg("check for protected number...\n");
755 protect_number (sql_numero);
756 logmsg("protected number: %s\n", sql_numero);
757
758 sprintf (tmp_file, "%s/%s%.2d.tmp", dir_tmp, sql_refgrp, sql_seqgrp);
759 logmsg("tmp_file: [%s]\n", tmp_file);
760
761 sprintf (file_name, "%s/%s%.2d", dir_outgoing, sql_refgrp, sql_seqgrp);
762 logmsg("file_name: [%s]\n", file_name);
763
764 only_digits (sql_numero);
765 logmsg("numero (only digits): [%s]\n", sql_numero);
766
767 if (!(fp = fopen (tmp_file, "w"))) {
768 logmsg("error: cannot create file name %s\n", file_name);
769 EXEC SQL WHENEVER SQLERROR DO return (sql_log_error (STAT_ERROR, "cannot close t_sms_flux_cursor cursor"));
770 if(sms_default_line == NO_LINE) {
771 EXEC SQL CLOSE t_sms_flux_cursor_1;
772 } else if (sms_line != sms_default_line) {
773 EXEC SQL CLOSE t_sms_flux_cursor_2;
774 } else {
775 EXEC SQL CLOSE t_sms_flux_cursor_3;
776 }
777 utlUpdateLog (0, 1); /* fail */
778 return STAT_ERROR;
779 }
780
781 if ((fprintf (fp, "REF: %s\n", sql_refsms) < 0) ||
782 (fprintf (fp, "NUM: %s\n", sql_numero) < 0) ||
783 (fprintf (fp, "TMS: %s\n", get_str_time ()) < 0) ||
784 (fprintf (fp, "%s", sql_texte) < 0)) {
785 logmsg("error: write header of report SMS failed\n");
786 fclose (fp);
787 EXEC SQL WHENEVER SQLERROR DO return (sql_log_error (STAT_ERROR, "cannot close t_sms_flux_cursor cursor"));
788 if(sms_default_line == NO_LINE) {
789 EXEC SQL CLOSE t_sms_flux_cursor_1;
790 } else if (sms_line != sms_default_line) {
791 EXEC SQL CLOSE t_sms_flux_cursor_2;
792 } else {
793 EXEC SQL CLOSE t_sms_flux_cursor_3;
794 }
795 utlUpdateLog (0, 1); /* fail */
796 return STAT_ERROR;
797 }
798
799 fflush (fp);
800 fclose (fp);
801
802 if (rename (tmp_file, file_name)) {
803 logmsg("error: cannot rename [%s] to [%s]\n", tmp_file, file_name);
804 EXEC SQL WHENEVER SQLERROR DO return (sql_log_error (STAT_ERROR, "cannot close t_sms_flux_cursor cursor"));
805 if(sms_default_line == NO_LINE) {
806 EXEC SQL CLOSE t_sms_flux_cursor_1;
807 } else if (sms_line != sms_default_line) {
808 EXEC SQL CLOSE t_sms_flux_cursor_2;
809 } else {
810 EXEC SQL CLOSE t_sms_flux_cursor_3;
811 }
812 utlUpdateLog (0, 1); /* fail */
813 return STAT_ERROR;
814 }
815
816 logmsg("SMS %s sent to spool\n", file_name);
817
818 EXEC SQL WHENEVER SQLERROR DO return (sql_log_error (STAT_ERROR, "cannot update etat to ENC"));
819 EXEC SQL WHENEVER NOT FOUND continue;
820 EXEC SQL UPDATE t_sms_flux SET etat = 'ENC' WHERE refsms = :sql_refsms;
821
822 EXEC SQL WHENEVER SQLERROR DO return (sql_log_error (STAT_ERROR, "cannot update t_elements"));
823 EXEC SQL WHENEVER NOT FOUND continue;
824 EXEC SQL UPDATE t_elements
825 SET LIBELLE = 'SMS - EMISSION EN COURS ' || TO_CHAR (SYSDATE, 'DD/MM/YYYY HH24:MI')
826 WHERE typeelem='sm' AND refelem=:sql_refsms;
827
828 utlUpdateLog (1, 0); /* ok */
829
830 logmsg("SMS %s done\n", sql_refsms);
831 } /* End of Fetch Loop */
832
833 EXEC SQL WHENEVER SQLERROR DO return (sql_log_error (STAT_ERROR, "cannot close t_sms_flux_cursor cursor"));
834 if(sms_default_line == NO_LINE) {
835 EXEC SQL CLOSE t_sms_flux_cursor_1;
836 } else if (sms_line != sms_default_line) {
837 EXEC SQL CLOSE t_sms_flux_cursor_2;
838 } else {
839 EXEC SQL CLOSE t_sms_flux_cursor_3;
840 }
841
842 log_msg (LOG_INFO, "flux session done\n");
843 return SUCCESS;
844}
845/********************************************************************************
846 Function: set_sms_stat
847 In: file name with SMS message
848 Out: STAT_OK on success
849 STAT_NOTFOUND on not found
850 STAT_ERROR on fail
851Description: Set the SMS status
852********************************************************************************/
853static int set_sms_stat (char *ref_sms, char *etat)
854{
855 EXEC SQL BEGIN DECLARE SECTION;
856 SQL40 sql_refsms;
857 SQL120 sql_etat;
858 EXEC SQL END DECLARE SECTION;
859
860 logmsg("set SMS status: [%s] [%s]\n", ref_sms, etat);
861
862 strcpy (sql_refsms, ref_sms);
863 strcpy (sql_etat, etat);
864
865 EXEC SQL WHENEVER SQLERROR DO return (sql_log_error (STAT_ERROR, "cannot set SMS stat"));
866 EXEC SQL WHENEVER NOT FOUND DO return (sql_log_error (STAT_NOTFOUND, "not found error when set SMS stat"));
867 EXEC SQL UPDATE t_sms_flux
868 SET etat = :sql_etat, dtfin = SYSDATE
869 WHERE refsms = :sql_refsms;
870
871 if (!strcmp(etat, VD_ABREV_TRT)) { /*OK*/
872 EXEC SQL WHENEVER SQLERROR DO return (sql_log_error (STAT_ERROR, "cannot update t_elements"));
873 EXEC SQL WHENEVER NOT FOUND continue;
874 EXEC SQL UPDATE t_elements
875 SET LIBELLE = 'SMS EMIS LE ' || TO_CHAR (SYSDATE, 'DD/MM/YYYY HH24:MI')
876 WHERE typeelem='sm' AND refelem=:sql_refsms;
877 } else if ( !strcmp(etat, VD_ABREV_EPL) || !strcmp(etat, VD_ABREV_EPR)) { /*KO*/
878 EXEC SQL WHENEVER SQLERROR DO return (sql_log_error (STAT_ERROR, "cannot update t_elements"));
879 EXEC SQL WHENEVER NOT FOUND continue;
880 EXEC SQL UPDATE t_elements
881 SET LIBELLE = 'SMS - PROBLEME EMISSION ' || TO_CHAR (SYSDATE, 'DD/MM/YYYY HH24:MI')
882 WHERE typeelem='sm' AND refelem=:sql_refsms;
883 }
884
885 logmsg("update stat done\n", sql_refsms);
886
887
888 if ( (strcmp(sql_etat, VD_ABREV_EPL) == 0) ||
889 (strcmp(sql_etat, VD_ABREV_TRT) == 0) ||
890 (strcmp(sql_etat, VD_ABREV_EPR) == 0) ) {
891 return (archive_flux(ref_sms));
892 }
893
894 return STAT_OK;
895}
896/********************************************************************************
897 Function: archive_flux
898 In: ID SMS
899 Out: STAT_OK on success
900 STAT_NOTFOUND on not found
901 STAT_ERROR on fail
902Description: archive SMS
903********************************************************************************/
904static int archive_flux(char *ref_sms)
905{
906 EXEC SQL BEGIN DECLARE SECTION;
907 SQL40 sql_refsms;
908 EXEC SQL END DECLARE SECTION;
909
910 EXEC SQL WHENEVER SQLERROR DO return (sql_log_error(STAT_ERROR, "cannot insert data in t_sms_sauv"));
911 EXEC SQL WHENEVER NOT FOUND DO return (sql_log_error (STAT_NOTFOUND, "not found error when archive SMS"));
912
913 strcpy(sql_refsms, ref_sms);
914
915 EXEC SQL INSERT INTO t_sms_sauv(SELECT * FROM t_sms_flux WHERE refsms = :sql_refsms);
916
917 logmsg("archive SMS\n", sql_refsms);
918
919 EXEC SQL WHENEVER SQLERROR DO return (sql_log_error(STAT_ERROR, "cannot delete data from t_sms_flux"));
920 EXEC SQL WHENEVER NOT FOUND DO return (sql_log_error (STAT_NOTFOUND, "not found error when delete SMS"));
921 EXEC SQL DELETE FROM t_sms_flux WHERE refsms = :sql_refsms;
922
923 logmsg("delete SMS\n", sql_refsms);
924
925 return STAT_OK;
926}
927/********************************************************************************
928 Function: parse_snd_message
929 In: file name with SMS message
930 Out: STAT_OK on success
931 STAT_NOTFOUND on not found
932 STAT_ERROR on fail
933Description: Parse a SMS file
934********************************************************************************/
935static int parse_stat (char *file_name)
936{
937 int res = 0;
938 FILE *fp;
939 char sms_ref[MAX_SMS_DATA], sms_idx[MAX_SMS_DATA], sms_sfn[MAX_SMS_DATA];
940 char sms_tms[MAX_SMS_DATA], sms_tms2[MAX_SMS_DATA], sms_rep[MAX_SMS_DATA];
941
942 logmsg("parse SMS file %s\n", file_name);
943
944 memset (sms_ref, sizeof (sms_ref), '\0');
945 memset (sms_idx, sizeof (sms_idx), '\0');
946 memset (sms_sfn, sizeof (sms_sfn), '\0');
947 memset (sms_tms, sizeof (sms_tms), '\0');
948 memset (sms_tms2, sizeof (sms_tms2), '\0');
949 memset (sms_rep, sizeof (sms_rep), '\0');
950
951 if (!(fp = fopen (file_name, "r"))) {
952 logmsg("error: cannot open stat file %s\n", file_name);
953 return STAT_NOTFOUND;
954 }
955
956 res = fscanf (fp, "REF: %s\nIDX: %s\nSFN: %s\nTMS: %s %s\nREP: %s", sms_ref, sms_idx, sms_sfn, sms_tms, sms_tms2, sms_rep);
957
958 if (res != 6 || !strlen (sms_ref) || !strlen (sms_idx) || !strlen (sms_sfn)
959 || !strlen (sms_tms) || !strlen (sms_tms2) || !strlen (sms_rep)) {
960 logmsg("error: invalid file format\n");
961 fclose (fp);
962 return STAT_NOTFOUND;
963 }
964
965 fclose (fp);
966
967 strcpy (sms_tms, " ");
968 strcpy (sms_tms, sms_tms2);
969
970 logmsg("sms_ref: [%s]\n", sms_ref);
971 logmsg("sms_idx: [%s]\n", sms_idx);
972 logmsg("sms_sfn: [%s]\n", sms_sfn);
973 logmsg("sms_tms: [%s]\n", sms_tms);
974 logmsg("sms_rep: [%s]\n", sms_rep);
975
976 if (!strcmp (sms_rep, SMS_STAT_SENT)) {
977 return set_sms_stat (sms_ref, VD_ABREV_ATR);
978 } else if (!strcmp (sms_rep, SMS_STAT_DELIVERED)) {
979 return set_sms_stat (sms_ref, VD_ABREV_TRT);
980 } else if (!strncmp (sms_rep, SMS_STAT_SEND_FAILED, strlen (SMS_STAT_SEND_FAILED))) {
981 return set_sms_stat (sms_ref, VD_ABREV_EPL);
982 } else if (!strncmp (sms_rep, SMS_STAT_NOT_DELIVERED, strlen (SMS_STAT_NOT_DELIVERED))) {
983 return set_sms_stat (sms_ref, VD_ABREV_EPR);
984 } else if (!strcmp (sms_rep, SMS_STAT_RECEIVED)) {
985 return STAT_OK;
986 }
987
988 return set_sms_stat (sms_ref, VD_ABREV_EPR);
989 logmsg("error: unknown status\n");
990 return STAT_NOTFOUND;
991}
992/********************************************************************************
993 Function: process_spool
994 In: (no arguments)
995 Out: STAT_NOTFOUND on not found
996 STAT_ERROR on fail
997Description: Process the fax queue
998********************************************************************************/
999static int process_spool (int line)
1000{
1001 int num_entries, i, ret = STAT_OK;
1002 struct dirent **namelist, **list;
1003 char file_stat[PATH_MAX + 1], file_done[PATH_MAX + 1];
1004
1005 logmsg("process_flux\n");
1006
1007 if ((num_entries = scandir(dir_stat, &namelist, NULL, alphasort)) < 0) {
1008 logmsg("cannot open directory %s\n", dir_outgoing);
1009 return STAT_OK;
1010 /*return FALSE;*/
1011 }
1012
1013 logmsg("number of dir entries is %d \n", num_entries);
1014
1015 if (num_entries > 2) { /* Memory Leak */
1016 for (i = 0, list = namelist; i < num_entries; i++) {
1017 if (strcmp ((*list)->d_name, ".") && strcmp ((*list)->d_name, "..")) {
1018 sprintf (file_stat, "%s/%s", dir_stat, (*list)->d_name);
1019 logmsg("process stat: %s\n", file_stat);
1020
1021 if (parse_stat (file_stat) == STAT_OK) {
1022 logmsg("STAT reported\n");
1023 sprintf (file_done, "%s/%s.OK", dir_done, (*list)->d_name);
1024 } else {
1025 logmsg("error: cannot report stat\n");
1026 sprintf (file_done, "%s/%s.KO", dir_done, (*list)->d_name);
1027 /* ret = STAT_ERROR; */
1028 }
1029
1030 logmsg("done as: %s\n", file_done);
1031
1032 if (rename (file_stat, file_done)) {
1033 logmsg("error: cannot rename [%s] to [%s]\n", file_stat, file_done);
1034 ret = STAT_ERROR;
1035 }
1036 }
1037
1038 free(*list);
1039 *list++;
1040 }
1041
1042 do_commit ();
1043 free(namelist);
1044 }
1045
1046 logmsg("send sms session done with res: %d\n", ret);
1047
1048 return ret;
1049}
1050
1051/********************************************************************************
1052 Function: get default email from $IMX_CLT/config/MailAliases.txt
1053 In: mail_receipt_def
1054 Out: mail_receipt_def, STAT_OK
1055Description: Used by Process the incomming SMS queue
1056********************************************************************************/
1057static int get_mail_def(char *mail_receipt_def)/*dead code!*/
1058{
1059 char mail_conf_name[256], *cp1, buf1[256];
1060 FILE *fp;
1061
1062 sprintf (mail_conf_name, "%s/config/MailAliases.txt", getenv("IMX_CLT"));
1063
1064 if (!(fp = fopen(mail_conf_name, "r"))) {
1065 logmsg("\nCan't open MailAliases.txt");
1066 } else {
1067 fgets(buf1, 256, fp);
1068 cp1 = strstr(buf1, ":");
1069 if (cp1) {
1070 sscanf(cp1, ":%s", mail_receipt_def);
1071 }
1072
1073 fflush(fp);
1074 fclose(fp);
1075
1076 }
1077
1078 logmsg("DEF MAIL=%s\n", mail_receipt_def);
1079 return STAT_OK;
1080}
1081
1082/********************************************************************************
1083 Function: move_weird_file
1084 In: Croupted file
1085 Out: TRUE on success
1086 FALSE on fail
1087Description: Move corrupted SMS file to failed directory
1088********************************************************************************/
1089static int move_weird_file(char *src_file)
1090{
1091 char *ptr, tmpf[PATH_MAX + 1];
1092
1093 ptr = strrchr(src_file, '/');
1094 if (ptr == NULL) {
1095 ptr = src_file;
1096 } else {
1097 ptr++;
1098 }
1099
1100 if (!*ptr) {
1101 logmsg("Weird a?\n");
1102 return FALSE;
1103 }
1104
1105 snprintf(tmpf, PATH_MAX, "%s.XXXXXXXX", ptr);
1106 ptr = tempnam(dir_failed, tmpf);
1107 if (ptr == NULL) {
1108 logmsg("cannot generate temporary file name for [%s]: [%d] : [%s]\n", src_file, errno, strerror(errno));
1109 return FALSE;
1110 }
1111
1112 if (access(ptr, F_OK) == 0) {
1113 logmsg("generated unique file name [%s] already exists!!!\n", ptr);
1114 free(ptr);
1115 return FALSE;
1116 }
1117
1118 logmsg("moving [%s] => [%s]\n", src_file, ptr);
1119
1120 if (rename (src_file, ptr)) {
1121 logmsg("error: cannot rename [%s] to [%s] : [%d] : [%s]\n", src_file, ptr, errno, strerror(errno));
1122 free(ptr);
1123 return FALSE;
1124 }
1125
1126 free(ptr);
1127
1128 return TRUE;
1129}
1130
1131
1132static char encoding_table[] = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
1133 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
1134 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
1135 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
1136 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
1137 'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
1138 'w', 'x', 'y', 'z', '0', '1', '2', '3',
1139 '4', '5', '6', '7', '8', '9', '+', '/'};
1140static char *decoding_table = NULL;
1141static int mod_table[] = {0, 2, 1};
1142
1143
1144static char *base64_encode(const char *data, size_t input_length, size_t *output_length)
1145{
1146 int i, j;
1147 char *encoded_data;
1148
1149 logmsg("Try to alloc [%d] memory\n", input_length);
1150 *output_length = 4 * input_length;
1151 logmsg("Try to alloc [%d] memory\n", *output_length);
1152 if ((encoded_data = calloc(*output_length, 3)) == NULL) {
1153 logmsg("Failed to alloc [%d] memory\n", *output_length);
1154 return NULL;
1155 }
1156
1157 for (i = 0, j = 0; i < input_length;) {
1158
1159 uint32_t octet_a = i < input_length ? data[i++] : 0;
1160 uint32_t octet_b = i < input_length ? data[i++] : 0;
1161 uint32_t octet_c = i < input_length ? data[i++] : 0;
1162
1163 uint32_t triple = (octet_a << 0x10) + (octet_b << 0x08) + octet_c;
1164
1165 encoded_data[j++] = encoding_table[(triple >> 3 * 6) & 0x3F];
1166 encoded_data[j++] = encoding_table[(triple >> 2 * 6) & 0x3F];
1167 encoded_data[j++] = encoding_table[(triple >> 1 * 6) & 0x3F];
1168 encoded_data[j++] = encoding_table[(triple >> 0 * 6) & 0x3F];
1169 }
1170
1171 for (i = 0; i < mod_table[input_length % 3]; i++) {
1172 encoded_data[*output_length - 1 - i] = '=';
1173 }
1174 encoded_data[*output_length - 1 - i] = 0;
1175
1176 return encoded_data;
1177}
1178
1179
1180
1181/**
1182 ** Convert USC2 character to UTF8
1183 **
1184 ** @param usc2 The character in USC2(UTF-16 - modern)
1185 ** @param utf8 Memory to hold the UTF8 representation - minimum 6 bytes
1186 **
1187 ** @retval Number of bytes written, on success
1188 ** @retval -1 if error.
1189 **
1190 ** @remark This works as a conversion from UCS-2 or UTF-16 for most code points,
1191 ** but does not deal with the code points from U+D7FF to U+DFFF or those
1192 ** above U+FFFF.
1193 **/
1194static int ucs2_to_utf8 (uint16_t ucs2, uint8_t *utf8)
1195{
1196 if (ucs2 < 0x80) {
1197 utf8[0] = ucs2;
1198 return 1;
1199 }
1200 if (ucs2 >= 0x80 && ucs2 < 0x800) {
1201 utf8[0] = (ucs2 >> 6) | 0xC0;
1202 utf8[1] = (ucs2 & 0x3F) | 0x80;
1203 return 2;
1204 }
1205 if (ucs2 >= 0x800 && ucs2 < 0xFFFF) {
1206 utf8[0] = ((ucs2 >> 12) ) | 0xE0;
1207 utf8[1] = ((ucs2 >> 6 ) & 0x3F) | 0x80;
1208 utf8[2] = ((ucs2 ) & 0x3F) | 0x80;
1209 return 3;
1210 }
1211 return -1;
1212}
1213
1214/**
1215 ** Convert a USC2 message to UTF8 message
1216 ** The source message representation is ascii coded USC2 characters (4 bytes each)
1217 **
1218 ** @param src Source message
1219 ** @param dst Destination message. Minimum size should be 6 * strlen(src)/4 + 1
1220 **
1221 ** @retval size of the message in UTF8
1222 ** @retval -1 on error (invalid symbol
1223 **/
1224static int msg_from_usc2(const char *src, char *dst)
1225{
1226 char tmp[5], utf8[7];
1227 uint16_t ucs2;
1228 int sz, len = 0;
1229
1230 while (*src) {
1231
1232 memcpy(tmp, src, 4);
1233 tmp[4] = 0;
1234 ucs2 = strtoul(tmp, NULL, 16);
1235 if ((sz = ucs2_to_utf8(ucs2, utf8)) == -1) {
1236 return -1;
1237 }
1238 memcpy(dst, utf8, sz); /* Not optimal!!! */
1239 dst += sz;
1240 len += sz; /* No negatives here, so it is OK */
1241 src += 4;
1242 }
1243
1244 *dst = 0;
1245
1246 return len;
1247}
1248
1249
1250/**
1251 ** Fuzzy and incorrect detection of UISC16 symbols message
1252 **/
1253static int is_ucs2(const char *src, size_t len)
1254{
1255 int flag = 0;
1256 size_t i;
1257
1258 assert(src);
1259
1260 logmsg("is_ucs2 checking messages [%s] with length: [%d]!\n", src, len);
1261
1262 if (len > 2) {
1263 if (src[len - 1] == '\n' && src[len - 2] != '\n') {
1264 len--;
1265 }
1266 }
1267
1268 if (len == 0 || len % 4 != 0) {
1269 logmsg("is_ucs2 failed on length: [%d]!\n", len);
1270 return 0;
1271 }
1272
1273 for (i = 0; i < len - 1; i++) {
1274 if (!isxdigit(src[i])) {
1275 logmsg("is_ucs2 failed on isxdigit!\n");
1276 return 0;
1277 }
1278 if (src[i] > '9') {
1279 flag++;
1280 }
1281 }
1282
1283 return flag > 0 ? 1 : 0;
1284}
1285
1286
1287static int exec_pclose_status(FILE *pf)
1288{
1289 int status;
1290
1291 do
1292 {
1293 status = pclose(pf);
1294
1295 if (status == -1)
1296 {
1297 logmsg("Could not pclose child!!!\n");
1298 return -1;
1299 }
1300
1301 if (WIFEXITED(status))
1302 {
1303 logmsg("child exited, status=%d\n", WEXITSTATUS(status));
1304 }
1305 else if (WIFSIGNALED(status))
1306 {
1307 logmsg("child killed (signal %d)\n", WTERMSIG(status));
1308 }
1309 else if (WIFSTOPPED(status))
1310 {
1311 logmsg("child stopped (signal %d)\n", WSTOPSIG(status));
1312#ifdef WIFCONTINUED /* Not all implementations support this - opengroup.org */
1313 }
1314 else if (WIFCONTINUED(status))
1315 {
1316 logmsg("child continued\n");
1317#endif
1318 }
1319 else /* Non-standard case -- may never happen */
1320 {
1321 logmsg("Unexpected status (0x%x)\n", status);
1322 }
1323 }
1324 while (!WIFEXITED(status) && !WIFSIGNALED(status));
1325
1326 return status == 0 ? 0 : -1;
1327}
1328
1329
1330static int sendmail_send(const char *sql_mail_receipt, const char *mail_subj, const char *message)
1331{
1332 const char *command = "/usr/sbin/sendmail -v -t 2>&1 > /dev/null";
1333 char *buff, *b64, *ubuff;
1334 int sz = 0;
1335 size_t len64;
1336 FILE *pf;
1337
1338
1339 buff = calloc(655350, 1);
1340 ubuff = calloc(655350, 1);
1341 msg_from_usc2(message, ubuff);
1342 sz = strlen(ubuff);
1343 logmsg("utf8 message: [%d]\n", sz);
1344 if ((b64 = base64_encode(ubuff, sz, &len64)) == NULL) {
1345 return -1;
1346 }
1347 b64[len64] = 0;
1348 free(ubuff);
1349
1350 logmsg("base64 message: [%d] -> [%s]\n", len64, b64);
1351
1352 sz = 0;
1353 sz += sprintf(buff + sz, "Subject: %s\r\n", mail_subj);
1354 sz += sprintf(buff + sz, "Importance: normal\r\n");
1355 sz += sprintf(buff + sz, "X-Priority: 1\r\n");
1356 sz += sprintf(buff + sz, "X-MSMail-Priority: High\r\n");
1357 /* sz += sprintf(buff + sz, "From: %s\r\n"); */
1358 sz += sprintf(buff + sz, "To: %s\r\n", sql_mail_receipt);
1359 sz += sprintf(buff + sz, "MIME-Version: 1.0\r\n");
1360 sz += sprintf(buff + sz, "Return-Path: <>\r\n");
1361 sz += sprintf(buff + sz, "X-mailer: iMX SMS, %s, Build %s %s\r\n", texte_rcs_id, __DATE__, __TIME__);
1362 sz += sprintf(buff + sz, "Content-Type: multipart/alternative; boundary=047d7b874d1871eaa004c8dbf9fe\r\n");
1363 sz += sprintf(buff + sz, "\r\n");
1364 sz += sprintf(buff + sz, "--047d7b874d1871eaa004c8dbf9fe\r\n");
1365 sz += sprintf(buff + sz, "Content-Type: text/plain; charset=UTF-8\r\n");
1366 sz += sprintf(buff + sz, "Content-Transfer-Encoding: base64\r\n");
1367 sz += sprintf(buff + sz, "\r\n");
1368 sz += sprintf(buff + sz, "%s\r\n", b64);
1369 sz += sprintf(buff + sz, "--047d7b874d1871eaa004c8dbf9fe\r\n");
1370 sz += sprintf(buff + sz, "Content-Type: text/html; charset=UTF-8\r\n");
1371 sz += sprintf(buff + sz, "Content-Transfer-Encoding: base64\r\n");
1372 sz += sprintf(buff + sz, "\r\n");
1373 sz += sprintf(buff + sz, "%s\r\n", b64);
1374 sz += sprintf(buff + sz, "--047d7b874d1871eaa004c8dbf9fe--\r\n");
1375
1376 free(b64);
1377
1378 logmsg("SMTP: [%s]\n", buff);
1379
1380 if ((pf = popen(command, "w")) == NULL)
1381 {
1382 logmsg("Cannot spawn sendmail : [%s]!!\n", strerror(errno));
1383 free(buff);
1384 return;
1385 }
1386
1387
1388 /* End of SMTP protocol */
1389 fprintf(pf, "%s\r\n.\r\n", buff);
1390
1391 fflush(pf);
1392
1393 exec_pclose_status(pf);
1394
1395 logmsg("SMTP session over\n", buff);
1396
1397 free(buff);
1398
1399 return 0;
1400}
1401/********************************************************************************
1402 Function: process_incomming
1403 In: (no arguments)
1404 Out: STAT_ERROR on fail
1405Description: Process the incomming SMS queue
1406********************************************************************************/
1407static int process_incoming(int line)
1408{
1409 int num_entries, i, res, ucs2_flag = 0;
1410 char full_file[PATH_MAX + 1], file_done[PATH_MAX + 1], sms_idx[5], sms_tmr[15], sms_tmr2[15];
1411 char cmd[1024], mail_subj[1024], mail_text[1024];
1412 struct dirent **namelist, **list;
1413 FILE *fp;
1414 int iDossCount;
1415 char Doss[11];
1416 EXEC SQL BEGIN DECLARE SECTION;
1417 SQL40 sql_refsms, sql_numero;
1418 SQL300 sql_texte, sql_mail_receipt;
1419 VARCHAR lib_doss[40];
1420 VARCHAR lib_interne[40];
1421 EXEC SQL END DECLARE SECTION;
1422 logmsg("process incoming session\n");
1423
1424 /*get_mail_def(mail_receipt_def);*/
1425
1426 EXEC SQL WHENEVER SQLERROR DO return (sql_log_error (STAT_ERROR, "cannot select from t_ligne_sms"));
1427 EXEC SQL WHENEVER NOT FOUND DO strcpy(sql_mail_receipt,'\0');
1428 EXEC SQL SELECT nom
1429 INTO :sql_mail_receipt
1430 FROM t_sms_ligne
1431 WHERE ligne = 10
1432 AND nom IS NOT NULL;
1433 if ((num_entries = scandir(dir_incoming, &namelist, NULL, alphasort)) < 0) {
1434 logmsg("cannot open directory %s\n", dir_incoming);
1435 /*return STAT_ERROR;*/
1436 return STAT_OK;
1437 }
1438 logmsg("number of dir entries is %d\n", num_entries);
1439 if (num_entries > 2) {
1440 for (i = 0, list = namelist; i < num_entries; i++) {
1441 if (strcmp ((*list)->d_name, ".") && strcmp ((*list)->d_name, "..")) {
1442 logmsg("process SMS: %s\n", (*list)->d_name);
1443 EXEC SQL DECLARE conf_curs CURSOR for
1444 SELECT UPPER(libdossier), UPPER (libinterne)
1445 FROM t_mail_general
1446 WHERE libdossier IS NOT NULL AND ROWNUM < 2;
1447 EXEC SQL WHENEVER SQLERROR DO return (sql_log_error (STAT_ERROR, "cannot open conf_curs\n"));
1448 EXEC SQL OPEN conf_curs;
1449 EXEC SQL WHENEVER SQLERROR DO return (sql_log_error (STAT_ERROR, "cannot fetch from conf_curs\n"));
1450 EXEC SQL WHENEVER NOT FOUND GOTO END_CONF_CUR; /*logmsg("Warning no parameters not found!!!\n");*/
1451 for (;;) {
1452 EXEC SQL FETCH conf_curs
1453 INTO :lib_doss, :lib_interne;
1454 lib_doss.arr[lib_doss.len] = (char) 0;
1455 lib_interne.arr[lib_interne.len] = (char) 0;
1456 }
1457END_CONF_CUR:
1458 EXEC SQL CLOSE conf_curs;
1459 logmsg("Key words extracted from the DB. libdossier:[%s], libinterne:[%s]\n", lib_doss.arr, lib_interne.arr);
1460 sprintf (full_file, "%s/%s", dir_incoming, (*list)->d_name);
1461 sprintf(file_done, "%s/%s.mailed", dir_done, (*list)->d_name);
1462 logmsg("Incoming process: full_file=%s file_done=%s\n", full_file, file_done);
1463
1464 /* If we cannot open the file - report it and continue */
1465 if (!(fp = fopen (full_file, "r"))) {
1466 logmsg("error: cannot open SMS file %s\n", full_file);
1467 continue;
1468 }
1469 res = fscanf (fp, "IDX: %s\nNUM: %s\nTMR: %s %s\n", sms_idx, sql_numero, sms_tmr, sms_tmr2);
1470 if (res != 4 || !strlen (sms_idx) || !strlen (sql_numero) || !strlen (sms_tmr) || !strlen (sms_tmr2)) {
1471 logmsg("error: invalid file format\n");
1472 fclose (fp);
1473 move_weird_file(full_file);
1474 continue;
1475 }
1476 res = fread(mail_text, 1, 1023, fp);
1477 if (!res) {
1478 logmsg("no received SMS text \n");
1479 /*return STAT_ERROR;*/ /*It is just an enter. not an error*/
1480 }
1481 mail_text[res] = 0;
1482
1483 /* check if we have a weird USC16 message text from the daemon */
1484 logmsg("SMS txte: [%d] -> [%s]\n", res, mail_text);
1485 ucs2_flag = is_ucs2(mail_text, res);
1486
1487 /* otl_newref("SMS", sql_refsms);
1488 */
1489 logmsg("IDX: [%s]\n", sms_idx);
1490 logmsg("num: [%s]\n", sql_numero);
1491 logmsg("tmr: [%s]\n", sms_tmr);
1492 logmsg("tmr2: [%s]\n", sms_tmr2);
1493 logmsg("SMS txte: [%s]\n", mail_text);
1494
1495 if (strcmp(sql_mail_receipt, "\0") == 0) { /*not found email in line 10 => search the email into dossiers*/
1496 iDossCount = get_mail_addr(sql_numero, sql_mail_receipt, Doss);
1497 logmsg("Sending to mail:[%s], DossCount:[%d], RefDoss:[%s]\n", sql_mail_receipt, iDossCount, Doss);
1498 } else {
1499 iDossCount = 0; /*found email in line 10 => DO NOT search into dossiers*/
1500 }
1501 if (iDossCount == 1) {
1502 sprintf(mail_subj, "\"SMS de %s, %s %s %s\"", sql_numero, lib_doss.arr, lib_interne.arr, Doss);
1503 } else {
1504 if (strlen(sql_mail_receipt) > 0) {
1505 sprintf(mail_subj, "\"SMS de %s\"", sql_numero);
1506 }
1507 }
1508
1509 if (strlen(sql_mail_receipt) > 0) { /*we have a valid mail from line 10 or dossier*/
1510
1511 if (ucs2_flag) {
1512 logmsg("UCS2 message detected.\n");
1513 logmsg("Subject: [%s]\n", mail_subj);
1514 logmsg("Recpt: [%s]\n", sql_mail_receipt);
1515 logmsg("Body: [%s]\n", mail_text);
1516 sendmail_send(sql_mail_receipt, mail_subj, mail_text);
1517 }
1518 else {
1519 sprintf(cmd, "mail -s %s \"%s\" < \"%s\"", mail_subj, sql_mail_receipt, full_file);
1520 logmsg("\nCMD=%s\n", cmd);
1521 system(cmd);
1522 }
1523 }
1524 if (rename (full_file, file_done)) {
1525 logmsg("error: cannot rename [%s] to [%s]\n", full_file, file_done);
1526 }
1527 }
1528 free(*list);
1529 *list++;
1530 }
1531 free(namelist);
1532 }
1533 logmsg("process incoming sms session done\n");
1534 return STAT_OK;
1535}
1536
1537/********************************************************************************
1538 Function: sms_queue
1539 In: (no arguments)
1540 Out: STAT_NOTFOUND on not found
1541 STAT_ERROR on fail
1542Description: Process the fax queue
1543********************************************************************************/
1544static int sms_queue (void)
1545{
1546
1547 for (;; ) {
1548 if (process_flux () == STAT_ERROR) {
1549 do_rollback ();
1550 logmsg("SMS flux error\n");
1551 return STAT_ERROR;
1552 }
1553
1554 do_quiet_commit ();
1555
1556 if (process_incoming (sms_line) == STAT_ERROR) {
1557 logmsg("SMS incoming error\n");
1558 return STAT_ERROR;
1559 }
1560
1561 do_quiet_commit ();
1562
1563 if (process_spool (sms_line) == STAT_ERROR) {
1564 logmsg("SMS spool error\n");
1565 return STAT_ERROR;
1566 }
1567
1568 sleep (3);
1569 }
1570}
1571/********************************************************************************
1572 Function: get_mail_addr
1573 In: phone number
1574 Out: e-mail address
1575Description: gets the e-mail address of a manager responsable for this file
1576********************************************************************************/
1577static int get_mail_addr(char *tel, char *mail_addr, char *RefDoss)
1578{
1579 int i;
1580
1581 EXEC SQL BEGIN DECLARE SECTION;
1582 VARCHAR sql_email[81], sql_RefDoss[11];
1583 char sql_tel1[41], sql_tel2[41];
1584 int sql_rangmt;
1585 int sql_DossCount;
1586 EXEC SQL END DECLARE SECTION;
1587
1588 i = 0;
1589 sql_rangmt = 0;
1590
1591 logmsg("get_mail_addr in params. Tel:[%s], Addr:[%s]\n", tel, mail_addr);
1592
1593 sql_tel1[0] = '\0';
1594 sql_tel2[0] = '\0';
1595 sql_email.arr[0] = (char) 0;
1596 sql_email.len = 0;
1597 sql_RefDoss.arr[0] = (char) 0;
1598 sql_RefDoss.len = 0;
1599
1600 if (strlen(tel) == 0) {
1601 logmsg("Telephone number is empty. Returning default address\n");
1602 return 1;
1603 } else {
1604 if (check_phone_prefix(tel, sql_tel1, sql_tel2) != 0) {
1605 strcpy(sql_tel1, "0");
1606 strcat(sql_tel1, tel);
1607 strcpy(sql_tel2, tel);
1608 }
1609 logmsg("Checking for numbers: [%s],[%s] in DB\n", sql_tel1, sql_tel2);
1610 }
1611
1612 EXEC SQL DECLARE mail_cursor CURSOR for
1613 SELECT rangmt, gp.email, COUNT(DISTINCT(gd.refdoss))
1614 FROM t_intervenants ti, g_dossier gd, vv_tels vt, g_personnel gp
1615 WHERE ti.refdoss = gd.refdoss
1616 AND vt.refindividu = ti.refindividu
1617 AND gd.rangmt = gp.refperso
1618 AND ((tel = :sql_tel1) OR (tel = :sql_tel2))
1619 GROUP BY rangmt, email;
1620
1621 EXEC SQL WHENEVER SQLERROR DO return (sql_log_error (STAT_ERROR, "cannot open cursor mail_cursor"));
1622 EXEC SQL WHENEVER NOT FOUND DO logmsg("Phone number unknown.");
1623
1624 EXEC SQL OPEN mail_cursor;
1625
1626 EXEC SQL WHENEVER SQLERROR DO return (sql_log_error (STAT_ERROR, "cannot fetch from mail_cursor cursor"));
1627 EXEC SQL WHENEVER NOT FOUND DO break;
1628
1629 for (;;) {
1630 EXEC SQL FETCH mail_cursor
1631 INTO :sql_rangmt, :sql_email, :sql_DossCount;
1632
1633 sql_email.arr[sql_email.len] = (char)0;
1634 logmsg("Iteration %d : Found. rangmt:[%d], email:[%s], RefdossCount:[%d]\n", i, sql_rangmt, sql_email.arr, sql_DossCount);
1635
1636 i++;
1637
1638 if (i > 1) {
1639 logmsg("More then one gestionaire for this number. Sending to default.\n");
1640 return 0;
1641 }
1642 }
1643
1644 if (i == 0) {
1645 logmsg("Number unknown to DB\n");
1646 return 0;
1647 } else {
1648 if (sql_DossCount == 1) {
1649 logmsg("Mono Dossier Found. Select refdoss.\n");
1650
1651 EXEC SQL WHENEVER SQLERROR DO return (sql_log_error (STAT_ERROR, "Error selecting refdoss."));
1652 EXEC SQL WHENEVER NOT FOUND DO logmsg("No refdoss found.\n");
1653
1654 EXEC SQL SELECT DISTINCT(gd.refdoss)
1655 INTO :sql_RefDoss
1656 FROM t_intervenants ti, g_dossier gd, vv_tels vt
1657 WHERE ti.refdoss = gd.refdoss
1658 AND vt.refindividu = ti.refindividu
1659 AND ((tel = :sql_tel1) OR (tel = :sql_tel2));
1660
1661 sql_RefDoss.arr[sql_RefDoss.len] = (char)0;
1662
1663 logmsg("Found refdoss:[%s]\n", sql_RefDoss.arr);
1664 }
1665
1666 if (sql_email.len > 0) {
1667 if (sql_DossCount == 1) {
1668 strcpy(RefDoss, sql_RefDoss.arr);
1669 strcpy(mail_addr, sql_email.arr);
1670 logmsg("Mail found: [%s]. Refdoss [%s]\n", sql_email.arr, RefDoss);
1671 return 1;
1672 } else {
1673 strcpy(mail_addr, sql_email.arr);
1674 logmsg("Mail found: [%s].\n", sql_email.arr);
1675 return 0;
1676 }
1677 } else {
1678 logmsg("e-mail not set in DB for rangmt = [%d]\n", sql_rangmt);
1679 }
1680 }
1681
1682
1683 return 0;
1684}
1685
1686/** \brief Fix Country Code.
1687 * \param [in] tel - Original number.
1688 * \param [out] tel1 - Number w/o country code.
1689 * \param [out] tel2 - Number with country code starting with 00.
1690 * \retval 0 - If Country code is found
1691 * \retval 1 - If not found.
1692 *
1693 * Chek is phone start with +Country Code.
1694 * If yes sets tel1 and tel2.
1695 ********************************************************************************/
1696static int check_phone_prefix(char *tel, char *tel1, char *tel2)
1697{
1698 int i = 0;
1699
1700 while (strcmp(phone_prefix[i], "000") != 0) {
1701 if (strncmp(tel, phone_prefix[i], strlen(phone_prefix[i])) == 0) {
1702 logmsg("Prefix found: <%s>\n", phone_prefix[i]);
1703
1704 strcpy(tel1, "0");
1705 strcat(tel1, tel + strlen(phone_prefix[i]));
1706
1707 strcpy(tel2, "00");
1708 strcat(tel2, tel + 1);
1709
1710 return 0;
1711 }
1712 i++;
1713 }
1714
1715 return 1;
1716}
1717
1718
1719/********************************************************************************
1720 Function: main
1721 In: line
1722 Out: 1 - invalid number of arguents
1723 2 - cannot connect to db
1724 3 - init the environment failed
1725 4 - sql error occuered
1726Description: The startup point
1727********************************************************************************/
1728int main (int argc, char *argv[])
1729{
1730 if (argc > 1) {
1731 if ((sms_line = strtoul(argv[1], NULL, 10)) <= 0) {
1732 fprintf (stderr, "usage: %s invalid line number: %s\n", argv[0], argv[1]);
1733 return 1;
1734 }
1735 }
1736
1737 set_log_file_name();
1738 printf ("%s\n", log_file_name);
1739 logmsg("sms_queue version %s started at line %d\n", VERSION, sms_line);
1740
1741 ConnectOracle();
1742
1743 if (init_env() != STAT_OK) {
1744 DisconnectOracle();
1745 return 3;
1746 }
1747
1748 if (sms_line == -1) {
1749 fprintf(stderr, "SMS line not determined! Exiting!\n");
1750 return 3;
1751 }
1752
1753 signal(SIGQUIT, on_extit);
1754 signal(SIGINT , on_extit);
1755 signal(SIGKILL, on_extit);
1756
1757 utlInitLog ("sms_queue", "sms_queue");
1758
1759 /* only a sql error will break the loop */
1760 while (sms_queue () != STAT_ERROR) {
1761 logmsg("EXCEPTION:\n");
1762 do_rollback ();
1763 }
1764
1765 logmsg("sql error is occured\n");
1766
1767 signal(SIGQUIT, SIG_DFL);
1768 signal(SIGINT , SIG_DFL);
1769 signal(SIGKILL, SIG_DFL);
1770
1771 utlFinalizeLog ();
1772 DisconnectOracle();
1773
1774 return 4;
1775}
1776
1777/*@}*/
1778
1779/** \defgroup mod_sms SMS Processing.
1780 * \ingroup com_fsi*/
1781
1782/************************ Revision history logmsg*********************************
1783
1784 $Log: sms_queue.pc,v $
1785 Revision 1.24 2016/09/30 14:45:19 ninikolov
1786 TTS KEY*: CODIXDEV-2329
1787 FUNC CHANGES*: Add Logs in DB
1788 TECH CHANGES*: Add Logs in DB
1789 TESTS:
1790 DEPENDENCIES:
1791
1792 Revision 1.23 2015/05/14 09:12:58 ninikolov
1793
1794 TTS KEY*:
1795 FUNC CHANGES*:
1796 TECH CHANGES*:
1797 TESTS:
1798 DEPENDENCIES:
1799 Add issueing sms's by printer.
1800
1801 Revision 1.22 2014/11/25 14:59:42 ninikolov
1802 TTS KEY*:
1803 FUNC CHANGES*:ql_log_error
1804 TECH CHANGES*: int -> size_t
1805 TESTS:
1806 DEPENDENCIES:
1807
1808 Revision 1.21 2013/11/15 15:54:28 ninikolov
1809 TTS KEY*:
1810 FUNC CHANGES*:
1811 TECH CHANGES*: Set default SMS Size to 1024. Fetch texte with convert to UTF8.
1812 TESTS:
1813 DEPENDENCIES:
1814 SMS files must be in UTF-8 enconding.
1815
1816 Revision 1.20 2013/09/27 12:24:20 knikitov
1817 TTS KEY*: CGI-4313
1818 FUNC CHANGES*:
1819 TECH CHANGES*: Use functions ConnectOracle and DisconnectOracle to connect Oracle.
1820 TESTS: No
1821 DEPENDENCIES: No
1822
1823 Revision 1.19 2012/10/22 08:48:03 bkostov
1824 use unly the line which is passed as an argument; do not use ten lines;
1825
1826 Revision 1.18 2012/09/21 15:14:49 bkostov
1827 CLIENT:
1828 fix the incorrect forming of the subject of the email
1829
1830 Revision 1.17 2012/09/10 09:12:40 vmladenov
1831 UCS2 TPDU handling.
1832
1833
1834 ************************* Revision history logmsg********************************/