Exemple #1
0
int main(int argc, char **argv)
{
	const static char annotate = '#';
	char *ptr_annotate = NULL;
    char    path[128] = {0};
	char	line[128] = {0};
	char	*buf = NULL;
	char	*ptr = NULL;
    size_t  buf_sz = 0;
	pid_t	pid = -1;
//    int     len = 0;

	if ((argc == 0) && (strcmp(argv[1], "-d") != 0))
	{
		if ((pid = create_daemon()) < 0)
			_exit(-1);
		else if (pid > 0)
			_exit(1);
	}

    openlog("vp-promon", LOG_CONS|LOG_PID|LOG_PERROR, LOG_USER);

    sprintf(path, "%s/promon.conf", PATH_CFG);

	if ( ! t_read_full_file(path, &buf, &buf_sz, 0))
	{
		logdbg_fmt("Open configure file failed!(%s)\n", path);
		return -1;
	}

	ptr = buf;
	while ((ptr = loop_line_from_buf(ptr, line, sizeof(line))) != NULL)
	{
		if ((ptr_annotate = strchr(line, annotate)) != NULL)
			*ptr_annotate = '\0';
		trimleft(line);
        /*
        if (line[strlen(line)-1] == '&')
            line[strlen(line)] = '\0';
            */

		if (line[0] == '\0')
			continue ;

		if ((pid = create_daemon()) < 0)
			break;
		else if (pid == 0)
			do_promon(line);	
	}
	oss_free(&buf);

	return 0;
}
Exemple #2
0
/*
	* Handle options to control the daemon
	*/
void daemon_manager(const char *bin, const char *cmd)
{
				pid_t pid;
				char *str;

				str = str_tolower(cmd);

				if (strcmp(str, "start") == 0) {
								if (load_pid_file() > 0) {
												printf("Daemon is already running\n");
												exit(EXIT_FAILURE);
								}

								pid = create_daemon(bin);
								/* If the returned pid is < 0, there was a problem with the
											fork and we exit with a failure */
								if (pid < 0) {
												free(str);
												exit(EXIT_FAILURE);
								}
								/* If the returned pid > 0 it is the pid of the child and we are
											the parent. Save the pid to the pid file and exit with success */
								if (pid > 0) {
												save_pid_file(pid);
												free(str);
												exit(EXIT_SUCCESS);
								}

								/* If this point is reached, the fork was successfull and we
											are the child process. Continue as daemon from here on. */

				} else if (strcmp(str, "stop") == 0) {
								pid = load_pid_file();
								if (pid <= 0) {
												printf("No pid file, cannot stop\n");
												exit(EXIT_FAILURE);
								}
								/* Send a SIGTERM signal to the daemon */
								kill(pid, SIGTERM);

								remove_pid_file();

								exit(EXIT_SUCCESS);

				} else if (strcmp(str, "restart") == 0 ) {
								/* Leave empty for now */
				}

				free(str);
}
Exemple #3
0
int main (int argc, char * argv[]) {
    /* availability options */
    char * opts = "d";
    /* processed option */
    int c;

    int sock_id;

    /* dodanie handlera na SIGINT */
    signal(SIGINT, sigint_handler);

    /* check if define more than one option */
    if (argc == 2) {
        /* iteration by each of option */
        while ((c = getopt(argc, argv, opts)) != -1) {
            switch (c) {
                /* for 'u' run daemon */
                case 'd':
                    create_daemon();
                    break;
                /* for unrecognized option */
                case '?':
                default:
                    printf("Ignore passed options\n");
            }
        }
    }

    printf("=== create server ===\n\n");

    /* create socket */
    sock_id = create_socket_tcp();

    /* bind server to defined port */
    bind_port(sock_id, PORT);

    /* server waiting for client */
    listen_for_client_tcp(sock_id, MAX_QUEUE);

    /* handle client */
    handle_incoming_client(sock_id, send_time_to_socket, 1);

    return 0;
}
Exemple #4
0
int main(int argc, char **argv)
{
	struct daemon *daemon;
	struct config *cfg;
	int ret;

	/*
	   if(!check_root()) {
	   fprintf(stderr, "permission denied, root only\n");
	   exit(EXIT_FAILURE);
	   }
	 */
	if(argc < 3) {
		daemonize();
	}
	signal(SIGPIPE, SIG_IGN);

	ret = log_init(HADM_LOG_CONF, HADM_SERVER_LOG_CAT);
	if(ret < 0) {
		exit(EXIT_FAILURE);
	}

	cfg = load_config(CONFIG_FILE);
	if(cfg == NULL) {
		log_error("load config file failed, please check config file!");
		exit(EXIT_FAILURE);
	}

	daemon = create_daemon(cfg);
	if(daemon == NULL) {
		exit(EXIT_FAILURE);
	}

	if(init_daemon(daemon) < 0) {
		exit(EXIT_FAILURE);
	}

	daemon_run(daemon);

	return 0;
}
Exemple #5
0
/*
 * @ proto_type: the proxy type of raw-vsudp or raw-vstcp
 * @ arg: the param of pass videostream process.
 */
int start_vstream_proxy(char * proto_type, char * arg[])
{
    pid_t pid;
    char  exec_path[128];

    //sprintf(exec_path, "%s/%s", DEFAULT_APP_DIR, proto_type);
    sprintf(exec_path, "%s/%s", g_p_app_dir, proto_type);

    signal(SIGCHLD, SIG_IGN);

    if ((pid = create_daemon()) < 0)
        _exit(-1);
    else if (pid == 0) {
        if (execv(exec_path, arg) == -1) {
            syslog(LOG_INFO, "start_vstream_proxy() failed");
            return -1;
        }
    }

    return pid;
}
Exemple #6
0
static void server_loop(const char *socket_path, const char *pidfile_path,
                        int debug, int timeout, int quiet)
{
    struct sockaddr_un	my_addr, from_addr;
    struct flock		fl;
    socklen_t		fromlen;
    int32_t			reply_len = 0;
    uuid_t			uu;
    mode_t			save_umask;
    char			reply_buf[1024], *cp;
    char			op, str[37];
    int			i, s, ns, len, num;
    int			fd_pidfile, ret;

    fd_pidfile = open(pidfile_path, O_CREAT | O_RDWR, 0664);
    if (fd_pidfile < 0) {
        if (!quiet)
            fprintf(stderr, "Failed to open/create %s: %s\n",
                    pidfile_path, strerror(errno));
        exit(1);
    }
    cleanup_pidfile = pidfile_path;
    cleanup_socket = 0;
    signal(SIGALRM, terminate_intr);
    alarm(30);
    fl.l_type = F_WRLCK;
    fl.l_whence = SEEK_SET;
    fl.l_start = 0;
    fl.l_len = 0;
    fl.l_pid = 0;
    while (fcntl(fd_pidfile, F_SETLKW, &fl) < 0) {
        if ((errno == EAGAIN) || (errno == EINTR))
            continue;
        if (!quiet)
            fprintf(stderr, "Failed to lock %s: %s\n",
                    pidfile_path, strerror(errno));
        exit(1);
    }
    ret = call_daemon(socket_path, 0, reply_buf, sizeof(reply_buf), 0, 0);
    if (ret > 0) {
        if (!quiet)
            printf(_("uuidd daemon already running at pid %s\n"),
                   reply_buf);
        exit(1);
    }
    alarm(0);

    if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
        if (!quiet)
            fprintf(stderr, _("Couldn't create unix stream "
                              "socket: %s"), strerror(errno));
        exit(1);
    }

    /*
     * Make sure the socket isn't using fd numbers 0-2 to avoid it
     * getting closed by create_daemon()
     */
    while (!debug && s <= 2) {
        s = dup(s);
        if (s < 0) {
            perror("dup");
            exit(1);
        }
    }

    /*
     * Create the address we will be binding to.
     */
    my_addr.sun_family = AF_UNIX;
    strncpy(my_addr.sun_path, socket_path, sizeof(my_addr.sun_path));
    my_addr.sun_path[sizeof(my_addr.sun_path)-1] = '\0';
    (void) unlink(socket_path);
    save_umask = umask(0);
    if (bind(s, (const struct sockaddr *) &my_addr,
             sizeof(struct sockaddr_un)) < 0) {
        if (!quiet)
            fprintf(stderr,
                    _("Couldn't bind unix socket %s: %s\n"),
                    socket_path, strerror(errno));
        exit(1);
    }
    (void) umask(save_umask);

    if (listen(s, 5) < 0) {
        if (!quiet)
            fprintf(stderr, _("Couldn't listen on unix "
                              "socket %s: %s\n"), socket_path,
                    strerror(errno));
        exit(1);
    }

    cleanup_socket = socket_path;
    if (!debug)
        create_daemon();
    signal(SIGHUP, terminate_intr);
    signal(SIGINT, terminate_intr);
    signal(SIGTERM, terminate_intr);
    signal(SIGALRM, terminate_intr);
    signal(SIGPIPE, SIG_IGN);

    sprintf(reply_buf, "%8d\n", getpid());
    if (ftruncate(fd_pidfile, 0)) {} /* Silence warn_unused_result */
    write_all(fd_pidfile, reply_buf, strlen(reply_buf));
    if (fd_pidfile > 1)
        close(fd_pidfile); /* Unlock the pid file */

    while (1) {
        fromlen = sizeof(from_addr);
        if (timeout > 0)
            alarm(timeout);
        ns = accept(s, (struct sockaddr *) &from_addr, &fromlen);
        alarm(0);
        if (ns < 0) {
            if ((errno == EAGAIN) || (errno == EINTR))
                continue;
            perror("accept");
            exit(1);
        }
        len = read(ns, &op, 1);
        if (len != 1) {
            if (len < 0)
                perror("read");
            else
                printf(_("Error reading from client, "
                         "len = %d\n"), len);
            goto shutdown_socket;
        }
        if ((op == 4) || (op == 5)) {
            if (read_all(ns, (char *) &num, sizeof(num)) != 4)
                goto shutdown_socket;
            if (debug)
                printf(_("operation %d, incoming num = %d\n"),
                       op, num);
        } else if (debug)
            printf("operation %d\n", op);

        switch(op) {
        case UUIDD_OP_GETPID:
            sprintf(reply_buf, "%d", getpid());
            reply_len = strlen(reply_buf)+1;
            break;
        case UUIDD_OP_GET_MAXOP:
            sprintf(reply_buf, "%d", UUIDD_MAX_OP);
            reply_len = strlen(reply_buf)+1;
            break;
        case UUIDD_OP_TIME_UUID:
            num = 1;
            uuid__generate_time(uu, &num);
            if (debug) {
                uuid_unparse(uu, str);
                printf(_("Generated time UUID: %s\n"), str);
            }
            memcpy(reply_buf, uu, sizeof(uu));
            reply_len = sizeof(uu);
            break;
        case UUIDD_OP_RANDOM_UUID:
            num = 1;
            uuid__generate_random(uu, &num);
            if (debug) {
                uuid_unparse(uu, str);
                printf(_("Generated random UUID: %s\n"), str);
            }
            memcpy(reply_buf, uu, sizeof(uu));
            reply_len = sizeof(uu);
            break;
        case UUIDD_OP_BULK_TIME_UUID:
            uuid__generate_time(uu, &num);
            if (debug) {
                uuid_unparse(uu, str);
                printf(_("Generated time UUID %s and %d "
                         "following\n"), str, num);
            }
            memcpy(reply_buf, uu, sizeof(uu));
            reply_len = sizeof(uu);
            memcpy(reply_buf+reply_len, &num, sizeof(num));
            reply_len += sizeof(num);
            break;
        case UUIDD_OP_BULK_RANDOM_UUID:
            if (num < 0)
                num = 1;
            if (num > 1000)
                num = 1000;
            if (num*16 > (int) (sizeof(reply_buf)-sizeof(num)))
                num = (sizeof(reply_buf)-sizeof(num)) / 16;
            uuid__generate_random((unsigned char *) reply_buf +
                                  sizeof(num), &num);
            if (debug) {
                printf(_("Generated %d UUID's:\n"), num);
                for (i=0, cp=reply_buf+sizeof(num);
                        i < num; i++, cp+=16) {
                    uuid_unparse((unsigned char *)cp, str);
                    printf("\t%s\n", str);
                }
            }
            reply_len = (num*16) + sizeof(num);
            memcpy(reply_buf, &num, sizeof(num));
            break;
        default:
            if (debug)
                printf(_("Invalid operation %d\n"), op);
            goto shutdown_socket;
        }
        write_all(ns, (char *) &reply_len, sizeof(reply_len));
        write_all(ns, reply_buf, reply_len);
shutdown_socket:
        close(ns);
    }
}
Exemple #7
0
static void server_loop(const char *socket_path, const char *pidfile_path,
			const struct uuidd_cxt_t *uuidd_cxt)
{
	struct sockaddr_un	from_addr;
	socklen_t		fromlen;
	int32_t			reply_len = 0;
	uuid_t			uu;
	char			reply_buf[1024], *cp;
	char			op, str[UUID_STR_LEN];
	int			i, ns, len, num;
	int			s = 0;
	int			fd_pidfile = -1;
	int			ret;

#ifdef USE_SOCKET_ACTIVATION
	if (!uuidd_cxt->no_sock)	/* no_sock implies no_fork and no_pid */
#endif
	{

		signal(SIGALRM, terminate_intr);
		alarm(30);
		if (pidfile_path)
			fd_pidfile = create_pidfile(pidfile_path, uuidd_cxt->quiet);

		ret = call_daemon(socket_path, UUIDD_OP_GETPID, reply_buf,
				  sizeof(reply_buf), 0, NULL);
		if (ret > 0) {
			if (!uuidd_cxt->quiet)
				warnx(_("uuidd daemon is already running at pid %s"),
				       reply_buf);
			exit(EXIT_FAILURE);
		}
		alarm(0);

		s = create_socket(socket_path,
				  (!uuidd_cxt->debug || !uuidd_cxt->no_fork),
				  uuidd_cxt->quiet);
		if (listen(s, SOMAXCONN) < 0) {
			if (!uuidd_cxt->quiet)
				warn(_("couldn't listen on unix socket %s"), socket_path);
			exit(EXIT_FAILURE);
		}

		if (!uuidd_cxt->debug && !uuidd_cxt->no_fork)
			create_daemon();

		if (pidfile_path) {
			sprintf(reply_buf, "%8d\n", getpid());
			ignore_result( ftruncate(fd_pidfile, 0) );
			write_all(fd_pidfile, reply_buf, strlen(reply_buf));
			if (fd_pidfile > 1)
				close(fd_pidfile); /* Unlock the pid file */
		}

	}

	signal(SIGHUP, terminate_intr);
	signal(SIGINT, terminate_intr);
	signal(SIGTERM, terminate_intr);
	signal(SIGALRM, terminate_intr);
	signal(SIGPIPE, SIG_IGN);

#ifdef USE_SOCKET_ACTIVATION
	if (uuidd_cxt->no_sock) {
		if (sd_listen_fds(0) != 1)
			errx(EXIT_FAILURE, _("no or too many file descriptors received"));

		s = SD_LISTEN_FDS_START + 0;
	}
#endif

	while (1) {
		fromlen = sizeof(from_addr);
		if (uuidd_cxt->timeout > 0)
			alarm(uuidd_cxt->timeout);
		ns = accept(s, (struct sockaddr *) &from_addr, &fromlen);
		alarm(0);
		if (ns < 0) {
			if ((errno == EAGAIN) || (errno == EINTR))
				continue;
			else
				err(EXIT_FAILURE, "accept");
		}
		len = read(ns, &op, 1);
		if (len != 1) {
			if (len < 0)
				warn(_("read failed"));
			else
				warnx(_("error reading from client, len = %d"),
						len);
			goto shutdown_socket;
		}
		if ((op == UUIDD_OP_BULK_TIME_UUID) ||
		    (op == UUIDD_OP_BULK_RANDOM_UUID)) {
			if (read_all(ns, (char *) &num, sizeof(num)) != 4)
				goto shutdown_socket;
			if (uuidd_cxt->debug)
				fprintf(stderr, _("operation %d, incoming num = %d\n"),
				       op, num);
		} else if (uuidd_cxt->debug)
			fprintf(stderr, _("operation %d\n"), op);

		switch (op) {
		case UUIDD_OP_GETPID:
			sprintf(reply_buf, "%d", getpid());
			reply_len = strlen(reply_buf) + 1;
			break;
		case UUIDD_OP_GET_MAXOP:
			sprintf(reply_buf, "%d", UUIDD_MAX_OP);
			reply_len = strlen(reply_buf) + 1;
			break;
		case UUIDD_OP_TIME_UUID:
			num = 1;
			__uuid_generate_time(uu, &num);
			if (uuidd_cxt->debug) {
				uuid_unparse(uu, str);
				fprintf(stderr, _("Generated time UUID: %s\n"), str);
			}
			memcpy(reply_buf, uu, sizeof(uu));
			reply_len = sizeof(uu);
			break;
		case UUIDD_OP_RANDOM_UUID:
			num = 1;
			__uuid_generate_random(uu, &num);
			if (uuidd_cxt->debug) {
				uuid_unparse(uu, str);
				fprintf(stderr, _("Generated random UUID: %s\n"), str);
			}
			memcpy(reply_buf, uu, sizeof(uu));
			reply_len = sizeof(uu);
			break;
		case UUIDD_OP_BULK_TIME_UUID:
			__uuid_generate_time(uu, &num);
			if (uuidd_cxt->debug) {
				uuid_unparse(uu, str);
				fprintf(stderr, P_("Generated time UUID %s "
						   "and %d following\n",
						   "Generated time UUID %s "
						   "and %d following\n", num - 1),
				       str, num - 1);
			}
			memcpy(reply_buf, uu, sizeof(uu));
			reply_len = sizeof(uu);
			memcpy(reply_buf + reply_len, &num, sizeof(num));
			reply_len += sizeof(num);
			break;
		case UUIDD_OP_BULK_RANDOM_UUID:
			if (num < 0)
				num = 1;
			if (num > 1000)
				num = 1000;
			if (num * UUID_LEN > (int) (sizeof(reply_buf) - sizeof(num)))
				num = (sizeof(reply_buf) - sizeof(num)) / UUID_LEN;
			__uuid_generate_random((unsigned char *) reply_buf +
					      sizeof(num), &num);
			if (uuidd_cxt->debug) {
				fprintf(stderr, P_("Generated %d UUID:\n",
						   "Generated %d UUIDs:\n", num), num);
				for (i = 0, cp = reply_buf + sizeof(num);
				     i < num;
				     i++, cp += UUID_LEN) {
					uuid_unparse((unsigned char *)cp, str);
					fprintf(stderr, "\t%s\n", str);
				}
			}
			reply_len = (num * UUID_LEN) + sizeof(num);
			memcpy(reply_buf, &num, sizeof(num));
			break;
		default:
			if (uuidd_cxt->debug)
				fprintf(stderr, _("Invalid operation %d\n"), op);
			goto shutdown_socket;
		}
		write_all(ns, (char *) &reply_len, sizeof(reply_len));
		write_all(ns, reply_buf, reply_len);
	shutdown_socket:
		close(ns);
	}
}
Exemple #8
0
int main(int argc, char **argv)
{
    if (argc != 3 && argc != 4) {
        usage(argv[0]);
        exit(0);
    }
    
    char cfg_file[MAX_LINE] = {0};
    int make_deamon = 0;
    
    int ch;
    const char *args = "c:dh";
    while ((ch = getopt(argc, argv, args)) != -1) {
        switch (ch) {
            case 'c':
                snprintf(cfg_file, sizeof(cfg_file), "%s", optarg);
                break;
            case 'd':
                make_deamon = 1;
                break;
                
            case 'h':
            default:
                usage(argv[0]);
                exit(0);
                break;
        }
    }
    
    if (make_deamon == 1) {
        // create deamon
        create_daemon(config_st.chdir_path);
    }
    
    // init log
    ctlog("ctserver", LOG_PID|LOG_NDELAY, LOG_MAIL);
    
    // read config
    dict_conf = open_config(cfg_file);
    if (dict_conf == NULL) {
        printf("parse config fail");
        return 1;
    }
    if (read_config(dict_conf) != 0) {
        return 1;
    }
    log_level = atoi(config_st.log_level);
    
    if (chdir(config_st.chdir_path) == -1) {
        log_error("can not start: unable to change directory:%s", config_st.chdir_path);
        return 1;
    }
    log_debug("bind_port:%s", config_st.bind_port);
    log_debug("log_level:%s", config_st.log_level);
    log_debug("chdir_path:%s", config_st.chdir_path);
    log_debug("max_childs:%s", config_st.max_childs);
    log_debug("child_prog:%s", config_st.child_prog);
    log_debug("child_cf:%s", config_st.child_cf);
    
    // Get Local Host Name
    char local_hostname[MAX_LINE] = {0};
    if (gethostname(local_hostname, sizeof(local_hostname)) != 0) {
        snprintf(local_hostname, sizeof(local_hostname), "unknown");
    }
    log_debug("local_hostname:%s", local_hostname);
    
    
    // ---------- ----------
    
    childs_st = (struct childs_t *)malloc((atoi(config_st.max_childs) + 1) * sizeof(struct childs_t));
    if (childs_st == NULL) {
        log_error("malloc childs [%d] faild:[%d]:%s", (atoi(config_st.max_childs) + 1), errno, strerror(errno));
        exit(1);
    }
    
    int i = 0;
    for (i=0; i<(atoi(config_st.max_childs) +1); i++) {
        init_child_with_idx(i);
    }
    
    
    // Start Server
    int connfd, epfd, sockfd, n, nread, nwrite;
    struct sockaddr_in local, remote;
    socklen_t addrlen;
    
    
    // Create Listen Socket
    int bind_port = atoi(config_st.bind_port);
    if ((listen_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
        log_error("socket fail:[%d]:%s", errno, strerror(errno));
        exit(1);
    }

	// 设置套接字选项避免地址使用错误,解决: Address already in use
	int on = 1;
    if ((setsockopt(listen_fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on))) < 0) {
        log_error("setsockopt failed");
        exit(1);
    }
    
    // Set Listen FD Nonblock
    if (set_nonblocking(listen_fd) != 0) {
        exit(1);
    }
    
    bzero(&local, sizeof(local));
    local.sin_family = AF_INET;
    local.sin_addr.s_addr = htonl(INADDR_ANY);
    local.sin_port = htons(bind_port);
    if (bind(listen_fd, (struct sockaddr *)&local, sizeof(local)) < 0) {
        log_error("bind local %d failed:[%d]%s", bind_port, errno, strerror(errno));
        exit(1);
    }
    log_info("bind local %d succ", bind_port);
    
    if (listen(listen_fd, atoi(config_st.max_childs)) != 0) {
        log_error("listen fd[%d] max_number[%d] failed:[%d]%s", listen_fd, atoi(config_st.max_childs), errno, strerror(errno));
        exit(1);
    }
    
    // Ignore pipe signal
    sig_pipeignore();
    // Catch signal which is child program exit
    sig_catch(SIGCHLD, sigchld_exit);
    
    // epoll create fd
    epoll_event_num = atoi(config_st.max_childs) + 1;
    epoll_evts = NULL;
    epoll_fd = -1;
    epoll_nfds = -1;
    
    int epoll_i = 0;
    
    epoll_evts = (struct epoll_event *)malloc(epoll_event_num * sizeof(struct epoll_event));
    if (epoll_evts == NULL) {
        log_error("malloc for epoll event fail");
        exit(1);
    }
    
    epoll_fd = epoll_create(epoll_event_num);
    if (epoll_fd == -1) {
        log_error("epoll_create max_number[%d] failed:[%d]%s", epoll_event_num, errno, strerror(errno));
        exit(1);
    }
    
    struct epoll_event ev;
    ev.events = EPOLLIN;
    ev.data.fd = listen_fd;
    if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, ev.data.fd, &ev) == -1) {
        log_error("epoll_ctl: listen_socket failed:[%d]%s", errno, strerror(errno));
        exit(1);
    }
    
    epoll_num_running = 0;
    
    for (;;) {
        
        epoll_nfds = epoll_wait(epoll_fd, epoll_evts, epoll_event_num, -1);
        
        if (epoll_nfds == -1) {
            if (errno == EINTR) {
                // 收到中断信号
                log_info("epoll_wait recive EINTR signal, continue");
                continue;
            }
            
            exit(1);
        }
        
        log_debug("epoll_num_running:%d nfds:%d", epoll_num_running, epoll_nfds);
        for (epoll_i = 0; epoll_i < epoll_nfds; epoll_i++) {
            sig_childblock();
            
            int evt_fd = epoll_evts[epoll_i].data.fd;
            if (evt_fd == listen_fd) {
                // new connect
                if ((connfd = accept(listen_fd, (struct sockaddr *)&remote, &addrlen)) > 0) {

                    char *ipaddr = inet_ntoa(remote.sin_addr);
                    log_debug("accept client:%s", ipaddr);
                    
                    char greet_buf[MAX_LINE] = {0};
                    
                    // get a new index from child list
                    int i = get_idle_idx_from_childs();
                    if (i == -1) {
                        log_error("get_idle_idx_from_childs_t fail: maybe client queue is full.");
                        
                        // send to client error information
                        n = snprintf(greet_buf, sizeof(greet_buf), "%s ERR %s%s", FAIL_CODE, local_hostname, DATA_END);
                        nwrite = write(connfd, greet_buf, n);
                        log_debug("send client fd[%d]:[%d]%s", connfd, nwrite, greet_buf);
                        
                        continue;
                    }
                    childs_st[i].used = 1;
                    
                    // get client ip and port.
                    struct sockaddr_in sa;
                    int len = sizeof(sa);
                    if (!getpeername(connfd, (struct sockaddr *)&sa, &len)) {
                        n = snprintf(childs_st[i].client_info.ip, sizeof(childs_st[i].client_info.ip), "%s", inet_ntoa(sa.sin_addr));
                        n = snprintf(childs_st[i].client_info.port, sizeof(childs_st[i].client_info.port), "%d", ntohs(sa.sin_port));
                        log_info("accept client:%s:%s", childs_st[i].client_info.ip, childs_st[i].client_info.port);
                    }
                    
                    
                    int pi1[2];
                    int pi2[2];
                    if (pipe(pi1) == -1) {
                        log_error("unable to create pipe:[%d]%s", errno, strerror(errno));
                        
                        // send to client error information
                        n = snprintf(greet_buf, sizeof(greet_buf), "%s ERR %s%s", FAIL_CODE, local_hostname, DATA_END);
                        nwrite = write(connfd, greet_buf, n);
                        log_debug("send client fd[%d]:[%d]%s", connfd, nwrite, greet_buf);
                        
                        continue;
                    }
                    if (pipe(pi2) == -1) {
                        log_error("unable to create pipe:[%d]%s", errno, strerror(errno));
                        
                        close(pi1[0]);
                        close(pi1[1]);
                        pi1[0] = -1;
                        pi1[1] = -1;
                        
                        // send to client error information
                        n = snprintf(greet_buf, sizeof(greet_buf), "%s ERR %s%s", FAIL_CODE, local_hostname, DATA_END);
                        nwrite = write(connfd, greet_buf, n);
                        log_debug("send client fd[%d]:[%d]%s", connfd, nwrite, greet_buf);
                        
                        continue;
                    }
                    log_debug("create pi1[0]:%d pi1[1]:%d", pi1[0], pi1[1]);
                    log_debug("create pi2[0]:%d pi2[1]:%d", pi2[0], pi2[1]);
                    
                    // create unique id
                    n = create_unique_id(childs_st[i].sid, sizeof(childs_st[i].sid));
                    if (n != 16) {
                        log_error("create unique id fail");
                        
                        close(pi1[0]);
                        close(pi1[1]);
                        close(pi2[0]);
                        close(pi2[1]);
                        
                        // send to client error information
                        n = snprintf(greet_buf, sizeof(greet_buf), "%s SYSTEM ERR %s%s", FAIL_CODE, local_hostname, DATA_END);
                        nwrite = write(connfd, greet_buf, n);
                        log_debug("send client fd[%d]:[%d]%s", connfd, nwrite, greet_buf);
                        
                        continue;
                    }
                    log_debug("create mid:%s", childs_st[i].sid);
                    
                    // 当程序执行exec函数时本fd将被系统自动关闭,表示不传递给exec创建的新进程
                    fcntl(pi1[1], F_SETFD, FD_CLOEXEC);
                    fcntl(pi2[0], F_SETFD, FD_CLOEXEC);
                    fcntl(listen_fd, F_SETFD, FD_CLOEXEC);
                    
                    
                    int f = fork();
                    if (f < 0) {
                        log_error("fork fail:[%d]%s", errno, strerror(errno));
                        
                        close(pi1[0]);
                        close(pi1[1]);
                        pi1[0] = -1;
                        pi1[1] = -1;
                        
                        close(pi2[0]);
                        close(pi2[1]);
                        pi2[0] = -1;
                        pi2[1] = -1;
                        
                        // send to client error information
                        n = snprintf(greet_buf, sizeof(greet_buf), "%s SYSTEM ERR %s%s", FAIL_CODE, local_hostname, DATA_END);
                        nwrite = write(connfd, greet_buf, n);
                        log_debug("send client fd[%d]:[%d]%s", connfd, nwrite, greet_buf);
                        
                        continue;
                    
                    } else if (f == 0) {
                        // 子进程
                        close(pi1[1]);
                        close(pi2[0]);
                        pi1[1] = -1;
                        pi2[0] = -1;
                        
                        close(listen_fd);
                        listen_fd = -1;
                        
                        if (fd_move(2, connfd) == -1) {
                            log_error("%s fd_move(2, %d) failed:[%d]%s", childs_st[i].sid, connfd, errno, strerror(errno));
                            _exit(111);
                        }
                        
                        // read from 0
                        if (fd_move(0, pi1[0])) {
                            log_error("%s fd_move(0, %d) failed:[%d]%s", childs_st[i].sid, pi1[0], errno, strerror(errno));
                            _exit(111);
                        }
                        
                        // write to 1
                        if (fd_move(1, pi2[1])) {
                            log_error("%s fd_move(1, %d) failed:[%d]%s", childs_st[i].sid, pi2[1], errno, strerror(errno));
                            _exit(111);
                        }
                        
                        // lunach child program
                        char exe_sid[MAX_LINE] = {0};
                        char exe_cfg[MAX_LINE] = {0};
                        char exe_remote[MAX_LINE] = {0};
                        
                        snprintf(exe_sid, sizeof(exe_sid), "-m%s", childs_st[i].sid);
                        snprintf(exe_cfg, sizeof(exe_cfg), "-c%s", config_st.child_cf);
                        snprintf(exe_remote, sizeof(exe_remote), "-r%s:%s", childs_st[i].client_info.ip, childs_st[i].client_info.port);
                        
                        char *args[5];
                        args[0] = config_st.child_prog;
                        args[1] = exe_sid;
                        args[2] = exe_cfg;
                        args[3] = exe_remote;
                        args[4] = 0;
                        
						char log_exec[MAX_LINE*3] = {0};
						char *plog_exec = log_exec;
						int len = 0;
						int i=0;
						while (args[i] != 0) {
							int n = snprintf(plog_exec + len, sizeof(log_exec) - len, "%s ", args[i]);
							len += n;	
							i++;
						}

                        log_info("Exec:[%s]", log_exec);
                        
                        if (execvp(*args, args) == -1) {
                            log_error("execvp fail:[%d]%s", errno, strerror(errno));
                            _exit(111);
                        }
                        
                        _exit(100);
                        
                    }
                    
                    // 父进程
                    log_debug("add child index:%d pid:%lu", i, f);
                    childs_st[i].pid = f;
                    
                    close(pi1[0]);
                    close(pi2[1]);
                    pi1[0] = -1;
                    pi2[1] = -1;
                    
                    close(connfd);
                    connfd = -1;
                    
                    childs_st[i].pfd_r = pi2[0];
                    childs_st[i].pfd_w = pi1[1];
                    
                    if (set_nonblocking(childs_st[i].pfd_r)) {
                        log_error("set nonblocking fd[%d] fail", childs_st[i].pfd_r);
                    }
                    
                    struct epoll_event pipe_r_ev;
                    pipe_r_ev.events = EPOLLIN | EPOLLET;
                    pipe_r_ev.data.fd = childs_st[i].pfd_r;
                    if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, pipe_r_ev.data.fd, &pipe_r_ev) == -1) {
                        log_error("epoll_ctl client fd[%d] EPOLL_CTL_ADD failed:[%d]%s", pipe_r_ev.data.fd, errno, strerror(errno));
                    }
                    log_debug("epoll_add fd[%d]", pipe_r_ev.data.fd);
                    
                    epoll_num_running++;
                    
                } else if (connfd == -1) {
                    if (errno != EAGAIN && errno != ECONNABORTED && errno != EPROTO && errno != EINTR) {
                        log_error("accept failed:[%d]%s", errno, strerror(errno));
                    }
                    
                    continue;
                }
                
            } else if (epoll_evts[epoll_i].events & EPOLLIN) {
                // 有可读事件从子进程过来
                int idx = get_idx_with_sockfd(evt_fd);
                if (idx < 0) {
                    log_error("get_idx_with_sockfd(%d) fail, so not process", evt_fd);
                    continue;
                }
                log_debug("%s get event EPOLLIN: epoll_i[%d] fd[%d] get fd[%d], used[%d]", childs_st[idx].sid, epoll_i, epoll_evts[epoll_i].data.fd, childs_st[idx].pfd_r, childs_st[idx].used);
                
                // 读取内容
                char cbuf[MAX_LINE] = {0};
                nread = read(childs_st[idx].pfd_r, cbuf, sizeof(cbuf));
                log_debug("read buf:'[%d]%s' from child", n, cbuf);

                
            } else if ((epoll_evts[epoll_i].events & EPOLLHUP)
                       && (epoll_evts[epoll_i].data.fd != listen_fd)) {
                // 有子进程退出
                int idx = get_idx_with_sockfd(evt_fd);
                if (idx < 0) {
                    log_error("get_idx_with_sockfd(%d) fail, so not process", evt_fd);
                    
                    continue;
                }
                log_debug("%s get event EPOLLHUP: epoll_i[%d] fd[%d] get fd[%d], used[%d]", childs_st[idx].sid, epoll_i, epoll_evts[epoll_i].data.fd, childs_st[idx].pfd_r, childs_st[idx].used);
                
                epoll_delete_evt(epoll_fd, childs_st[idx].pfd_r);
                
                // 子进程清理
                clean_child_with_idx(idx);
                
                continue;
                
            }
            
        }
        
        sig_childunblock();
    }
    
    close(epoll_fd);
    close(listen_fd);
    
    epoll_fd = -1;
    listen_fd = -1;

	if (childs_st != NULL) {
		free(childs_st);
		childs_st = NULL;
	}

	if (epoll_evts != NULL) {
		free(epoll_evts);
		epoll_evts = NULL;
	}
    
    log_info("I'm finish");
    
    return 0;
    
}
Exemple #9
0
int main(int argc, char **argv)
{
    if (argc != 3 && argc != 4) {
        usage(argv[0]);
        exit(0);
    }
    
    char cfg_file[MAX_LINE] = {0};
    int make_deamon = 0;
	unsigned int exit_time = 0;
    
    int ch;
    const char *args = "c:dh";
    while ((ch = getopt(argc, argv, args)) != -1) {
        switch (ch) {
            case 'c':
                snprintf(cfg_file, sizeof(cfg_file), "%s", optarg);
                break;
            case 'd':
                make_deamon = 1;
                break;
                
            case 'h':
            default:
                usage(argv[0]);
                exit(0);
                break;
        }
    }
    
    if (make_deamon == 1) {
        // create deamon
        create_daemon(config_t.chdir_path);
    }
    
    // init log
    ctlog(argv[0], LOG_PID|LOG_NDELAY, LOG_MAIL);
    
    // read config
    dict_conf = open_config(cfg_file);
    if (dict_conf == NULL) {
        printf("parse config fail");
        return 1;
    }
    if (read_config(dict_conf) != 0) {
        return 1;
    }
    log_level = atoi(config_t.log_level);
    
    if (chdir(config_t.chdir_path) == -1) {
        log_error("can not start: unable to change directory:%s", config_t.chdir_path);
        return 1;
    }
    log_debug("log_level:%s", config_t.log_level);
    log_debug("chdir_path:%s", config_t.chdir_path);
    log_debug("offset_path:%s", config_t.offset_path);
    log_debug("max_childs:%s", config_t.max_childs);
    
    // ---------- ----------
    
    childs_t = (struct childs_st *)malloc((atoi(config_t.max_childs) + 1) * sizeof(struct childs_st));
    if (childs_t == NULL) {
        log_error("malloc childs [%d] faild:[%d]:%s", (atoi(config_t.max_childs) + 1), errno, strerror(errno));
        exit(1);
    }
    
    int i = 0;
    for (i=0; i<(atoi(config_t.max_childs) +1); i++) {
        init_child_with_idx(i);
    }
    
    // 捕抓子进程退出信号
    sig_catch(SIGCHLD, sigchld_exit);
    
    
    // ------ 开始 ------
    // 初始化,读取文件索引内容
    struct tm *tmp;
    struct stat st;
    
    char now_str[1024] = {0};
    time_t cur = time(NULL);
    
    tmp = localtime(&cur);
    strftime(now_str, sizeof(now_str) - 1, "%Y%m%d", tmp);
    
    if (*(config_t.offset_path) == '\0') {
        config_t.offset_path[0] = '.';
        config_t.offset_path[1] = '\0';
    } else {
        if ( is_dir_exits(config_t.offset_path) != 0 ) {
            log_error("is_dir_exit fail");
            return 1;
        }
    }
    
    char offset_file[MAX_LINE] = {0};
    snprintf(offset_file, sizeof(offset_file), "%s/%s.%s", config_t.offset_path, OFFSET_FILENAME, now_str);
    
    struct file_info_t file_info_st;
    if (init_for_rindex(&file_info_st, offset_file) != 0) {
        printf("init_for_rindex fail\n");
        log_error("init_for_rindex fail");
        return 1;
    }
    
    
    // 打开被分析的文件
    char buf[BUF_SIZE] = {0};
    FILE *fp = fopen(config_t.process_file, "r");
    if (!fp) {
        printf("open file:%s fail:%m\n", config_t.process_file);
        log_error("open file:%s fail:%m", config_t.process_file);
        if (file_info_st.file_rindex_fd)
            close(file_info_st.file_rindex_fd);
        return 1;
    }
    
    // 如果偏移量大于0,则偏移文件到上次读取的地方
    if (file_info_st.rindex_offset > 0) {
        if (lseek(fileno(fp), file_info_st.rindex_offset, SEEK_SET) == -1) {
            printf("lseek fail:%m\n");
            log_error("lseek fail:%m");
            fclose(fp);
            if (file_info_st.file_rindex_fd)
                close(file_info_st.file_rindex_fd);
            return 1;
        }
    }
    
    // 循环读取文件,读一行分析,如果是逻辑开始行, 创建一个子进程去执行
    while (1) {
        if (!fgets(buf, sizeof(buf)-1, fp)) {
            // 读取失败
            if (is_need_master_exit(fileno(fp), config_t.process_file, atoi(config_t.exit_time)) == 1) {
                log_info("file:%s was expire, bye!", config_t.process_file);
                goto MASTER_BYE;
            }
            
            log_debug("fgets is null, sleep 5 second");
            sleep(atoi(config_t.wait_sleep));
            
            continue;
        }
        
        if (*buf == '\0') {
            continue;
        }
        
        
        if ( strstr(buf, " qmail-smtpd[")
            && strstr(buf, "]: [INFO] mail_process ICID:")
            && strstr(buf, " LOGExe:[-M") ) {
        
            // 保存当前读取的偏移量
            file_info_st.rindex_offset = ftell(fp);
            if (file_info_st.rindex_offset > 0) {
                snprintf(file_info_st.file_rindex_offset_ptr, 1023, "%ld", file_info_st.rindex_offset);
            }
            
            
            // 处理
            process_via_child(buf, fp, file_info_st.rindex_offset);
        }
    }
    
MASTER_BYE:
    fclose(fp);
    
    if (file_info_st.file_rindex_fd)
        close(file_info_st.file_rindex_fd);
    
    if (childs_t != NULL) {
        free(childs_t);
        childs_t = NULL;
    }
    
    return 0;
    
}
Exemple #10
0
int start_server(int port_number, const char* dir_name, int period)
{
	pthread_t tid;                                  /* Passed to pthread_create */
	struct thread_arg* targ;                /* Used to pass arguments to threads */
	pthread_attr_t tattr;                   /* Specifies that thread should be detached */
	fd_set master;                                  /* Keep track of all connections / pipes to multiplex */
	fd_set read_fds;                        /* Copy of master for select to populate */
	int fdmax;                                              /* Highest numbered file descriptor */
	int i;                                                  /* Used to index the master fd list */
	int listener;                                   /* Listening socket of the server */
	int newfd;                                      /* New connection socket fd */
	struct sockaddr_in local_addr;  /* Local connection info */
	struct sockaddr_in remote_addr; /* Remote connection info */
	socklen_t addr_len;                     /* Address length */
	int pipe_buff[1];                               /* Get sockets into here */
	pipe_buff[0] = 0;

	// Init signal mask
	struct sigaction sa;
	sigemptyset(&sa.sa_mask);
	sa.sa_flags = 0;
	sa.sa_handler = SIG_IGN;

	// Start each thread in detached mode, since we don't care about
	// their return values
	pthread_attr_init(&tattr);
	pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED);

	// Initialize the memory pool to store the direntries
	direntry_pool = init_mempool(sizeof(struct direntry), 512);

	// Set done to 0
	done = 0;

	// Initialize the clients linked list
	clients = (struct clientlist*)malloc(sizeof(struct clientlist));
	clients->head = NULL;
	clients->tail = NULL;
	clients->count = 0;

	// Copy into global init_dir
	strcpy(init_dir, dir_name);
	gperiod = period;

	// Initialize pipe
	if (pipe(remove_client_pipes) < 0) {
		syslog(LOG_ERR, "Cannot create IPC in server.");
		exit(1);
	}

	// Get full path of the directory
	if (realpath(dir_name, full_path) == NULL) {
		syslog(LOG_ERR, "Cannot resolve full path.");
		exit(1);
	}

