bool beanstalk::list_tube_used(string& buf) { buf.clear(); // 虽然读操作过程也会清空缓存 string cmdline(128); cmdline.format("list-tube-used\r\n"); ACL_ARGV* tokens = beanstalk_request(cmdline); if (tokens == NULL) { logger_error("'%s' error", cmdline.c_str()); return false; } if (tokens->argc < 2 || strcasecmp(tokens->argv[0], "USING")) { logger_error("'%s' error %s", cmdline.c_str(), tokens->argv[0]); errbuf_ = tokens->argv[0]; acl_argv_free(tokens); close(); return false; } buf = tokens->argv[1]; acl_argv_free(tokens); return true; }
int smtp_data(SMTP_CLIENT *client) { ACL_ARGV *tokens; int ret; client->smtp_code = 0; client->buf[0] = 0; ret = acl_vstream_fprintf(client->conn, "DATA\r\n"); if (ret == ACL_VSTREAM_EOF) { acl_msg_error("%s(%d): send data error(%s)", __FUNCTION__, __LINE__, acl_last_serror()); return -1; } ret = acl_vstream_gets_nonl(client->conn, client->buf, client->size); if (ret == ACL_VSTREAM_EOF) { acl_msg_error("%s(%d): gets data's reply error(%s)", __FUNCTION__, __LINE__, acl_last_serror()); return -1; } tokens = acl_argv_split(client->buf, "\t "); client->smtp_code = atoi(tokens->argv[0]); if (client->smtp_code != 354) { acl_msg_error("%s(%d): data denied, error(%d), line(%s)", __FUNCTION__, __LINE__, client->smtp_code, client->buf); acl_argv_free(tokens); return -1; } acl_argv_free(tokens); return 0; }
unsigned long long beanstalk::put(const void* data, size_t n, unsigned pri /* = 1024 */, unsigned delay /* = 0 */, unsigned int ttr /* = 60 */) { errbuf_.clear(); string cmdline(128); cmdline.format("put %u %u %u %u\r\n", pri, delay, ttr, (unsigned int) n); ACL_ARGV* tokens = beanstalk_request(cmdline, data, n); if (tokens == NULL) { logger_error("'%s' error", cmdline.c_str()); return 0; } if (tokens->argc < 2 || strcasecmp(tokens->argv[0], "INSERTED")) { logger_error("'%s' error", cmdline.c_str()); errbuf_ = tokens->argv[0]; acl_argv_free(tokens); close(); return 0; } #ifdef MINGW unsigned long long id = (unsigned long long) atol(tokens->argv[1]); #else unsigned long long id = (unsigned long long) atoll(tokens->argv[1]); #endif acl_argv_free(tokens); return id; }
bool master_udp::run_alone(const char* addrs, const char* path /* = NULL */, unsigned int count /* = 1 */) { // 每个进程只能有一个实例在运行 acl_assert(has_called == false); has_called = true; daemon_mode_ = false; __count_limit = count; acl_assert(addrs && *addrs); #ifdef ACL_WINDOWS acl_init(); #endif ACL_EVENT* eventp = acl_event_new_select(1, 0); set_event(eventp); // 设置基类的事件句柄 ACL_ARGV* tokens = acl_argv_split(addrs, ";,| \t"); ACL_ITER iter; acl_foreach(iter, tokens) { const char* addr = (const char*) iter.data; ACL_VSTREAM* sstream = acl_vstream_bind(addr, 0); if (sstream == NULL) { logger_error("bind %s error %s", addr, last_serror()); close_sstreams(); acl_event_free(eventp); acl_argv_free(tokens); return false; } acl_event_enable_read(eventp, sstream, 0, read_callback, sstream); socket_stream* ss = NEW socket_stream(); if (ss->open(sstream) == false) logger_fatal("open stream error!"); sstream->context = ss; sstreams_.push_back(ss); } acl_argv_free(tokens); // 初始化配置参数 conf_.load(path); service_pre_jail(NULL, NULL); service_init(NULL, NULL); while (!__stop) acl_event_loop(eventp); service_exit(NULL, NULL); // 必须在调用 acl_event_free 前调用 close_sstreams,因为在关闭 // 网络流对象时依然有对 ACL_EVENT 引擎的使用 close_sstreams(); acl_event_free(eventp); return true; }
int smtp_quit(SMTP_CLIENT *client) { int ret; ACL_ARGV *tokens; client->smtp_code = 0; client->buf[0] = 0; ret = acl_vstream_fprintf(client->conn, "QUIT\r\n"); if (ret == ACL_VSTREAM_EOF) { acl_msg_error("%s(%d): send quit cmd error(%s)", __FUNCTION__, __LINE__, acl_last_serror()); return -1; } ret = acl_vstream_gets_nonl(client->conn, client->buf, client->size); if (ret == ACL_VSTREAM_EOF) { acl_msg_error("%s(%d): gets quit's reply error(%s)", __FUNCTION__, __LINE__, acl_last_serror()); return -1; } tokens = acl_argv_split(client->buf, "\t "); client->smtp_code = atoi(tokens->argv[0]); if (client->smtp_code != 221) { acl_msg_error("%s(%d): quit's reply: %d", __FUNCTION__, __LINE__, client->smtp_code); acl_argv_free(tokens); return -1; } acl_argv_free(tokens); return 0; }
int smtp_rcpt(SMTP_CLIENT *client, const char *to) { int ret; ACL_ARGV *tokens; client->smtp_code = 0; client->buf[0] = 0; ret = acl_vstream_fprintf(client->conn, "RCPT TO: <%s>\r\n", to); if (ret == ACL_VSTREAM_EOF) { acl_msg_error("%s(%d): send rcpt error(%s)", __FUNCTION__, __LINE__, acl_last_serror()); return -1; } ret = acl_vstream_gets_nonl(client->conn, client->buf, client->size); if (ret == ACL_VSTREAM_EOF) { acl_msg_error("%s(%d): gets rcpt's reply error(%s)", __FUNCTION__, __LINE__, acl_last_serror()); return -1; } tokens = acl_argv_split(client->buf, "\t "); client->smtp_code = atoi(tokens->argv[0]); if (client->smtp_code != 250) { acl_msg_error("%s(%d): rcpt's reply error(%d), line(%s)", __FUNCTION__, __LINE__, client->smtp_code, client->buf); acl_argv_free(tokens); return -1; } acl_argv_free(tokens); return 0; }
unsigned beanstalk::ignore_one(const char* tube) { string cmdline(128); cmdline.format("ignore %s\r\n", tube); ACL_ARGV* tokens = beanstalk_request(cmdline); if (tokens == NULL) { logger_error("'%s' error", cmdline.c_str()); return 0; } if (tokens->argc < 2 || strcasecmp(tokens->argv[0], "WATCHING")) { logger_error("'%s' error %s", cmdline.c_str(), tokens->argv[0]); errbuf_ = tokens->argv[0]; acl_argv_free(tokens); close(); return 0; } unsigned n = (unsigned) atoi(tokens->argv[1]); acl_argv_free(tokens); // 如果服务器返回所关注的队列数为 0,肯定是出错了,因为至少还有一个 // 缺省队列:default,所以此时需要关闭连接,以尽量消除与本连接相关 // 的错误,下一个命令会自动进行重连操作以恢复操作过程 if (n == 0) { logger_error("'%s' error, tube watched is 0", cmdline.c_str()); errbuf_ = "no_watching"; close(); } return n; }
bool queue_manager::parse_path(const char* path, string* home, string* queueName, string* queueSub) { if (path == NULL || *path == 0) { logger_error("path invalid!"); return false; } /* WINDOWS 支持 '/' 和 '\\' 两种分隔符 */ // 数据格式: /home/queueName/queueSub ACL_ARGV *argv = acl_argv_split(path, "/\\"); if (argv->argc < 3) { logger_error("path(%s) invalid", path); acl_argv_free(argv); return false; } // 取得home home->clear(); // 如果第一个字符为 PATH_SEP 则需要补齐 if (*path == PATH_SEP) home->push_back(PATH_SEP); *home += argv->argv[argv->argc - 3]; // 取得队列名 *queueName = argv->argv[argv->argc - 2]; // 取得队列子目录名 *queueSub = argv->argv[argv->argc - 1]; acl_argv_free(argv); return true; }
int beanstalk::kick(unsigned n) { string cmdline(128); cmdline.format("kick %u\r\n", n); ACL_ARGV* tokens = beanstalk_request(cmdline); if (tokens == NULL) { logger_error("'%s' error", cmdline.c_str()); return -1; } if (strcasecmp(tokens->argv[0], "KICKED")) { logger_error("'%s' error %s", cmdline.c_str(), tokens->argv[0]); errbuf_ = tokens->argv[0]; acl_argv_free(tokens); return -1; } int ret; if (tokens->argc >= 2) ret = atoi(tokens->argv[1]); else ret = 0; acl_argv_free(tokens); return ret; }
// 分析一个服务器地址,格式:IP:PORT[:MAX_CONN] // 返回值 < 0 表示非法的地址 static int check_addr(const char* addr, string& buf, size_t default_count) { // 数据格式:IP:PORT[:CONNECT_COUNT] ACL_ARGV* tokens = acl_argv_split(addr, ":|"); if (tokens->argc < 2) { logger_error("invalid addr: %s", addr); acl_argv_free(tokens); return -1; } int port = atoi(tokens->argv[1]); if (port <= 0 || port >= 65535) { logger_error("invalid addr: %s, port: %d", addr, port); acl_argv_free(tokens); return -1; } buf.format("%s:%d", tokens->argv[0], port); int conn_max; if (tokens->argc >= 3) conn_max = atoi(tokens->argv[2]); else conn_max = (int) default_count; if (conn_max < 0) conn_max = (int) default_count; acl_argv_free(tokens); return conn_max; }
int smtp_data_end(SMTP_CLIENT *client) { int ret; ACL_ARGV *tokens; client->smtp_code = 0; client->buf[0] = 0; ret = acl_vstream_fprintf(client->conn, "\r\n.\r\n"); if (ret == ACL_VSTREAM_EOF) { acl_msg_error("%s(%d): send mail eof error(%s)", __FUNCTION__, __LINE__, acl_last_serror()); return -1; } ret = acl_vstream_gets_nonl(client->conn, client->buf, client->size); if (ret == ACL_VSTREAM_EOF) { acl_msg_error("%s(%d): gets mail eof's reply error(%s)", __FUNCTION__, __LINE__, acl_last_serror()); return -1; } tokens = acl_argv_split(client->buf, "\t "); client->smtp_code = atoi(tokens->argv[0]); if (client->smtp_code != 250) { acl_msg_error("%s(%d): send mail error(%d), line: %s", __FUNCTION__, __LINE__, client->smtp_code, client->buf); acl_argv_free(tokens); return -1; } acl_argv_free(tokens); return 0; }
bool master_aio::run_alone(const char* addrs, const char* path /* = NULL */, aio_handle_type ht /* = ENGINE_SELECT */) { acl_assert(__handle == NULL); daemon_mode_ = false; #ifdef WIN32 acl_init(); #endif std::vector<aio_listen_stream*> sstreams; ACL_ARGV* tokens = acl_argv_split(addrs, ";,| \t"); ACL_ITER iter; // 初始化配置参数 conf_.load(path); __handle = NEW aio_handle(ht); ACL_AIO* aio = __handle->get_handle(); acl_assert(aio); ACL_EVENT* eventp = acl_aio_event(aio); set_event(eventp); // 设置基类的事件句柄 acl_foreach(iter, tokens) { const char* addr = (const char*) iter.data; aio_listen_stream* sstream = NEW aio_listen_stream(__handle); // 监听指定的地址 if (sstream->open(addr) == false) { logger_error("listen %s error: %s", addr, last_serror()); close_all_listener(sstreams); // XXX: 为了保证能关闭监听流,应在此处再 check 一下 __handle->check(); acl_argv_free(tokens); return (false); } sstream->add_accept_callback(this); } acl_argv_free(tokens); service_pre_jail(NULL); service_init(NULL); while (true) { // 如果返回 false 则表示不再继续,需要退出 if (__handle->check() == false) { logger("aio_server stop now ..."); break; } } close_all_listener(sstreams); __handle->check(); service_exit(NULL); return true; }
unsigned long long beanstalk::peek_fmt(string& buf, const char* fmt, ...) { buf.clear(); // 虽然读操作过程也会清空缓存 string cmdline(128); va_list ap; va_start(ap, fmt); cmdline.vformat(fmt, ap); va_end(ap); ACL_ARGV* tokens = beanstalk_request(cmdline); if (tokens == NULL) { logger_error("'%s' error", cmdline.c_str()); return 0; } if (tokens->argc < 3 || strcasecmp(tokens->argv[0], "FOUND")) { errbuf_ = tokens->argv[0]; acl_argv_free(tokens); return 0; } #ifdef MINGW unsigned long long id = (unsigned long long) atol(tokens->argv[1]); #else unsigned long long id = (unsigned long long) atoll(tokens->argv[1]); #endif unsigned short n = (unsigned short) atoi(tokens->argv[2]); acl_argv_free(tokens); if (n == 0) { logger_error("peek data's length 0"); errbuf_ = "peek"; close(); return 0; } // 读取规定的字节数 if (conn_.read(buf, n, true) == false) { logger_error("peek read body failed"); errbuf_ = "read"; close(); return 0; } else if (conn_.gets(cmdline) == false) { logger_error("peek: gets last line falied"); errbuf_ = "gets"; close(); return 0; } return id; }
bool master_proc::run_alone(const char* addrs, const char* path /* = NULL */, int count /* = 1 */) { // 每个进程只能有一个实例在运行 acl_assert(has_called == false); has_called = true; daemon_mode_ = false; __count_limit = count; acl_assert(addrs && *addrs); #ifdef ACL_WINDOWS acl_cpp_init(); #endif ACL_EVENT* eventp = acl_event_new_select(1, 0); set_event(eventp); // 调用基类方法设置事件引擎句柄 std::vector<ACL_VSTREAM*> sstreams; ACL_ARGV* tokens = acl_argv_split(addrs, ";,| \t"); ACL_ITER iter; acl_foreach(iter, tokens) { const char* addr = (const char*) iter.data; ACL_VSTREAM* sstream = acl_vstream_listen(addr, 128); if (sstream == NULL) { logger_error("listen %s error %s", addr, last_serror()); close_all_listener(sstreams); acl_argv_free(tokens); return false; } service_on_listen(sstream); acl_event_enable_listen(eventp, sstream, 0, listen_callback, sstream); sstreams.push_back(sstream); } acl_argv_free(tokens); // 初始化配置参数 conf_.load(path); service_pre_jail(NULL, NULL); service_init(NULL, NULL); while (!__stop) acl_event_loop(eventp); close_all_listener(sstreams); acl_event_free(eventp); service_exit(NULL, NULL); return true; }
void connect_manager::set_service_list(const char* addr_list, int count, int conn_timeout, int rw_timeout) { if (addr_list == NULL || *addr_list == 0) { logger("addr_list null"); return; } // 创建连接池服务集群 char* buf = acl_mystrdup(addr_list); char* addrs = acl_mystr_trim(buf); ACL_ARGV* tokens = acl_argv_split(addrs, ";,"); ACL_ITER iter; acl::string addr; acl_foreach(iter, tokens) { const char* ptr = (const char*) iter.data; int max = check_addr(ptr, addr, count); if (max < 0) { logger_error("invalid server addr: %s", addr.c_str()); continue; } (void) set(addr.c_str(), max, conn_timeout, rw_timeout); logger("add one service: %s, max connect: %d", addr.c_str(), max); } acl_argv_free(tokens); acl_myfree(buf); }
unsigned beanstalk::watch(const char* tube) { // 先检查是否已经监控相同队列 std::vector<char*>::iterator it = tubes_watched_.begin(); for (; it != tubes_watched_.end(); ++it) { if (strcmp(*it, tube) == 0) break; } string cmdline(128); cmdline.format("watch %s\r\n", tube); ACL_ARGV* tokens = beanstalk_request(cmdline); if (tokens == NULL) { logger_error("'%s' error", cmdline.c_str()); return 0; } if (tokens->argc < 2 || strcasecmp(tokens->argv[0], "WATCHING")) { logger_error("'%s' error %s", cmdline.c_str(), tokens->argv[0]); errbuf_ = tokens->argv[0]; acl_argv_free(tokens); close(); return 0; } unsigned n = (unsigned) atoi(tokens->argv[1]); acl_argv_free(tokens); // 如果服务器返回所关注的队列数为 0,肯定是出错了,因为至少还有一个 // 缺省队列:default,所以此时需要关闭连接,以尽量消除与本连接相关 // 的错误,下一个命令会自动进行重连操作以恢复操作过程 if (n == 0) { logger_error("'%s' error, tube watched is 0", cmdline.c_str()); errbuf_ = "watching"; close(); } // 添加进监控集合中 else if (it == tubes_watched_.end()) tubes_watched_.push_back(acl_mystrdup(tube)); return n; }
bool queue_manager::parse_filePath(const char* filePath, string* home, string* queueName, string* queueSub, string* partName, string* extName) { if (filePath == NULL || *filePath == 0) { logger_error("filePath invalid!"); return false; } // 格式为: /home/queue_name/queue_sub_node/file_name.file_ext ACL_ARGV *argv = acl_argv_split(filePath, "/\\"); if (argv->argc < 4) { logger_error("filePath(%s) invalid", filePath); acl_argv_free(argv); return false; } home->clear(); // 如果第一个字符为 PATH_SEP 则需要补齐 if (*filePath == PATH_SEP) home->push_back(PATH_SEP); // 仅存储根路径部分 for (int i = 0; i < argv->argc - 3; i++) { if (i > 0 && home->length() > 0) (*home) += PATH_SEP; (*home) += argv->argv[i]; } // 取得队列名 *queueName = argv->argv[argv->argc - 3]; *queueSub = argv->argv[argv->argc - 2]; // 继续分析文件名部分 bool ret = parse_fileName(argv->argv[argv->argc - 1], partName, extName); acl_argv_free(argv); return ret; }
bool beanstalk::list_tubes_fmt(string& buf, const char* fmt, ...) { buf.clear(); // 虽然读操作过程也会清空缓存 string cmdline(128); va_list ap; va_start(ap, fmt); cmdline.vformat(fmt, ap); va_end(ap); ACL_ARGV* tokens = beanstalk_request(cmdline); if (tokens == NULL) { logger_error("'%s' error", cmdline.c_str()); return false; } if (tokens->argc < 2 || strcasecmp(tokens->argv[0], "OK")) { errbuf_ = tokens->argv[0]; acl_argv_free(tokens); close(); return false; } unsigned short n = (unsigned short) atoi(tokens->argv[1]); acl_argv_free(tokens); if (n == 0) { logger_error("list data's length 0"); errbuf_ = "length"; close(); return false; } // 读取规定的字节数 if (conn_.read(buf, n, true) == false) { logger_error("peek read body failed"); errbuf_ = "read"; close(); return false; } return true; }
int http_hdr_res_status_parse(HTTP_HDR_RES *hh, const char *dbuf) { char myname[] = "http_hdr_res_status_parse"; ACL_ARGV *status_argv; char *ptr; if (hh == NULL || dbuf == NULL) { acl_msg_error("%s, %s(%d): input invalid", __FILE__, myname, __LINE__); return (-1); } /* data: HTTP/1.1 XXX info */ status_argv = acl_argv_split(dbuf, "\t "); if (status_argv->argc < 2) { acl_msg_error("%s, %s(%d): invalid reply status line=%s", __FILE__, myname, __LINE__, dbuf); acl_argv_free(status_argv); return (-1); } ptr = acl_argv_index(status_argv, 0); if (http_hdr_parse_version(&hh->hdr, ptr) < 0) { acl_argv_free(status_argv); return (-1); } ptr = acl_argv_index(status_argv, 1); if (ptr == NULL) acl_msg_fatal("%s, %s(%d): null value, idx=1, argc=%d", __FILE__, myname, __LINE__, status_argv->argc); hh->reply_status = atoi(ptr); if (hh->reply_status < 0) { acl_msg_error("%s, %s(%d): invalid status(%d)", __FILE__, myname, __LINE__, hh->reply_status); acl_argv_free(status_argv); return (-1); } acl_argv_free(status_argv); return (0); }
unsigned beanstalk::beanstalk_watch(const char* tube) { if (conn_.format("watch %s\r\n", tube) == -1) { logger_error("'watch %s' failed: %s", tube, last_serror()); errbuf_ = "watch"; return 0; } string line(128); if (conn_.gets(line) == false) { logger_error("'watch %s' error(%s): reply ailed", last_serror(), tube); errbuf_ = "watch"; return 0; } ACL_ARGV* tokens = acl_argv_split(line.c_str(), "\t "); if (tokens->argc < 2 || strcasecmp(tokens->argv[0], "WATCHING")) { logger_error("'watch %s' error: %s", tube, line.c_str()); errbuf_ = tokens->argv[0]; acl_argv_free(tokens); close(); return 0; } unsigned n = (unsigned) atoi(tokens->argv[1]); acl_argv_free(tokens); // 如果服务器返回所关注的队列数为 0,肯定是出错了,因为至少还有一个 // 缺省队列:default,所以此时需要关闭连接,以尽量消除与本连接相关 // 的错误,下一个命令会自动进行重连操作以恢复操作过程 if (n == 0) { logger_error("'watch %s' error(%s), tube watched is 0", line.c_str(), tube); errbuf_ = line.c_str(); close(); } return n; }
int smtp_ehlo(SMTP_CLIENT *client, const char *ehlo) { int ret; char *ptr; ACL_ARGV *tokens; client->buf[0] = 0; client->smtp_code = 0; ret = acl_vstream_fprintf(client->conn, "EHLO %s\r\n", ehlo); if (ret == ACL_VSTREAM_EOF) { acl_msg_error("%s(%d): set EHLO error(%s)", __FUNCTION__, __LINE__, acl_last_serror()); return -1; } while (1) { ret = acl_vstream_gets_nonl(client->conn, client->buf, client->size); if (ret == ACL_VSTREAM_EOF) { acl_msg_error("%s(%d): get EHLO's reply error(%s)", __FUNCTION__, __LINE__, acl_last_serror()); return -1; } else if (ret < 3) { acl_msg_warn("%s(%d): EHLO's reply(%s) tool short", __FUNCTION__, __LINE__, client->buf); continue; } if (strncmp(client->buf, "250", 3) != 0) { ret = client->buf[3]; client->buf[3] = 0; client->smtp_code = atoi(client->buf); client->buf[3] = ret; acl_msg_error("%s(%d): EHLO's reply(%s) code(%d) error", __FUNCTION__, __LINE__, client->buf, ret); return -1; } else client->smtp_code = 250; if (ret == 3) break; ptr = client->buf + 4; tokens = acl_argv_split(ptr, " ="); smtp_ehlo_flag(client, tokens); acl_argv_free(tokens); if (client->buf[3] == ' ') break; } return 0; }
bool beanstalk::bury(unsigned long long id, unsigned int pri /* = 1024 */) { string cmdline(128); cmdline.format("bury %llu %u\r\n", id, pri); ACL_ARGV* tokens = beanstalk_request(cmdline); if (tokens == NULL) { logger_error("'%s' error", cmdline.c_str()); return false; } if (strcasecmp(tokens->argv[0], "BURIED")) { logger_error("'%s' error %s", cmdline.c_str(), tokens->argv[0]); errbuf_ = tokens->argv[0]; acl_argv_free(tokens); return false; } acl_argv_free(tokens); return true; }
bool beanstalk::touch(unsigned long long id) { string cmdline(128); cmdline.format("touch %llu\r\n", id); ACL_ARGV* tokens = beanstalk_request(cmdline); if (tokens == NULL) { logger_error("'%s' error", cmdline.c_str()); return false; } if (strcasecmp(tokens->argv[0], "TOUCHED")) { logger_error("'%s' error %s", cmdline.c_str(), tokens->argv[0]); errbuf_ = tokens->argv[0]; acl_argv_free(tokens); return false; } acl_argv_free(tokens); return true; }
bool beanstalk::pause_tube(const char* tube, unsigned delay) { string cmdline(128); cmdline.format("pause-tube %s %u\r\n", tube, delay); ACL_ARGV* tokens = beanstalk_request(cmdline); if (tokens == NULL) { logger_error("'%s' error", cmdline.c_str()); return false; } if (strcasecmp(tokens->argv[0], "PAUSED")) { logger_error("'%s' error %s", cmdline.c_str(), tokens->argv[0]); errbuf_ = tokens->argv[0]; acl_argv_free(tokens); return false; } acl_argv_free(tokens); return true; }
bool beanstalk::release(unsigned long long id, unsigned pri /* = 1024 */, unsigned delay /* = 0*/) { string cmdline(128); cmdline.format("release %llu %u %u\r\n", id, pri, delay); ACL_ARGV* tokens = beanstalk_request(cmdline); if (tokens == NULL) { logger_error("'%s' error", cmdline.c_str()); return false; } if (strcasecmp(tokens->argv[0], "RELEASED")) { logger_error("'%s' error %s", cmdline.c_str(), tokens->argv[0]); errbuf_ = tokens->argv[0]; acl_argv_free(tokens); return false; } acl_argv_free(tokens); return true; }
// value 格式:xxx=xxx; domain=xxx; expires=xxx; path=xxx bool HttpCookie::setCookie(const char* value) { if (value == NULL || *value == 0) return false; ACL_ARGV* tokens = acl_argv_split(value, ";"); acl_assert(tokens->argc > 0); HTTP_PARAM param; // 从第一个 name=value 字段中取得 cookie 名及 cookie 值 if (splitNameValue(tokens->argv[0], ¶m) == false) { acl_argv_free(tokens); return false; } // name 肯定非 "\0",而 value 可以为 "\0" name_ = dbuf_->dbuf_strdup(param.name); value_ = dbuf_->dbuf_strdup(param.value); for (int i = 1; i < tokens->argc; i++) { if (splitNameValue(tokens->argv[i], ¶m) == false) continue; if (*(param.value) == 0) continue; if (strcasecmp(param.name, "domain") == 0) setDomain(param.value); else if (strcasecmp(param.name, "expires") == 0) setExpires(param.value); else if (strcasecmp(param.name, "path") == 0) setPath(param.value); else add(param.name, param.value); } acl_argv_free(tokens); return true; }
hstable::hstable(int id, const char* dbn, const char* tbl, const char* idx, const char* flds) { id_ = id; dbn_ = acl_mystrdup(dbn); tbl_ = acl_mystrdup(tbl); idx_ = acl_mystrdup(idx); flds_ = acl_mystrdup(flds); ACL_ARGV *tokens = acl_argv_split(flds, ",; \t"); nfld_ = tokens->argc; acl_argv_free(tokens); values_ = (char**) acl_mycalloc(nfld_, sizeof(char*)); }
static void quote_split(const char* str, const char* delim) { ACL_ITER iter; ACL_ARGV *tokens = acl_argv_quote_split(str, delim); printf("---------------------------------------------\r\n"); printf("str = [%s], delim = [%s]\r\n", str, delim); acl_foreach(iter, tokens) { const char* ptr = (const char*) iter.data; printf("%s\r\n", ptr); } acl_argv_free(tokens); }
void acl_clean_env(char **preserve_list) { #ifdef ACL_UNIX extern char **environ; char **env = environ; #elif defined(ACL_WINDOWS) extern char **_environ; char **env = _environ; #endif ACL_ARGV *save_list; char *value; char **cpp; char *eq; /* * Preserve or specify selected environment variables. */ #define STRING_AND_LENGTH(x, y) (x), (ssize_t) (y) save_list = acl_argv_alloc(10); for (cpp = preserve_list; *cpp; cpp++) if ((eq = strchr(*cpp, '=')) != 0) acl_argv_addn(save_list, STRING_AND_LENGTH(*cpp, eq - *cpp), STRING_AND_LENGTH(eq + 1, strlen(eq + 1)), (char *) 0); else if ((value = acl_safe_getenv(*cpp)) != 0) acl_argv_add(save_list, *cpp, value, (char *) 0); /* * Truncate the process environment, if available. On some systems * (Ultrix!), environ can be a null pointer. */ if (env) env[0] = 0; /* * Restore preserved environment variables. */ for (cpp = save_list->argv; *cpp; cpp += 2) #ifdef ACL_UNIX if (setenv(cpp[0], cpp[1], 1)) #elif defined(ACL_WINDOWS) if (!SetEnvironmentVariable(cpp[0], cpp[1])) #endif acl_msg_error("setenv(%s, %s): %s", cpp[0], cpp[1], acl_last_serror()); /* * Cleanup. */ acl_argv_free(save_list); }
int smtp_mail(SMTP_CLIENT *client, const char *from) { int ret; ACL_ARGV *tokens; client->smtp_code = 0; client->buf[0] = 0; /* 发送 mail from 信息 */ ret = acl_vstream_fprintf(client->conn, "MAIL FROM: <%s>\r\n", from); if (ret == ACL_VSTREAM_EOF) { acl_msg_error("%s(%d): send mail from error(%s)", __FUNCTION__, __LINE__, acl_last_serror()); return -1; } /* 读取响应信息 */ ret = acl_vstream_gets_nonl(client->conn, client->buf, client->size); if (ret == ACL_VSTREAM_EOF) { acl_msg_error("%s(%d): gets mail from's reply error(%s)", __FUNCTION__, __LINE__, acl_last_serror()); return (-1); } tokens = acl_argv_split(client->buf, "\t "); client->smtp_code = atoi(tokens->argv[0]); if (client->smtp_code != 250) { acl_msg_error("%s(%d): mail from error(%d), line(%s)", __FUNCTION__, __LINE__, client->smtp_code, client->buf); acl_argv_free(tokens); return -1; } acl_argv_free(tokens); return 0; }