Beispiel #1
0
static void handle_login(Octstr *packet, Octstr *out, int sequence) {
	Octstr *user = eat_string_parm(packet, 10, 32);
	Octstr *pass = eat_string_parm(packet, 11, 32);

	if (user == NULL)
		user = octstr_create("");
	if (pass == NULL)
		pass = octstr_create("");

	if (logging == LOG_packets)
		printf("RCV: Login user '%s', password '%s'\n",
			octstr_get_cstr(user), octstr_get_cstr(pass));

	if (octstr_str_compare(user, username) == 0 &&
	    octstr_str_compare(pass, password) == 0) {
		if (logging == LOG_packets)
			printf("SND: Login OK\n");
		send_packet(out, 51, sequence, 0);
	} else {
		send_error(out, 51, sequence, "100", "invalid login");
	}

	octstr_destroy(user);
	octstr_destroy(pass);
}
Beispiel #2
0
static inline void get_octstr_value(Octstr **os, const List *r, const int i)
{
    *os = octstr_duplicate(gwlist_get((List*)r, i));
    if (octstr_str_compare(*os, "_NULL_") == 0) {
        octstr_destroy(*os);
        *os = NULL;
    }
}
Beispiel #3
0
int parse_charset(Octstr *os)
{
    Octstr *charset = NULL;
    Octstr *number = NULL;
    int i, j, cut = 0, ret = 0;

    gw_assert(os != NULL);
    charset = octstr_duplicate(os);
    
    /* The charset might be in lower case, so... */
    octstr_convert_range(charset, 0, octstr_len(charset), toupper);

    /*
     * The character set is handled in two parts to make things easier. 
     * The cutting.
     */
    if ((cut = octstr_search_char(charset, '_', 0)) > 0) {
        number = octstr_copy(charset, cut + 1, (octstr_len(charset) - (cut + 1)));
        octstr_truncate(charset, cut);
    } 
    else if ((cut = octstr_search_char(charset, '-', 0)) > 0) {
        number = octstr_copy(charset, cut + 1, (octstr_len(charset) - (cut + 1)));
        octstr_truncate(charset, cut);
    }

    /* And table search. */
    for (i = 0; character_sets[i].charset != NULL; i++)
        if (octstr_str_compare(charset, character_sets[i].charset) == 0) {
            for (j = i; octstr_str_compare(charset, 
                                           character_sets[j].charset) == 0; j++)
                if (octstr_str_compare(number, character_sets[j].nro) == 0) {
                    ret = character_sets[j].MIBenum;
                    break;
                }
            break;
        }

    /* UTF-8 is the default value */
    if (character_sets[i].charset == NULL)
        ret = character_sets[i-1].MIBenum;

    octstr_destroy(number);
    octstr_destroy(charset);

    return ret;
}
Beispiel #4
0
int store_init(Cfg *cfg, const Octstr *type, const Octstr *fname, long dump_freq,
               void *pack_func, void *unpack_func)
{
    int ret;
    
    store_msg_pack = pack_func;
    store_msg_unpack = unpack_func;

    if (type == NULL || octstr_str_compare(type, "file") == 0) {
        ret = store_file_init(fname, dump_freq);
    } else if (octstr_str_compare(type, "spool") == 0) {
        ret = store_spool_init(fname);
#ifdef HAVE_REDIS
    } else if (octstr_str_compare(type, "redis") == 0) {
        ret = store_redis_init(cfg);
#endif
    } else {
        error(0, "Unknown 'store-type' defined.");
        ret = -1;
    }

    return ret;
}
Beispiel #5
0
static int string_in_list(Octstr *s, List *l)
{
     int i, n;
     
     for (i = 0, n = gwlist_len(l); i<n; i++) {
	  Octstr *x = gwlist_get(l,i);
	  char *p = octstr_get_cstr(x);
	  
	  if (p[0] == '+' ||
	      p[0] == '/' || p[0] == '-')
	       p++;	  
	  if (octstr_str_compare(s, p) == 0)
	       return 1;
     }
     return 0;
}
Beispiel #6
0
static List *make_mm_flags(List *oflags, List *flag_cmds)
{
     List *l = oflags ? oflags : gwlist_create();
     int i, n;

     for (i = 0, n = gwlist_len(l); i < n; i++) { /* cleanup list. */
	  Octstr *x = gwlist_get(l,i);
	  int ch = octstr_get_char(x, 0);
	  
	  if (ch == '+' || ch == '-' || ch == '/')
	       octstr_delete(x,0,1);
     }
     
     for (i = 0, n = (flag_cmds ? gwlist_len(flag_cmds) : 0); i<n; i++) {
	  Octstr *x = gwlist_get(flag_cmds,i);
	  int ch = octstr_get_char(x, 0);
	  char *s = octstr_get_cstr(x);
	  int j, m, cmd;
	  
	  if (ch == '+' || ch == '-' || ch == '/') {
	       s++;
	       cmd = ch;
	  } else 
	       cmd = '+';
	  
	  /* Find it in original. If existent, remove it. */
	  for (j = 0, m = gwlist_len(l); j < m; j++) 
	       if (octstr_str_compare(gwlist_get(l,j),s) == 0)  { 
		    Octstr *y = gwlist_get(l,j);
		    gwlist_delete(l,j,1);
		    octstr_destroy(y);
		    j--;
		    m--;
	       } 
	  
	  if (cmd == '+' || cmd == '/')
	       gwlist_append(l, octstr_create(s));
     }     


     return l;
}
Beispiel #7
0
static void httpd_serve(HTTPClient *client, Octstr *ourl, List *headers,
    	    	    	Octstr *body, List *cgivars)
{
    Octstr *reply, *final_reply, *url;
    char *content_type;
    char *header, *footer;
    int status_type;
    int i;
    long pos;

    reply = final_reply = NULL; /* for compiler please */
    url = octstr_duplicate(ourl);

    /* Set default reply format according to client
     * Accept: header */
    if (http_type_accepted(headers, "text/vnd.wap.wml")) {
	status_type = BBSTATUS_WML;
	content_type = "text/vnd.wap.wml";
    }
    else if (http_type_accepted(headers, "text/html")) {
	status_type = BBSTATUS_HTML;
	content_type = "text/html";
    }
    else if (http_type_accepted(headers, "text/xml")) {
	status_type = BBSTATUS_XML;
	content_type = "text/xml";
    } else {
	status_type = BBSTATUS_TEXT;
	content_type = "text/plain";
    }

    /* kill '/cgi-bin' prefix */
    pos = octstr_search(url, octstr_imm("/cgi-bin/"), 0);
    if (pos != -1)
        octstr_delete(url, pos, 9);
    else if (octstr_get_char(url, 0) == '/')
        octstr_delete(url, 0, 1);

    /* look for type and kill it */
    pos = octstr_search_char(url, '.', 0);
    if (pos != -1) {
        Octstr *tmp = octstr_copy(url, pos+1, octstr_len(url) - pos - 1);
        octstr_delete(url, pos, octstr_len(url) - pos);

        if (octstr_str_compare(tmp, "txt") == 0)
            status_type = BBSTATUS_TEXT;
        else if (octstr_str_compare(tmp, "html") == 0)
            status_type = BBSTATUS_HTML;
        else if (octstr_str_compare(tmp, "xml") == 0)
            status_type = BBSTATUS_XML;
        else if (octstr_str_compare(tmp, "wml") == 0)
            status_type = BBSTATUS_WML;

        octstr_destroy(tmp);
    }

    for (i=0; httpd_commands[i].command != NULL; i++) {
        if (octstr_str_compare(url, httpd_commands[i].command) == 0) {
            reply = httpd_commands[i].function(cgivars, status_type);
            break;
        }
    }

    /* check if command found */
    if (httpd_commands[i].command == NULL) {
        char *lb = bb_status_linebreak(status_type);
	reply = octstr_format("Unknown command `%S'.%sPossible commands are:%s",
            ourl, lb, lb);
        for (i=0; httpd_commands[i].command != NULL; i++)
            octstr_format_append(reply, "%s%s", httpd_commands[i].command, lb);
    }

    gw_assert(reply != NULL);

    if (status_type == BBSTATUS_HTML) {
	header = "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 3.2//EN\">\n"
 	    "<html>\n<title>" GW_NAME "</title>\n<body>\n<p>";
	footer = "</p>\n</body></html>\n";
	content_type = "text/html";
    } else if (status_type == BBSTATUS_WML) {
	header = "<?xml version=\"1.0\"?>\n"
            "<!DOCTYPE wml PUBLIC \"-//WAPFORUM//DTD WML 1.1//EN\" "
            "\"http://www.wapforum.org/DTD/wml_1.1.xml\">\n"
            "\n<wml>\n <card>\n  <p>";
	footer = "  </p>\n </card>\n</wml>\n";
	content_type = "text/vnd.wap.wml";
    } else if (status_type == BBSTATUS_XML) {
	header = "<?xml version=\"1.0\"?>\n"
            "<gateway>\n";
        footer = "</gateway>\n";
    } else {
	header = "";
	footer = "";
	content_type = "text/plain";
    }
    final_reply = octstr_create(header);
    octstr_append(final_reply, reply);
    octstr_append_cstr(final_reply, footer);
    
    /* debug("bb.http", 0, "Result: '%s'", octstr_get_cstr(final_reply));
     */
    http_destroy_headers(headers);
    headers = list_create();
    http_header_add(headers, "Content-Type", content_type);

    http_send_reply(client, HTTP_OK, headers, final_reply);

    octstr_destroy(url);
    octstr_destroy(ourl);
    octstr_destroy(body);
    octstr_destroy(reply);
    octstr_destroy(final_reply);
    http_destroy_headers(headers);
    http_destroy_cgiargs(cgivars);
}
Beispiel #8
0
long date_parse_http(Octstr *date)
{
    long pos;
    struct universaltime t;
    Octstr *monthstr = NULL;

    /* First, skip the leading day-of-week string. */
    pos = octstr_search_char(date, ' ', 0);
    if (pos < 0 || pos == octstr_len(date) - 1)
        return -1;
    pos++;  /* Skip the space */

    /* Distinguish between the three acceptable formats */
    if (isdigit(octstr_get_char(date, pos)) &&
        octstr_get_char(date, pos + 2) == ' ') {
        if (octstr_len(date) - pos < (long)strlen("06 Nov 1994 08:49:37 GMT"))
            goto error;
        if (octstr_parse_long(&t.day, date, pos, 10) != pos + 2)
            goto error;
        monthstr = octstr_copy(date, pos + 3, 3);
        if (octstr_parse_long(&t.year, date, pos + 7, 10) != pos + 11)
            goto error;
        if (octstr_parse_long(&t.hour, date, pos + 12, 10) != pos + 14)
            goto error;
        if (octstr_parse_long(&t.minute, date, pos + 15, 10) != pos + 17)
            goto error;
        if (octstr_parse_long(&t.second, date, pos + 18, 10) != pos + 20)
            goto error;
        /* Take the GMT part on faith. */
    } else if (isdigit(octstr_get_char(date, pos)) &&
               octstr_get_char(date, pos + 2) == '-') {
        if (octstr_len(date) - pos < (long)strlen("06-Nov-94 08:49:37 GMT"))
            goto error;
        if (octstr_parse_long(&t.day, date, pos, 10) != pos + 2)
            goto error;
        monthstr = octstr_copy(date, pos + 3, 3);
        if (octstr_parse_long(&t.year, date, pos + 7, 10) != pos + 9)
            goto error;
        if (t.year > 60)
            t.year += 1900;
        else
            t.year += 2000;
        if (octstr_parse_long(&t.hour, date, pos + 10, 10) != pos + 12)
            goto error;
        if (octstr_parse_long(&t.minute, date, pos + 13, 10) != pos + 15)
            goto error;
        if (octstr_parse_long(&t.second, date, pos + 16, 10) != pos + 18)
            goto error;
        /* Take the GMT part on faith. */
    } else {
        if (octstr_len(date) - pos < (long)strlen(" 6 08:49:37 1994"))
            goto error;
        monthstr = octstr_copy(date, pos, 3);
        if (octstr_parse_long(&t.day, date, pos + 4, 10) != pos + 6)
            goto error;
        if (octstr_parse_long(&t.hour, date, pos + 7, 10) != pos + 9)
            goto error;
        if (octstr_parse_long(&t.minute, date, pos + 10, 10) != pos + 12)
            goto error;
        if (octstr_parse_long(&t.second, date, pos + 13, 10) != pos + 15)
            goto error;
        if (octstr_parse_long(&t.year, date, pos + 16, 10) != pos + 20)
            goto error;
    }

    for (t.month = 0; t.month < 12; t.month++) {
        if (octstr_str_compare(monthstr, monthname[t.month]) == 0)
            break;
    }
    if (t.month == 12)
        goto error;

    octstr_destroy(monthstr);
    return date_convert_universal(&t);

error:
    octstr_destroy(monthstr);
    return -1;
}
Beispiel #9
0
Numhash *numhash_create(char *seek_url)
{
    int		loc, lines = 0;
    List	*request_headers, *reply_headers;
    Octstr	*url, *final_url, *reply_body;
    Octstr	*type, *charset;
    
    char    *data, *ptr, numbuf[100];
    int		status;
    Numhash	*table;

    url = octstr_create(seek_url);
    request_headers = gwlist_create();
    status = http_get_real(HTTP_METHOD_GET, url, request_headers, &final_url,
			    &reply_headers, &reply_body);
    octstr_destroy(url);
    octstr_destroy(final_url);
    gwlist_destroy(request_headers, NULL);

    if (status != HTTP_OK) {
	http_destroy_headers(reply_headers);
	octstr_destroy(reply_body);
	error(0, "Cannot load numhash!");
	return NULL;
    }
    http_header_get_content_type(reply_headers, &type, &charset);
    octstr_destroy(charset);
    http_destroy_headers(reply_headers);
    
    if (octstr_str_compare(type, "text/plain") != 0) {
        octstr_destroy(reply_body);
        error(0, "Strange content type <%s> for numhash - expecting 'text/plain'"
                 ", operatiom fails", octstr_get_cstr(type));
        octstr_destroy(type);
        return NULL;
    }
    octstr_destroy(type);
    
    ptr = data = octstr_get_cstr(reply_body);
    while(*ptr) {
	if (*ptr == '\n') lines++;
	ptr++;
    }
    debug("numhash", 0, "Total %d lines in %s", lines, seek_url);

    table = numhash_init(lines+10, NUMHASH_AUTO_HASH);  	/* automatic hash */

    /* now, parse the number information */

    lines = 0;
  
    while((ptr = strchr(data, '\n'))) {	/* each line is ended with linefeed */
	*ptr = '\0';
	while(*data != '\0' && isspace(*data))
	    data++;
	if (*data != '#') {
	    loc = 0;
	    while (*data != '\0') {
		if (isdigit(*data))
		    numbuf[loc++] = *data;
		else if (*data == ' ' || *data == '+' || *data == '-')
			;
		else break;
		data++;
	    }
	    if (loc) {
		numbuf[loc] = '\0';
		numhash_add_number(table, numbuf);
		lines++;
	    }
	    else
		warning(0, "Corrupted line '%s'", data);
	}
	data = ptr+1;	/* next row... */
    }
    octstr_destroy(reply_body); 

    info(0, "Read from <%s> total of %ld numbers", seek_url, table->number_total);
    return table;
}
Beispiel #10
0
static int _x_octstr_str_compare(Octstr *s, char *p)
{
     return (octstr_str_compare(s,p) == 0);
}
Beispiel #11
0
/* Format of Index file:
 * each message is described by a single line:
 * df state flag1 flag2 flag3 ...
 */
static int update_mmbox_index(int fd, char *mmbox_dir, int cmd, 
			      Octstr *df, Octstr *state, List *flags, long msgsize)
{
     char fbuf[256], linbuf[1024];
     int tempfd;
     FILE *fp;
     
     /* Make a temp file. */
     
     sprintf(fbuf, "%.128s/t%s.%ld.%ld",
	     mmbox_dir, IDXFILE, time(NULL), random() % 1000);

     tempfd = open(fbuf, 
		   O_RDWR|O_CREAT|O_EXCL, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP);
     if (tempfd < 0 ) { 
	  error(0, "mmbox.update_index: Failed to open temp file %s: error = %s\n", 
		fbuf, strerror(errno));
	  
	  goto done;
     } else if (mm_lockfile(tempfd, fbuf, 0) != 0) { /* Lock it. */
	  error(0, "mmbox.update_index: Failed lock  temp file %s: error = %s\n", 
		     fbuf, strerror(errno));

	  unlock_and_close(tempfd);
	  tempfd = -1;
	  goto done;
	  
     }
     fp = fdopen(fd, "r");
     
     if (!fp) {
	  error(0, "mmbox.update_index: Failed fdopen on tempfd, file %s: error = %s\n",
		
		fbuf, strerror(errno));
		  
	  unlock_and_close(tempfd);
	  tempfd = -1;
	  goto done;
     }
     
     while (fgets(linbuf, sizeof linbuf, fp) != NULL) {
	  char idx[128], xstate[32];
	  Octstr *outs = NULL;
	  int i;
	  int size;
	  
	  sscanf(linbuf, "%s %s %d%n", idx, xstate, &size, &i);
	  
	  if (df && octstr_str_compare(df, idx) == 0)
	       if (cmd == ITEM_DEL || cmd == ITEM_ADD)
		    goto loop; /* Skip it. */
	       else  { /* MOD. */
		    Octstr *p = linearise_string_list(flags, " ");
		    outs = octstr_format("%S %S %d %S\n", df, state, msgsize, p);
		    octstr_destroy(p);
	       }
	  else { /* Copy out as-is */
	       char *p = skip_space(linbuf + i);
	       outs = octstr_format("%s %s %d %s%s",
				    idx, xstate, 
				    size,
				    p,
				    (strchr(p, '\n') != NULL ? "" : "\n"));
	  }
     loop:
	  if (outs) {
	       if (octstr_len(outs) > 0) 
		    octstr_write_to_socket(tempfd, outs);	       
	       octstr_destroy(outs);
	  }
     }     

     if (cmd == ITEM_ADD) { /* Finally, for ADD, just add it. */
	  Octstr *s, *p = linearise_string_list(flags, " ");
	  s = octstr_format("%S %S %d %S\n", df, state, msgsize, p);
	  octstr_destroy(p);	  
	  octstr_write_to_socket(tempfd, s);	       
	  octstr_destroy(s);	  
     }
     fsync(tempfd);     

     sprintf(linbuf, "%.128s/%s",
	     mmbox_dir, IDXFILE);
     rename(fbuf, linbuf);

     unlock_and_fclose(fp);
 done:

     return tempfd;
}
Beispiel #12
0
/*
 * Create one URLTranslation. Return NULL for failure, pointer to it for OK.
 */
