⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 urltrans.c

📁 The Kannel Open Source WAP and SMS gateway works as both an SMS gateway, for implementing keyword b
💻 C
📖 第 1 页 / 共 3 页
字号:
/* ====================================================================  * The Kannel Software License, Version 1.0  *  * Copyright (c) 2001-2004 Kannel Group   * Copyright (c) 1998-2001 WapIT Ltd.    * All rights reserved.  *  * Redistribution and use in source and binary forms, with or without  * modification, are permitted provided that the following conditions  * are met:  *  * 1. Redistributions of source code must retain the above copyright  *    notice, this list of conditions and the following disclaimer.  *  * 2. Redistributions in binary form must reproduce the above copyright  *    notice, this list of conditions and the following disclaimer in  *    the documentation and/or other materials provided with the  *    distribution.  *  * 3. The end-user documentation included with the redistribution,  *    if any, must include the following acknowledgment:  *       "This product includes software developed by the  *        Kannel Group (http://www.kannel.org/)."  *    Alternately, this acknowledgment may appear in the software itself,  *    if and wherever such third-party acknowledgments normally appear.  *  * 4. The names "Kannel" and "Kannel Group" must not be used to  *    endorse or promote products derived from this software without  *    prior written permission. For written permission, please   *    contact org@kannel.org.  *  * 5. Products derived from this software may not be called "Kannel",  *    nor may "Kannel" appear in their name, without prior written  *    permission of the Kannel Group.  *  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE  * DISCLAIMED.  IN NO EVENT SHALL THE KANNEL GROUP OR ITS CONTRIBUTORS  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,   * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT   * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR   * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,   * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE   * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,   * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.  * ====================================================================  *  * This software consists of voluntary contributions made by many  * individuals on behalf of the Kannel Group.  For more information on   * the Kannel Group, please see <http://www.kannel.org/>.  *  * Portions of this software are based upon software originally written at   * WapIT Ltd., Helsinki, Finland for the Kannel project.   */ /* * urltrans.c - URL translations * * Lars Wirzenius */#include <ctype.h>#include <errno.h>#include <limits.h>#include <stdlib.h>#include <string.h>#include <time.h>#include "urltrans.h"#include "gwlib/gwlib.h"#include "gw/sms.h"#include "gwlib/regex.h"/*********************************************************************** * Definitions of data structures. These are not visible to the external * world -- they may be accessed only via the functions declared in * urltrans.h. *//* * Hold one keyword/options entity */struct URLTranslation {    Octstr *keyword;	/* keyword in SMS (similar) query */    List *aliases;	/* keyword aliases, List of Octstr */    int type;		/* see enumeration in header file */    Octstr *pattern;	/* url, text or file-name pattern */    Octstr *prefix;	/* for prefix-cut */    Octstr *suffix;	/* for suffix-cut */    Octstr *faked_sender;/* works only with certain services */    Octstr *default_sender;/* Default sender to sendsms-user */    long max_messages;	/* absolute limit of reply messages */    int concatenation;	/* send long messages as concatenated SMS's if true */    Octstr *split_chars;/* allowed chars to be used to split message */    Octstr *split_suffix;/* chars added to end after each split (not last) */    int omit_empty;	/* if the reply is empty, is notification send */    Octstr *header;	/* string to be inserted to each SMS */    Octstr *footer;	/* string to be appended to each SMS */    List *accepted_smsc; /* smsc id's allowed to use this service. If not set,			    all messages can use this service */        Octstr *name;	/* Translation name */    Octstr *username;	/* send sms username */    Octstr *password;	/* password associated */    Octstr *forced_smsc;/* if smsc id is forcet to certain for this user */    Octstr *default_smsc; /* smsc id if none given in http send-sms request */    Octstr *allow_ip;	/* allowed IPs to request send-sms with this     	    	    	   account */    Octstr *deny_ip;	/* denied IPs to request send-sms with this account */    Octstr *allowed_prefix;	/* Prefixes (of sender) allowed in this translation, or... */    Octstr *denied_prefix;	/* ...denied prefixes */    Octstr *allowed_recv_prefix; /* Prefixes (of receiver) allowed in this translation, or... */    Octstr *denied_recv_prefix;	/* ...denied prefixes */    Numhash *white_list;	/* To numbers allowed, or ... */    Numhash *black_list; /* ...denied numbers */    int assume_plain_text; /* for type: octet-stream */    int accept_x_kannel_headers; /* do we accept special headers in reply */    int strip_keyword;	/* POST body */    int send_sender;	/* POST headers */        int args;    int has_catchall_arg;    int catch_all;    Octstr *dlr_url;	/* Url to call for delivery reports */    regex_t *keyword_regex;       /* the compiled regular expression for the keyword*/    regex_t *accepted_smsc_regex;    regex_t *allowed_prefix_regex;    regex_t *denied_prefix_regex;    regex_t *allowed_receiver_prefix_regex;    regex_t *denied_receiver_prefix_regex;    regex_t *white_list_regex;    regex_t *black_list_regex;};/* * Hold the list of all translations. */struct URLTranslationList {    List *list;    Dict *dict;		/* Dict of lowercase Octstr keywords*/    Dict *names;	/* Dict of lowercase Octstr names */};/*********************************************************************** * Declarations of internal functions. These are defined at the end of * the file. */static long count_occurences(Octstr *str, Octstr *pat);static URLTranslation *create_onetrans(CfgGroup *grp);static void destroy_onetrans(void *ot);static URLTranslation *find_translation(URLTranslationList *trans, 					List *words, Octstr *smsc,					Octstr *sender, Octstr *receiver, int *reject);static URLTranslation *find_default_translation(URLTranslationList *trans,						Octstr *smsc, Octstr *sender, Octstr *receiver,						int *reject);static URLTranslation *find_black_list_translation(URLTranslationList *trans,						Octstr *smsc);/*********************************************************************** * Implementations of the functions declared in urltrans.h. See the * header for explanations of what they should do. */static void destroy_keyword_list(void *list){    list_destroy(list, NULL);}URLTranslationList *urltrans_create(void) {    URLTranslationList *trans;        trans = gw_malloc(sizeof(URLTranslationList));    trans->list = list_create();    trans->dict = dict_create(1024, destroy_keyword_list);    trans->names = dict_create(1024, destroy_keyword_list);    return trans;}void urltrans_destroy(URLTranslationList *trans) {    list_destroy(trans->list, destroy_onetrans);    dict_destroy(trans->names);    dict_destroy(trans->dict);    gw_free(trans);}int urltrans_add_one(URLTranslationList *trans, CfgGroup *grp){    URLTranslation *ot;    long i;    List *list, *list2;    Octstr *alias;        ot = create_onetrans(grp);    if (ot == NULL)	return -1;		    list_append(trans->list, ot);        list2 = dict_get(trans->names, ot->name);    if (list2 == NULL) {    	list2 = list_create();	dict_put(trans->names, ot->name, list2);    }    list_append(list2, ot);    if (ot->keyword == NULL || ot->type == TRANSTYPE_SENDSMS)    	return 0;    list = dict_get(trans->dict, ot->keyword);    if (list == NULL) {    	list = list_create();	dict_put(trans->dict, ot->keyword, list);    }    list_append(list, ot);    for (i = 0; i < list_len(ot->aliases); ++i) {	alias = list_get(ot->aliases, i);	list = dict_get(trans->dict, alias);	if (list == NULL) {	    list = list_create();	    dict_put(trans->dict, alias, list);	}	list_append(list, ot);    }    return 0;}int urltrans_add_cfg(URLTranslationList *trans, Cfg *cfg) {    CfgGroup *grp;    List *list;        list = cfg_get_multi_group(cfg, octstr_imm("sms-service"));    while (list && (grp = list_extract_first(list)) != NULL) {	if (urltrans_add_one(trans, grp) == -1) {	    list_destroy(list, NULL);	    return -1;	}    }    list_destroy(list, NULL);        list = cfg_get_multi_group(cfg, octstr_imm("sendsms-user"));    while (list && (grp = list_extract_first(list)) != NULL) {	if (urltrans_add_one(trans, grp) == -1) {	    list_destroy(list, NULL);	    return -1;	}    }    list_destroy(list, NULL);    return 0;}URLTranslation *urltrans_find(URLTranslationList *trans, Octstr *text,			      Octstr *smsc, Octstr *sender, Octstr *receiver) {    List *words;    URLTranslation *t = NULL;    int reject = 0;        /* do not panic if text == NULL */    if (text != NULL) {        words = octstr_split_words(text);        t = find_translation(trans, words, smsc, sender, receiver, &reject);        list_destroy(words, octstr_destroy_item);    }        if (reject)	t = find_black_list_translation(trans, smsc);    if (t == NULL) {	t = find_default_translation(trans, smsc, sender, receiver, &reject);	if (reject)	    t = find_black_list_translation(trans, smsc);    }    return t;}URLTranslation *urltrans_find_service(URLTranslationList *trans, Msg *msg){    URLTranslation *t;    List *list;        list = dict_get(trans->names, msg->sms.service);    if (list != NULL) {       t = list_get(list, 0);    } else  {       t = NULL;    }    return t;}URLTranslation *urltrans_find_username(URLTranslationList *trans, 				       Octstr *name){    URLTranslation *t;    int i;    gw_assert(name != NULL);    for (i = 0; i < list_len(trans->list); ++i) {	t = list_get(trans->list, i);	if (t->type == TRANSTYPE_SENDSMS) {	    if (octstr_compare(name, t->username) == 0)		return t;	}    }    return NULL;}/* * Remove the first word and the whitespace that follows it from * the start of the message data. */static void strip_keyword(Msg *request){              int ch;    long pos;    pos = 0;    for (; (ch = octstr_get_char(request->sms.msgdata, pos)) >= 0; pos++)        if (isspace(ch))            break;    for (; (ch = octstr_get_char(request->sms.msgdata, pos)) >= 0; pos++)        if (!isspace(ch))            break;    octstr_delete(request->sms.msgdata, 0, pos);}/* * Trans being NULL means that we are servicing ppg (doing dlr, but this does not * concern us here). */Octstr *urltrans_get_pattern(URLTranslation *t, Msg *request){    Octstr *enc;    int nextarg, j;    struct tm tm;    int num_words;    List *word_list;    Octstr *result, *pattern;    long pattern_len;    long pos;    int c;    long i;    Octstr *temp;    Octstr *url, *reply; /* For and If delivery report */    url = reply = NULL;        if (request->sms.sms_type != report_mo && t->type == TRANSTYPE_SENDSMS)        return octstr_create("");    if (request->sms.msgdata) {        word_list = octstr_split_words(request->sms.msgdata);        num_words = list_len(word_list);    } else {    	word_list = list_create();        num_words = 0;    }    result = octstr_create("");    /* check if this is a delivery report message or not */    if (request->sms.sms_type != report_mo) {        pattern = t->pattern;    } else {        /* this is a DLR message */        reply = octstr_duplicate(request->sms.msgdata);        url = octstr_duplicate(request->sms.dlr_url);        pattern = url;        if (octstr_len(pattern) == 0) {            if (t && octstr_len(t->dlr_url)) {                pattern = t->dlr_url;            } else {                list_destroy(word_list, octstr_destroy_item);                return octstr_create("");            }        }    }    pattern_len = octstr_len(pattern);    nextarg = 1;    pos = 0;    for (;;) {        while (pos < pattern_len) {            c = octstr_get_char(pattern, pos);            if (c == '%' && pos + 1 < pattern_len)                break;            octstr_append_char(result, c);            ++pos;        }        if (pos == pattern_len)            break;    switch (octstr_get_char(pattern, pos + 1)) {	case 'k':	    if (num_words <= 0)		break;	    enc = octstr_duplicate(list_get(word_list, 0));	    octstr_url_encode(enc);	    octstr_append(result, enc);	    octstr_destroy(enc);	    break;	case 's':	    if (nextarg >= num_words)		break;	    enc = octstr_duplicate(list_get(word_list, nextarg));	    octstr_url_encode(enc);	    octstr_append(result, enc);	    octstr_destroy(enc);	    ++nextarg;	    break;	case 'S':	    if (nextarg >= num_words)		break;	    temp = list_get(word_list, nextarg);	    for (i = 0; i < octstr_len(temp); ++i) {		if (octstr_get_char(temp, i) == '*')		    octstr_append_char(result, '~');		else		    octstr_append_char(result, octstr_get_char(temp, i));	    }	    ++nextarg;	    break;	case 'r':	    for (j = nextarg; j < num_words; ++j) {		enc = octstr_duplicate(list_get(word_list, j));		octstr_url_encode(enc);		if (j != nextarg)		    octstr_append_char(result, '+');		octstr_append(result, enc);		octstr_destroy(enc);	    }	    break;    	/* NOTE: the sender and receiver is already switched in	 *    message, so that's why we must use 'sender' when	 *    we want original receiver and vice versa	 */	case 'P':	    enc = octstr_duplicate(request->sms.sender);    	    octstr_url_encode(enc);	    octstr_append(result, enc);	    octstr_destroy(enc);	    break;	case 'p':	    enc = octstr_duplicate(request->sms.receiver);	    octstr_url_encode(enc);	    octstr_append(result, enc);	    octstr_destroy(enc);	    break;	case 'Q':	    if (strncmp(octstr_get_cstr(request->sms.sender), "00", 2) == 0) {		enc = octstr_copy(request->sms.sender, 2, 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -