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

📄 mms_util.c

📁 手机端彩信的编解码、以及接收和发送。非常有用。
💻 C
📖 第 1 页 / 共 4 页
字号:
static int lockfile(int fd, int shouldblock)
{
     int n, stop;     
     unsigned flg = shouldblock ? 0 : LOCK_NB;

     do {
       n = flock(fd, LOCK_EX|flg);
       if (n < 0) {
	    if (errno == EINTR)
		 stop = 0;
	    else
		 stop = 1;
       } else	    
	    stop = 1;
     } while (!stop);
     
     return (n == 0) ? 0 : errno; 
}

static int check_lock(int fd, char *fname)
{
     struct stat fs = {0}, ds = {0};
     
     /* You might grab a lock on a file, but the file 
      * might be changed just before you grabbed the lock. Detect that and fail..
      */
     if (fstat(fd, &ds) < 0 || 
	 stat(fname, &fs) < 0 ||
	 
	 ds.st_nlink != fs.st_nlink ||
	 memcmp(&ds.st_dev,&fs.st_dev, sizeof ds.st_dev) != 0 ||
	 memcmp(&ds.st_ino,&fs.st_ino, sizeof ds.st_ino) != 0 ||
	 ds.st_uid != fs.st_uid ||
	 ds.st_gid != fs.st_gid ||
	 ds.st_size != fs.st_size)
	  return -1;
     else 
	  return 0;
}

int mm_lockfile(int fd, char *fname, int shouldblock)
{
     int ret = lockfile(fd,shouldblock);

     if (ret != 0 || 
	 (ret = check_lock(fd,fname)) != 0)
	  return ret;     
     return 0;
}

void mms_collect_envdata_from_msgheaders(List *mh, List **xto, 
					 Octstr **subject, 
					 Octstr **otransid, time_t *expiryt, 
					 time_t *deliveryt, long default_msgexpiry)
{

     Octstr *s;
     List *l = http_header_find_all(mh, "To");
     if (l) { 
	  int i, n;
	  for (i = 0, n = gwlist_len(l); i<n; i++) {
	       Octstr *name, *value;
	       http_header_get(l, i, &name, &value);
	       gwlist_append(*xto, value);
	       octstr_destroy(name);

	  }
	  http_destroy_headers(l);
     }
     
     l = http_header_find_all(mh, "Cc");
     if (l) { 
	  int i, n;
	  for (i = 0, n = gwlist_len(l); i<n; i++) {
	       Octstr *name, *value;
	       http_header_get(l, i, &name, &value);
	       gwlist_append(*xto, value);
	       octstr_destroy(name);

	  }
	  http_destroy_headers(l);
     }
     
     
     l = http_header_find_all(mh, "Bcc");
     if (l) { 
	  int i, n;

	  for (i = 0, n = gwlist_len(l); i<n; i++) {
	       Octstr *name, *value;
	       http_header_get(l, i, &name, &value);
	       gwlist_append(*xto, value);
	       octstr_destroy(name);

	  }
	  http_destroy_headers(l);
     }
                   
     /* Find expiry and delivery times */
     if (expiryt) {
	  s = http_header_value(mh, octstr_imm("X-Mms-Expiry"));
	  if (s) {
	       *expiryt = date_parse_http(s);
	       octstr_destroy(s);
	  } else 
	       *expiryt = time(NULL) + default_msgexpiry;
     }
     
     if (deliveryt) {
	  s = http_header_value(mh, octstr_imm("X-Mms-Delivery-Time"));
	  if (s) {
	       *deliveryt = date_parse_http(s);
	       octstr_destroy(s);
	  } else 
	       *deliveryt = 0;
     }
     if (subject)
	  *subject = http_header_value(mh, octstr_imm("Subject"));

     if (otransid)
	  *otransid = http_header_value(mh, octstr_imm("X-Mms-Transaction-ID")); 

}

unsigned long _mshash(char *s)
{
     unsigned h = 0;
     
     while (*s) {
	  unsigned int ch = tolower(*s);
	  s++;
          h += ((unsigned)(ch) << 4) + 1249;
     }
     return h;
}

int isphonenum(Octstr *s)
{
     int i = 0, n = octstr_len(s);
     char *cs;

     if (s && octstr_len(s) >= 1 && 
	  octstr_get_cstr(s)[0] == '+')
	  i++;
     for ( cs = octstr_get_cstr(s); i<n; i++)
	  if (!gw_isdigit(cs[i]))
	       return 0;
     return 1;
}