static URLTranslation *create_onetrans(CfgGroup *grp)
{
    URLTranslation *ot;
    Octstr *url, *post_url, *post_xml, *text, *file, *exec;
    Octstr *accepted_smsc, *accepted_account, *forced_smsc, *default_smsc;
    Octstr *grpname;
    int is_sms_service, regex_flag = REG_EXTENDED;
    Octstr *accepted_smsc_regex;
    Octstr *accepted_account_regex;
    Octstr *allowed_prefix_regex;
    Octstr *denied_prefix_regex;
    Octstr *allowed_receiver_prefix_regex;
    Octstr *denied_receiver_prefix_regex;
    Octstr *white_list_regex;
    Octstr *black_list_regex;
    Octstr *keyword_regex;
    Octstr *os, *tmp;
    
    grpname = cfg_get_group_name(grp);
    if (grpname == NULL)
    	return NULL;

    if (octstr_str_compare(grpname, "sms-service") == 0)
        is_sms_service = 1;
    else if (octstr_str_compare(grpname, "sendsms-user") == 0)
        is_sms_service = 0;
    else {
        octstr_destroy(grpname);
        return NULL;
    }
    octstr_destroy(grpname);

    ot = gw_malloc(sizeof(URLTranslation));
    memset(ot, 0, sizeof(*ot));
    
    if (is_sms_service) {
        cfg_get_bool(&ot->catch_all, grp, octstr_imm("catch-all"));

        ot->dlr_url = cfg_get(grp, octstr_imm("dlr-url"));
        if (cfg_get_integer(&ot->dlr_mask, grp, octstr_imm("dlr-mask")) == -1)
            ot->dlr_mask = DLR_UNDEFINED;
        ot->alt_charset = cfg_get(grp, octstr_imm("alt-charset"));
	    
        url = cfg_get(grp, octstr_imm("get-url"));
        if (url == NULL)
            url = cfg_get(grp, octstr_imm("url"));
	    
	post_url = cfg_get(grp, octstr_imm("post-url"));
	post_xml = cfg_get(grp, octstr_imm("post-xml"));
	file = cfg_get(grp, octstr_imm("file"));
	text = cfg_get(grp, octstr_imm("text"));
	exec = cfg_get(grp, octstr_imm("exec"));
	if (url != NULL) {
	    ot->type = TRANSTYPE_GET_URL;
	    ot->pattern = octstr_duplicate(url);
	} else if (post_url != NULL) {
	    ot->type = TRANSTYPE_POST_URL;
	    ot->pattern = octstr_duplicate(post_url);
	    ot->catch_all = 1;
	} else if (post_xml != NULL) {
	    ot->type = TRANSTYPE_POST_XML;
	    ot->pattern = octstr_duplicate(post_xml);
	    ot->catch_all = 1;
	} else if (file != NULL) {
	    ot->type = TRANSTYPE_FILE;
	    ot->pattern = octstr_duplicate(file);
	} else if (text != NULL) {
	    ot->type = TRANSTYPE_TEXT;
	    ot->pattern = octstr_duplicate(text);
	} else if (exec != NULL) {
	    ot->type = TRANSTYPE_EXECUTE;
	    ot->pattern = octstr_duplicate(exec);
	} else {
	    octstr_destroy(url);
	    octstr_destroy(post_url);
	    octstr_destroy(post_xml);
	    octstr_destroy(file);
	    octstr_destroy(text);
	    octstr_destroy(exec);
	    error(0, "Configuration group `sms-service' "
	    	     "did not specify get-url, post-url, post-xml, file or text.");
    	    goto error;
	}
	octstr_destroy(url);
	octstr_destroy(post_url);
	octstr_destroy(post_xml);
	octstr_destroy(file);
	octstr_destroy(text);
	octstr_destroy(exec);

	tmp = cfg_get(grp, octstr_imm("keyword"));
        keyword_regex = cfg_get(grp, octstr_imm("keyword-regex"));
	if (tmp == NULL && keyword_regex == NULL) {
	    error(0, "Group 'sms-service' must include either 'keyword' or 'keyword-regex'.");
	    goto error;
	}
	if (tmp != NULL && keyword_regex != NULL) {
	    error(0, "Group 'sms-service' may inlcude either 'keyword' or 'keyword-regex'.");
	    octstr_destroy(tmp);
	    octstr_destroy(keyword_regex);
	    goto error;
	}
	
	if (tmp != NULL && octstr_str_compare(tmp, "default") == 0) {
	    /* default sms-service */
	    ot->keyword_regex = NULL;
	    octstr_destroy(tmp);
	} else if (tmp != NULL) {
	    Octstr *aliases;
	    
	    /* convert to regex */
	    regex_flag |= REG_ICASE;
	    keyword_regex = octstr_format("^[ ]*(%S", tmp);
	    octstr_destroy(tmp);

	    aliases = cfg_get(grp, octstr_imm("aliases"));
	    if (aliases != NULL) {
	        long i;
	        List *l;

	        l = octstr_split(aliases, octstr_imm(";"));
	        octstr_destroy(aliases);
	        
	        for (i = 0; i < gwlist_len(l); ++i) {
	            os = gwlist_get(l, i);
	            octstr_format_append(keyword_regex, "|%S", os);
	        }
	        gwlist_destroy(l, octstr_destroy_item);
	    }
	    
	    octstr_append_cstr(keyword_regex, ")[ ]*");
	}

        if (keyword_regex != NULL && (ot->keyword_regex = gw_regex_comp(keyword_regex, regex_flag)) == NULL) {
            error(0, "Could not compile pattern '%s'", octstr_get_cstr(keyword_regex));
            octstr_destroy(keyword_regex);
            goto error;
        }

	ot->name = cfg_get(grp, octstr_imm("name"));
	if (ot->name == NULL)
	    ot->name = keyword_regex ? octstr_duplicate(keyword_regex) : octstr_create("default");
	octstr_destroy(keyword_regex);

	accepted_smsc = cfg_get(grp, octstr_imm("accepted-smsc"));
	if (accepted_smsc != NULL) {
	    ot->accepted_smsc = octstr_split(accepted_smsc, octstr_imm(";"));
	    octstr_destroy(accepted_smsc);
	}
	accepted_account = cfg_get(grp, octstr_imm("accepted-account"));
	if (accepted_account != NULL) {
	    ot->accepted_account = octstr_split(accepted_account, octstr_imm(";"));
	    octstr_destroy(accepted_account);
	}
        accepted_smsc_regex = cfg_get(grp, octstr_imm("accepted-smsc-regex"));
        if (accepted_smsc_regex != NULL) { 
            if ( (ot->accepted_smsc_regex = gw_regex_comp(accepted_smsc_regex, REG_EXTENDED)) == NULL)
            panic(0, "Could not compile pattern '%s'", octstr_get_cstr(accepted_smsc_regex));
            octstr_destroy(accepted_smsc_regex);
        }
        accepted_account_regex = cfg_get(grp, octstr_imm("accepted-account-regex"));
        if (accepted_account_regex != NULL) { 
            if ( (ot->accepted_account_regex = gw_regex_comp(accepted_account_regex, REG_EXTENDED)) == NULL)
            panic(0, "Could not compile pattern '%s'", octstr_get_cstr(accepted_account_regex));
            octstr_destroy(accepted_account_regex);
        }

	cfg_get_bool(&ot->assume_plain_text, grp, 
		     octstr_imm("assume-plain-text"));
	cfg_get_bool(&ot->accept_x_kannel_headers, grp, 
		     octstr_imm("accept-x-kannel-headers"));
	cfg_get_bool(&ot->strip_keyword, grp, octstr_imm("strip-keyword"));
	cfg_get_bool(&ot->send_sender, grp, octstr_imm("send-sender"));
	
	ot->prefix = cfg_get(grp, octstr_imm("prefix"));
	ot->suffix = cfg_get(grp, octstr_imm("suffix"));
        ot->allowed_recv_prefix = cfg_get(grp, octstr_imm("allowed-receiver-prefix"));
        allowed_receiver_prefix_regex = cfg_get(grp, octstr_imm("allowed-receiver-prefix-regex"));
        if (allowed_receiver_prefix_regex != NULL) {
            if ((ot->allowed_receiver_prefix_regex = gw_regex_comp(allowed_receiver_prefix_regex, REG_EXTENDED)) == NULL)
            panic(0, "Could not compile pattern '%s'", octstr_get_cstr(allowed_receiver_prefix_regex));
            octstr_destroy(allowed_receiver_prefix_regex);
        }

	ot->allowed_recv_prefix = cfg_get(grp, octstr_imm("allowed-receiver-prefix"));
	ot->denied_recv_prefix = cfg_get(grp, octstr_imm("denied-receiver-prefix"));
        denied_receiver_prefix_regex = cfg_get(grp, octstr_imm("denied-receiver-prefix-regex"));
        if (denied_receiver_prefix_regex != NULL) {
            if ((ot->denied_receiver_prefix_regex = gw_regex_comp(denied_receiver_prefix_regex, REG_EXTENDED)) == NULL)
            panic(0, "Could not compile pattern '%s'",octstr_get_cstr(denied_receiver_prefix_regex));
            octstr_destroy(denied_receiver_prefix_regex);
        }

	ot->args = count_occurences(ot->pattern, octstr_imm("%s"));
	ot->args += count_occurences(ot->pattern, octstr_imm("%S"));
	ot->has_catchall_arg = 
	    (count_occurences(ot->pattern, octstr_imm("%r")) > 0) ||
	    (count_occurences(ot->pattern, octstr_imm("%a")) > 0);

    } else {
	ot->type = TRANSTYPE_SENDSMS;
	ot->pattern = octstr_create("");
	ot->args = 0;
	ot->has_catchall_arg = 0;
	ot->catch_all = 1;
	ot->username = cfg_get(grp, octstr_imm("username"));
	ot->password = cfg_get(grp, octstr_imm("password"));
	ot->dlr_url = cfg_get(grp, octstr_imm("dlr-url"));
	grp_dump(grp);
	if (ot->password == NULL) {
	    error(0, "Password required for send-sms user");
	    goto error;
	}
	ot->name = cfg_get(grp, octstr_imm("name"));
	if (ot->name == NULL)
	    ot->name = octstr_duplicate(ot->username);

	forced_smsc = cfg_get(grp, octstr_imm("forced-smsc"));
	default_smsc = cfg_get(grp, octstr_imm("default-smsc"));
	if (forced_smsc != NULL) {
	    if (default_smsc != NULL) {
		info(0, "Redundant default-smsc for send-sms user %s", 
		     octstr_get_cstr(ot->username));
	    }
	    ot->forced_smsc = forced_smsc;
	    octstr_destroy(default_smsc);
	} else  if (default_smsc != NULL)
	    ot->default_smsc = default_smsc;

	ot->deny_ip = cfg_get(grp, octstr_imm("user-deny-ip"));
	ot->allow_ip = cfg_get(grp, octstr_imm("user-allow-ip"));
	ot->default_sender = cfg_get(grp, octstr_imm("default-sender"));
    }
    
    ot->allowed_prefix = cfg_get(grp, octstr_imm("allowed-prefix"));
    allowed_prefix_regex = cfg_get(grp, octstr_imm("allowed-prefix-regex"));
    if (allowed_prefix_regex != NULL) {
        if ((ot->allowed_prefix_regex = gw_regex_comp(allowed_prefix_regex, REG_EXTENDED)) == NULL)
            panic(0, "Could not compile pattern '%s'", octstr_get_cstr(allowed_prefix_regex));
        octstr_destroy(allowed_prefix_regex);
    }
    ot->denied_prefix = cfg_get(grp, octstr_imm("denied-prefix"));
    denied_prefix_regex = cfg_get(grp, octstr_imm("denied-prefix-regex"));
    if (denied_prefix_regex != NULL) {
        if ((ot->denied_prefix_regex = gw_regex_comp(denied_prefix_regex, REG_EXTENDED)) == NULL)
            panic(0, "Could not compile pattern '%s'", octstr_get_cstr(denied_prefix_regex));
        octstr_destroy(denied_prefix_regex);
    }
    
    os = cfg_get(grp, octstr_imm("white-list"));
    if (os != NULL) {
        ot->white_list = numhash_create(octstr_get_cstr(os));
        octstr_destroy(os);
    }
    white_list_regex = cfg_get(grp, octstr_imm("white-list-regex"));
    if (white_list_regex != NULL) {
        if ((ot->white_list_regex = gw_regex_comp(white_list_regex, REG_EXTENDED)) == NULL)
            panic(0, "Could not compile pattern '%s'", octstr_get_cstr(white_list_regex));
        octstr_destroy(white_list_regex);
    }

    os = cfg_get(grp, octstr_imm("black-list"));
    if (os != NULL) {
        ot->black_list = numhash_create(octstr_get_cstr(os));
        octstr_destroy(os);
    }
    black_list_regex = cfg_get(grp, octstr_imm("black-list-regex"));
    if (black_list_regex != NULL) {
        if ((ot->black_list_regex = gw_regex_comp(black_list_regex, REG_EXTENDED)) == NULL)
            panic(0, "Could not compile pattern '%s'", octstr_get_cstr(black_list_regex));
        octstr_destroy(black_list_regex);
    }

    if (cfg_get_integer(&ot->max_messages, grp, octstr_imm("max-messages")) == -1)
	ot->max_messages = 1;
    cfg_get_bool(&ot->concatenation, grp, octstr_imm("concatenation"));
    cfg_get_bool(&ot->omit_empty, grp, octstr_imm("omit-empty"));
    
    ot->header = cfg_get(grp, octstr_imm("header"));
    ot->footer = cfg_get(grp, octstr_imm("footer"));
    ot->faked_sender = cfg_get(grp, octstr_imm("faked-sender"));
    ot->split_chars = cfg_get(grp, octstr_imm("split-chars"));
    ot->split_suffix = cfg_get(grp, octstr_imm("split-suffix"));

    if ( (ot->prefix == NULL && ot->suffix != NULL) ||
	 (ot->prefix != NULL && ot->suffix == NULL) ) {
	warning(0, "Service : suffix and prefix are only used"
		   " if both are set.");
    }
    if ((ot->prefix != NULL || ot->suffix != NULL) &&
        ot->type != TRANSTYPE_GET_URL) {
	warning(0, "Service : suffix and prefix are only used"
                   " if type is 'get-url'.");
    }
    
    return ot;

error:
    error(0, "Couldn't create a URLTranslation.");
    destroy_onetrans(ot);
    return NULL;
}