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; }
acl_pthread_mutex_t *acl_pthread_mutex_create(void) { const char *myname = "acl_pthread_mutex_create"; acl_pthread_mutex_t *mutex; mutex = acl_mycalloc(1, sizeof(acl_pthread_mutex_t)); if (mutex == NULL) { acl_msg_error("%s, %s(%d): calloc error(%s)", __FILE__, myname, __LINE__, acl_last_serror()); return NULL; } mutex->dynamic = 1; /* Create the mutex, with initial value signaled */ mutex->id = CreateMutex(NULL, FALSE, NULL); if (!mutex->id) { acl_msg_error("%s, %s(%d): CreateMutex error(%s)", __FILE__, myname, __LINE__, acl_last_serror()); acl_myfree(mutex); return NULL; } return mutex; }
int main(int argc, char *argv[]) { ACL_VSTREAM *sstream, *client; const char *addr = "127.0.0.1:30082"; acl_init(); sstream = acl_vstream_listen(addr, 128); if (sstream == NULL) { printf("listen on %s error(%s)\r\n", addr, acl_last_serror()); getchar(); return (0); } printf("listening on %s ...\r\n", addr); while (1) { client = acl_vstream_accept(sstream, NULL, 0); if (client == NULL) { printf("accept error(%s)\r\n", acl_last_serror()); break; } echo(client); acl_vstream_close(client); } printf("Over now\r\n"); getchar(); return (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; }
static int gid_store_sync(GID_STORE *store) { char buf[1024]; /* 需要先将文件内容清空 */ #if 0 if (acl_file_ftruncate(store->fh.fp, 0) < 0) { acl_msg_error("%s(%d), %s: ftruncate %s error(%s)", __FILE__, __LINE__, __FUNCTION__, ACL_VSTREAM_PATH(store->fh.fp), acl_last_serror()); return (-1); } #endif if (acl_vstream_fseek(store->fh.fp, SEEK_SET, 0) < 0) { acl_msg_error("%s(%d), %s: fseek %s error(%s)", __FILE__, __LINE__, __FUNCTION__, ACL_VSTREAM_PATH(store->fh.fp), acl_last_serror()); } snprintf(buf, sizeof(buf), "%s:%s %d %lld %lld %lld\r\n", store->tag, store->sid, store->step, store->cur_gid, store->min_gid, store->max_gid); /* 初始化文件内容: tag:sid step cur_gid min_gid max_gid\r\n */ if (acl_vstream_writen(store->fh.fp, buf, strlen(buf)) == ACL_VSTREAM_EOF) { acl_msg_error("%s(%d), %s: write to %s error(%s)", __FILE__, __LINE__, __FUNCTION__, ACL_VSTREAM_PATH(store->fh.fp), acl_last_serror()); return (-1); } return (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; }
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; }
// 动态加载 iconv.dll 库 static void __iconv_dll_load(void) { if (__iconv_dll != NULL) logger_fatal("__iconv_dll not null"); __iconv_dll = acl_dlopen("iconv.dll"); if (__iconv_dll == NULL) logger_fatal("load iconv.dll error: %s", acl_last_serror()); __iconv_open = (iconv_open_fn) acl_dlsym(__iconv_dll, "libiconv_open"); if (__iconv_open == NULL) logger_fatal("load iconv_open from iconv.dll error: %s", acl_last_serror()); __iconv_close = (iconv_close_fn) acl_dlsym(__iconv_dll, "libiconv_close"); if (__iconv_close == NULL) logger_fatal("load iconv_close from iconv.dll error: %s", acl_last_serror()); __iconv = (iconv_fn) acl_dlsym(__iconv_dll, "libiconv"); if (__iconv == NULL) logger_fatal("load iconv from iconv.dll error: %s", acl_last_serror()); __iconvctl = (iconvctl_fn) acl_dlsym(__iconv_dll, "libiconvctl"); if (__iconvctl == NULL) logger_fatal("load iconvctl from iconv.dll error: %s", acl_last_serror()); logger("iconv.dll loaded"); atexit(__iconv_dll_unload); }
static void acl_pthread_init_once(void) { const char *myname = "acl_pthread_init_once"; int i; acl_pthread_mutex_init(&__thread_lock, NULL); __thread_inited = 1; for (i = 0; i < ACL_PTHREAD_KEYS_MAX; i++) { __tls_key_list[i].destructor = NULL; __tls_key_list[i].key = ACL_TLS_OUT_OF_INDEXES; } __tls_value_list_key = TlsAlloc(); if (__tls_value_list_key == ACL_TLS_OUT_OF_INDEXES) acl_msg_fatal("%s(%d): TlsAlloc error(%s)", myname, __LINE__, acl_last_serror()); if (__tls_value_list_key < 0 || __tls_value_list_key >= ACL_PTHREAD_KEYS_MAX) { acl_msg_fatal("%s(%d): TlsAlloc error(%s), not in(%d, %d)", myname, __LINE__, acl_last_serror(), 0, ACL_PTHREAD_KEYS_MAX); } __tls_key_list[__tls_value_list_key].destructor = NULL; __tls_key_list[__tls_value_list_key].key = __tls_value_list_key; }
void acl_set_core_limit(unsigned long long int max) { const char *myname = "set_limit"; struct rlimit rlim, rlim_new; #if !defined(ACL_MACOSX) && !defined(ACL_SUNOS5) \ && !defined(ACL_FREEBSD) && !defined(MINGW) if (prctl(PR_SET_DUMPABLE, 1) < 0) { acl_msg_warn("%s(%d): prctl error(%s)", myname, __LINE__, acl_last_serror()); } #endif if (getrlimit(RLIMIT_CORE, &rlim) == 0) { if (max == 0) max = RLIM_INFINITY; rlim_new.rlim_cur = rlim_new.rlim_max = max; if (setrlimit(RLIMIT_CORE, &rlim_new) != 0) { /* failed. try raising just to the old max */ rlim_new.rlim_cur = rlim_new.rlim_max = rlim.rlim_max; if (setrlimit(RLIMIT_CORE, &rlim_new) != 0) acl_msg_warn("%s(%d): can't set core limit: %s", myname, __LINE__, acl_last_serror()); } } else { if (max == 0) max = RLIM_INFINITY; rlim.rlim_cur = max; rlim.rlim_max = max; if (setrlimit(RLIMIT_CORE, &rlim) != 0) acl_msg_warn("%s(%d): can't set core limit: %s", myname, __LINE__, acl_last_serror()); } }
bool queue_file::move_file(const char* queueName, const char* extName) { acl::string buf(256); bool once_again = false; while (true) { buf.clear(); buf << m_home << PATH_SEP << queueName << PATH_SEP << m_queueSub << PATH_SEP << m_partName << "." << extName; #ifdef WIN32 // 在win32下必须先关闭文件句柄 this->close(); #endif if (rename(m_filePath.c_str(), buf.c_str()) == 0) break; // 如果返回错误原因是目标路径不存在,则尝试创建目录结构 if (once_again || acl_last_error() != ENOENT) { logger_error("move from %s to %s error(%s), errno: %d, %d", m_filePath.c_str(), buf.c_str(), acl_last_serror(), acl_last_error(), ENOENT); return (false); } // 设置重试标志位 once_again = true; buf.clear(); buf << m_home << PATH_SEP << queueName << PATH_SEP << m_queueSub; // 创建队列目录 if (acl_make_dirs(buf.c_str(), 0700) == -1) { logger_error("mkdir: %s error(%s)", buf.c_str(), acl_last_serror()); return false; } } #ifdef WIN32 // win32 下需要重新再打开 return (open(m_home, queueName, m_queueSub, m_partName, extName)); #else if (m_queueName != queueName) ACL_SAFE_STRNCPY(m_queueName, queueName, sizeof(m_queueName)); if (m_extName != extName) ACL_SAFE_STRNCPY(m_extName, extName, sizeof(m_extName)); m_filePath.clear(); m_filePath << m_home << PATH_SEP << m_queueName << PATH_SEP << m_queueSub << PATH_SEP << m_partName << "." << m_extName; #endif return (true); }
int acl_read_wait(ACL_SOCKET fd, int timeout) { const char *myname = "acl_read_wait"; int op = EPOLL_CTL_ADD, delay = timeout * 1000, *epoll_fd; struct epoll_event ee, events[1]; acl_assert(acl_pthread_once(&epoll_once, thread_epoll_init) == 0); epoll_fd = (int*) acl_pthread_getspecific(epoll_key); if (epoll_fd == NULL) { epoll_fd = (int*) acl_mymalloc(sizeof(int)); acl_assert(acl_pthread_setspecific(epoll_key, epoll_fd) == 0); if ((unsigned long) acl_pthread_self() == acl_main_thread_self()) { main_epoll_read_fd = epoll_fd; atexit(main_epoll_end); } *epoll_fd = epoll_create(1); } ee.events = EPOLLIN | EPOLLHUP | EPOLLERR; ee.data.u64 = 0; ee.data.fd = fd; if (epoll_ctl(*epoll_fd, op, fd, &ee) == -1) { acl_msg_error("%s(%d): epoll_ctl error: %s, fd: %d", myname, __LINE__, acl_last_serror(), fd); return -1; } if (epoll_wait(*epoll_fd, events, 1, delay) == -1) { acl_msg_error("%s(%d): epoll_wait error: %s, fd: %d", myname, __LINE__, acl_last_serror(), fd); return -1; } if ((events[0].events & (EPOLLERR | EPOLLHUP)) != 0) return -1; if ((events[0].events & EPOLLIN) == 0) { acl_set_error(ACL_ETIMEDOUT); return -1; } ee.events = 0; ee.data.u64 = 0; ee.data.fd = fd; if (epoll_ctl(*epoll_fd, EPOLL_CTL_DEL, fd, &ee) == -1) { acl_msg_error("%s(%d): epoll_ctl error: %s, fd: %d", myname, __LINE__, acl_last_serror(), fd); return -1; } return 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; }
int acl_read_wait(ACL_SOCKET fd, int timeout) { const char *myname = "acl_read_wait"; struct pollfd fds; int delay = timeout * 1000; time_t begin; fds.events = POLLIN | POLLHUP | POLLERR; fds.fd = fd; acl_set_error(0); for (;;) { time(&begin); switch (poll(&fds, 1, delay)) { case -1: if (acl_last_error() == ACL_EINTR) continue; acl_msg_error("%s(%d), %s: poll error(%s), fd: %d", __FILE__, __LINE__, myname, acl_last_serror(), (int) fd); return -1; case 0: acl_msg_warn("%s(%d), %s: poll timeout: %s, fd: %d, " "delay: %d, spent: %ld", __FILE__, __LINE__, myname, acl_last_serror(), fd, delay, (long) (time(NULL) - begin)); acl_set_error(ACL_ETIMEDOUT); return -1; default: if (fds.revents & (POLLHUP | POLLERR)) { acl_msg_warn("%s(%d), %s: poll error: %s, " "fd: %d, delay: %d, spent: %ld", __FILE__, __LINE__, myname, acl_last_serror(), fd, delay, (long) (time(NULL) - begin)); return -1; } else if ((fds.revents & POLLIN)) return 0; else { acl_msg_warn("%s(%d), %s: poll error: %s, " "fd: %d, delay: %d, spent: %ld", __FILE__, __LINE__, myname, acl_last_serror(), fd, delay, (long) (time(NULL) - begin)); return -1; } } } }
// 动态加载 zlib.dll 库 static void __zlib_dll_load(void) { if (__zlib_dll != NULL) logger_fatal("__zlib_dll not null"); #ifdef WIN32 __zlib_dll = acl_dlopen("zlib.dll"); #else __zlib_dll = acl_dlopen("libz.so"); #endif if (__zlib_dll == NULL) logger_fatal("load zlib.dll error: %s", acl_last_serror()); __deflateInit = (deflateInit_fn) acl_dlsym(__zlib_dll, "deflateInit_"); if (__deflateInit == NULL) logger_fatal("load deflateInit from zlib.dll error: %s", acl_last_serror()); __deflate = (deflate_fn) acl_dlsym(__zlib_dll, "deflate"); if (__deflate == NULL) logger_fatal("load deflate from zlib.dll error: %s", acl_last_serror()); __deflateReset = (deflateReset_fn) acl_dlsym(__zlib_dll, "deflateReset"); if (__deflateReset == NULL) logger_fatal("load deflateReset from zlib.dll error: %s", acl_last_serror()); __deflateEnd = (deflateEnd_fn) acl_dlsym(__zlib_dll, "deflateEnd"); if (__deflateEnd == NULL) logger_fatal("load deflateEnd from zlib.dll error: %s", acl_last_serror()); __inflateInit = (inflateInit_fn) acl_dlsym(__zlib_dll, "inflateInit2_"); if (__inflateInit == NULL) logger_fatal("load inflateInit from zlib.dll error: %s", acl_last_serror()); __inflate = (inflate_fn) acl_dlsym(__zlib_dll, "inflate"); if (__inflate == NULL) logger_fatal("load inflate from zlib.dll error: %s", acl_last_serror()); __inflateReset = (inflateReset_fn) acl_dlsym(__zlib_dll, "inflateReset"); if (__inflateReset == NULL) logger_fatal("load inflateReset from zlib.dll error: %s", acl_last_serror()); __inflateEnd = (inflateEnd_fn) acl_dlsym(__zlib_dll, "inflateEnd"); if (__inflateEnd == NULL) logger_fatal("load inflateEnd from zlib.dll error: %s", acl_last_serror()); logger("zlib.dll loaded"); atexit(__zlib_dll_unload); }
int acl_stream_connect(const char *path, int block_mode, int unused_timeout) { const char *myname = "acl_stream_connect"; #ifdef ACL_FREEBSD path = path; block_mode = block_mode; unused_timeout = unused_timeout; acl_msg_fatal("%s(%d): not support!", myname, __LINE__); return -1; #else int pair[2]; int fifo; unused_timeout = unused_timeout; /* * The requested file system object must exist, otherwise we can't reach * the server. */ if ((fifo = open(path, O_WRONLY | O_NONBLOCK, 0)) < 0) return -1; /* * Create a pipe, and send one pipe end to the server. */ if (pipe(pair) < 0) acl_msg_fatal("%s: pipe: %s", myname, acl_last_serror()); if (ioctl(fifo, I_SENDFD, pair[1]) < 0) acl_msg_fatal("%s: send file descriptor: %s", myname, acl_last_serror()); close(pair[1]); /* * This is for {unix,inet}_connect() compatibility. */ if (block_mode == ACL_NON_BLOCKING) acl_non_blocking(pair[0], ACL_NON_BLOCKING); /* * Cleanup. */ close(fifo); /* * Keep the other end of the pipe. */ return pair[0]; #endif /* ACL_FREEBSD */ }
static int zdb_dat_scan_path(ZDB *db, const char *path, int (*walk_fn)(ZDB_DAT_STORE *store)) { const char *myname = "zdb_dat_scan_path"; ZDB_DAT_STORE *store; ACL_SCAN_DIR *scan; const char *fname; char pathbuf[256]; int ret = 0; scan = acl_scan_dir_open(path, 1); if (scan == NULL) { acl_msg_error("%s(%d): open dir %s error(%s)", myname, __LINE__, path, acl_last_serror()); return (-1); } while (1) { fname = acl_scan_dir_next_file(scan); if (fname == NULL) { acl_msg_info("%s(%d): scan over for %s", myname, __LINE__, path); break; } if (strrncasecmp(fname, ".dat", 4) != 0) { acl_msg_info("%s(%d): skip %s/%s", myname, __LINE__, acl_scan_dir_path(scan), fname); continue; } snprintf(pathbuf, sizeof(pathbuf), "%s/%s", acl_scan_dir_path(scan), fname); store = zdb_dat_store_open(db, pathbuf); if (store == NULL) { acl_msg_error("%s(%d): open file(%s) error(%s)", myname, __LINE__, pathbuf, acl_last_serror()); break; } ret = walk_fn(store); zdb_dat_store_close(store); if (ret < 0) { acl_msg_error("%s(%d): walk_fn ret: %d, break", myname, __LINE__, ret); break; } } acl_scan_dir_close(scan); return (ret); }
int main(int argc, char *argv[]) { test(argv[1]); return 0; ACL_VSTREAM *client; const char *addr; char buf[1024]; int ret; if (argc != 2) { printf("usage: %s addr\n", argv[0]); return (0); } addr = argv[1]; acl_msg_open("connect.log", argv[0]); printf("connecting %s ...\n", argv[1]); //acl_poll_prefered(1); for (int i = 0; i < 10000; i++) { client = acl_vstream_connect(addr, ACL_BLOCKING, 10, 10, 4096); if (client == NULL) { printf("connect %s error(%s)\n", addr, acl_last_serror()); return (1); } printf("connect %s ok, %s\n", addr, acl_last_serror()); } printf(">>>>>>connect all ok\r\n"); pause(); sleep(100); acl_vstream_fprintf(client, "%s", "line1\nline2\nline3\nline4\nline5\nline6\nline7\n"); while (1) { ret = acl_vstream_gets_nonl(client, buf, sizeof(buf)); if (ret > 0) { printf("gets from %s: %s\n", addr, buf); } else if (ret == ACL_VSTREAM_EOF) { printf("get over\r\n"); break; } } acl_vstream_close(client); return (0); }
int acl_sane_socketpair(int domain, int type, int protocol, ACL_SOCKET result[2]) { ACL_SOCKET listener = acl_inet_listen("127.0.0.1:0", 1, ACL_BLOCKING); char addr[64]; (void) domain; result[0] = ACL_SOCKET_INVALID; result[1] = ACL_SOCKET_INVALID; if (listener == ACL_SOCKET_INVALID) { acl_msg_error("%s(%d), %s: listen error %s", __FILE__, __LINE__, __FUNCTION__, acl_last_serror()); return -1; } acl_tcp_set_nodelay(listener); if (acl_getsockname(listener, addr, sizeof(addr)) < 0) { acl_msg_error("%s(%d), %s: getoskname error %s", __FILE__, __LINE__, __FUNCTION__, acl_last_serror()); acl_socket_close(listener); return -1; } result[0] = acl_inet_connect(addr, ACL_BLOCKING, 0); if (result[0] == ACL_SOCKET_INVALID) { acl_msg_error("%s(%d), %s: connect %s error %s", __FILE__, __LINE__, __FUNCTION__, addr, acl_last_serror()); acl_socket_close(listener); return -1; } result[1] = acl_inet_accept(listener); acl_socket_close(listener); if (result[1] == ACL_SOCKET_INVALID) { acl_msg_error("%s(%d), %s: accept error %s", __FILE__, __LINE__, __FUNCTION__, acl_last_serror()); acl_socket_close(result[0]); result[0] = ACL_SOCKET_INVALID; return -1; } acl_tcp_set_nodelay(result[0]); acl_tcp_set_nodelay(result[1]); return 0; }
static void test(void) { ACL_FILE_HANDLE fds[2]; char buf[1024]; int ret; if (acl_pipe(fds) < 0) { printf("acl_pipe error(%s)\n", acl_last_serror()); return; } sprintf(buf, "hello client"); ret = acl_file_write(fds[0], buf, strlen(buf), 0, 0); if (ret == ACL_VSTREAM_EOF) { printf("write to client error(%s)\n", acl_last_serror()); acl_pipe_close(fds); return; } printf(">>>server: write to client ok\n"); ret = acl_file_read(fds[1], buf, sizeof(buf), 0, 0); if (ret == ACL_VSTREAM_EOF) { printf(">>>client: read from server error(%s)\n", acl_last_serror()); acl_pipe_close(fds); return; } buf[ret] = 0; printf(">>>client: read from server ok(%s)\n", buf); sprintf(buf, "hello server"); ret = acl_file_write(fds[1], buf, strlen(buf), 0, 0); if (ret == ACL_VSTREAM_EOF) { printf("write to server error(%s)\n", acl_last_serror()); acl_pipe_close(fds); return; } printf(">>>client: write to server ok\n"); ret = acl_file_read(fds[0], buf, sizeof(buf), 0, 0); if (ret == ACL_VSTREAM_EOF) { printf(">>>server: read from client error(%s)\n", acl_last_serror()); acl_pipe_close(fds); return; } printf(">>>server: read from client ok(%s)\n", buf); acl_pipe_close(fds); }
ssize_t tls_prng_dev_read(TLS_PRNG_SRC *dev, size_t len) { const char *myname = "tls_prng_dev_read"; unsigned char buffer[UCHAR_MAX]; ssize_t count; size_t rand_bytes; if (len <= 0) acl_msg_panic("%s: bad read length: %ld", myname, (long) len); if (len > sizeof(buffer)) rand_bytes = sizeof(buffer); else rand_bytes = len; errno = 0; #ifdef ACL_UNIX count = acl_timed_read(dev->fd.file, buffer, (int) rand_bytes, dev->timeout, NULL); #elif defined(WIN32) count = acl_file_read(dev->fd.file, buffer, (int) rand_bytes, dev->timeout, NULL); #endif if (count > 0) { if (acl_msg_verbose) acl_msg_info("%s: read %ld bytes from entropy device %s", myname, (long) count, dev->name); RAND_seed(buffer, count); } else { if (acl_msg_verbose) acl_msg_info("%s: cannot read %ld bytes from entropy device %s: %s", myname, (long) rand_bytes, dev->name, acl_last_serror()); } return (count); }
static int disable_write(EVENT_KERNEL *ev, ACL_EVENT_FDTABLE *fdp) { const char *myname = "disable_write"; ACL_VSTREAM *stream = fdp->stream; ACL_SOCKET sockfd = ACL_VSTREAM_SOCK(stream); int err, ret = 0; fdp->flag &= ~EVENT_FDTABLE_FLAG_DEL_WRITE; fdp->flag &= ~EVENT_FDTABLE_FLAG_WRITE; fdp->event_type &= ~(ACL_EVENT_WRITE | ACL_EVENT_CONNECT); if ((fdp->flag & EVENT_FDTABLE_FLAG_READ)) { #if (ACL_EVENTS_KERNEL_STYLE == ACL_EVENTS_STYLE_KQUEUE) EVENT_REG_DEL_WRITE(err, ev->event_fd, sockfd); #else EVENT_REG_MOD_READ(err, ev->event_fd, sockfd, fdp); #endif } else { #ifdef USE_FDMAP acl_fdmap_del(ev->fdmap, sockfd); #endif #ifdef EVENT_REG_DEL_BOTH EVENT_REG_DEL_BOTH(err, ev->event_fd, sockfd); #else EVENT_REG_DEL_WRITE(err, ev->event_fd, sockfd); #endif ret = 1; } if (err < 0) { acl_msg_fatal("%s: %s: %s, err(%d), fd(%d), ret(%d)", myname, EVENT_REG_DEL_TEXT, acl_last_serror(), err, sockfd, ret); } return (ret); }
static void enable_write(EVENT_KERNEL *ev, ACL_EVENT_FDTABLE *fdp) { const char *myname = "enable_write"; ACL_SOCKET sockfd = ACL_VSTREAM_SOCK(fdp->stream); int err; fdp->flag &= ~EVENT_FDTABLE_FLAG_ADD_WRITE; fdp->flag |= EVENT_FDTABLE_FLAG_WRITE; if ((fdp->flag & EVENT_FDTABLE_FLAG_READ)) { #if (ACL_EVENTS_KERNEL_STYLE == ACL_EVENTS_STYLE_KQUEUE) EVENT_REG_ADD_WRITE(err, ev->event_fd, sockfd, fdp); #else EVENT_REG_MOD_RDWR(err, ev->event_fd, sockfd, fdp); #endif } else { EVENT_REG_ADD_WRITE(err, ev->event_fd, sockfd, fdp); } if (err < 0) { acl_msg_fatal("%s: %s: %s, err(%d), fd(%d)", myname, EVENT_REG_ADD_TEXT, acl_last_serror(), err, sockfd); } }
int acl_sem_wait_timeout(ACL_SEM *sem, unsigned int timeout) { const char *myname = "acl_sem_wait_timeout"; int retval; DWORD dwMilliseconds; if (sem == NULL) { acl_msg_error("%s, %s(%d): input invalid", __FILE__, myname, __LINE__); return -1; } if (timeout == ACL_MUTEX_MAXWAIT) dwMilliseconds = INFINITE; else dwMilliseconds = (DWORD) timeout; switch (WaitForSingleObject(sem->id, dwMilliseconds)) { case WAIT_OBJECT_0: --sem->count; retval = 0; break; case WAIT_TIMEOUT: retval = ACL_ETIMEDOUT; break; default: acl_msg_error("%s, %s(%d): WaitForSingleObject() failed", __FILE__, myname, __LINE__, acl_last_serror()); retval = -1; break; } return retval; }
int acl_sem_post(ACL_SEM *sem) { const char *myname = "acl_sem_post"; if (sem == NULL) { acl_msg_error("%s, %s(%d): input invalid", __FILE__, myname, __LINE__); return -1; } /* Increase the counter in the first place, because * after a successful release the semaphore may * immediately get destroyed by another thread which * is waiting for this semaphore. */ ++sem->count; if (ReleaseSemaphore(sem->id, 1, NULL) == FALSE) { --sem->count; /* restore */ acl_msg_error("%s, %s(%d): ReleaseSemaphore() failed", __FILE__, myname, __LINE__, acl_last_serror()); return -1; } return 0; }
acl_int64 acl_scan_dir_size(const char *pathname, int recursive, int *nfile, int *ndir) { const char *myname = "acl_scan_dir_size"; ACL_SCAN_DIR *scan; acl_int64 size; if (pathname == NULL || *pathname == 0) { acl_msg_error("%s(%d), %s: pathname null", __FILE__, __LINE__, myname); return -1; } scan = acl_scan_dir_open(pathname, recursive); if (scan == NULL) { acl_msg_error("%s(%d), %s: dir_open error: %s, path: %s", __FILE__, __LINE__, myname, acl_last_serror(), pathname); return -1; } size = acl_scan_dir_size2(scan, nfile, ndir); acl_scan_dir_close(scan); return size; }
TLS_SCACHE *tls_scache_open(const char *dbname, const char *cache_label, int verbose, int timeout) { const char *myname = "tls_scache_open"; TLS_SCACHE *cp; DICT *dict; /* * Logging. */ if (verbose) acl_msg_info("open %s TLS cache %s", cache_label, dbname); /* * Open the dictionary with O_TRUNC, so that we never have to worry about * opening a damaged file after some process terminated abnormally. */ #ifdef SINGLE_UPDATER #define DICT_FLAGS (DICT_FLAG_DUP_REPLACE) #elif defined(ACL_UNIX) #define DICT_FLAGS \ (DICT_FLAG_DUP_REPLACE | DICT_FLAG_LOCK | DICT_FLAG_SYNC_UPDATE) #elif defined(WIN32) #define DICT_FLAGS \ (DICT_FLAG_DUP_REPLACE | DICT_FLAG_SYNC_UPDATE) #endif dict = dict_open(dbname, O_RDWR | O_CREAT | O_TRUNC, DICT_FLAGS); /* * Sanity checks. */ if (dict->lock_fd < 0) acl_msg_fatal("%s: dictionary %s is not a regular file", myname, dbname); #ifdef SINGLE_UPDATER if (acl_myflock(dict->lock_fd, INTERNAL_LOCK, MYFLOCK_OP_EXCLUSIVE | MYFLOCK_OP_NOWAIT) < 0) acl_msg_fatal("%s: cannot lock dictionary %s for exclusive use: %s", myname, dbname, acl_last_serror()); #endif if (dict->update == 0) acl_msg_fatal("%s: dictionary %s does not support update operations", myname, dbname); if (dict->delete_it == 0) acl_msg_fatal("%s: dictionary %s does not support delete operations", myname, dbname); if (dict->sequence == 0) acl_msg_fatal("%s: dictionary %s does not support sequence operations", myname, dbname); /* * Create the TLS_SCACHE object. */ cp = (TLS_SCACHE *) acl_mymalloc(sizeof(*cp)); cp->flags = 0; cp->db = dict; cp->cache_label = acl_mystrdup(cache_label); cp->verbose = verbose; cp->timeout = timeout; cp->saved_cursor = 0; return (cp); }
int master_threads::service_on_accept(ACL_VSTREAM* client) { // client->context 不应被占用 if (client->context != NULL) logger_fatal("client->context not null!"); socket_stream* stream = NEW socket_stream(); if (stream->open(client) == false) { logger_error("open stream error(%s)", acl_last_serror()); delete stream; return -1; } // 设置 client->context 为流对象 client->context = stream; acl_assert(__mt != NULL); if (__mt->thread_on_accept(stream) == false) { client->context = NULL; // 解释与连接流的绑定关系,这样可以防止在删除流对象时 // 真正关闭了连接流,因为该流连接需要在本函数返回后由 // 框架自动关闭 (void) stream->unbind(); // 删除流对象 delete stream; // 让框架关闭连接流 return -1; } return 0; }
static int http_demo(ACL_VSTREAM *cstream, const char* res, size_t len) { char buf[8192]; int ret; cstream->rw_timeout = __rw_timeout; while (1) { ret = acl_vstream_gets_nonl(cstream, buf, sizeof(buf) - 1); if (ret == ACL_VSTREAM_EOF) { printf("gets error: %s\r\n", acl_last_serror()); return -1; } buf[ret] = 0; if (strcasecmp(buf, "stop") == 0) { __stop = 1; printf("----stop now----\r\n"); break; } if (ret == 0) break; } if (acl_vstream_writen(cstream, res, len) == ACL_VSTREAM_EOF) { printf("write error\r\n"); return -1; } return 0; }
bool server_socket::open(const char* addr) { #ifndef ACL_WINDOWS if (strchr(addr, '/') != NULL) { fd_ = acl_unix_listen(addr, backlog_, block_ ? ACL_BLOCKING : ACL_NON_BLOCKING); unix_sock_ = true; ACL_SAFE_STRNCPY(addr_, addr, sizeof(addr_)); } else #endif fd_ = acl_inet_listen(addr, backlog_, block_ ? ACL_BLOCKING : ACL_NON_BLOCKING); if (fd_ == ACL_SOCKET_INVALID) { logger_error("listen %s error %s", addr, last_serror()); unix_sock_ = false; ACL_SAFE_STRNCPY(addr_, addr, sizeof(addr_)); return false; } if (unix_sock_) return true; // 之所以再用 getsockname 重新获得一些监听地址,主要是为了应对当输入的 addr // 为 ip:0 的情形,即当给定的地址中的端口为 0 时要求操作系统自动分配一个端口号 if (acl_getsockname(fd_, addr_, sizeof(addr_)) < 0) { logger_error("getsockname error: %s", acl_last_serror()); ACL_SAFE_STRNCPY(addr_, addr, sizeof(addr_)); } return true; }