int main(int argc, char **argv) { int c, r; char *hostname, *service; struct tunsess *tun; struct sigaction sigact; int local_tunid; openlog("tunneldigger-client", 0, 0); while ((c = getopt(argc, argv, "dhfu:l:b:p:i:s:t:L:")) != EOF) { switch (c) { case 'h': /* show help */ print_help(); exit(EXIT_SUCCESS); break; case 'f': /* don't daemonize */ dont_daemonize = 1; break; case 'd': debug_flag = 1; break; case 'u': /* connection UUID */ uuid = strdup(optarg); break; case 'l': /* local IP address */ local_ip = strdup(optarg); break; case 'b': /* broker in <host>:<port> form */ if (parse_broker(optarg, &hostname, &service) != 0) { fprintf(stderr, "invalid broker specification\n"); exit(EXIT_FAILURE); } break; case 'i': /* tunnel interface name */ ifname = strdup(optarg); break; case 's': /* hook script */ script = strdup(optarg); break; case 't': /* tunnel id */ local_tunid = atoi(optarg); break; case 'L': /* limit bandwidth down */ limit_down = atoi(optarg); break; default: fprintf(stderr, "use '-h' for help\n", c); break; } } l2tp_init(); if (!uuid) { printf ("the uuid is required\n"); exit(EXIT_FAILURE); } tun = ts_new(hostname, service); tun->local_tunid = local_tunid; tun->ifname = strdup(ifname); /* create and bind a socket, and connect it */ if ((r=ts_socket_bind_connect(tun)) != 0) { error("unable to obtain bound socket\n"); exit(EXIT_FAILURE); } /* request a cookie */ if ((r=ts_get_cookie(tun)) != 0) { error("unable to get cookie\n"); exit(EXIT_FAILURE); } /* request a tunnel */ if ((r=ts_get_tunnel(tun)) != 0) { error("unable to get tunnel\n"); exit(EXIT_FAILURE); } /* create the tunnel */ if (ts_create_tunnel(tun) != 0) { error("unable to create tunnel (is l2tp_eth loaded?)!\n"); exit(EXIT_FAILURE); } /* handle SIGINT */ sigact.sa_handler = signal_handler; sigemptyset(&sigact.sa_mask); if (sigaction(SIGINT, &sigact, NULL) < 0) { error("couldn't set signal handler\n"); } /* keep the tunnel alive, and respond to PMTU discovery requests */ ts_keepalive(tun); error("closing tunnel\n"); if (ts_delete_tunnel(tun) != 0) { error("unable to delete tunnel!\n"); exit(EXIT_FAILURE); } ts_close(tun); }
static int wlog_get_fmsaccesslog_lines(Tcl_Interp *interpreter, int fd, uint32 start, uint32 end, Tcl_Obj **ret_list) { Tcl_Obj *list = NULL; Tcl_Obj *line_obj = NULL; tstring *line_buf = NULL; char buf[wlog_log_buf_size]; uint32 cur_line = 0; uint32 seg_start = 0; uint32 i = 0; int count = 0; int err = 0; char *cp; bail_null(ret_list); list = Tcl_NewListObj(0, NULL); bail_null(list); do { if (cur_line + 1 >= end) { break; } errno = 0; count = read(fd, buf, wlog_log_buf_size); if (count == -1 && errno == EINTR) { continue; } bail_require_errno(count >= 0, I_("Reading log file '%s'"), file_fmsaccesslog_path); while (( cp = memchr(buf, '\0' , count )) != NULL ) *cp = ' '; while (( cp = memchr(buf, '<' , count )) != NULL ) *cp = '['; while (( cp = memchr(buf, '>' , count )) != NULL ) *cp = ']'; /* look for a newline inside the buffer */ seg_start = 0; for (i = 0; i < (uint32)count; ++i) { if (buf[i] == '\n') { if (cur_line + 1 >= start && cur_line + 1 < end) { if (!line_buf) { err = ts_new(&line_buf); bail_error(err); } err = ts_append_str_frag(line_buf, buf, seg_start, i - seg_start); bail_error(err); line_obj = Tcl_NewStringObj(ts_str(line_buf), ts_length(line_buf)); bail_null(line_obj); err = Tcl_ListObjAppendElement(interpreter, list, line_obj); bail_require(err == TCL_OK); err = 0; ts_free(&line_buf); } seg_start = i + 1; ++cur_line; } } if (seg_start < (uint32)count) { if (cur_line + 1 >= start && cur_line + 1 < end) { if (!line_buf) { err = ts_new(&line_buf); bail_error(err); } err = ts_append_str_frag(line_buf, buf, seg_start, (uint32)count - seg_start); bail_error(err); } } } while (count > 0); *ret_list = list; list = NULL; bail: if (list) { Tcl_DecrRefCount(list); } ts_free(&line_buf); return(err); }
int main(int argc, char *argv[]) { int opt, i, n, rc=-1; struct epoll_event ev; CF.prog = argv[0]; CF.now = time(NULL); utarray_new(CF.rdkafka_options,&ut_str_icd); utarray_new(CF.rdkafka_topic_options,&ut_str_icd); void *res; while ( (opt = getopt(argc, argv, "hv+N:n:d:b:t:c:C:")) != -1) { switch(opt) { case 'v': CF.verbose++; break; case 'n': CF.nthread=atoi(optarg); break; case 'd': CF.dir=strdup(optarg); break; case 't': CF.topic=strdup(optarg); break; case 'b': CF.broker=strdup(optarg); break; case 'c': utarray_push_back(CF.rdkafka_options,&optarg); break; case 'C': utarray_push_back(CF.rdkafka_topic_options,&optarg); break; case 'h': default: usage(); } } if (CF.dir == NULL) usage(); if (CF.broker == NULL) usage(); if (CF.topic == NULL) CF.topic = CF.dir; /* stats (time series) for input/output tracking */ CF.spr_msgs_ts = ts_new(6, STATS_INTERVAL ,&ts_int_mm); CF.kaf_msgs_ts = ts_new(6, STATS_INTERVAL, &ts_int_mm); CF.kaf_bytes_ts = ts_new(6, STATS_INTERVAL, &ts_int_mm); /* block all signals. we take signals synchronously via signalfd */ sigset_t all; sigfillset(&all); sigprocmask(SIG_SETMASK,&all,NULL); /* a few signals we'll accept via our signalfd */ sigset_t sw; sigemptyset(&sw); for(n=0; n < sizeof(sigs)/sizeof(*sigs); n++) sigaddset(&sw, sigs[n]); /* create the signalfd for receiving signals */ CF.signal_fd = signalfd(-1, &sw, 0); if (CF.signal_fd == -1) { fprintf(stderr,"signalfd: %s\n", strerror(errno)); goto done; } /* set up the epoll instance */ CF.epoll_fd = epoll_create(1); if (CF.epoll_fd == -1) { fprintf(stderr,"epoll: %s\n", strerror(errno)); goto done; } if (setup_nano() < 0) goto done; /* add descriptors of interest */ if (new_epoll(EPOLLIN, CF.signal_fd)) goto done; // signal socket /* fire up threads */ rc = pthread_create(&CF.spr_thread, NULL, spr_worker, NULL); if (rc) goto done; CF.enc_thread = malloc(sizeof(pthread_t)*CF.nthread); if (CF.enc_thread == NULL) goto done; long id; for(i=0; i < CF.nthread; i++) { id = i; rc = pthread_create(&CF.enc_thread[i],NULL,enc_worker,(void*)id); if (rc) goto done; } CF.kaf_thread = malloc(sizeof(pthread_t)*CF.nthread); if (CF.kaf_thread == NULL) goto done; for(i=0; i < CF.nthread; i++) { id = i; rc = pthread_create(&CF.kaf_thread[i],NULL,kaf_worker,(void*)id); if (rc) goto done; } alarm(1); while (epoll_wait(CF.epoll_fd, &ev, 1, -1) > 0) { if (ev.data.fd == CF.signal_fd) { if (handle_signal() < 0) goto done; } } rc = 0; done: CF.shutdown=1; nn_term(); fprintf(stderr,"shutting down threads:\n"); fprintf(stderr,"spoolreader...\n"); if (CF.spr_thread) { pthread_cancel(CF.spr_thread); pthread_join(CF.spr_thread,NULL); } fprintf(stderr,"encoders...\n"); if (CF.enc_thread) { for(i=0; i < CF.nthread; i++) { pthread_cancel(CF.enc_thread[i]); pthread_join(CF.enc_thread[i],NULL); } } fprintf(stderr,"transmitters...\n"); if (CF.kaf_thread) { for(i=0; i < CF.nthread; i++) { pthread_cancel(CF.kaf_thread[i]); pthread_join(CF.kaf_thread[i],NULL); } } fprintf(stderr,"terminating...\n"); if (CF.ingress_socket_push >= 0) nn_close(CF.ingress_socket_push); if (CF.ingress_socket_pull >= 0) nn_close(CF.ingress_socket_pull); if (CF.egress_socket_push >= 0) nn_close(CF.egress_socket_push); if (CF.egress_socket_pull >= 0) nn_close(CF.egress_socket_pull); if (CF.egress_socket_filepath) unlink(CF.egress_socket_filepath); if (CF.ingress_socket_filepath) unlink(CF.ingress_socket_filepath); if (CF.epoll_fd != -1) close(CF.epoll_fd); if (CF.signal_fd != -1) close(CF.signal_fd); ts_free(CF.spr_msgs_ts); ts_free(CF.kaf_msgs_ts); ts_free(CF.kaf_bytes_ts); if (CF.enc_thread) free(CF.enc_thread); if (CF.kaf_thread) free(CF.kaf_thread); utarray_free(CF.rdkafka_options); utarray_free(CF.rdkafka_topic_options); return rc; }