void do_pred_testing(void) { int sts; config_vars vars; FILE *conf = NULL; conf = open_config(); read_config(conf); (void)fclose(conf); dump_tree(stdout); for (;;) { sts = read_test_values(stdin, &vars); if (sts == EOF) break; if (sts == 0) { (void)fprintf(stderr, "Bad input line\n"); continue; } if (eval_tree(&vars)) { (void)fprintf(stdout, "true\n"); } else { (void)fprintf(stdout, "false\n"); } } }
void config_save(char *filename) { FILE *output = open_config(filename, "w"); ConfigEntry *e = configdefs; if(!output) return; do switch(e->type) { case CFGT_INT: fprintf(output, "%s = %i\n", e->name, config_intval_p(e)); break; case CFGT_KEYBINDING: fprintf(output, "%s = K%i\n", e->name, config_intval_p(e)); break; case CFGT_STRING: fprintf(output, "%s = %s\n", e->name, config_strval_p(e)); break; } while((++e)->name); fclose(out); printf("config_save(): Saved config '%s'\n", filename); }
int main(int argc, char *argv[]) { int i; init(); /* Init some variables (like malloc timestamp string, encrypt text string, etc.) */ check_par(argc, argv); /* Check command arguments number */ open_config(argv); /* Open config file and check if it failed */ open_log(argv); /* Open log file and check if it failed */ get_ipaddr(); /* Get server IP address */ create_socket(); /* Create a socket */ bind_socket(); /* Bind the socket */ listen_socket(); /* Listen at the socket */ print_server_info(); /* Print server information */ while (TRUE) { /* Read until the end of file */ if (read_flag) { if (fscanf(fcfg, "%s", enc_txt) == EOF) { finish_flag = 1; break; } else { fscanf(fcfg, "%s", dec_txt); } } read_flag = 0; init_select(); /* Select function */ if (select_func() == -1) break; for (i = 0; i < max_fds + 1; i++) { if (FD_ISSET(i, &rfds)) { if (i == sockfd) { /* If have a new client connect */ if (accept_new_cli() == -1) break; /* Try to accept new client */ if (check_connect() == -1) break; /* Check connect message from client */ if (print_client_info() == -1) break; /* Print the information of client side */ store_client_ip(); /* Store the client ip address */ break; } else { /* If have new message from client side */ client_ip = get_host_by_sockfd(i); /* Get the client ip address by socket */ recv_socket_msg(i, recv_mark); /* Get the message from socket */ handle_client_msg(i); /* Handle client message (SUCCESS_MSG, FAILURE_MSG, DISPATCH_MSG, etc.) */ break; } } if (main_flag == EXIT_FAILURE) break; } if (main_flag == EXIT_FAILURE) break; } remained_cli = ask_clients_quit(); /* Ask clients quit and count the remain clients number */ wait_clients_quit(); /* Wait for all clients quit */ quit_server(); /* Clean up and quit server, also print the message to log */ return main_flag; }
/* * Returns the session name from the config file. * The caller is responsible for freeing the returned string. * On error, NULL is returned. */ char *config_read_session_name(char *path) { int ret; FILE *fp; char var[NAME_MAX], *session_name; #if (NAME_MAX == 255) #define NAME_MAX_SCANF_IS_A_BROKEN_API "254" #endif session_name = zmalloc(NAME_MAX); if (session_name == NULL) { ERR("Out of memory"); goto error; } fp = open_config(path, "r"); if (fp == NULL) { ERR("Can't find valid lttng config %s/.lttngrc", path); MSG("Did you create a session? (lttng create <my_session>)"); free(session_name); goto error; } while (!feof(fp)) { if ((ret = fscanf(fp, "%" NAME_MAX_SCANF_IS_A_BROKEN_API "[^'=']=%" NAME_MAX_SCANF_IS_A_BROKEN_API "s\n", var, session_name)) != 2) { if (ret == -1) { ERR("Missing session=NAME in config file."); goto error_close; } continue; } if (strcmp(var, "session") == 0) { goto found; } } error_close: free(session_name); ret = fclose(fp); if (ret < 0) { PERROR("close config read session name"); } error: return NULL; found: ret = fclose(fp); if (ret < 0) { PERROR("close config read session name found"); } return session_name; }
void init_with_conf(CONFDATA *data) { FILE *fp; /*打开并初始化配置数据*/ if((fp=open_config(data))==NULL) return; fclose(fp); }
void load_config(char *filename) { FILE *input = open_config(filename, "r"); int c, i = 0, found, line = 0; char buffer[CONFIG_LOAD_BUFFERSIZE]; char key[CONFIG_LOAD_BUFFERSIZE]; char val[CONFIG_LOAD_BUFFERSIZE]; config_preset(); if(!input) { printf("Configfile either not readable or existing."); return; } while((c = fgetc(input)) != EOF) { if(c == '#' && !i) { i = 0; while(fgetc(input) != '\n'); } else if(c == ' ') { if(!i) SYNTAXERROR buffer[i] = 0; i = 0; strcpy(key, buffer); found = 0; while((c = fgetc(input)) != EOF) { if(c == '=') { if(++found > 1) SYNTAXERROR } else if(c != ' ') { if(!found || c == '\n') SYNTAXERROR do { if(c == '\n') { if(!i) SYNTAXERROR buffer[i] = 0; i = 0; strcpy(val, buffer); found = 0; ++line; config_set(key, val); break; } else { buffer[i++] = c; if(i == CONFIG_LOAD_BUFFERSIZE) BUFFERERROR } } while((c = fgetc(input)) != EOF); break; } } if(found) SYNTAXERROR } else {
keylist * parse_config_file ( const char * config ){ char * buf; keylist * param; buf = open_config ( config ); if ( ! buf ) return NULL; param = parse_config ( buf ); free ( buf ); return param; }
Errcode rewrite_config(void) /* Copy ram image of configuration file header to config file in startup * directory only rewrites header */ { Errcode err; XFILE *xf; err = open_config(&xf, FALSE); if (err >= Success) { err = xffwrite(xf, &vconfg, sizeof(vconfg)); xffclose(&xf); } return err; }
/* * Creates the empty config file at the path. * On success, returns 0; * on error, returns -1. */ static int create_config_file(char *path) { int ret; FILE *fp; fp = open_config(path, "w+"); if (fp == NULL) { ERR("Unable to create config file"); ret = -1; goto error; } ret = fclose(fp); error: return ret; }
void ndisapi NdisOpenConfiguration(ndis_status *status, ndis_handle_t *configuration_handle, ndis_handle_t wrapper_configuration_context) { struct ndis_adapter *adapter = (struct ndis_adapter *) wrapper_configuration_context; struct section *sect; struct ndis_config *cfg; NDISTRACE("NdisOpenConfiguration"); sect = get_config_section(adapter); cfg = open_config(sect); if (!cfg) { *status = NDIS_STATUS_FAILURE; return; } *configuration_handle = cfg; *status = 0; }
void hotproc_init(void) { char h_configfile[MAXPATHLEN]; FILE *conf; int sep = __pmPathSeparator(); snprintf(h_configfile, sizeof(h_configfile), "%s%c" "proc" "%c" "hotproc.conf", pmGetConfig("PCP_PMDAS_DIR"), sep, sep); conf = open_config(h_configfile); /* Hotproc configured */ if (conf != NULL) { if (read_config(conf)) { conf_gen = 1; } fclose(conf); } }
/* * Append data to the config file in file_path * On success, returns 0; * on error, returns -1. */ static int write_config(char *file_path, size_t size, char *data) { FILE *fp; size_t len; int ret = 0; fp = open_config(file_path, "a"); if (fp == NULL) { ret = -1; goto end; } /* Write session name into config file */ len = fwrite(data, size, 1, fp); if (len != 1) { ret = -1; } if (fclose(fp)) { PERROR("close write_config"); } end: return ret; }
Errcode init_config(Boolean force_create) /* Attempt to read v.cfg file and check file data. If can't find file or bad data and force_create is true then assume default values and create a new file. If can't create a new file or find it, it is a fatal error. Returns Success if a new config was created, 1 if it was read in < Success if a fatal error occurred and a config file could not be read or created. This reports the fatal error via softerr(). */ { Errcode goodret; Errcode err; XFILE *xf; AA_config incfg; goodret = 1; /* optimism */ err = open_config(&xf, FALSE); if (err < Success) goto bad_open; if (xffread(xf, &incfg, sizeof(incfg)) < Success) goto bad_config; /* check magic and size fields */ if( incfg.id.type != VCFG_MAGIC || incfg.id.size != sizeof(AA_config) || incfg.id.version != VCFG_VERSION) { goto bad_config; } vconfg = incfg; goto done; bad_open: if (!force_create) { if(!soft_yes_no_box("!%s","noconfig",vb.config_name)) goto reported; } else goodret = 0; goto create_it; bad_config: /* we do not have a valid file. Create a new one? */ xffclose(&xf); if (!force_create) { if(!soft_yes_no_box("!%s","badconfig",vb.config_name)) goto reported; } create_it: err = open_config(&xf, TRUE); if (err < Success) goto fatal_error; /* prepare default initial record to write */ err = default_temp_path(vconfg.temp_path); if (err < Success) goto fatal_error; incfg = vconfg; /* defaults or good one read in (won't hurt) */ /* create and fill paths list with zeros */ err = xffwrite(xf, &incfg, sizeof(incfg)); if (err < Success) goto fatal_error; done: xffclose(&xf); err = set_temp_path(vconfg.temp_path); if (err < Success) { err = default_temp_path(vconfg.temp_path); if (err < Success) goto fatal_error; err = set_temp_path(vconfg.temp_path); if (err < Success) goto fatal_error; } return goodret; reported: err = Err_reported; fatal_error: xffclose(&xf); vb.config_name = NULL; /* disable write/open ability */ return(softerr(err,"!%s", "fatal_create",vb.config_name)); }
int main(int argc, char *argv[]) { /* int argi; for (argi=1; argi < argc; argi++) {printf("parameter: %s\n", argv[argi]);} */ gst_init(&argc, &argv); gtk_init(&argc, &argv); start_GUI(); g_signal_connect(G_OBJECT(drawing_area), "draw", G_CALLBACK(on_draw_event), NULL); g_signal_connect(main_window, "destroy", G_CALLBACK(gtk_main_quit), NULL); g_signal_connect(main_window, "key_press_event", G_CALLBACK(klawisz), 1); g_signal_connect(main_window, "key_release_event", G_CALLBACK(klawisz), 0); g_signal_connect(servocontroller_enable_button, "clicked", G_CALLBACK(toggle_servocontroller), TRUE); g_signal_connect(servocontroller_disable_button, "clicked", G_CALLBACK(toggle_servocontroller), FALSE); g_signal_connect(check_button_regulator, "clicked", G_CALLBACK(toggle_ESC_callback), NULL); g_signal_connect(record_start_button, "clicked", G_CALLBACK(switch_Recording), NULL); g_signal_connect(record_stop_button, "clicked", G_CALLBACK(switch_Recording), NULL); g_signal_connect(check_button_video, "clicked", G_CALLBACK(toggle_video_button_callback), NULL); g_signal_connect_swapped(G_OBJECT(main_window), "destroy", G_CALLBACK(zamknij), NULL); switch (tryb_wysylania) { case 1: g_signal_connect(reconnect_button, "clicked", G_CALLBACK(open_TCP_socket), NULL); break; default: //TODO: close socket, reopen socket break; } /* wczytuje wartości zmiennych z pliku config.cfg */ open_config(argv[1]); /* distinguishes between USB and Bluetooth connection */ //TODO: https://linux.die.net/man/8/udevadm if (0 == access("/dev/input/by-id/usb-Sony_Computer_Entertainment_Wireless_Controller-joystick", 0)) { g_print("Joystick file exists - USB mapping\n"); gtk_progress_bar_set_text(progress3, "touchpad X:"); gtk_progress_bar_set_text(progress4, "touchpad Y:"); gtk_progress_bar_set_text(progress5, "axis 8:"); } else if (access("/dev/input/by-id/usb-Microsoft_Controller_0000000000000000000000000000-joystick", 0) == 0) { g_print("Xbox One controller - USB mapping\n"); button[2] = 3; // "triangle" - "Y" button[3] = 2; // "square" - "X" button[8] = 6; // share - view button[9] = 7; // options - menu button[10] = 8; // PlayStation - Xbox button[11] = 9; // left stick press button[12] = 10; // right stick press } else { g_print("Joystick file doesn't exist - Bluetooth mapping\n"); axis[6] = 6; axis[7] = 7; axis[9] = 9; axis[10] = 10; axis[11] = 11; gtk_progress_bar_set_text(progress3, "gyro X?"); gtk_progress_bar_set_text(progress4, "gyro Y?"); gtk_progress_bar_set_text(progress5, "gyro Z?"); } /* wyświetla wszystkie elementy okna */ gtk_widget_show_all(main_window); // UDP if (tryb_wysylania == 0) { open_UDP_socket(); video_start(); video_receive(); } // TCP if (tryb_wysylania == 1) { // connect on startup open_TCP_socket(); /* wysyła pakiet z numerem kamery i adresem IP na jaki ma być streamingowany obraz z kamery */ introduce_yourself_TCP(); } // UDP, old if (tryb_wysylania == 2) { open_UDP_socket(); /* wysyła pakiet z numerem kamery i adresem IP na jaki ma być streamowany obraz z kamery */ video_start(); /* rozpoczyna wyświetlanie obrazu */ video_receive(); } /* uruchamia "audio_receive" z opóźnieniem 100 milisekund (właściwie co 100 milisekund) wymaga tego specyfika protokołu TCP */ g_timeout_add(100, audio_receive, NULL); /* FIXME: są problemy z dźwiękiem, chyba chodzi o synchronizację dźwięku z obrazem */ /* wykrywanie joysticka przy starcie programu */ wykryj_joystick(); /* hides one of fullscreen buttons and recording stop button */ if (isFullscreen) { gtk_widget_hide(fullscreen_enable_button); gtk_window_fullscreen(GTK_WINDOW(main_window)); } else { gtk_widget_hide(fullscreen_disable_button); /* gtk_window_unfullscreen(GTK_WINDOW(main_window)); */ } gtk_widget_hide(servocontroller_enable_button); gtk_widget_hide(record_stop_button); gtk_main(); /* Out of the main loop, clean up nicely */ g_print("Stopping playback\n"); gst_element_set_state(pipeline, GST_STATE_NULL); g_print("Deleting pipeline\n"); gst_object_unref(GST_OBJECT(pipeline)); return 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; }
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; }