Beispiel #1
0
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;
}
Beispiel #2
0
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;
}
Beispiel #3
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;
}
Beispiel #4
0
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;
}
Beispiel #5
0
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;
}
Beispiel #6
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;
}
Beispiel #7
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;
}
Beispiel #8
0
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;
}
Beispiel #9
0
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;
}
Beispiel #10
0
// 分析一个服务器地址,格式: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;
}
Beispiel #11
0
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;
}
Beispiel #12
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;
}
Beispiel #13
0
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;
}
Beispiel #14
0
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;
}
Beispiel #15
0
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);
}
Beispiel #16
0
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;
}
Beispiel #17
0
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;
}
Beispiel #18
0
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;
}
Beispiel #19
0
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);
}
Beispiel #20
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;
}
Beispiel #21
0
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;
}
Beispiel #22
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;
}
Beispiel #23
0
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;
}
Beispiel #24
0
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;
}
Beispiel #25
0
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;
}
Beispiel #26
0
// 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], &param) == 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], &param) == 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;
}
Beispiel #27
0
	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*));
	}
Beispiel #28
0
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);
}
Beispiel #29
0
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);
}
Beispiel #30
0
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;
}