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

📄 mms_util.c

📁 手机端彩信的编解码、以及接收和发送。非常有用。
💻 C
📖 第 1 页 / 共 4 页
字号:
/*
 * Mbuni - Open  Source MMS Gateway 
 * 
 * Misc. functions
 * 
 * Copyright (C) 2003 - 2005, Digital Solutions Ltd. - http://www.dsmagic.com
 *
 * Paul Bagyenda <bagyenda@dsmagic.com>
 * 
 * This program is free software, distributed under the terms of
 * the GNU General Public License, with a few exceptions granted (see LICENSE)
 */ 
#include <sys/file.h>
#include <ctype.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <errno.h>
#include <dlfcn.h>
#include <strings.h>

#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include "mms_util.h"
#include "mms_queue.h"
#include "mms_uaprof.h"

#ifdef HAVE_LIBSSL
#include <openssl/md5.h>
#endif

Octstr *_mms_cfg_getx(mCfgGrp *grp, Octstr *item)
{
     Octstr *v = mms_cfg_get(grp, item);
     
     return v ? v : octstr_create("");
}


int mms_load_core_settings(mCfgGrp *cgrp)
{
     Octstr *log, *alog;
     Octstr *http_proxy_host;
     long loglevel;
     
     if (cgrp == NULL)
	  panic(0,"Missing required group `core' in config file!");
     
     /* Set the log file. */
     log = mms_cfg_get(cgrp, octstr_imm("log-file"));
     if (log != NULL) {
       if (mms_cfg_get_int(cgrp, octstr_imm("log-level"), &loglevel) == -1)
	       loglevel = 0;
	  log_open(octstr_get_cstr(log), loglevel, GW_NON_EXCL);
	  octstr_destroy(log);
     }
     
     /* Get access log and open it. */
     alog = mms_cfg_get(cgrp, octstr_imm("access-log"));
     if (alog) {
	  alog_open(octstr_get_cstr(alog), 1, 1);
	  octstr_destroy(alog);
     }

     /* look for http proxy. If set, use it. */
     if ((http_proxy_host = mms_cfg_get(cgrp, octstr_imm("http-proxy-host"))) != NULL) {
	  
	  Octstr *username = mms_cfg_get(cgrp, 
					octstr_imm("http-proxy-username"));
	  Octstr *password = mms_cfg_get(cgrp, 
					octstr_imm("http-proxy-password"));
	  List *exceptions = mms_cfg_get_list(cgrp,
					     octstr_imm("http-proxy-exceptions"));
	  Octstr *except_regex = mms_cfg_get(cgrp, 
					octstr_imm("http-proxy-exceptions-regex"));
	  long http_proxy_port = -1; 
	  
	  mms_cfg_get_int(cgrp, octstr_imm("http-proxy-port"), &http_proxy_port);

	  if (http_proxy_port > 0)
	       http_use_proxy(http_proxy_host, http_proxy_port, 
			      exceptions, username, password, except_regex);
	  octstr_destroy(http_proxy_host);
	  octstr_destroy(username);
	  octstr_destroy(password);
	  octstr_destroy(except_regex);
	  gwlist_destroy(exceptions, octstr_destroy_item);
     }

#ifdef HAVE_LIBSSL
     /* We expect that gwlib_init() has been called already, so only need
      * to setup cert files.
      * -- adapted from gwlib/conn.c
      */
     {
	  Octstr *ssl_client_certkey_file = NULL;
	  Octstr *ssl_server_cert_file    = NULL;
	  Octstr *ssl_server_key_file     = NULL;
	  Octstr *ssl_trusted_ca_file     = NULL;
	  
	  /*
	   * check if SSL is desired for HTTP servers and then
	   * load SSL client and SSL server public certificates 
	   * and private keys
	   */    
	  ssl_client_certkey_file = mms_cfg_get(cgrp, octstr_imm("ssl-client-certkey-file"));
	  if (ssl_client_certkey_file != NULL) 
	       use_global_client_certkey_file(ssl_client_certkey_file);
	  
	  ssl_server_cert_file = mms_cfg_get(cgrp, octstr_imm("ssl-server-cert-file"));
	  ssl_server_key_file = mms_cfg_get(cgrp, octstr_imm("ssl-server-key-file"));
	  
	  if (ssl_server_cert_file != NULL && ssl_server_key_file != NULL) 
	       use_global_server_certkey_file(ssl_server_cert_file, 
					      ssl_server_key_file);
	  
	  ssl_trusted_ca_file = mms_cfg_get(cgrp, octstr_imm("ssl-trusted-ca-file"));
	  
	  use_global_trusted_ca_file(ssl_trusted_ca_file);
	  
	  octstr_destroy(ssl_client_certkey_file);
	  octstr_destroy(ssl_server_cert_file);
	  octstr_destroy(ssl_server_key_file);
	  octstr_destroy(ssl_trusted_ca_file);       
     }
#endif

     return 0;
}


Octstr *mms_maketransid(char *qf, Octstr *mmscname)
{
     Octstr *res;
     Octstr *x, *y = NULL;
     static int ct;
     
     if (!qf) 
	  x = octstr_format("msg.%ld.x%d.%d.%d",
			    (long)time(NULL) % 10000, (++ct % 1000), getpid()%100, random()%100);
     else
	  x = octstr_create(qf);
          
     res = octstr_format("%S-%S", mmscname, x);
     
     octstr_destroy(x);
     octstr_destroy(y);

     return res;
}

extern Octstr *mms_getqf_fromtransid(Octstr *transid)
{
     int i;
     
     if (transid == NULL)
	return NULL;
     i = octstr_search_char(transid, '-', 0);
     if (i < 0)
	  i = octstr_search_char(transid, '@', 0); /* XXX backward compartibility. */
     
     return (i >= 0) ? octstr_copy(transid, i+1, octstr_len(transid)) : octstr_duplicate(transid);
}

Octstr *mms_isodate(time_t t)
{
    Octstr *current_time;
    struct tm now;

    now = gw_gmtime(t);
    current_time = octstr_format("%04d-%02d-%02dT%02d:%02d:%02dZ", 
                                 now.tm_year + 1900, now.tm_mon + 1, 
                                 now.tm_mday, now.tm_hour, now.tm_min, 
                                 now.tm_sec);

    return current_time;
}

void mms_lib_init(void)
{
     srandom(time(NULL)); /* Seed random number generator. */
     gwlib_init();
     mms_strings_init();
}

void mms_lib_shutdown(void)
{
     mms_strings_shutdown();
     gwlib_shutdown();
}

static void strip_quotes(Octstr *s)
{
     int l = s ? octstr_len(s) : 0;

     if (l == 0)
	  return;
     if (octstr_get_char(s, 0) == '"') {
	  octstr_delete(s, 0, 1);
	  l--;
     }
     if (octstr_get_char(s, l-1) == '"')
	  octstr_delete(s, l-1, 1);     
}

List  *get_value_parameters(Octstr *params)
{
     int i,n, k = 0;
     List *h = http_create_empty_headers();
     Octstr *xparams = octstr_duplicate(params);

     octstr_format_append(xparams, ";"); /* So parsing is easier. (aka cheap hack) */

     for (i = 0, n = octstr_len(xparams); i < n; i++) {
	  int c = octstr_get_char(xparams, i);

	  if (c == ';') {
	       int j  = octstr_search_char(xparams, '=', k);
	       Octstr *name, *value;
	       if (j > 0 && j < i) {
		    name = octstr_copy(xparams, k, j - k);
		    value = octstr_copy(xparams, j+1,i-j-1);
		    octstr_strip_blanks(name);
		    octstr_strip_blanks(value);
		    strip_quotes(value);
		    if (octstr_len(name) > 0)
			 http_header_add(h, 
					 octstr_get_cstr(name), 
					 octstr_get_cstr(value));
		    octstr_destroy(name); 
		    octstr_destroy(value);
	       }
	       k = i + 1;
	  } else if (c == '"') 
	       i += http_header_quoted_string_len(xparams, i) - 1;	  
     }
     octstr_destroy(xparams);
     return h;
}

int split_header_value(Octstr *value, Octstr **base_value, Octstr **params)
{

     int i, n;
     for (i = 0, n = octstr_len(value); i < n; i++) {
	  int c = octstr_get_char(value, i);

	  if (c == ';')
	       break;
	  else if (c == '"') 
	       i += http_header_quoted_string_len(value, i) - 1;	  
     }

     *base_value = octstr_duplicate(value);     
     if (i < n) {
	  *params = octstr_copy(value, i+1, octstr_len(value));
	  octstr_delete(*base_value, i, octstr_len(*base_value));
     } else 
	  *params = octstr_create("");
     return 0;

}

int get_content_type(List *hdrs, Octstr **type, Octstr **params)
{
     
     Octstr *v;
     
     v = http_header_find_first(hdrs, "Content-Type");	  
     *params =NULL;

     if (!v) {
	  *type = octstr_create("application/octet-stream");
	  *params = octstr_create("");
	  return -1;          
     }

     split_header_value(v, type, params);

     octstr_destroy(v);
     return 0;
}