/* Doesn't handle IP addresses very well */
void _mms_fixup_address(Octstr *address, char *unified_prefix)
{
     int i;
     Octstr *typ;

     if (!address) return;
     i = octstr_search_char(address, '@', 0);     
     if (i>0) /* an email address. */
	  return;
     
     i = octstr_search(address, octstr_imm("/TYPE="), 0);
     if (i > 0) {
	  typ = octstr_copy(address, i, octstr_len(address));
	  octstr_delete(address, i, octstr_len(address));
     } else 
	  typ = NULL;

     if (isphonenum(address) || (typ && octstr_str_compare(typ, "/TYPE=PLMN") == 0)) {
	  if (unified_prefix)
	       normalize_number(unified_prefix, &address);
	  octstr_append(address, octstr_imm("/TYPE=PLMN"));
     } else if (typ) 
	  octstr_append(address, typ);     
     else
	  octstr_append(address, octstr_imm("@unknown"));     
     octstr_destroy(typ);
}

/* compare, reversed result! */
static int comp_fn(void *item, void *pattern)
{
     return (octstr_case_compare(item, pattern) == 0) ? 1 : 0;
}
int is_allowed_host(Octstr *host, Octstr *host_list)
{
     List *l;
     int ret;
     gw_assert(host_list);
     gw_assert(host);
     
     l = octstr_split(host_list, octstr_imm(";"));

     ret = (gwlist_search(l, host, comp_fn) != NULL) ? 1 : 0;
     
     gwlist_destroy(l, (void *)octstr_destroy);
     
     return ret;
}

#define SHELLCHARS "'|\"()[]{}$&!?*><%`\n \t\\"
void escape_shell_chars(Octstr *str)
{
     Octstr *tmp;
     int i, n;

     octstr_strip_blanks(str);

     tmp = octstr_duplicate(str);
     octstr_delete(str, 0, octstr_len(str));

     for (i = 0, n = octstr_len(tmp); i < n; i++) {
	  int ch = octstr_get_char(tmp,i);

	  if (strchr(SHELLCHARS, ch) != NULL)
	       octstr_append_char(str, '\\');
	  octstr_append_char(str, ch);	
     }
     octstr_destroy(tmp);
}

int parse_cgivars(List *request_headers, Octstr *request_body,
		  List **cgivars, List **cgivar_ctypes)
{
     Octstr *ctype = NULL, *charset = NULL; 
     int ret = 0;
     
     if (request_body == NULL || 
	 octstr_len(request_body) == 0 || cgivars == NULL)
	  return 0; /* Nothing to do, this is a normal GET request. */
     
     http_header_get_content_type(request_headers, &ctype, &charset);

     if (*cgivars == NULL)
	  *cgivars = gwlist_create();

     if (*cgivar_ctypes == NULL)
	  *cgivar_ctypes = gwlist_create();

     if (!ctype) {
	  warning(0, "MMS: Parse CGI Vars: Missing Content Type!");
	  ret = -1;
	  goto done;
     }

     if (octstr_case_compare(ctype, octstr_imm("application/x-www-form-urlencoded")) == 0) {
	  /* This is a normal POST form */
	  List *l = octstr_split(request_body, octstr_imm("&"));
	  Octstr *v;

	  while ((v = gwlist_extract_first(l)) != NULL) {
	       List *r = octstr_split(v, octstr_imm("="));
	       
	       if (gwlist_len(r) == 0)
		    warning(0, "MMS: Parse CGI Vars: Missing CGI var name/value in POST data: %s",
			    octstr_get_cstr(request_body));
	       else {
		    HTTPCGIVar *x = gw_malloc(sizeof *x);
		    x->name =  gwlist_extract_first(r);
		    x->value = gwlist_extract_first(r);
		    if (!x->value)
			 x->value = octstr_imm("");
		
		    octstr_strip_blanks(x->name);
		    octstr_strip_blanks(x->value);
		    
		    octstr_url_decode(x->name);
		    octstr_url_decode(x->value);
		    
		    gwlist_append(*cgivars, x);
	       }
	       octstr_destroy(v);
	       gwlist_destroy(r, octstr_destroy_item);
	  }
	  gwlist_destroy(l, NULL);
     } else if (octstr_case_compare(ctype, octstr_imm("multipart/form-data")) == 0) {
	  /* multi-part form data */
	  MIMEEntity *m = mime_http_to_entity(request_headers, request_body);
	  int i, n;
	  
	  if (!m) {
	       warning(0, "MMS: Parse CGI Vars: Failed to parse multipart/form-data body: %s",
		       octstr_get_cstr(request_body));
	       ret = -1;
	       goto done;
	  }
	  /* Go through body parts, pick out what we need. */
	  for (i = 0, n = mime_entity_num_parts(m); i < n; i++) {
	       MIMEEntity *mp = mime_entity_get_part(m, i);
	       List   *headers = mime_entity_headers(mp);
	       Octstr *body = mime_entity_body(mp);
 	       Octstr *ct = http_header_value(headers, 
					      octstr_imm("Content-Type"));      
	       Octstr *cd = http_header_value(headers, 
					      octstr_imm("Content-Disposition"));
	       Octstr *name = http_get_header_parameter(cd, octstr_imm("name"));

	       if (name) {
		    HTTPCGIVar *x = gw_malloc(sizeof *x);
		    
		    /* Strip quotes */
		    if (octstr_get_char(name, 0) == '"') {
			 octstr_delete(name, 0, 1);		    
			 octstr_truncate(name, octstr_len(name) - 1);
		    }
		    
		    x->name = octstr_duplicate(name);
		    x->value = octstr_duplicate(body);
		    
		    gwlist_append(*cgivars, x);
		    
		    if (ct) { /* If the content type is set, use it. */
			 x = gw_malloc(sizeof *x);
			 x->name = octstr_duplicate(name);
			 x->value = octstr_duplicate(ct);
			 
			 gwlist_append(*cgivar_ctypes, x);
		    }
		    octstr_destroy(name);
	       }

	       octstr_destroy(ct);	       
	       octstr_destroy(cd);	       
	       octstr_destroy(body);
	       http_destroy_headers(headers);
	       mime_entity_destroy(mp);
	  }
	  mime_entity_destroy(m);
	  
     } else /* else it is nothing that we know about, so simply go away... */
	  ret = -1;
done:
     octstr_destroy(ctype);
     octstr_destroy(charset);	       
     return ret;
}

