urltrans.c
上传用户:gzpyjq
上传日期:2013-01-31
资源大小:1852k
文件大小:30k
源码类别:

手机WAP编程

开发平台:

WINDOWS

  1. /*
  2.  * urltrans.c - URL translations
  3.  *
  4.  * Lars Wirzenius
  5.  */
  6. #include <ctype.h>
  7. #include <errno.h>
  8. #include <limits.h>
  9. #include <stdlib.h>
  10. #include <string.h>
  11. #include <time.h>
  12. #include "urltrans.h"
  13. #include "gwlib/gwlib.h"
  14. #include "gw/sms.h"
  15. /***********************************************************************
  16.  * Definitions of data structures. These are not visible to the external
  17.  * world -- they may be accessed only via the functions declared in
  18.  * urltrans.h.
  19.  */
  20. /*
  21.  * Hold one keyword/options entity
  22.  */
  23. struct URLTranslation {
  24.     Octstr *keyword; /* keyword in SMS (similar) query */
  25.     List *aliases; /* keyword aliases, List of Octstr */
  26.     int type; /* see enumeration in header file */
  27.     Octstr *pattern; /* url, text or file-name pattern */
  28.     Octstr *prefix; /* for prefix-cut */
  29.     Octstr *suffix; /* for suffix-cut */
  30.     Octstr *faked_sender;/* works only with certain services */
  31.     Octstr *default_sender;/* Default sender to sendsms-user */
  32.     long max_messages; /* absolute limit of reply messages */
  33.     int concatenation; /* send long messages as concatenated SMS's if true */
  34.     Octstr *split_chars;/* allowed chars to be used to split message */
  35.     Octstr *split_suffix;/* chars added to end after each split (not last) */
  36.     int omit_empty; /* if the reply is empty, is notification send */
  37.     Octstr *header; /* string to be inserted to each SMS */
  38.     Octstr *footer; /* string to be appended to each SMS */
  39.     List *accepted_smsc; /* smsc id's allowed to use this service. If not set,
  40.     all messages can use this service */
  41.     
  42.     Octstr *name; /* Translation name */
  43.     Octstr *username; /* send sms username */
  44.     Octstr *password; /* password associated */
  45.     Octstr *forced_smsc;/* if smsc id is forcet to certain for this user */
  46.     Octstr *default_smsc; /* smsc id if none given in http send-sms request */
  47.     Octstr *allow_ip; /* allowed IPs to request send-sms with this 
  48.                   account */
  49.     Octstr *deny_ip; /* denied IPs to request send-sms with this account */
  50.     Octstr *allowed_prefix; /* Prefixes (of sender) allowed in this translation, or... */
  51.     Octstr *denied_prefix; /* ...denied prefixes */
  52.     Octstr *allowed_recv_prefix; /* Prefixes (of receiver) allowed in this translation, or... */
  53.     Octstr *denied_recv_prefix; /* ...denied prefixes */
  54.     Numhash *white_list; /* To numbers allowed, or ... */
  55.     Numhash *black_list; /* ...denied numbers */
  56.     int assume_plain_text; /* for type: octet-stream */
  57.     int accept_x_kannel_headers; /* do we accept special headers in reply */
  58.     int strip_keyword; /* POST body */
  59.     int send_sender; /* POST headers */
  60.     
  61.     int args;
  62.     int has_catchall_arg;
  63.     int catch_all;
  64.     Octstr *dlr_url; /* Url to call for delivery reports */
  65. };
  66. /*
  67.  * Hold the list of all translations.
  68.  */
  69. struct URLTranslationList {
  70.     List *list;
  71.     Dict *dict; /* Dict of lowercase Octstr keywords*/
  72.     Dict *names; /* Dict of lowercase Octstr names */
  73. };
  74. /***********************************************************************
  75.  * Declarations of internal functions. These are defined at the end of
  76.  * the file.
  77.  */
  78. static long count_occurences(Octstr *str, Octstr *pat);
  79. static URLTranslation *create_onetrans(CfgGroup *grp);
  80. static void destroy_onetrans(void *ot);
  81. static URLTranslation *find_translation(URLTranslationList *trans, 
  82. List *words, Octstr *smsc,
  83. Octstr *sender, Octstr *receiver, int *reject);
  84. static URLTranslation *find_default_translation(URLTranslationList *trans,
  85. Octstr *smsc, Octstr *sender, Octstr *receiver,
  86. int *reject);
  87. static URLTranslation *find_black_list_translation(URLTranslationList *trans,
  88. Octstr *smsc);
  89. /***********************************************************************
  90.  * Implementations of the functions declared in urltrans.h. See the
  91.  * header for explanations of what they should do.
  92.  */
  93. static void destroy_keyword_list(void *list)
  94. {
  95.     list_destroy(list, NULL);
  96. }
  97. URLTranslationList *urltrans_create(void) 
  98. {
  99.     URLTranslationList *trans;
  100.     
  101.     trans = gw_malloc(sizeof(URLTranslationList));
  102.     trans->list = list_create();
  103.     trans->dict = dict_create(1024, destroy_keyword_list);
  104.     trans->names = dict_create(1024, destroy_keyword_list);
  105.     return trans;
  106. }
  107. void urltrans_destroy(URLTranslationList *trans) 
  108. {
  109.     list_destroy(trans->list, destroy_onetrans);
  110.     dict_destroy(trans->names);
  111.     dict_destroy(trans->dict);
  112.     gw_free(trans);
  113. }
  114. int urltrans_add_one(URLTranslationList *trans, CfgGroup *grp)
  115. {
  116.     URLTranslation *ot;
  117.     long i;
  118.     List *list, *list2;
  119.     Octstr *alias;
  120.     
  121.     ot = create_onetrans(grp);
  122.     if (ot == NULL)
  123. return -1;
  124.     list_append(trans->list, ot);
  125.     
  126.     list2 = dict_get(trans->names, ot->name);
  127.     if (list2 == NULL) {
  128.      list2 = list_create();
  129. dict_put(trans->names, ot->name, list2);
  130.     }
  131.     list_append(list2, ot);
  132.     if (ot->keyword == NULL || ot->type == TRANSTYPE_SENDSMS)
  133.      return 0;
  134.     list = dict_get(trans->dict, ot->keyword);
  135.     if (list == NULL) {
  136.      list = list_create();
  137. dict_put(trans->dict, ot->keyword, list);
  138.     }
  139.     list_append(list, ot);
  140.     for (i = 0; i < list_len(ot->aliases); ++i) {
  141. alias = list_get(ot->aliases, i);
  142. list = dict_get(trans->dict, alias);
  143. if (list == NULL) {
  144.     list = list_create();
  145.     dict_put(trans->dict, alias, list);
  146. }
  147. list_append(list, ot);
  148.     }
  149.     return 0;
  150. }
  151. int urltrans_add_cfg(URLTranslationList *trans, Cfg *cfg) 
  152. {
  153.     CfgGroup *grp;
  154.     List *list;
  155.     
  156.     list = cfg_get_multi_group(cfg, octstr_imm("sms-service"));
  157.     while (list && (grp = list_extract_first(list)) != NULL) {
  158. if (urltrans_add_one(trans, grp) == -1) {
  159.     list_destroy(list, NULL);
  160.     return -1;
  161. }
  162.     }
  163.     list_destroy(list, NULL);
  164.     
  165.     list = cfg_get_multi_group(cfg, octstr_imm("sendsms-user"));
  166.     while (list && (grp = list_extract_first(list)) != NULL) {
  167. if (urltrans_add_one(trans, grp) == -1) {
  168.     list_destroy(list, NULL);
  169.     return -1;
  170. }
  171.     }
  172.     list_destroy(list, NULL);
  173.     return 0;
  174. }
  175. URLTranslation *urltrans_find(URLTranslationList *trans, Octstr *text,
  176.       Octstr *smsc, Octstr *sender, Octstr *receiver) 
  177. {
  178.     List *words;
  179.     URLTranslation *t;
  180.     int reject = 0;
  181.     
  182.     words = octstr_split_words(text);
  183.     
  184.     t = find_translation(trans, words, smsc, sender, receiver, &reject);
  185.     list_destroy(words, octstr_destroy_item);
  186.     if (reject)
  187. t = find_black_list_translation(trans, smsc);
  188.     if (t == NULL) {
  189. t = find_default_translation(trans, smsc, sender, receiver, &reject);
  190. if (reject)
  191.     t = find_black_list_translation(trans, smsc);
  192.     }
  193.     return t;
  194. }
  195. URLTranslation *urltrans_find_service(URLTranslationList *trans, Msg *msg)
  196. {
  197.     URLTranslation *t;
  198.     List *list;
  199.     
  200.     list = dict_get(trans->names, msg->sms.service);
  201.     if (list != NULL) {
  202.        t = list_get(list, 0);
  203.     } else  {
  204.        t = NULL;
  205.     }
  206.     return t;
  207. }
  208. URLTranslation *urltrans_find_username(URLTranslationList *trans, 
  209.        Octstr *name)
  210. {
  211.     URLTranslation *t;
  212.     int i;
  213.     gw_assert(name != NULL);
  214.     for (i = 0; i < list_len(trans->list); ++i) {
  215. t = list_get(trans->list, i);
  216. if (t->type == TRANSTYPE_SENDSMS) {
  217.     if (octstr_compare(name, t->username) == 0)
  218. return t;
  219. }
  220.     }
  221.     return NULL;
  222. }
  223. /*
  224.  * Remove the first word and the whitespace that follows it from
  225.  * the start of the message data.
  226.  */
  227. static void strip_keyword(Msg *request)
  228. {          
  229.     int ch;
  230.     long pos;
  231.     pos = 0;
  232.     for (; (ch = octstr_get_char(request->sms.msgdata, pos)) >= 0; pos++)
  233.         if (isspace(ch))
  234.             break;
  235.     for (; (ch = octstr_get_char(request->sms.msgdata, pos)) >= 0; pos++)
  236.         if (!isspace(ch))
  237.             break;
  238.     octstr_delete(request->sms.msgdata, 0, pos);
  239. }
  240. Octstr *urltrans_get_pattern(URLTranslation *t, Msg *request)
  241. {
  242.     Octstr *enc;
  243.     int nextarg, j;
  244.     struct tm tm;
  245.     int num_words;
  246.     List *word_list;
  247.     Octstr *result, *pattern;
  248.     long pattern_len;
  249.     long pos;
  250.     int c;
  251.     long i;
  252.     Octstr *temp;
  253.     Octstr *url, *reply; /* For and If delivery report */
  254.     url = reply = NULL;
  255.     
  256.     if (request->sms.sms_type != report && t->type == TRANSTYPE_SENDSMS)
  257.         return octstr_create("");
  258.     word_list = octstr_split_words(request->sms.msgdata);
  259.     num_words = list_len(word_list);
  260.     result = octstr_create("");
  261.     /* check if this is a delivery report message or not */
  262.     if (request->sms.sms_type != report) {
  263.         pattern = t->pattern;
  264.     } else {
  265.         /* this is a DLR message */
  266.         reply = octstr_duplicate(request->sms.msgdata);
  267.         url = octstr_duplicate(request->sms.dlr_url);
  268.         pattern = url;
  269.         if (octstr_len(pattern) == 0) {
  270.             if (octstr_len(t->dlr_url)) {
  271.                 pattern = t->dlr_url;
  272.             } else {
  273.                 list_destroy(word_list, octstr_destroy_item);
  274.                 return octstr_create("");
  275.             }
  276.         }
  277.     }
  278.     pattern_len = octstr_len(pattern);
  279.     nextarg = 1;
  280.     pos = 0;
  281.     for (;;) {
  282.         while (pos < pattern_len) {
  283.             c = octstr_get_char(pattern, pos);
  284.             if (c == '%' && pos + 1 < pattern_len)
  285.                 break;
  286.             octstr_append_char(result, c);
  287.             ++pos;
  288.         }
  289.         if (pos == pattern_len)
  290.             break;
  291.     switch (octstr_get_char(pattern, pos + 1)) {
  292.     case 'k':
  293.     if (num_words <= 0)
  294. break;
  295.     enc = octstr_duplicate(list_get(word_list, 0));
  296.     octstr_url_encode(enc);
  297.     octstr_append(result, enc);
  298.     octstr_destroy(enc);
  299.     break;
  300. case 's':
  301.     if (nextarg >= num_words)
  302. break;
  303.     enc = octstr_duplicate(list_get(word_list, nextarg));
  304.     octstr_url_encode(enc);
  305.     octstr_append(result, enc);
  306.     octstr_destroy(enc);
  307.     ++nextarg;
  308.     break;
  309. case 'S':
  310.     if (nextarg >= num_words)
  311. break;
  312.     temp = list_get(word_list, nextarg);
  313.     for (i = 0; i < octstr_len(temp); ++i) {
  314. if (octstr_get_char(temp, i) == '*')
  315.     octstr_append_char(result, '~');
  316. else
  317.     octstr_append_char(result, octstr_get_char(temp, i));
  318.     }
  319.     ++nextarg;
  320.     break;
  321. case 'r':
  322.     for (j = nextarg; j < num_words; ++j) {
  323. enc = octstr_duplicate(list_get(word_list, j));
  324. octstr_url_encode(enc);
  325. if (j != nextarg)
  326.     octstr_append_char(result, '+');
  327. octstr_append(result, enc);
  328. octstr_destroy(enc);
  329.     }
  330.     break;
  331.     
  332. /* NOTE: the sender and receiver is already switched in
  333.  *    message, so that's why we must use 'sender' when
  334.  *    we want original receiver and vice versa
  335.  */
  336. case 'P':
  337.     enc = octstr_duplicate(request->sms.sender);
  338.          octstr_url_encode(enc);
  339.     octstr_append(result, enc);
  340.     octstr_destroy(enc);
  341.     break;
  342. case 'p':
  343.     enc = octstr_duplicate(request->sms.receiver);
  344.     octstr_url_encode(enc);
  345.     octstr_append(result, enc);
  346.     octstr_destroy(enc);
  347.     break;
  348. case 'Q':
  349.     if (strncmp(octstr_get_cstr(request->sms.sender), "00", 2) == 0) {
  350. enc = octstr_copy(request->sms.sender, 2, 
  351.             octstr_len(request->sms.sender));
  352. octstr_url_encode(enc);
  353. octstr_format_append(result, "%%2B%S", enc);
  354. octstr_destroy(enc);
  355.     } else {
  356. enc = octstr_duplicate(request->sms.sender);
  357.           octstr_url_encode(enc);
  358. octstr_append(result, enc);
  359. octstr_destroy(enc);
  360.     }
  361.     break;
  362. case 'q':
  363.     if (strncmp(octstr_get_cstr(request->sms.receiver),"00",2)==0) {
  364. enc = octstr_copy(request->sms.receiver, 2, 
  365.             octstr_len(request->sms.receiver));
  366. octstr_url_encode(enc);
  367. octstr_format_append(result, "%%2B%S", enc);
  368. octstr_destroy(enc);
  369.     } else {
  370. enc = octstr_duplicate(request->sms.receiver);
  371. octstr_url_encode(enc);
  372. octstr_append(result, enc);
  373. octstr_destroy(enc);
  374.     }
  375.     break;
  376. case 'a':
  377.     for (j = 0; j < num_words; ++j) {
  378. enc = octstr_duplicate(list_get(word_list, j));
  379. octstr_url_encode(enc);
  380. if (j > 0)
  381.     octstr_append_char(result, '+');
  382. octstr_append(result, enc);
  383. octstr_destroy(enc);
  384.     }
  385.     break;
  386. case 'b':
  387.     enc = octstr_duplicate(request->sms.msgdata);
  388.     octstr_url_encode(enc);
  389.     octstr_append(result, enc);
  390.     octstr_destroy(enc);
  391.     break;
  392. case 't':
  393.     tm = gw_gmtime(request->sms.time);
  394.     octstr_format_append(result, "%04d-%02d-%02d+%02d:%02d:%02d",
  395.  tm.tm_year + 1900,
  396.  tm.tm_mon + 1,
  397.  tm.tm_mday,
  398.  tm.tm_hour,
  399.  tm.tm_min,
  400.  tm.tm_sec);
  401.     break;
  402. case 'i':
  403.     if (request->sms.smsc_id == NULL)
  404. break;
  405.     enc = octstr_duplicate(request->sms.smsc_id);
  406.     octstr_url_encode(enc);
  407.     octstr_append(result, enc);
  408.     octstr_destroy(enc);
  409.     break;
  410. case 'n':
  411.     if (request->sms.service == NULL)
  412. break;
  413.     enc = octstr_duplicate(request->sms.service);
  414.     octstr_url_encode(enc);
  415.     octstr_append(result, enc);
  416.     octstr_destroy(enc);
  417.     break;
  418. case 'd':
  419.     enc = octstr_create("");
  420.     octstr_append_decimal(enc, request->sms.dlr_mask);
  421.     octstr_url_encode(enc);
  422.     octstr_append(result, enc);
  423.     octstr_destroy(enc);
  424.     break;
  425. case 'A':
  426.     enc = octstr_duplicate(reply);
  427.     octstr_url_encode(enc);
  428.     octstr_append(result, enc);
  429.     octstr_destroy(enc);
  430.     break;
  431. case 'c':
  432.     octstr_append_decimal(result, request->sms.coding);
  433.     break;
  434. case 'C':
  435.     if(octstr_len(request->sms.charset)) {
  436. octstr_append(result, request->sms.charset);
  437.     } else {
  438. switch (request->sms.coding) {
  439.     case DC_UNDEF:
  440.     case DC_7BIT:
  441. octstr_append(result, octstr_imm("gsm"));
  442. break;
  443.     case DC_8BIT:
  444. octstr_append(result, octstr_imm("binary"));
  445. break;
  446.     case DC_UCS2:
  447. octstr_append(result, octstr_imm("UTF16-BE"));
  448. break;
  449. }
  450.     }
  451.     break;
  452. case 'u':
  453.     if(octstr_len(request->sms.udhdata)) {
  454. enc = octstr_duplicate(request->sms.udhdata);
  455. octstr_url_encode(enc);
  456. octstr_append(result, enc);
  457. octstr_destroy(enc);
  458.     }
  459.     break;
  460. case '%':
  461.     octstr_format_append(result, "%%");
  462.     break;
  463. default:
  464.     octstr_format_append(result, "%%%c",
  465.                 octstr_get_char(pattern, pos + 1));
  466.     break;
  467. }
  468. pos += 2;
  469.     }
  470.     /*
  471.      * this SHOULD be done in smsbox, not here, but well,
  472.      * much easier to do here
  473.      */
  474.     if ( (t->type == TRANSTYPE_POST_URL || t->type == TRANSTYPE_POST_XML)
  475.     && t->strip_keyword)
  476. strip_keyword(request);
  477.     octstr_destroy(url);
  478.     octstr_destroy(reply);
  479.     list_destroy(word_list, octstr_destroy_item);
  480.     return result;
  481. }
  482. int urltrans_type(URLTranslation *t) 
  483. {
  484.     return t->type;
  485. }
  486. Octstr *urltrans_prefix(URLTranslation *t) 
  487. {
  488.     return t->prefix;
  489. }
  490. Octstr *urltrans_suffix(URLTranslation *t) 
  491. {
  492.     return t->suffix;
  493. }
  494. Octstr *urltrans_default_sender(URLTranslation *t) 
  495. {
  496.     return t->default_sender;
  497. }
  498. Octstr *urltrans_faked_sender(URLTranslation *t) 
  499. {
  500.     return t->faked_sender;
  501. }
  502. int urltrans_max_messages(URLTranslation *t) 
  503. {
  504.     return t->max_messages;
  505. }
  506. int urltrans_concatenation(URLTranslation *t) 
  507. {
  508.     return t->concatenation;
  509. }
  510. Octstr *urltrans_split_chars(URLTranslation *t) 
  511. {
  512.     return t->split_chars;
  513. }
  514. Octstr *urltrans_split_suffix(URLTranslation *t) 
  515. {
  516.     return t->split_suffix;
  517. }
  518. int urltrans_omit_empty(URLTranslation *t) 
  519. {
  520.     return t->omit_empty;
  521. }
  522. Octstr *urltrans_header(URLTranslation *t) 
  523. {
  524.     return t->header;
  525. }
  526. Octstr *urltrans_footer(URLTranslation *t) 
  527. {
  528.     return t->footer;
  529. }
  530. Octstr *urltrans_name(URLTranslation *t) 
  531. {
  532.     return t->name;
  533. }
  534. Octstr *urltrans_username(URLTranslation *t) 
  535. {
  536.     return t->username;
  537. }
  538. Octstr *urltrans_password(URLTranslation *t) 
  539. {
  540.     return t->password;
  541. }
  542. Octstr *urltrans_forced_smsc(URLTranslation *t) 
  543. {
  544.     return t->forced_smsc;
  545. }
  546. Octstr *urltrans_default_smsc(URLTranslation *t) 
  547. {
  548.     return t->default_smsc;
  549. }
  550. Octstr *urltrans_allow_ip(URLTranslation *t) 
  551. {
  552.     return t->allow_ip;
  553. }
  554. Octstr *urltrans_deny_ip(URLTranslation *t) 
  555. {
  556.     return t->deny_ip;
  557. }
  558. Octstr *urltrans_allowed_prefix(URLTranslation *t) 
  559. {
  560.     return t->allowed_prefix;
  561. }
  562. Octstr *urltrans_denied_prefix(URLTranslation *t) 
  563. {
  564.     return t->denied_prefix;
  565. }
  566. Octstr *urltrans_allowed_recv_prefix(URLTranslation *t) 
  567. {
  568.     return t->allowed_recv_prefix;
  569. }
  570. Octstr *urltrans_denied_recv_prefix(URLTranslation *t) 
  571. {
  572.     return t->denied_recv_prefix;
  573. }
  574. Numhash *urltrans_white_list(URLTranslation *t)
  575. {
  576.     return t->white_list;
  577. }
  578. Numhash *urltrans_black_list(URLTranslation *t)
  579. {
  580.     return t->black_list;
  581. }
  582. int urltrans_assume_plain_text(URLTranslation *t) 
  583. {
  584.     return t->assume_plain_text;
  585. }
  586. int urltrans_accept_x_kannel_headers(URLTranslation *t) 
  587. {
  588.     return t->accept_x_kannel_headers;
  589. }
  590. int urltrans_strip_keyword(URLTranslation *t) 
  591. {
  592.     return t->strip_keyword;
  593. }
  594. int urltrans_send_sender(URLTranslation *t) 
  595. {
  596.     return t->send_sender;
  597. }
  598. /***********************************************************************
  599.  * Internal functions.
  600.  */
  601. /*
  602.  * Create one URLTranslation. Return NULL for failure, pointer to it for OK.
  603.  */
  604. static URLTranslation *create_onetrans(CfgGroup *grp)
  605. {
  606.     URLTranslation *ot;
  607.     Octstr *aliases, *url, *post_url, *post_xml, *text, *file, *exec;
  608.     Octstr *accepted_smsc, *forced_smsc, *default_smsc;
  609.     Octstr *grpname, *sendsms_user, *sms_service;
  610.     int is_sms_service;
  611.     
  612.     grpname = cfg_get_group_name(grp);
  613.     if (grpname == NULL)
  614.      return NULL;
  615.     sms_service = octstr_imm("sms-service");
  616.     sendsms_user = octstr_imm("sendsms-user");
  617.     if (octstr_compare(grpname, sms_service) == 0)
  618.      is_sms_service = 1;
  619.     else if (octstr_compare(grpname, sendsms_user) == 0)
  620.      is_sms_service = 0;
  621.     else {
  622. octstr_destroy(grpname);
  623. return NULL;
  624.     }
  625.     octstr_destroy(grpname);
  626.     ot = gw_malloc(sizeof(URLTranslation));
  627.     ot->keyword = NULL;
  628.     ot->aliases = NULL;
  629.     ot->pattern = NULL;
  630.     ot->prefix = NULL;
  631.     ot->suffix = NULL;
  632.     ot->faked_sender = NULL;
  633.     ot->default_sender = NULL;
  634.     ot->split_chars = NULL;
  635.     ot->split_suffix = NULL;
  636.     ot->footer = NULL;
  637.     ot->header = NULL;
  638.     ot->name = NULL;
  639.     ot->username = NULL;
  640.     ot->password = NULL;
  641.     ot->omit_empty = 0;
  642.     ot->accepted_smsc = NULL;
  643.     ot->forced_smsc = NULL;
  644.     ot->default_smsc = NULL;
  645.     ot->allow_ip = NULL;
  646.     ot->deny_ip = NULL;
  647.     ot->allowed_prefix = NULL;
  648.     ot->denied_prefix = NULL;
  649.     ot->allowed_recv_prefix = NULL;
  650.     ot->denied_recv_prefix = NULL;
  651.     ot->white_list = NULL;
  652.     ot->black_list = NULL;
  653.     
  654.     if (is_sms_service) {
  655. cfg_get_bool(&ot->catch_all, grp, octstr_imm("catch-all"));
  656. ot->dlr_url = cfg_get(grp, octstr_imm("dlr-url"));
  657.     
  658. url = cfg_get(grp, octstr_imm("get-url"));
  659. if (url == NULL)
  660.     url = cfg_get(grp, octstr_imm("url"));
  661.     
  662. post_url = cfg_get(grp, octstr_imm("post-url"));
  663. post_xml = cfg_get(grp, octstr_imm("post-xml"));
  664. file = cfg_get(grp, octstr_imm("file"));
  665. text = cfg_get(grp, octstr_imm("text"));
  666. exec = cfg_get(grp, octstr_imm("exec"));
  667. if (url != NULL) {
  668.     ot->type = TRANSTYPE_GET_URL;
  669.     ot->pattern = url;
  670. } else if (post_url != NULL) {
  671.     ot->type = TRANSTYPE_POST_URL;
  672.     ot->pattern = post_url;
  673.     ot->catch_all = 1;
  674. } else if (post_xml != NULL) {
  675.     ot->type = TRANSTYPE_POST_XML;
  676.     ot->pattern = post_xml;
  677.     ot->catch_all = 1;
  678. } else if (file != NULL) {
  679.     ot->type = TRANSTYPE_FILE;
  680.     ot->pattern = file;
  681. } else if (text != NULL) {
  682.     ot->type = TRANSTYPE_TEXT;
  683.     ot->pattern = text;
  684. } else if (exec != NULL) {
  685.     ot->type = TRANSTYPE_EXECUTE;
  686.     ot->pattern = exec;
  687. } else {
  688.     error(0, "Configuration group `sms-service' "
  689.           "did not specify get-url, post-url, post-xml, file or text.");
  690.          goto error;
  691. }
  692. ot->keyword = cfg_get(grp, octstr_imm("keyword"));
  693. if (ot->keyword == NULL) {
  694.     error(0, "Group 'sms-service' must include 'keyword'.");
  695.     goto error;
  696. }
  697. octstr_convert_range(ot->keyword, 0, octstr_len(ot->keyword), 
  698.                tolower);
  699. ot->name = cfg_get(grp, octstr_imm("name"));
  700. if (ot->name == NULL)
  701.     ot->name = octstr_duplicate(ot->keyword);
  702. aliases = cfg_get(grp, octstr_imm("aliases"));
  703. if (aliases == NULL)
  704.     ot->aliases = list_create();
  705. else {
  706.     long i;
  707.     Octstr *os;
  708.     ot->aliases = octstr_split(aliases, octstr_imm(";"));
  709.     octstr_destroy(aliases);
  710.     for (i = 0; i < list_len(ot->aliases); ++i) {
  711. os = list_get(ot->aliases, i);
  712.      octstr_convert_range(os, 0, octstr_len(os), tolower);
  713.     }
  714. }
  715. accepted_smsc = cfg_get(grp, octstr_imm("accepted-smsc"));
  716. if (accepted_smsc != NULL) {
  717.     ot->accepted_smsc = octstr_split(accepted_smsc, octstr_imm(";"));
  718.     octstr_destroy(accepted_smsc);
  719. }
  720. cfg_get_bool(&ot->assume_plain_text, grp, 
  721.      octstr_imm("assume-plain-text"));
  722. cfg_get_bool(&ot->accept_x_kannel_headers, grp, 
  723.      octstr_imm("accept-x-kannel-headers"));
  724. cfg_get_bool(&ot->strip_keyword, grp, octstr_imm("strip-keyword"));
  725. cfg_get_bool(&ot->send_sender, grp, octstr_imm("send-sender"));
  726. ot->prefix = cfg_get(grp, octstr_imm("prefix"));
  727. ot->suffix = cfg_get(grp, octstr_imm("suffix"));
  728. ot->allowed_recv_prefix = cfg_get(grp, octstr_imm("allowed-receiver-prefix"));
  729.     ot->denied_recv_prefix = cfg_get(grp, octstr_imm("denied-receiver-prefix"));
  730. ot->args = count_occurences(ot->pattern, octstr_imm("%s"));
  731. ot->args += count_occurences(ot->pattern, octstr_imm("%S"));
  732. ot->has_catchall_arg = 
  733.     (count_occurences(ot->pattern, octstr_imm("%r")) > 0) ||
  734.     (count_occurences(ot->pattern, octstr_imm("%a")) > 0);
  735.     } else {
  736. ot->type = TRANSTYPE_SENDSMS;
  737. ot->pattern = octstr_create("");
  738. ot->args = 0;
  739. ot->has_catchall_arg = 0;
  740. ot->catch_all = 1;
  741. ot->username = cfg_get(grp, octstr_imm("username"));
  742. ot->password = cfg_get(grp, octstr_imm("password"));
  743. ot->dlr_url = cfg_get(grp, octstr_imm("dlr-url"));
  744. if (ot->password == NULL) {
  745.     error(0, "Password required for send-sms user");
  746.     goto error;
  747. }
  748. ot->name = cfg_get(grp, octstr_imm("name"));
  749. if (ot->name == NULL)
  750.     ot->name = octstr_duplicate(ot->username);
  751. forced_smsc = cfg_get(grp, octstr_imm("forced-smsc"));
  752. default_smsc = cfg_get(grp, octstr_imm("default-smsc"));
  753. if (forced_smsc != NULL) {
  754.     if (default_smsc != NULL) {
  755. info(0, "Redundant default-smsc for send-sms user %s", 
  756.      octstr_get_cstr(ot->username));
  757.     }
  758.     ot->forced_smsc = forced_smsc;
  759.     octstr_destroy(default_smsc);
  760. } else  if (default_smsc != NULL)
  761.     ot->default_smsc = default_smsc;
  762. ot->deny_ip = cfg_get(grp, octstr_imm("user-deny-ip"));
  763. ot->allow_ip = cfg_get(grp, octstr_imm("user-allow-ip"));
  764. ot->default_sender = cfg_get(grp, octstr_imm("default-sender"));
  765.     }
  766.     ot->allowed_prefix = cfg_get(grp, octstr_imm("allowed-prefix"));
  767.     ot->denied_prefix = cfg_get(grp, octstr_imm("denied-prefix"));
  768.     {
  769. Octstr *os;
  770. os = cfg_get(grp, octstr_imm("white-list"));
  771. if (os != NULL) {
  772.     ot->white_list = numhash_create(octstr_get_cstr(os));
  773.     octstr_destroy(os);
  774. }
  775. os = cfg_get(grp, octstr_imm("black-list"));
  776. if (os != NULL) {
  777.     ot->black_list = numhash_create(octstr_get_cstr(os));
  778.     octstr_destroy(os);
  779. }
  780.     }
  781.     if (cfg_get_integer(&ot->max_messages, grp, 
  782.                octstr_imm("max-messages")) == -1)
  783. ot->max_messages = 1;
  784.     cfg_get_bool(&ot->concatenation, grp, 
  785.  octstr_imm("concatenation"));
  786.     cfg_get_bool(&ot->omit_empty, grp, 
  787.  octstr_imm("omit-empty"));
  788.     
  789.     ot->header = cfg_get(grp, octstr_imm("header"));
  790.     ot->footer = cfg_get(grp, octstr_imm("footer"));
  791.     ot->faked_sender = cfg_get(grp, octstr_imm("faked-sender"));
  792.     ot->split_chars = cfg_get(grp, octstr_imm("split-chars"));
  793.     ot->split_suffix = cfg_get(grp, octstr_imm("split-suffix"));
  794.     if ( (ot->prefix == NULL && ot->suffix != NULL) ||
  795.  (ot->prefix != NULL && ot->suffix == NULL) ) {
  796. warning(0, "Service <%s>: suffix and prefix are only used"
  797.    " if both are set.", octstr_get_cstr(ot->keyword));
  798.     }
  799.     if ((ot->prefix != NULL || ot->suffix != NULL) &&
  800.         ot->type != TRANSTYPE_GET_URL) {
  801. warning(0, "Service <%s>: suffix and prefix are only used"
  802.                    " if type is 'get-url'.", octstr_get_cstr(ot->keyword));
  803.     }
  804.     
  805.     return ot;
  806. error:
  807.     error(0, "Couldn't create a URLTranslation.");
  808.     destroy_onetrans(ot);
  809.     return NULL;
  810. }
  811. /*
  812.  * Free one URLTranslation.
  813.  */
  814. static void destroy_onetrans(void *p) 
  815. {
  816.     URLTranslation *ot;
  817.     
  818.     ot = p;
  819.     if (ot != NULL) {
  820. octstr_destroy(ot->keyword);
  821. list_destroy(ot->aliases, octstr_destroy_item);
  822. octstr_destroy(ot->dlr_url);
  823. octstr_destroy(ot->pattern);
  824. octstr_destroy(ot->prefix);
  825. octstr_destroy(ot->suffix);
  826. octstr_destroy(ot->default_sender);
  827. octstr_destroy(ot->faked_sender);
  828. octstr_destroy(ot->split_chars);
  829. octstr_destroy(ot->split_suffix);
  830. octstr_destroy(ot->header);
  831. octstr_destroy(ot->footer);
  832. list_destroy(ot->accepted_smsc, octstr_destroy_item);
  833. octstr_destroy(ot->name);
  834. octstr_destroy(ot->username);
  835. octstr_destroy(ot->password);
  836. octstr_destroy(ot->forced_smsc);
  837. octstr_destroy(ot->default_smsc);
  838. octstr_destroy(ot->allow_ip);
  839. octstr_destroy(ot->deny_ip);
  840. octstr_destroy(ot->allowed_prefix);
  841. octstr_destroy(ot->denied_prefix);
  842. octstr_destroy(ot->allowed_recv_prefix);
  843. octstr_destroy(ot->denied_recv_prefix);
  844. numhash_destroy(ot->white_list);
  845. numhash_destroy(ot->black_list);
  846. gw_free(ot);
  847.     }
  848. }
  849. /*
  850.  * Find the appropriate translation 
  851.  */
  852. static URLTranslation *find_translation(URLTranslationList *trans, 
  853. List *words, Octstr *smsc, Octstr *sender, Octstr *receiver, int *reject)
  854. {
  855.     Octstr *keyword;
  856.     int i, n;
  857.     URLTranslation *t;
  858.     List *list;
  859.     
  860.     n = list_len(words);
  861.     if (n == 0)
  862. return NULL;
  863.     keyword = list_get(words, 0);
  864.     keyword = octstr_duplicate(keyword);
  865.     octstr_convert_range(keyword, 0, octstr_len(keyword), tolower);
  866.     
  867.     list = dict_get(trans->dict, keyword);
  868.     t = NULL;
  869.     for (i = 0; i < list_len(list); ++i) {
  870. t = list_get(list, i);
  871. /* if smsc_id set and accepted_smsc exist, accept
  872.  * translation only if smsc id is in accept string
  873.  */
  874. if (smsc && t->accepted_smsc) {
  875.     if (!list_search(t->accepted_smsc, smsc, octstr_item_match)) {
  876. t = NULL;
  877. continue;
  878.     }
  879. }
  880. /* Have allowed for sender */
  881. if (t->allowed_prefix && ! t->denied_prefix &&
  882.    (does_prefix_match(t->allowed_prefix, sender) != 1)) {
  883.     t = NULL;
  884.     continue;
  885. }
  886. /* Have denied for sender */
  887. if (t->denied_prefix && ! t->allowed_prefix &&
  888.    (does_prefix_match(t->denied_prefix, sender) == 1)) {
  889.     t = NULL;
  890.     continue;
  891. }
  892. /* Have allowed for receiver */
  893. if (t->allowed_recv_prefix && ! t->denied_recv_prefix &&
  894.    (does_prefix_match(t->allowed_recv_prefix, receiver) != 1)) {
  895.     t = NULL;
  896.     continue;
  897. }
  898. /* Have denied for receiver */
  899. if (t->denied_recv_prefix && ! t->allowed_recv_prefix &&
  900.    (does_prefix_match(t->denied_recv_prefix, receiver) == 1)) {
  901.     t = NULL;
  902.     continue;
  903. }
  904. if (t->white_list &&
  905.     numhash_find_number(t->white_list, sender) < 1) {
  906.     t = NULL; *reject = 1;
  907.     continue;
  908. }   
  909. if (t->black_list &&
  910.     numhash_find_number(t->black_list, sender) == 1) {
  911.     t = NULL; *reject = 1;
  912.     continue;
  913. }   
  914. /* Have allowed and denied */
  915. if (t->denied_prefix && t->allowed_prefix &&
  916.    (does_prefix_match(t->allowed_prefix, sender) != 1) &&
  917.    (does_prefix_match(t->denied_prefix, sender) == 1) ) {
  918.     t = NULL;
  919.     continue;
  920. }
  921. if (t->catch_all)
  922.     break;
  923. if (n - 1 == t->args)
  924.     break;
  925. if (t->has_catchall_arg && n - 1 >= t->args)
  926.     break;
  927. t = NULL;
  928.     }
  929.     /* Only return reject if there's only blacklisted smsc's */
  930.     if(t != NULL)
  931. *reject = 0;
  932.     octstr_destroy(keyword);    
  933.     return t;
  934. }
  935. static URLTranslation *find_default_translation(URLTranslationList *trans,
  936. Octstr *smsc, Octstr *sender, Octstr *receiver,
  937. int *reject)
  938. {
  939.     URLTranslation *t;
  940.     int i;
  941.     List *list;
  942.     *reject = 0;
  943.     list = dict_get(trans->dict, octstr_imm("default"));
  944.     t = NULL;
  945.     for (i = 0; i < list_len(list); ++i) {
  946. t = list_get(list, i);
  947. if (smsc && t->accepted_smsc) {
  948.     if (!list_search(t->accepted_smsc, smsc, octstr_item_match)) {
  949. t = NULL;
  950. continue;
  951.     }
  952. }
  953. /* Have allowed sender */
  954. if (t->allowed_prefix && ! t->denied_prefix &&
  955.         (does_prefix_match(t->allowed_prefix, sender) != 1)) {
  956.     t = NULL;
  957.     continue;
  958. }
  959. /* Have denied sender */
  960. if (t->denied_prefix && ! t->allowed_prefix &&
  961.         (does_prefix_match(t->denied_prefix, sender) == 1)) {
  962.     t = NULL;
  963.     continue;
  964. }
  965. /* Have allowed receiver */
  966. if (t->allowed_recv_prefix && ! t->denied_recv_prefix &&
  967.         (does_prefix_match(t->allowed_recv_prefix, receiver) != 1)) {
  968.     t = NULL;
  969.     continue;
  970. }
  971. /* Have denied receiver */
  972. if (t->denied_recv_prefix && ! t->allowed_recv_prefix &&
  973.         (does_prefix_match(t->denied_recv_prefix, receiver) == 1)) {
  974.     t = NULL;
  975.     continue;
  976. }
  977. if (t->white_list && numhash_find_number(t->white_list, sender) < 1) {
  978.     t = NULL; *reject = 1;
  979.     continue;
  980. }
  981. if (t->black_list && numhash_find_number(t->black_list, sender) == 1) {
  982.     t = NULL; *reject = 1;
  983.     continue;
  984.         }
  985. /* Have allowed and denied */
  986. if (t->denied_prefix && t->allowed_prefix &&
  987.         (does_prefix_match(t->allowed_prefix, sender) != 1) &&
  988.         (does_prefix_match(t->denied_prefix, sender) == 1) ) {
  989.     t = NULL;
  990.     continue;
  991. }
  992. break;
  993.     }
  994.     /* Only return reject if there's only blacklisted smsc's */
  995.     if(t != NULL)
  996. *reject = 0;
  997.     return t;
  998. }
  999. static URLTranslation *find_black_list_translation(URLTranslationList *trans,
  1000. Octstr *smsc)
  1001. {
  1002.     URLTranslation *t;
  1003.     int i;
  1004.     List *list;
  1005.     list = dict_get(trans->dict, octstr_imm("black-list"));
  1006.     t = NULL;
  1007.     for (i = 0; i < list_len(list); ++i) {
  1008. t = list_get(list, i);
  1009. if (smsc && t->accepted_smsc) {
  1010.     if (!list_search(t->accepted_smsc, smsc, octstr_item_match)) {
  1011. t = NULL;
  1012. continue;
  1013.     }
  1014. }
  1015. break;
  1016.     }
  1017.     return t;
  1018. }
  1019. /*
  1020.  * Count the number of times `pat' occurs in `str'.
  1021.  */
  1022. static long count_occurences(Octstr *str, Octstr *pat)
  1023. {
  1024.     long count;
  1025.     long pos;
  1026.     long len;
  1027.     
  1028.     count = 0;
  1029.     pos = 0;
  1030.     len = octstr_len(pat);
  1031.     while ((pos = octstr_search(str, pat, pos)) != -1) {
  1032.      ++count;
  1033. pos += len;
  1034.     }
  1035.     return count;
  1036. }