#ifdef DAEMONIZE
	create_daemon("dirapp");
#endif
#ifndef DAEMONIZE
	openlog("dirapp", LOG_CONS, LOG_DAEMON);
#endif

	// Make sure SIGPIPE is blocked
	if (sigaction(SIGPIPE, &sa, NULL) < 0) {
		syslog(LOG_WARNING, "SIGPIPE error");
	}

	// Signals for the signal thread to handle
	sigemptyset(&mask);
	sigaddset(&mask, SIGHUP);
	sigaddset(&mask, SIGTERM);
	sigaddset(&mask, SIGINT);
	sigaddset(&mask, SIGALRM);

	// Set the mask
	if (pthread_sigmask(SIG_BLOCK, &mask, NULL) != 0)
		syslog(LOG_WARNING, "pthread_sigmask failed");

	// Initialize file descriptor lists
	FD_ZERO(&master);
	FD_ZERO(&read_fds);

	// Setup local connection info
	memset(&local_addr, 0, sizeof(local_addr));
	local_addr.sin_family = AF_INET;
	local_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
	local_addr.sin_port = htons(port_number);

	// Create listener socket
	listener = socket(AF_INET, SOCK_STREAM, 0);

	// Try to bind
	if (bind(listener, (struct sockaddr*)&local_addr, sizeof(local_addr))) {
		syslog(LOG_ERR, "Cannot bind socket to address");
		exit(1);
	}

	// Now listen!
	if (listen(listener, MAX_CLIENTS) < 0) {
		syslog(LOG_ERR, "Cannot listen on socket");
		exit(1);
	}

	syslog(LOG_INFO, "Starting server!");

	// Have select check for incoming data
	FD_SET(remove_client_pipes[0], &master);
	FD_SET(listener, &master);
	fdmax = listener;

	// Initialize the direntry lists
	prevdir = init_direntrylist();
	curdir = init_direntrylist();

	// Initially populate list of file entries in monitored directory
	exploredir(prevdir, (const char*)full_path);

	// Start signal thread
	pthread_create(&tid, NULL, signal_thread, NULL);

	int errno = 0;

	// Main server loop
	while (1) {
		read_fds = master;

		if (select(fdmax + 1, &read_fds, NULL, NULL, NULL) == -1) {
			syslog(LOG_ERR, "select: %s", strerror(errno));
			exit(1);
		}

		for (i = 0; i <= fdmax; i++) {
			if (FD_ISSET(i, &read_fds)) {
				if (i == listener) {
					addr_len = sizeof(remote_addr);
					newfd = accept(listener, (struct sockaddr*)&remote_addr, &addr_len);

					if (newfd == -1) {
						syslog(LOG_WARNING, "Cannot new client.");
					} else {
						FD_SET(newfd, &master);
						if (newfd > fdmax) {
							fdmax = newfd;
						}

						syslog(LOG_INFO, "New connection from: %s:%d",
						       inet_ntoa(remote_addr.sin_addr),
						       ntohs(remote_addr.sin_port));
						// Add client to clients list in order to receive
						// updates
						pthread_create(&tid, &tattr, init_client, (void*)newfd);
					}
				} else if (i == remove_client_pipes[0]) {
					// Get the file descriptor of the socket that is to
					// be removed and store into the first position of
					// tmp_buff
					if (read(remove_client_pipes[0], pipe_buff, 1) <= 0) {
						syslog(LOG_ERR, "Cannot read in socket to close.");
					} else {
						// Remove socket from master list
						pthread_mutex_lock(&slock);
						FD_CLR(pipe_buff[0], &master);
						done = 1;
						pthread_mutex_unlock(&slock);

						// Tell kill_clients or whoever they
						// can procede
						pthread_cond_signal(&sready);
					}
				} else {
					// Handle disconnect
					targ = (struct thread_arg*)malloc(sizeof(struct thread_arg));
					targ->socket = i;
					targ->pipe = remove_client_pipes[1];

					pthread_create(&tid, &tattr, remove_client, (void*)targ);
					FD_CLR(i, &master);
				}
			}
		}
	}

	return 0;
}