static int is_mime_special_char(int ch)
{
     const char *x = "=;<>[]?()@:\\/,";
     char *p;
     for (p = (char *)x; *p; p++)
	  if (ch == *p)
	       return 1;
     return 0;
}
static int needs_quotes(Octstr *s)
{
     int i, n;
     if (!s) 
	  return 0;
     
     for (i = 0, n = octstr_len(s); i<n; i++) {
	  int ch = octstr_get_char(s,i);
	  if (isspace(ch) || is_mime_special_char(ch))
	       return 1;
     }
     return 0;
}

Octstr *make_value_parameters(List *params)
{
     Octstr *s = octstr_create(""), *name, *value;
     int i, n;

     for (i = 0, n = params ? gwlist_len(params) : 0; i<n; i++) {
	  int space;
	  http_header_get(params, i, &name, &value);
	  space = needs_quotes(value);
	  octstr_format_append(s, "%s%S=%s%S%s", 
			       (i==0) ? "" : "; ", 
			       name, 
			       (space) ? "\"" : "",
			       value,
			       (space) ? "\"" : "");
	  octstr_destroy(name);
	  octstr_destroy(value);
     }
     return s;
}

/* Take each header with a comma separated set of values (for To,Cc,Bcc),
 * re-create as a series of header/value pairs.
 * Remove all non-conformant headers (e.g. old unix-style from 
 */
void unpack_mimeheaders(MIMEEntity *mm)
{
     int i, n;
     List *h = http_create_empty_headers();
     List *headers = mime_entity_headers(mm);
     
     
     for (i = 0, n = gwlist_len(headers); i<n; i++) {
	  Octstr *header = NULL, *value = NULL;
	  List *l = NULL;
	  int j, m;
	  int skip;
	  
	  http_header_get(headers, i, &header, &value);
	  
	  if (header == NULL ||
	      octstr_str_compare(header, "X-Unknown") == 0 ||
	      octstr_search_chars(header, octstr_imm(" \n\t"), 0) >= 0) /* Don't allow space in the name. */ 
	       goto loop;
	  
	  if (octstr_case_compare(header, octstr_imm("Cc")) == 0 ||
	      octstr_case_compare(header, octstr_imm("To")) == 0 ||
	      octstr_case_compare(header, octstr_imm("Bcc")) == 0) 
	       skip = 0;
	  else 
	       skip = 1;
       /* XXX This may not be safe. Need to skip over quotes. */
	  if (!skip && octstr_search_char(value, ',', 0) > 0 && 
	      (l = http_header_split_value(value)) != NULL &&
	      gwlist_len(l) > 1) 
	       for (j = 0, m = gwlist_len(l); j<m; j++) 
		    http_header_add(h, octstr_get_cstr(header), 
				    octstr_get_cstr(gwlist_get(l, j)));
	  else
	       http_header_add(h, octstr_get_cstr(header), 
			       octstr_get_cstr(value));
	  
	  if (l) gwlist_destroy(l, (gwlist_item_destructor_t *)octstr_destroy);
	  
     loop:
	  octstr_destroy(header);
	  octstr_destroy(value);	  	  
     }

     mime_replace_headers(mm, h);
     http_destroy_headers(headers);
     http_destroy_headers(h);

}


/* Undo base64 content coding for mime entities that need it. */
void unbase64_mimeparts(MIMEEntity *m)
{
     int i, n;
     
     if ((n = mime_entity_num_parts(m)) > 0)
	  for (i = 0; i<n; i++) {
	       MIMEEntity *x = mime_entity_get_part(m, i);
	       unbase64_mimeparts(x);
	       mime_entity_replace_part(m, i, x);
	       mime_entity_destroy(x);
	  }
     else { /* A non-multipart message .*/
	  List *headers = mime_entity_headers(m);
	  Octstr *ctype = http_header_value(headers, octstr_imm("Content-Type"));
	  Octstr *te = http_header_value(headers, octstr_imm("Content-Transfer-Encoding"));
	  
	  if (DRM_CONTENT_TYPE(ctype))
	       goto done; /* leave it alone! */
	  if (ctype && te &&
	      octstr_case_compare(te,octstr_imm("base64")) == 0) {
	       Octstr *s = mime_entity_body(m);
	       octstr_base64_to_binary(s);

⌨️ 快捷键说明

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