/* get content-ID header, fix: WAP decoder may leave \" at beginning */
Octstr *_x_get_content_id(List *headers)
{
     Octstr *cid = http_header_value(headers, octstr_imm("Content-ID"));

     if (cid)
	  if (octstr_get_char(cid, 0) == '"' && 
	      octstr_get_char(cid, octstr_len(cid) - 1) != '"')
	       octstr_delete(cid, 0,1);
     return cid;
}

/* Utility: Take a header list, remove any boundary parameter from the content-type
 * element. We don't want this in the WSP packed content.
 */
void strip_boundary_element(List *headers, char *s)
{
     Octstr *ctype = NULL, *params = NULL;     
     Octstr *value;
     int n;
     
     gw_assert(headers);     

     if ((n = get_content_type(headers, &ctype, &params)) < 0) {
	  octstr_destroy(ctype);
	  ctype = NULL; /* no ctype found, so do not replace it! */
     } else if (ctype && 
		DRM_CONTENT_TYPE(ctype)) { 
	  octstr_destroy(ctype);
	  ctype = NULL; /* leave drm alone! */
     }

     if (s) {/* we are replacing the content type as well as stripping */
	  octstr_destroy(ctype);
	  ctype = octstr_create(s);
     }
	  
     if (params && ctype) {
	  List *h = get_value_parameters(params);
	  Octstr *ps;
	  http_header_remove_all(h,"boundary"); /* We  don't need the boundary param if it is there. */
	  ps = make_value_parameters(h);
	  
	  value = octstr_format("%S%s%S", ctype, 
				(ps && octstr_len(ps) > 0) ? "; " : "", 
				ps);
	  octstr_destroy(ps);
	  http_destroy_headers(h);
     } else 
	  value = ctype;
     if (value) {
	  http_header_remove_all(headers, "Content-Type");
	  http_header_add(headers, "Content-Type", octstr_get_cstr(value));     
     }
     if (ctype != value)
	  octstr_destroy(ctype);
     octstr_destroy(value);     
}


/* Mapping file extensions to content types. */
static struct {
     char *ctype,  *file_ext;
} exts[] = {
     {"text/plain", "txt"},
     {"image/jpeg",  "jpg"},
     {"image/jpeg",  "jpeg"},
     {"image/png",  "png"},
     {"image/tiff",  "tiff"},

⌨️ 快捷键说明

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