static void test61(void) { ACL_VSTRING* buf; buf = acl_vstring_alloc(256); acl_vstring_strcpy(buf, "hello world!"); acl_vstring_strcat(buf, "hello world!"); acl_vstring_strcat(buf, "hello world!"); acl_vstring_strcat(buf, "hello world!"); acl_vstring_strcat(buf, "hello world!"); acl_vstring_strcat(buf, "hello world!"); acl_vstring_strcat(buf, "hello world!"); acl_vstring_strcat(buf, "hello world!"); acl_vstring_strcat(buf, "hello world!"); acl_vstring_strcat(buf, "hello world!"); acl_vstring_strcat(buf, "hello world!"); acl_vstring_strcat(buf, "hello world!"); acl_vstring_strcat(buf, "hello world!"); acl_vstring_strcat(buf, "hello world!"); acl_vstring_strcat(buf, "hello world!"); acl_vstring_strcat(buf, "hello world!"); acl_vstring_strcat(buf, "hello world!"); acl_vstring_strcat(buf, "hello world!"); acl_vstring_strcat(buf, "hello world!"); acl_vstring_strcat(buf, "hello world!"); acl_vstring_strcat(buf, "hello world!"); acl_vstring_strcat(buf, "hello world!"); acl_vstring_strcat(buf, "hello world!"); acl_vstring_strcat(buf, "hello world!"); acl_vstring_strcat(buf, "hello world!"); acl_vstring_strcat(buf, "hello world!"); acl_vstring_strcat(buf, "hello world!"); acl_vstring_strcat(buf, "hello world!"); acl_vstring_strcat(buf, "hello world!"); acl_vstring_strcat(buf, "hello world!"); acl_vstring_strcat(buf, "hello world!"); acl_vstring_strcat(buf, "hello world!"); acl_vstring_strcat(buf, "hello world!"); acl_vstring_strcat(buf, "hello world!"); acl_vstring_strcat(buf, "hello world!"); acl_vstring_free(buf); }
HTTP_UTIL *http_util_req_new(const char *url, const char *method) { const char *myname = "http_util_req_new"; HTTP_UTIL *http_util = (HTTP_UTIL*) acl_mycalloc(1, sizeof(HTTP_UTIL)); const char *ptr, *host; if (url == NULL || *url == 0) { acl_msg_error("%s(%d): url invalid", myname, __LINE__); return (NULL); } if (method == NULL || *method == 0) { acl_msg_error("%s(%d): method invalid", myname, __LINE__); return (NULL); } if (acl_strncasecmp(url, "http://", sizeof("http://") - 1) != 0) { acl_msg_error("%s(%d): url(%s) invalid", myname, __LINE__, url); return (NULL); } if (strcmp(method, "GET") != 0 && strcmp(method, "POST") != 0 && strcmp(method, "HEAD") != 0 && strcmp(method, "CONNECT") != 0) { acl_msg_error("%s(%d): method(%s) invalid", myname, __LINE__, method); return (NULL); } http_util->hdr_req = http_hdr_req_create(url, method, "HTTP/1.1"); http_util->hdr_res = http_hdr_res_new(); http_util->http_res = http_res_new(http_util->hdr_res); http_util->req_buf = acl_vstring_alloc(4096); host = http_hdr_req_host(http_util->hdr_req); if (host) { ptr = strchr(host, ':'); if (ptr == NULL) snprintf(http_util->server_addr, sizeof(http_util->server_addr), "%s:80", host); else ACL_SAFE_STRNCPY(http_util->server_addr, host, sizeof(http_util->server_addr)); } http_util->conn_timeout = 10; http_util->rw_timeout = 10; return (http_util); }
void acl_proctl_stop_one(const char *progname, const char *progchild, int argc, char *argv[]) { const char *myname = "acl_proctl_stop_one"; char ebuf[256], buf[1024]; ACL_VSTREAM *client; ACL_VSTRING *child_args = NULL; int n; if (argc > 0) { int i; child_args = acl_vstring_alloc(256); for (i = 0; i < argc; i++) { if (i > 0) acl_vstring_strcat(child_args, " "); acl_vstring_strcat(child_args, "\""); acl_vstring_strcat(child_args, argv[i]); acl_vstring_strcat(child_args, "\""); } } client = proctl_client_open(progname); if (child_args) n = acl_vstream_fprintf(client, "%s|-d|STOP|-f|%s|-a|%s\r\n", progname, progchild, acl_vstring_str(child_args)); else n = acl_vstream_fprintf(client, "%s|-d|STOP|-f|%s\r\n", progname, progchild); if (child_args != NULL) acl_vstring_free(child_args); if (n == ACL_VSTREAM_EOF) acl_msg_fatal("%s(%d): fprintf to acl_proctl error(%s)", myname, __LINE__, acl_last_strerror(ebuf, sizeof(ebuf))); while (1) { n = acl_vstream_gets_nonl(client, buf, sizeof(buf)); if (n == ACL_VSTREAM_EOF) break; acl_msg_info("%s(%d): %s", myname, __LINE__, buf); } proctl_client_close(client); }
int main(int argc, char *argv[]) { char ch; char dns_ip[64], domain[128]; int dns_port = 53, ret; ACL_VSTRING *sbuf; dns_ip[0] = 0; domain[0] = 0; while ((ch = getopt(argc, argv, "h:p:d:")) > 0) { switch (ch) { case 'h': ACL_SAFE_STRNCPY(dns_ip, optarg, sizeof(dns_ip)); break; case 'p': dns_port = atoi(optarg); break; case 'd': ACL_SAFE_STRNCPY(domain, optarg, sizeof(domain)); break; default: usage(argv[0]); return (0); } } if (dns_ip[0] == 0 || domain[0] == 0) { usage(argv[0]); return (0); } sbuf = acl_vstring_alloc(128); ret = dns_lookup(domain, dns_ip, dns_port, sbuf); if (ret < 0) { printf("dns lookup(%s) error(%s)\r\n", domain, acl_vstring_str(sbuf)); acl_vstring_free(sbuf); return (0); } printf("domain: %s\r\n%s", domain, acl_vstring_str(sbuf)); acl_vstring_free(sbuf); return (0); }
const char *str_name_mask_opt(ACL_VSTRING *buf, const char *context, const NAME_MASK *table, int mask, int flags) { const char *myname = "name_mask"; const NAME_MASK *np; int len; static ACL_VSTRING *my_buf = 0; int delim = (flags & NAME_MASK_COMMA ? ',' : (flags & NAME_MASK_PIPE ? '|' : ' ')); if (buf == 0) { if (my_buf == 0) my_buf = acl_vstring_alloc(1); buf = my_buf; } ACL_VSTRING_RESET(buf); for (np = table; mask != 0; np++) { if (np->name == 0) { if (flags & NAME_MASK_FATAL) { acl_msg_fatal("%s: unknown %s bit in mask: 0x%x", myname, context, mask); } else if (flags & NAME_MASK_RETURN) { acl_msg_warn("%s: unknown %s bit in mask: 0x%x", myname, context, mask); return (0); } else if (flags & NAME_MASK_NUMBER) { acl_vstring_sprintf_append(buf, "0x%x%c", mask, delim); } break; } if (mask & np->mask) { mask &= ~np->mask; acl_vstring_sprintf_append(buf, "%s%c", np->name, delim); } } if ((len = (int) ACL_VSTRING_LEN(buf)) > 0) acl_vstring_truncate(buf, len - 1); ACL_VSTRING_TERMINATE(buf); return (STR(buf)); }
static SSL_SESSION *load_clnt_session(TLS_SESS_STATE *TLScontext) { const char *myname = "load_clnt_session"; SSL_SESSION *session = 0; ACL_VSTRING *session_data = acl_vstring_alloc(2048); /* * Prepare the query. */ if (TLScontext->log_level >= 2) acl_msg_info("looking for session %s in %s cache", TLScontext->serverid, TLScontext->cache_type); /* * We only get here if the cache_type is not empty. This code is not * called unless caching is enabled and the cache_type is stored in the * server SSL context. */ if (TLScontext->cache_type == 0) acl_msg_panic("%s: null client session cache type in session lookup", myname); /* * Look up and activate the SSL_SESSION object. Errors are non-fatal, * since caching is only an optimization. */ if (tls_mgr_lookup(TLScontext->cache_type, TLScontext->serverid, session_data) == TLS_MGR_STAT_OK) { session = tls_session_activate(STR(session_data), (int) LEN(session_data)); if (session) { if (TLScontext->log_level >= 2) acl_msg_info("reloaded session %s from %s cache", TLScontext->serverid, TLScontext->cache_type); } } /* * Clean up. */ acl_vstring_free(session_data); return (session); }
static void __post_jail_init_fn(char *unused_name, char **unused_argv) { char myname[] = "__post_jail_init_fn"; ACL_VSTRING *why = acl_vstring_alloc(100); unused_name = unused_name; unused_argv = unused_argv; if (acl_msg_verbose) acl_msg_info("%s(%d)->%s: test only", __FILE__, __LINE__, myname); __data_buf = acl_mymalloc(var_proxy_bufsize); if (__data_buf == NULL) acl_msg_fatal("%s(%d)->%s: malloc data_buf, serr = %s", __FILE__, __LINE__, myname, strerror(errno)); if (var_proxy_debug_request) { __request_stream = acl_safe_open(var_proxy_request_file, O_CREAT | O_RDWR | O_APPEND, 0600, (struct stat *) 0, (uid_t)-1, (uid_t )-1, why); if (__request_stream == NULL) acl_msg_fatal("%s(%d)->%s: can't open %s, err = %s", __FILE__, __LINE__, myname, var_proxy_request_file, acl_vstring_str(why)); } if (var_proxy_debug_respond) { __respond_stream = acl_safe_open(var_proxy_respond_file, O_CREAT | O_RDWR | O_APPEND, 0600, (struct stat *) 0, (uid_t)-1, (uid_t )-1, why); if (__respond_stream == NULL) acl_msg_fatal("%s(%d)->%s: can't open %s, err = %s", __FILE__, __LINE__, myname, var_proxy_respond_file, acl_vstring_str(why)); } acl_vstring_free(why); }
static void mail_from(MIME_NODE *node, const HEADER_OPTS *header_info) { //MIME_STATE *state = node->state; TOK822 *tree; TOK822 **addr_list; TOK822 **tpp; ACL_VSTRING *temp; const char *cp; temp = acl_vstring_alloc(10); cp = STR(node->buffer) + strlen(header_info->name) + 1; tree = tok822_parse(cp); addr_list = tok822_grep(tree, TOK822_ADDR); for (tpp = addr_list; *tpp; tpp++) { tok822_internalize(temp, tpp[0]->head, TOK822_STR_DEFL); if (header_info->type == HDR_SENDER) { if (node->header_sender) acl_myfree(node->header_sender); node->header_sender = acl_mystrdup(STR(temp)); break; } else if (header_info->type == HDR_FROM) { if (node->header_from) acl_myfree(node->header_from); node->header_from = acl_mystrdup(STR(temp)); break; } else if (header_info->type == HDR_REPLY_TO) { if (node->header_replyto) acl_myfree(node->header_replyto); node->header_replyto = acl_mystrdup(STR(temp)); break; } else if (header_info->type == HDR_RETURN_PATH) { if (node->header_returnpath) acl_myfree(node->header_returnpath); node->header_returnpath = acl_mystrdup(STR(temp)); } } acl_myfree(addr_list); tok822_free_tree(tree); acl_vstring_free(temp); }
static void b64_decode(const char *ptr) { ACL_VSTRING *str = acl_vstring_alloc(1); const char *p; #define DECODE(b,x,l) { \ if (acl_vstring_base64_decode((b),(x),(l)) == 0) { \ printf("bad base64 encoded string: %s\r\n", (x)); \ exit (1); \ } \ } DECODE(str, ptr, strlen(ptr)); p = acl_vstring_str(str); printf(">>>decode result:|%s|\n>>>orignal str: {%s}, len: %d\n", p, ptr, (int) ACL_VSTRING_LEN(str)); b64_encode(p); printf("len: %d, %d\n", (int) ACL_VSTRING_LEN(str), (int) strlen(p)); acl_vstring_free(str); }
ACL_TOKEN *acl_token_tree_create2(const char *s, const char *sep) { const char *myname = "acl_token_tree_create"; ACL_ARGV *argv; ACL_ITER iter; unsigned int flag; ACL_TOKEN *token_tree; const ACL_TOKEN *token; ACL_VSTRING *buf; token_tree = acl_token_new(); if (s == NULL || *s == 0) return (token_tree); buf = acl_vstring_alloc(256); argv = acl_argv_split(s, sep); acl_foreach(iter, argv) { char *word = (char*) iter.ptr; char *ptr = strchr(word, '|'); flag = ACL_TOKEN_F_STOP; if (ptr) { *ptr++ = 0; if (*ptr == 'D' || *ptr == 'd') flag |= ACL_TOKEN_F_DENY; if (*ptr == 'P' || *ptr == 'p') flag |= ACL_TOKEN_F_PASS; } token = acl_token_tree_add(token_tree, word, flag, NULL); if (token == NULL) { acl_msg_info("%s(%d): word(%s) discard", myname, __LINE__, word); } else { ACL_VSTRING_RESET(buf); acl_token_name(token, buf); /* acl_msg_info("%s(%d): add word(%s) ok, token's name(%s)", myname, __LINE__, word, STR(buf)); */ } }
static void update_str_vars(ACL_CONFIG_STR_TABLE cst[], const char *name, const ACL_CFG_LINE *item) { int i; ACL_VSTRING *buf; if (item->ncount <= 1) return; buf = acl_vstring_alloc(128); for (i = 1; i < item->ncount; i++) acl_vstring_strcat(buf, item->value[i]); for (i = 0; cst[i].name != 0; i++) { if (strcasecmp(cst[i].name, name) == 0) { acl_myfree(*(cst[i].target)); *(cst[i].target) = acl_vstring_export(buf); } } }
int main(int argc, char **argv) { static const NAME_MASK table[] = { "zero", 1 << 0, "one", 1 << 1, "two", 1 << 2, "three", 1 << 3, 0, 0, }; int mask; ACL_VSTRING *buf = acl_vstring_alloc(1); while (--argc && *++argv) { mask = name_mask("test", table, *argv); acl_vstream_printf("%s -> 0x%x -> %s\n", *argv, mask, str_name_mask("mask_test", table, mask)); acl_vstream_fflush(VSTREAM_OUT); } acl_vstring_free(buf); exit(0); }
static ACL_VSTRING *tls_scache_encode(TLS_SCACHE *cp, const char *cache_id, const char *session, ssize_t session_len) { TLS_SCACHE_ENTRY *entry; ACL_VSTRING *hex_data; ssize_t binary_data_len; /* * Assemble the TLS session cache entry. * * We could eliminate some copying by using incremental encoding, but * sessions are so small that it really does not matter. */ binary_data_len = session_len + offsetof(TLS_SCACHE_ENTRY, session); entry = (TLS_SCACHE_ENTRY *) acl_mymalloc(binary_data_len); entry->timestamp = time((time_t *) 0); memcpy(entry->session, session, session_len); /* * Encode the TLS session cache entry. */ hex_data = acl_vstring_alloc(2 * binary_data_len + 1); acl_hex_encode(hex_data, (char *) entry, binary_data_len); /* * Logging. */ if (cp->verbose) acl_msg_info("write %s TLS cache entry %s: time=%ld [data %ld bytes]", cp->cache_label, cache_id, (long) entry->timestamp, (long) session_len); /* * Clean up. */ acl_myfree(entry); return (hex_data); }
static void strip_address(ACL_VSTRING *vp, ssize_t start, TOK822 *addr) { ACL_VSTRING *tmp; /* * Emit plain <address>. Discard any comments or phrases. */ ACL_VSTRING_TERMINATE(vp); acl_msg_warn("stripping too many comments from address: %.100s...", acl_vstring_str(vp) + start); //acl_printable(vstring_str(vp) + start, '?')); //zsx acl_vstring_truncate(vp, start); ACL_VSTRING_ADDCH(vp, '<'); if (addr) { tmp = acl_vstring_alloc(100); tok822_internalize(tmp, addr, TOK822_STR_TERM); quote_822_local_flags(vp, acl_vstring_str(tmp), QUOTE_FLAG_8BITCLEAN | QUOTE_FLAG_APPEND); acl_vstring_free(tmp); } ACL_VSTRING_ADDCH(vp, '>'); }
void http_hdr_put_fmt(HTTP_HDR *hdr, const char *name, const char *fmt, ...) { char myname[] = "http_hdr_put_fmt"; va_list ap; HTTP_HDR_ENTRY *entry; ACL_VSTRING *strbuf = acl_vstring_alloc(1024); if (strbuf == NULL) { char ebuf[256]; acl_msg_fatal("%s, %s(%d): calloc error(%s)", __FILE__, myname, __LINE__, acl_last_strerror(ebuf, sizeof(ebuf))); } va_start(ap, fmt); acl_vstring_vsprintf_append(strbuf, fmt, ap); va_end(ap); entry = http_hdr_entry_build(name, acl_vstring_str(strbuf)); if (entry) http_hdr_append_entry(hdr, entry); acl_vstring_free(strbuf); }
static void notify_thread(void *arg) { const char *myname = "notify_thread"; WARN_INFO *info = (WARN_INFO*) arg; ACL_VSTREAM *client; ACL_VSTRING *buf; int ret; buf = acl_vstring_alloc(256); acl_vstring_sprintf(buf, "PROC=%s|PID=%d|RCPT=%s|info=%s\r\n", info->path, info->pid, info->notify_recipients, info->desc); client = acl_vstream_connect(info->notify_addr, ACL_BLOCKING, 60, 60, 1024); if (client == NULL) { acl_msg_error("%s(%d): connect %s error, info(%s)", myname, __LINE__, info->notify_addr, acl_vstring_str(buf)); acl_vstring_free(buf); warn_info_free(info); return; } /* 禁止将该句柄传递给子进程 */ acl_close_on_exec(ACL_VSTREAM_SOCK(client), ACL_CLOSE_ON_EXEC); ret = acl_vstream_writen(client, acl_vstring_str(buf), ACL_VSTRING_LEN(buf)); if (ret == ACL_VSTREAM_EOF) acl_msg_error("%s(%d): write to notify server error, info(%s)", myname, __LINE__, acl_vstring_str(buf)); else acl_msg_info("%s(%d): notify ok!", myname, __LINE__); acl_vstream_close(client); acl_vstring_free(buf); warn_info_free(info); }
static int sms_send(ACL_VSTREAM *client, const char *phone, const char *proc, int pid, const char *info, const char *ip) { ACL_VSTRING *buf = acl_vstring_alloc(256); ACL_XML *xml = acl_xml_alloc(); char res[1024]; int ret; acl_vstring_sprintf(buf, "<send_sms phone=\"%s\" message=\"proc:%s, pid:%d, ip:%s, info:%s\" />", phone, proc, pid, ip, info); if (acl_vstream_writen(client, acl_vstring_str(buf), ACL_VSTRING_LEN(buf)) == ACL_VSTREAM_EOF) { acl_msg_error("write to sms server error, msg: %s", acl_vstring_str(buf)); acl_vstring_free(buf); return (-1); } acl_msg_info(">>send: %s", acl_vstring_str(buf)); acl_vstring_free(buf); while (1) { ret = acl_vstream_read(client, res, sizeof(res) - 1); if (ret == ACL_VSTREAM_EOF) return (-1); res[ret] = 0; acl_xml_parse(xml, res); if (acl_xml_is_complete(xml, "send_sms")) { acl_msg_info("send ok!(%s)", res); break; } } return (0); }
/* 通知主线程,启动一个服务 */ static int proctl_monitor_cmd_start(ACL_VSTREAM *client, const char *filepath, const char *args) { const char *myname = "proctl_monitor_cmd_start"; ACL_VSTRING *cmdline; PROCTL_SERVICE *service; PROCTL_MSG *msg; if (filepath[0] == 0) { acl_vstream_fprintf(client, "-ERR|filepath null\r\n"); acl_msg_error("%s(%d): no filepath", myname, __LINE__); return (-1); } if (proctl_service_exist(filepath)) { acl_msg_error("%s(%d): child(%s) maybe be running!", myname, __LINE__, filepath); acl_vstream_fprintf(client, "-ERR|child(%s) maybe be running!\r\n", filepath); return (-1); } cmdline = acl_vstring_alloc(256); acl_vstring_strcpy(cmdline, "\""); acl_vstring_strcat(cmdline, filepath); acl_vstring_strcat(cmdline, "\""); if (args && *args) { acl_vstring_strcat(cmdline, " "); acl_vstring_strcat(cmdline, args); } service = proctl_service_alloc(filepath, cmdline); msg = proctl_msg_new(PROCTL_MSG_START); msg->service = service; proctl_msg_push(msg); return (0); }
static void test_json_build(void) { ACL_JSON* json = acl_json_alloc(); ACL_JSON_NODE* root, *node1, *node2, *node3, *node4; root = acl_json_create_obj(json); acl_json_node_append_child(json->root, root); node1 = acl_json_create_leaf(json, "name1", "value1"); acl_json_node_append_child(root, node1); node1 = acl_json_create_leaf(json, "name2", "value2"); acl_json_node_append_child(root, node1); node1 = acl_json_create_obj(json); node2 = acl_json_create_leaf(json, "name3", "value3"); acl_json_node_append_child(node1, node2); node2 = acl_json_create_node(json, "name4", node1); acl_json_node_append_child(root, node2); node3 = acl_json_create_bool(json, "VAR_BOOL", 0); acl_json_node_append_child(root, node3); node4 = acl_json_create_null(json, "VAR_NULL"); acl_json_node_append_child(root, node4); ////////////////////////////////////////////////////////////////////////// node1 = acl_json_create_array(json); node2 = acl_json_create_node(json, "name5", node1); acl_json_node_append_child(root, node2); node3 = acl_json_create_leaf(json, "name6", "value6"); acl_json_node_append_child(node1, node3); node3 = acl_json_create_leaf(json, "name7", "value7"); acl_json_node_append_child(node1, node3); node3 = acl_json_create_obj(json); acl_json_node_append_child(node1, node3); node2 = acl_json_create_leaf(json, "name8", "value8"); acl_json_node_append_child(node3, node2); node2 = acl_json_create_leaf(json, "name9", "value9"); acl_json_node_append_child(node3, node2); node4 = acl_json_create_array_bool(json, 1); acl_json_node_append_child(node1, node4); node4 = acl_json_create_array_null(json); acl_json_node_append_child(node1, node4); ////////////////////////////////////////////////////////////////////////// ACL_VSTRING *buf1 = acl_vstring_alloc(128); ACL_VSTRING *buf2 = acl_vstring_alloc(128); acl_json_build(json, buf1); acl_json_building(json, 1, build_callback, buf2); printf("%s\r\n", acl_vstring_str(buf1)); printf("%s\r\n", acl_vstring_str(buf2)); if (strcmp(STR(buf1), STR(buf2)) != 0) printf("BUILD ERROR\r\n"); else printf("BUILD OK\r\n"); acl_vstring_free(buf1); acl_vstring_free(buf2); acl_json_free(json); }
static ZDB_DISK *zdb_disks_load(const char *dbname, const char *dbpath) { const char *myname = "zdb_disks_load"; ACL_VSTRING *buf = acl_vstring_alloc(256); ACL_FILE *fp = NULL; char disk_info[INFO_LEN + 1]; ZDB_DISK *disk, *disks; ACL_ARRAY *a = NULL; ACL_ITER iter; int n, i; #undef RETURN #define RETURN(x) do { \ if (fp) \ acl_fclose(fp); \ acl_vstring_free(buf); \ if (a) \ acl_array_destroy(a, free_disk); \ return (x); \ } while (0) acl_vstring_sprintf(buf, "%s/.%s.disk", dbpath, dbname); fp = acl_fopen(STR(buf), "r"); if (fp == NULL) { acl_msg_error("%s(%d): fopen(%s) error(%s)", myname, __LINE__, STR(buf), acl_last_serror()); RETURN (NULL); } a = acl_array_create(10); while (1) { ACL_ARGV *argv; if (acl_fgets_nonl(disk_info, sizeof(disk_info), fp) == NULL) break; argv = acl_argv_split(disk_info, "|"); if (argv->argc != ITEM_CNT) { acl_msg_error("%s(%d): invalid line(%s)", myname, __LINE__, disk_info); acl_argv_free(argv); continue; } disk = (ZDB_DISK*) acl_mycalloc(1, sizeof(ZDB_DISK)); disk->path = acl_mystrdup(argv->argv[0]); disk->idisk = atoi(argv->argv[1]); disk->priority = atoi(argv->argv[2]); disk->limit = acl_atoui64(argv->argv[3]); disk->count = acl_atoui64(argv->argv[4]); if (acl_array_append(a, disk) < 0) acl_msg_fatal("%s(%d): add disk error(%s)", myname, __LINE__, acl_last_serror()); acl_argv_free(argv); } n = acl_array_size(a); if (n <= 0) { acl_msg_error("%s(%d): empty array of ZDB_DISK", myname, __LINE__); RETURN (NULL); } disks = (ZDB_DISK*) acl_mycalloc(n + 1, sizeof(ZDB_DISK)); i = 0; acl_foreach(iter, a) { disk = (ZDB_DISK*) iter.data; disks[i].limit = disk->limit; disks[i].count = disk->count; disks[i].path = acl_mystrdup(disk->path); disks[i].idisk = disk->idisk; disks[i].priority = disk->priority; disks[i].dat_ifiles = NULL; disks[i].dat_ifiles_size = 0; if (disks[i].idisk != i) { acl_msg_error("%s(%d): idisk(%d) != %d invalid for %s", myname, __LINE__, disks[i].idisk, i, disks[i].path); acl_myfree(disks); RETURN (NULL); } i++; }
int mac_parse(const char *value, MAC_PARSE_FN action, char *context) { const char *myname = "mac_parse"; ACL_VSTRING *buf = acl_vstring_alloc(1); /* result buffer */ const char *vp; /* value pointer */ const char *pp; /* open_paren pointer */ const char *ep; /* string end pointer */ static char open_paren[] = "({"; static char close_paren[] = ")}"; int level; int status = 0; #define SKIP(start, var, cond) \ for (var = start; *var && (cond); var++); acl_debug(DEBUG_MAC, 2) ("%s: %s", myname, value); for (vp = value; *vp;) { if (*vp != '$') { /* ordinary character */ ACL_VSTRING_ADDCH(buf, *vp); vp += 1; } else if (vp[1] == '$') { /* $$ becomes $ */ ACL_VSTRING_ADDCH(buf, *vp); vp += 2; } else { /* found bare $ */ if (ACL_VSTRING_LEN(buf) > 0) MAC_PARSE_ACTION(status, MAC_PARSE_LITERAL, buf, context); vp += 1; pp = open_paren; if (*vp == *pp || *vp == *++pp) { /* ${x} or $(x) */ level = 1; vp += 1; for (ep = vp; level > 0; ep++) { if (*ep == 0) { acl_msg_warn("truncated macro reference: \"%s\"", value); status |= MAC_PARSE_ERROR; break; } if (*ep == *pp) level++; if (*ep == close_paren[pp - open_paren]) level--; } if (status & MAC_PARSE_ERROR) break; acl_vstring_strncat(buf, vp, level > 0 ? ep - vp : ep - vp - 1); vp = ep; } else { /* plain $x */ SKIP(vp, ep, ACL_ISALNUM(*ep) || *ep == '_'); acl_vstring_strncat(buf, vp, ep - vp); vp = ep; } if (ACL_VSTRING_LEN(buf) == 0) { status |= MAC_PARSE_ERROR; acl_msg_warn("empty macro name: \"%s\"", value); break; } MAC_PARSE_ACTION(status, MAC_PARSE_EXPR, buf, context); } } if (ACL_VSTRING_LEN(buf) > 0 && (status & MAC_PARSE_ERROR) == 0) MAC_PARSE_ACTION(status, MAC_PARSE_LITERAL, buf, context); /* * Cleanup. */ acl_vstring_free(buf); return (status); }
char *acl_sane_basename(ACL_VSTRING *bp, const char *path) { const char *myname = "acl_sane_basename"; const char *first; const char *last; /* * Your buffer or mine? */ if (bp == 0) { acl_msg_error("%s(%d): bp null", myname, __LINE__); return (NULL); } /* * Special case: return "." for null or zero-length input. */ if (path == 0 || *path == 0) return (STR(acl_vstring_strcpy(bp, "."))); /* * Remove trailing '/' characters from input. Return "/" if input is all * '/' characters. */ last = path + strlen(path) - 1; #ifdef ACL_UNIX while (*last == '/') { #elif defined(ACL_MS_WINDOWS) while (*last == '/' || *last == '\\') { #endif if (last == path) return (STR(acl_vstring_strcpy(bp, "/"))); last--; } /* * The pathname does not end in '/'. Skip to last '/' character if any. */ first = last - 1; #ifdef ACL_UNIX while (first >= path && *first != '/') #elif defined(ACL_MS_WINDOWS) while (first >= path && *first != '/' && *first != '\\') #endif first--; return (STR(acl_vstring_strncpy(bp, first + 1, last - first))); } /* acl_sane_dirname - keep directory prefix */ char *acl_sane_dirname(ACL_VSTRING *bp, const char *path) { const char *myname = "acl_sane_dirname"; const char *last; /* * Your buffer or mine? */ if (bp == 0) { acl_msg_error("%s(%d): bp null", myname, __LINE__); return (NULL); } /* * Special case: return "." for null or zero-length input. */ if (path == 0 || *path == 0) return (STR(acl_vstring_strcpy(bp, "."))); /* * Remove trailing '/' characters from input. Return "/" if input is all * '/' characters. */ last = path + strlen(path) - 1; #ifdef ACL_UNIX while (*last == '/') { #elif defined(ACL_MS_WINDOWS) while (*last == '/' || *last == '\\') { #endif if (last == path) return (STR(acl_vstring_strcpy(bp, "/"))); last--; } /* * This pathname does not end in '/'. Skip to last '/' character if any. */ #ifdef ACL_UNIX while (last >= path && *last != '/') #elif defined(ACL_MS_WINDOWS) while (last >= path && *last != '/' && *last != '\\') #endif last--; if (last < path) /* no '/' */ return (STR(acl_vstring_strcpy(bp, "."))); /* * Strip trailing '/' characters from dirname (not strictly needed). */ #ifdef ACL_UNIX while (last > path && *last == '/') #elif defined(ACL_MS_WINDOWS) while (last > path && (*last == '/' || *last == '\\')) #endif last--; return (STR(acl_vstring_strncpy(bp, path, last - path + 1))); } #ifdef TEST #include "stdlib/acl_vstring_vstream.h" int main(int argc acl_unused, char **argv acl_unused) { ACL_VSTRING *buf = acl_vstring_alloc(10); char *dir; char *base; while (acl_vstring_gets_nonl(buf, ACL_VSTREAM_IN) > 0) { dir = acl_sane_dirname((ACL_VSTRING *) 0, STR(buf)); base = acl_sane_basename((ACL_VSTRING *) 0, STR(buf)); acl_vstream_printf("input=\"%s\" dir=\"%s\" base=\"%s\"\n", STR(buf), dir, base); } acl_vstream_fflush(ACL_VSTREAM_OUT); acl_vstring_free(buf); return (0); }
int main(int unused_ac, char **av) { ACL_VSTRING *inbuf = acl_vstring_alloc(10); int status; ARGV *argv = 0; ACL_EVENT *eventp = acl_event_new_select(1, 0); acl_msg_verbose = 3; mail_conf_read(); acl_msg_info("using config files in %s", var_config_dir); if (chdir(var_queue_dir) < 0) acl_msg_fatal("chdir %s: %s", var_queue_dir, acl_last_serror()); tls_mgr_open(eventp); while (acl_vstring_fgets_nonl(inbuf, ACL_VSTREAM_IN)) { argv = argv_split(STR(inbuf), " \t\r\n"); if (argv->argc == 0) { argv_free(argv); continue; } #define COMMAND(argv, str, len) \ (strcasecmp(argv->argv[0], str) == 0 && argv->argc == len) if (COMMAND(argv, "policy", 2)) { int cachable; status = tls_mgr_policy(argv->argv[1], &cachable); acl_vstream_printf("status=%d cachable=%d\n", status, cachable); } else if (COMMAND(argv, "seed", 2)) { ACL_VSTRING *buf = acl_vstring_alloc(10); ACL_VSTRING *hex = acl_vstring_alloc(10); int len = atoi(argv->argv[1]); status = tls_mgr_seed(buf, len); hex_encode(hex, STR(buf), LEN(buf)); acl_vstream_printf("status=%d seed=%s\n", status, STR(hex)); acl_vstring_free(hex); acl_vstring_free(buf); } else if (COMMAND(argv, "lookup", 3)) { ACL_VSTRING *buf = acl_vstring_alloc(10); status = tls_mgr_lookup(argv->argv[1], argv->argv[2], buf); acl_vstream_printf("status=%d session=%.*s\n", status, LEN(buf), STR(buf)); acl_vstring_free(buf); } else if (COMMAND(argv, "update", 4)) { status = tls_mgr_update(argv->argv[1], argv->argv[2], argv->argv[3], strlen(argv->argv[3])); acl_vstream_printf("status=%d\n", status); } else if (COMMAND(argv, "delete", 3)) { status = tls_mgr_delete(argv->argv[1], argv->argv[2]); acl_vstream_printf("status=%d\n", status); } else { acl_vstream_printf("usage:\n" "seed byte_count\n" "policy smtpd|smtp|lmtp\n" "lookup smtpd|smtp|lmtp cache_id\n" "update smtpd|smtp|lmtp cache_id session\n" "delete smtpd|smtp|lmtp cache_id\n"); } acl_vstream_fflush(ACL_VSTREAM_OUT); argv_free(argv); } acl_vstring_free(inbuf); acl_event_free(eventp); return (0); }
static void test_fseek2(int buflen) { ACL_VSTREAM *fp; ACL_VSTRING *why = acl_vstring_alloc(100); char filename[] ="./tmp.txt"; char buf[10]; int n; int offset, off2; int ch; fp = acl_safe_open(filename, O_CREAT | O_RDWR, 0600, (struct stat *) 0, (uid_t)-1, (uid_t )-1, why); if (fp == 0) acl_msg_fatal("%s(%d)->%s: can't open %s, serr = %s", __FILE__, __LINE__, __FUNCTION__, filename, acl_vstring_str(why)); fp->read_buf_len = buflen; ch = acl_vstream_getc(fp); printf("after read(1)(%d) >>> ch = %c, read_cnt = %d, offset=%d, %d\n", __LINE__, ch, (int) fp->read_cnt, (int) fp->offset, (int) fp->sys_offset); offset = acl_vstream_fseek2(fp, 0, SEEK_CUR); printf("after fseek(0)(%d) >>> ch = %c, read_cnt = %d, off = %d, offset=%d, %d\n\n", __LINE__, ch, (int)fp->read_cnt, offset, (int) fp->offset, (int) fp->sys_offset); ch = acl_vstream_getc(fp); printf("after read(1)(%d) >>> ch = %c, read_cnt = %d, offset=%d, %d\n", __LINE__, ch, (int) fp->read_cnt, (int) fp->offset, (int) fp->sys_offset); offset = acl_vstream_fseek2(fp, 0, SEEK_CUR); printf("after fseek(0)(%d) >>> ch = %c, read_cnt = %d, off = %d, %s, offset=%d, %d\n\n", __LINE__, ch, (int)fp->read_cnt, offset, strerror(errno), (int) fp->offset, (int) fp->sys_offset); offset = acl_vstream_fseek2(fp, 10, SEEK_CUR); off2 = lseek(ACL_VSTREAM_FILE(fp), 0, SEEK_CUR); printf("after fseek(10)(%d) >>> off=%d, lseek = %d, read_cnt = %d, offset=%d, %d\n\n", __LINE__, offset, off2, (int)fp->read_cnt, (int) fp->offset, (int) fp->sys_offset); n = acl_vstream_gets_nonl(fp, buf, sizeof(buf) - 1); printf("after read(getline)(%d) >>> buf = [%s], fp->read_cnt = %d, offset=%d, %d\n", __LINE__, buf, (int)fp->read_cnt, (int) fp->offset, (int) fp->sys_offset); offset = acl_vstream_fseek2(fp, 0, SEEK_CUR); printf("after fseek(0)(%d) >>> buf = [%s], read_cnt = %d, off = %d, offset=%d, %d\n\n", __LINE__, buf, (int) fp->read_cnt, offset, (int) fp->offset, (int) fp->sys_offset); ch = acl_vstream_getc(fp); printf("after read(1)(%d) >>> ch = %c, read_cnt = %d, offset=%d, %d\n", __LINE__, ch, (int)fp->read_cnt, (int) fp->offset, (int) fp->sys_offset); offset = acl_vstream_fseek2(fp, 0, SEEK_CUR); printf("after fseek(0)(%d) >>> ch = %c, read_cnt = %d, off = %d, offset=%d, %d\n\n", __LINE__, ch, (int) fp->read_cnt, offset, (int) fp->offset, (int) fp->sys_offset); n = acl_vstream_readn(fp, buf, 2); buf[n] = 0; printf("after read(buf)(%d) >>> buf = [%s], fp->read_cnt = %d, offset=%d, offset=%d, %d\n", __LINE__, buf, (int) fp->read_cnt, offset, (int) fp->offset, (int) fp->sys_offset); offset = acl_vstream_fseek2(fp, 10, SEEK_CUR); printf("after fseek(10)(%d) >>> read_cnt = %d, off = %d, offset=%d, %d\n\n", __LINE__, (int) fp->read_cnt, offset, (int) fp->offset, (int) fp->sys_offset); ch = acl_vstream_getc(fp); printf("after read(1)(%d) >>> ch = %c, read_cnt = %d, offset=%d, %d\n", __LINE__, ch, (int)fp->read_cnt, (int) fp->offset, (int) fp->sys_offset); offset = acl_vstream_fseek2(fp, 0, SEEK_CUR); printf("after fseek(0)(%d) >>> ch = %c, read_cnt = %d, off = %d, %s, offset=%d, %d\n\n", __LINE__, ch, (int) fp->read_cnt, offset, strerror(errno), (int) fp->offset, (int) fp->sys_offset); acl_vstring_free(why); acl_vstream_close(fp); }
ACL_VSTRING *tok822_externalize(ACL_VSTRING *vp, TOK822 *tree, int flags) { ACL_VSTRING *tmp; TOK822 *tp; ssize_t start = 0; TOK822 *addr = 0; ssize_t addr_len = 0; /* * Guard against a Sendmail buffer overflow (CERT advisory CA-2003-07). * The problem was that Sendmail could store too much non-address text * (comments, phrases, etc.) into a static 256-byte buffer. * * When the buffer fills up, fixed Sendmail versions remove comments etc. * and reduce the information to just <$g>, which expands to <address>. * No change is made when an address expression (text separated by * commas) contains no address. This fix reportedly also protects * Sendmail systems that are still vulnerable to this problem. * * Postfix takes the same approach, grudgingly. To avoid unnecessary damage, * Postfix removes comments etc. only when the amount of non-address text * in an address expression (text separated by commas) exceeds 250 bytes. * * With Sendmail, the address part of an address expression is the * right-most <> instance in that expression. If an address expression * contains no <>, then Postfix guarantees that it contains at most one * non-comment string; that string is the address part of the address * expression, so there is no ambiguity. * * Finally, we note that stress testing shows that other code in Sendmail * 8.12.8 bluntly truncates ``text <address>'' to 256 bytes even when * this means chopping the <address> somewhere in the middle. This is a * loss of control that we're not entirely comfortable with. However, * unbalanced quotes and dangling backslash do not seem to influence the * way that Sendmail parses headers, so this is not an urgent problem. */ #define MAX_NONADDR_LENGTH 250 #define RESET_NONADDR_LENGTH { \ start = ACL_VSTRING_LEN(vp); \ addr = 0; \ addr_len = 0; \ } #define ENFORCE_NONADDR_LENGTH do { \ if (addr && (ssize_t) ACL_VSTRING_LEN(vp) - addr_len > start + MAX_NONADDR_LENGTH) \ strip_address(vp, start, addr->head); \ } while(0) if (flags & TOK822_STR_WIPE) ACL_VSTRING_RESET(vp); if (flags & TOK822_STR_TRNC) RESET_NONADDR_LENGTH; for (tp = tree; tp; tp = tp->next) { switch (tp->type) { case ',': if (flags & TOK822_STR_TRNC) ENFORCE_NONADDR_LENGTH; ACL_VSTRING_ADDCH(vp, tp->type); ACL_VSTRING_ADDCH(vp, (flags & TOK822_STR_LINE) ? '\n' : ' '); if (flags & TOK822_STR_TRNC) RESET_NONADDR_LENGTH; continue; /* * XXX In order to correctly externalize an address, it is not * sufficient to quote individual atoms. There are higher-level * rules that say when an address localpart needs to be quoted. * We wing it with the quote_822_local() routine, which ignores * the issue of atoms in the domain part that would need quoting. */ case TOK822_ADDR: addr = tp; tmp = acl_vstring_alloc(100); tok822_internalize(tmp, tp->head, TOK822_STR_TERM); addr_len = ACL_VSTRING_LEN(vp); quote_822_local_flags(vp, acl_vstring_str(tmp), QUOTE_FLAG_8BITCLEAN | QUOTE_FLAG_APPEND); addr_len = ACL_VSTRING_LEN(vp) - addr_len; acl_vstring_free(tmp); break; case TOK822_ATOM: case TOK822_COMMENT: acl_vstring_strcat(vp, acl_vstring_str(tp->vstr)); break; case TOK822_QSTRING: ACL_VSTRING_ADDCH(vp, '"'); tok822_copy_quoted(vp, acl_vstring_str(tp->vstr), "\"\\\r\n"); ACL_VSTRING_ADDCH(vp, '"'); break; case TOK822_DOMLIT: ACL_VSTRING_ADDCH(vp, '['); tok822_copy_quoted(vp, acl_vstring_str(tp->vstr), "\\\r\n"); ACL_VSTRING_ADDCH(vp, ']'); break; case TOK822_STARTGRP: ACL_VSTRING_ADDCH(vp, ':'); break; case '<': if (tp->next && tp->next->type == '>') { addr = tp; addr_len = 0; } ACL_VSTRING_ADDCH(vp, '<'); break; default: if (tp->type >= TOK822_MINTOK) acl_msg_panic("tok822_externalize: unknown operator %d", tp->type); ACL_VSTRING_ADDCH(vp, tp->type); } if (tok822_append_space(tp)) ACL_VSTRING_ADDCH(vp, ' '); } if (flags & TOK822_STR_TRNC) ENFORCE_NONADDR_LENGTH; if (flags & TOK822_STR_TERM) ACL_VSTRING_TERMINATE(vp); return (vp); }
static void __add_cookie_item(ACL_HTABLE *table, const char *data) { /* data format: name=value */ const char *myname = "__add_cookie_item"; ACL_ARGV *argv = NULL; ACL_VSTRING *str = NULL; const char *name; char *value; char *ptr; int i; #undef RETURN #define RETURN do { \ if (argv) \ acl_argv_free(argv); \ return; \ } while(0); #undef TRUNC_BLANK #define TRUNC_BLANK(_x_) do { \ char *_ptr_; \ while(*_x_ == ' ' || *_x_ == '\t') \ _x_++; \ if (*_x_ == 0) \ RETURN; \ _ptr_ = _x_; \ while (*_ptr_) { \ if (*_ptr_ == ' ' || *_ptr_ == '\t') { \ *_ptr_ = 0; \ break; \ } \ _ptr_++; \ } \ } while (0); #undef TRUNC_BLANK_NORETURN #define TRUNC_BLANK_NORETURN(_x_) do { \ char *_ptr_; \ while(*_x_ == ' ' || *_x_ == '\t') \ _x_++; \ _ptr_ = _x_; \ while (*_ptr_) { \ if (*_ptr_ == ' ' || *_ptr_ == '\t') { \ *_ptr_ = 0; \ break; \ } \ _ptr_++; \ } \ } while (0); argv = acl_argv_split(data, "="); if (argv->argc < 2) /* data: "name" or "name="*/ RETURN; ptr = acl_argv_index(argv, 0); TRUNC_BLANK(ptr); name = ptr; /* 有些站点的COOKIE比较弱,如和讯的reg.hexun.com,COOKIE名会有重复 * 的情况,所以必须判断一下,不必重复存储相同名字的COOKIE值,即如果 * 出现重复COOKIE名,则只存储第一个,这样就避免了采用哈希方式存储的 * 漏内存的现象发生。--- zsx, 2008.1.8 */ if (acl_htable_find(table, name) != NULL) { RETURN; } str = acl_vstring_alloc(256); for (i = 1; i < argv->argc; i++) { ptr = acl_argv_index(argv, i); if (ptr == NULL) break; TRUNC_BLANK_NORETURN(ptr); if (*ptr == 0) continue; if (i == 1) acl_vstring_sprintf_append(str, "%s", ptr); else acl_vstring_sprintf_append(str, "=%s", ptr); } /* 将真实的存储数据的区域内存引出, 同时将外包结构内存释放, * POSTFIX真是个好东西:) ---zsx */ value = acl_vstring_export(str); if (acl_htable_enter(table, name, value) == NULL) acl_msg_fatal("%s, %s(%d): acl_htable_enter error=%s", __FILE__, myname, __LINE__, acl_last_serror()); RETURN; }
HTTP_HDR_REQ *http_hdr_req_create(const char *url, const char *method, const char *version) { const char *myname = "http_hdr_req_create"; HTTP_HDR_REQ *hdr_req; ACL_VSTRING *req_line = acl_vstring_alloc(256); HTTP_HDR_ENTRY *entry; const char *ptr; static char *__user_agent = "Mozilla/5.0 (Windows; U; Windows NT 5.0" "; zh-CN; rv:1.9.0.3) Gecko/2008092417 ACL/3.0.6"; if (url == NULL || *url == 0) { acl_msg_error("%s(%d): url invalid", myname, __LINE__); return NULL; } if (method == NULL || *method == 0) { acl_msg_error("%s(%d): method invalid", myname, __LINE__); return NULL; } if (version == NULL || *version == 0) { acl_msg_error("%s(%d): version invalid", myname, __LINE__); return NULL; } acl_vstring_strcpy(req_line, method); acl_vstring_strcat(req_line, " "); if (strncasecmp(url, "http://", sizeof("http://") - 1) == 0) url += sizeof("http://") - 1; else if (strncasecmp(url, "https://", sizeof("https://") - 1) == 0) url += sizeof("https://") -1; ptr = strchr(url, '/'); if (ptr) acl_vstring_strcat(req_line, ptr); else { ACL_VSTRING_ADDCH(req_line, '/'); ACL_VSTRING_TERMINATE(req_line); } acl_vstring_strcat(req_line, " "); acl_vstring_strcat(req_line, version); entry = http_hdr_entry_new(acl_vstring_str(req_line)); acl_vstring_free(req_line); if (entry == NULL) { acl_msg_error("%s(%d): http_hdr_entry_new return null for (%s)", myname, __LINE__, acl_vstring_str(req_line)); return NULL; } hdr_req = http_hdr_req_new(); http_hdr_append_entry(&hdr_req->hdr, entry); hdr_req->flag |= (HTTP_HDR_REQ_FLAG_PARSE_PARAMS | HTTP_HDR_REQ_FLAG_PARSE_COOKIE); if (http_hdr_req_line_parse(hdr_req) < 0) { http_hdr_req_free(hdr_req); return NULL; } hdr_req->host[0] = 0; __get_host_from_url(hdr_req->host, sizeof(hdr_req->host), url); if (hdr_req->host[0] != 0) http_hdr_put_str(&hdr_req->hdr, "Host", hdr_req->host); http_hdr_put_str(&hdr_req->hdr, "Connection", "Close"); http_hdr_put_str(&hdr_req->hdr, "User-Agent", __user_agent); return hdr_req; }
static void mime_content_type(MIME_NODE *node, const HEADER_OPTS *header_info) { const char *cp; ssize_t tok_count; MIME_STATE *state = node->state; #define PARSE_CONTENT_TYPE_HEADER(state, ptr) \ header_token(state->token, MIME_MAX_TOKEN, \ state->token_buffer, ptr, RFC2045_TSPECIALS, ';') cp = STR(node->buffer) + strlen(header_info->name) + 1; if ((tok_count = PARSE_CONTENT_TYPE_HEADER(state, &cp)) <= 0) { /* * other/whatever. */ node->ctype = MIME_CTYPE_OTHER; return; } /* tok_count > 0 */ /* * message/whatever body parts start with another block of message * headers that we may want to look at. The partial and external-body * subtypes cannot be subjected to 8-bit -> 7-bit conversion, so we * must properly recognize them. */ if (TOKEN_MATCH(state->token[0], "message")) { node->ctype = MIME_CTYPE_MESSAGE; node->stype = MIME_STYPE_OTHER; if (tok_count >= 3 && state->token[1].type == '/') { if (TOKEN_MATCH(state->token[2], "rfc822")) node->stype = MIME_STYPE_RFC822; else if (TOKEN_MATCH(state->token[2], "partial")) node->stype = MIME_STYPE_PARTIAL; else if (TOKEN_MATCH(state->token[2], "external-body")) node->stype = MIME_STYPE_EXTERN_BODY; } } /* * multipart/digest has default content type message/rfc822, * multipart/whatever has default content type text/plain. */ else if (TOKEN_MATCH(state->token[0], "multipart")) { node->ctype = MIME_CTYPE_MULTIPART; if (tok_count >= 3 && state->token[1].type == '/') { if (TOKEN_MATCH(state->token[2], "digest")) { node->ctype = MIME_CTYPE_MESSAGE; node->stype = MIME_STYPE_RFC822; } else if (TOKEN_MATCH(state->token[2], "alternative")) { node->stype = MIME_STYPE_ALTERNATIVE; } else if (TOKEN_MATCH(state->token[2], "related")) { node->stype = MIME_STYPE_RELATED; } else if (TOKEN_MATCH(state->token[2], "mixed")) { node->stype = MIME_STYPE_MIXED; } else { node->stype = MIME_STYPE_OTHER; } } else { node->ctype = MIME_CTYPE_TEXT; node->stype = MIME_STYPE_PLAIN; } /* * Yes, this is supposed to capture multiple boundary strings, * which are illegal and which could be used to hide content in * an implementation dependent manner. The code below allows us * to find embedded message headers as long as the sender uses * only one of these same-level boundary strings. * * Yes, this is supposed to ignore the boundary value type. */ while ((tok_count = PARSE_CONTENT_TYPE_HEADER(state, &cp)) >= 0) { if (tok_count < 3 || state->token[1].type != '=') continue; if (TOKEN_MATCH(state->token[0], "boundary")) { if (node->boundary == NULL) node->boundary = acl_vstring_alloc(256); /* 需要添加 "--" 做为分隔符的前导符 */ SCP(node->boundary, "--"); SCAT(node->boundary, state->token[2].u.value); break; } } } /* * text/whatever. Right now we don't really care if it is plain or * not, but we may want to recognize subtypes later, and then this * code can serve as an example. */ else if (TOKEN_MATCH(state->token[0], "text")) { node->ctype = MIME_CTYPE_TEXT; if (tok_count >= 3 && state->token[1].type == '/') { if (TOKEN_MATCH(state->token[2], "plain")) node->stype = MIME_STYPE_PLAIN; else if (TOKEN_MATCH(state->token[2], "html")) node->stype = MIME_STYPE_HTML; else node->stype = MIME_STYPE_OTHER; } else node->stype = MIME_STYPE_OTHER; while ((tok_count = PARSE_CONTENT_TYPE_HEADER(state, &cp)) >= 0) { if (tok_count < 3 || state->token[1].type != '=') continue; if (TOKEN_MATCH(state->token[0], "charset") && node->charset == NULL) { node->charset = acl_mystrdup(state->token[2].u.value); break; } } /* 如果没有字符集, 则缺省采用 gb2312 */ if (node->charset == NULL) node->charset = acl_mystrdup("gb2312"); } else if (TOKEN_MATCH(state->token[0], "image")) { node->ctype = MIME_CTYPE_IMAGE; if (tok_count >= 3 && state->token[1].type == '/') { if (TOKEN_MATCH(state->token[2], "jpeg")) node->stype = MIME_STYPE_JPEG; else if (TOKEN_MATCH(state->token[2], "gif")) node->stype = MIME_STYPE_GIF; else if (TOKEN_MATCH(state->token[2], "bmp")) node->stype = MIME_STYPE_BMP; else if (TOKEN_MATCH(state->token[2], "png")) node->stype = MIME_STYPE_PNG; else node->stype = MIME_STYPE_OTHER; } else node->stype = MIME_STYPE_OTHER; while ((tok_count = PARSE_CONTENT_TYPE_HEADER(state, &cp)) >= 0) { if (tok_count < 3 || state->token[1].type != '=') continue; if (TOKEN_MATCH(state->token[0], "name") && node->header_name == NULL) { node->header_name = acl_mystrdup(state->token[2].u.value); break; } } } else if (TOKEN_MATCH(state->token[0], "application")) { node->ctype = MIME_CTYPE_APPLICATION; if (tok_count >= 3 && state->token[1].type == '/') { if (TOKEN_MATCH(state->token[2], "octet-stream")) node->stype = MIME_STYPE_OCTET_STREAM; else node->stype = MIME_STYPE_OTHER; } while ((tok_count = PARSE_CONTENT_TYPE_HEADER(state, &cp)) >= 0) { if (tok_count < 3 || state->token[1].type != '=') continue; if (TOKEN_MATCH(state->token[0], "name") && node->header_name == NULL) { node->header_name = acl_mystrdup(state->token[2].u.value); break; } } } }
static int __log_open(const char *filename, void *ctx) { LOG_WRAP *h_log = (LOG_WRAP *) ctx; int logme = 0; char *facility_name = NULL; E_LOG_PRIORITY_T priority = E_LOG_INFO; E_LOG_ACTION_T action = E_LOG_PER_DAY; int flush = 1; size_t limit_size = 0; E_LOG_SYNC_ACTION_T sync_action = E_LOG_SEM_WITH_MT; char *sem_name = NULL; char *ptr, *pname; ACL_ARGV *env_argv; ACL_VSTRING *log_buf; int i; if (filename == NULL || *filename == 0) return (-1); acl_snprintf(h_log->filename, sizeof(h_log->filename), "%s", filename); /* env: facility:x, priority:x, action:x, flush:x, limit_size:x, sync_action:x, sem_name:x */ ptr = getenv("SERVICE_ENV"); if (ptr == NULL) return (-1); env_argv = acl_argv_split(ptr, ",\t "); if (env_argv == NULL) return (-1); if (env_argv->argc == 0) { acl_argv_free(env_argv); return (-1); } log_buf = acl_vstring_alloc(256); for (i = 0; i < env_argv->argc; i++) { pname = acl_argv_index(env_argv, i); ptr = strchr(pname, ':'); if (ptr == NULL) continue; *ptr++ = 0; if (*ptr == 0) continue; if (i == 0) acl_vstring_sprintf(log_buf, "%s:%s", pname, ptr); else acl_vstring_sprintf_append(log_buf, ", %s:%s", pname, ptr); if (strcasecmp(pname, "logme") == 0) { if (strcasecmp(ptr, "TRUE") == 0) logme = 1; } else if (strcasecmp(pname, "facility") == 0) { facility_name = ptr; } else if (strcasecmp(pname, "priority") == 0) { if (strcasecmp(ptr, "E_LOG_NOLOG") == 0) priority = E_LOG_NOLOG; else if (strcasecmp(ptr, "E_LOG_EMERG") == 0) priority = E_LOG_EMERG; else if (strcasecmp(ptr, "E_LOG_ALERT") == 0) priority = E_LOG_ALERT; else if (strcasecmp(ptr, "E_LOG_CRIT") == 0) priority = E_LOG_CRIT; else if (strcasecmp(ptr, "E_LOG_ERR") == 0) priority = E_LOG_ERR; else if (strcasecmp(ptr, "E_LOG_WARNING") == 0) priority = E_LOG_WARNING; else if (strcasecmp(ptr, "E_LOG_NOTICE") == 0) priority = E_LOG_NOTICE; else if (strcasecmp(ptr, "E_LOG_INFO") == 0) priority = E_LOG_INFO; else if (strcasecmp(ptr, "E_LOG_DEBUG") == 0) priority = E_LOG_DEBUG; } else if (strcasecmp(pname, "action") == 0) { if (strcasecmp(ptr, "E_LOG_PER_HOUR") == 0) action = E_LOG_PER_HOUR; else if (strcasecmp(ptr, "E_LOG_PER_DAY") == 0) action = E_LOG_PER_DAY; else if (strcasecmp(ptr, "E_LOG_PER_WEEK") == 0) action = E_LOG_PER_WEEK; else if (strcasecmp(ptr, "E_LOG_PER_MONTH") == 0) action = E_LOG_PER_MONTH; else if (strcasecmp(ptr, "E_LOG_PER_YEAR") == 0) action = E_LOG_PER_YEAR; else if (strcasecmp(ptr, "E_LOG_LIMIT_SIZE") == 0) action = E_LOG_LIMIT_SIZE; else if (strcasecmp(ptr, "E_LOG_SYSLOG") == 0) action = E_LOG_SYSLOG; } else if (strcasecmp(pname, "flush") == 0) { if (strcasecmp(ptr, "sync_flush") == 0) flush = 1; else if (strcasecmp(ptr, "async_flush") == 0) flush = 0; } else if (strcasecmp(pname, "limit_size") == 0) { limit_size = atoi(ptr); } else if (strcasecmp(pname, "sync_action") == 0) { if (strcasecmp(ptr, "E_LOG_NO_SYNC") == 0) sync_action = E_LOG_NO_SYNC; else if (strcasecmp(ptr, "E_LOG_THREAD_MUTEX") == 0) sync_action = E_LOG_THREAD_MUTEX; else if (strcasecmp(ptr, "E_LOG_FILE_LOCK") == 0) sync_action = E_LOG_FILE_LOCK; else if (strcasecmp(ptr, "E_LOG_SEM_WITH_MT") == 0) sync_action = E_LOG_SEM_WITH_MT; else if (strcasecmp(ptr, "E_LOG_FILE_APPEND_WITH_MT") == 0) sync_action = E_LOG_FILE_APPEND_WITH_MT; } else if (strcasecmp(pname, "sem_name") == 0) { sem_name = ptr; } } #if 0 LC_SysLogCreate(&h_log->h_log, h_log->filename); #endif if (action == E_LOG_LIMIT_SIZE) { if (limit_size == 0) limit_size = 512; /* set default size: 512 MB */ } else limit_size = 0; if (sync_action == E_LOG_SEM_WITH_MT) { if (sem_name == NULL || *sem_name == 0) { sem_name = acl_concatenate("/tmp/", acl_safe_basename(filename), ".sem", NULL); } else sem_name = acl_mystrdup(sem_name); } else if (sem_name) { sem_name = NULL; } h_log->h_log = e_log_new2(h_log->filename, priority, action, flush, limit_size, facility_name, sync_action, sem_name); if (sem_name) acl_myfree(sem_name); if (logme) { /* char cmd[1024], buf[512]; snprintf(buf, sizeof(buf), "filename=%s, priority=%d, action=%d, flush=%d, " "limit_size=%d, facility_name=%s, sync_action=%d, sem_name=%s", h_log->filename, priority, action, flush, limit_size, facility_name, sync_action, sem_name); snprintf(cmd, sizeof(cmd), "echo '%s, buf(%s)' >> /tmp/test1.log", acl_vstring_str(log_buf), buf); system(cmd); */ e_log2(h_log->h_log, "master_env: %s", acl_vstring_str(log_buf)); } e_log2(h_log->h_log, "filename=%s, priority=%d, action=%d, flush=%d, " "limit_size=%d, facility_name=%s, sync_action=%d, sem_name=%s", h_log->filename, priority, action, flush, limit_size, facility_name, sync_action, sem_name); if (log_buf) acl_vstring_free(log_buf); return (0); }
{ va_list ap; va_start(ap, fmt); ACL_VSTRING *vbf = acl_vstring_alloc(1); acl_vstring_vsprintf(vbf, fmt, ap); va_end(ap); printf("%s\n", acl_vstring_str(vbf)); acl_vstring_free(vbf); } int main(int argc acl_unused, char *argv[] acl_unused) { ACL_VSTRING *vp = acl_vstring_alloc(256); char *ptr; int i; size_t z; acl_vstring_strcpy(vp, "大家好,中国人民,Hi大家好, Hello World! 中国人民银行!"); printf(">>>%s\r\n", acl_vstring_str(vp)); ptr = acl_vstring_strstr(vp, "Hello"); if (ptr) printf(">>ok, find it, ptr = %s\r\n", ptr); else printf(">>error, no find it\r\n"); ptr = acl_vstring_strcasestr(vp, "WORLD"); if (ptr)