int main(int argc, char **argv) { //static const char OPTIONS[] = "hvlpsjPr:g:f::A:Ww:m:d:e:b:T:t:o:a:c:O:i:"; static const char OPTIONS[] = "A:a:b:c:D:d:E:e:F:f:g:hi:jlm:no:O:Ppr:sT:t:vWw:x:y:"; __sighandler_t sigint_original; char * const *file_names = NULL; size_t n_files = 0; int dither_mode = 0; int keep_power_on = 0; const char *waveform_id_str = "2"; int waveform_id = 2; int do_enumerate_waveforms = 0; int do_log_info = 0; int do_wait_power_off = 0; int do_synchro = 0; int do_infinite_loop = 0; int cfa = -1; int display_enable = 0; int do_fill = 0; int fill_color = 0xFF; int do_auto_rotate = 0; int rotation_angle = -1; int do_partial_update = 0; int use_manual_temperature = 0; int manual_temperature = 25; unsigned long pause_ms = 2000; const char *mode = NULL; const char *fbdev = NULL; const char *epdev = NULL; const char *background = NULL; struct plep_point offset = { 0, 0 }; enum epdoc_align_h align_h = EPDOC_ALIGN_H_NONE; enum epdoc_align_v align_v = EPDOC_ALIGN_V_NONE; struct plep_rect crop = { { 0, 0 }, { INT_MAX, INT_MAX } }; const char *doc_type = NULL; const char *conf_file = NULL; struct plep *plep; struct pldraw *pldraw; int onoff = -1; int c; int ret; int use_alternative_vsource = 0; while ((c = getopt(argc, argv, OPTIONS)) != -1) { switch (c) { case 'A': if (!strcmp(optarg, "l")) { use_alternative_vsource = 1; }else if (!strcmp(optarg, "h")) { use_alternative_vsource = 2; }else if (!strcmp(optarg, "lh")) { use_alternative_vsource = 3; }else if (!strcmp(optarg, "hl")) { use_alternative_vsource = 3; }else{ LOG("invalid alternative VSOURCE selection"); print_usage(); exit(EXIT_FAILURE); } break; case 'h': print_usage(); exit(EXIT_SUCCESS); break; case 'v': printf("%s v%s - %s\n%s\n%s\n", APP_NAME, VERSION, DESCRIPTION, COPYRIGHT, LICENSE); exit(EXIT_SUCCESS); break; case 'l': do_log_info = 1; break; case 'P': do_partial_update = 1; break; case 'p': do_wait_power_off = 1; break; case 's': do_synchro = 1; break; case 'j': do_infinite_loop = 1; break; case 'r': if (!strcmp(optarg, "auto")) { do_auto_rotate = 1; } else { unsigned long raw_angle; if (str2ul(optarg, &raw_angle) < 0) { LOG("failed to parse rotation angle"); print_usage(); exit(EXIT_FAILURE); } if ((raw_angle > 270) || (raw_angle % 90)) { LOG("invalid rotation angle"); print_usage(); exit(EXIT_FAILURE); } rotation_angle = raw_angle; } break; case 'g': if (str2ul(optarg, &pause_ms) < 0) { LOG("failed to parse pause duration"); print_usage(); exit(EXIT_FAILURE); } break; case 'f': if (optarg == NULL) { cfa = PLDRAW_CFA_GR_BW; } else { cfa = pldraw_get_cfa_id(optarg); if (cfa < 0) { LOG("Invalid CFA identifier: %s", optarg); print_usage(); exit(EXIT_FAILURE); } } break; case 'F':{ char* str = optarg; if (optarg == NULL) { // set color to white (0xFF) do_fill = 1; } else { do_fill = 1; if(!strncmp(optarg, "0x", 2) || !strncmp(optarg, "0X", 2)){ fill_color = strtoul(optarg, NULL, 16); }else{ fill_color = atoi(optarg); } } break; } case 'T': manual_temperature = atoi(optarg); use_manual_temperature = 1; break; case 'W': do_enumerate_waveforms = 1; break; case 'i': waveform_id_str = NULL; waveform_id = atoi(optarg); break; case 'w': waveform_id_str = optarg; break; case 'm': mode = optarg; break; case 'd': fbdev = optarg; break; case 'e': epdev = optarg; break; case 'b': background = optarg; break; case 't': doc_type = optarg; break; case 'o': if (parse_offset(&offset, optarg) < 0) { print_usage(); exit(EXIT_FAILURE); } break; case 'a': if (parse_alignment(&align_h, &align_v, optarg) < 0) { print_usage(); exit(EXIT_FAILURE); } break; case 'c': if (parse_crop(&crop, optarg) < 0) { print_usage(); exit(EXIT_FAILURE); } break; case 'O': conf_file = optarg; if (access(conf_file, F_OK)) { LOG_ERRNO("Configuration file"); exit(EXIT_FAILURE); } break; case 'x':{ onoff = atoi(optarg); break; } case 'E':{ //Enable Display N display_enable = atoi(optarg); if(display_enable > 3){ LOG("Invalid arguments"); exit(EXIT_FAILURE); } break; } case 'D':{ //disable Display N display_enable -= atoi(optarg); if(display_enable < -3){ LOG("Invalid arguments"); exit(EXIT_FAILURE); } break; } case 'y': dither_mode = atoi(optarg); LOG("dither_mode %i", dither_mode); if(display_enable < 0 || display_enable > 3){ LOG("Invalid arguments"); exit(EXIT_FAILURE); } break; case 'n':{ keep_power_on = 1; break; } case '?': default: LOG("Invalid arguments"); print_usage(); exit(EXIT_FAILURE); break; } } if (optind < argc) { file_names = &argv[optind]; n_files = argc - optind; } LOG("%s v%s", APP_NAME, VERSION); plep = plep_init(epdev, mode, conf_file); if (plep == NULL) { LOG("failed to initialise ePDC"); goto error_plep; } pldraw = pldraw_init(fbdev, conf_file); if (pldraw == NULL) { LOG("failed to initialise pldraw"); goto error_pldraw; } pldraw_set_plep(pldraw, plep); if(waveform_id_str){ waveform_id = plep_get_wfid(plep, waveform_id_str); if (waveform_id < 0) { LOG("Invalid waveform path: %s", waveform_id_str); goto error_pldraw; } } if (cfa >= 0) pldraw_set_cfa(pldraw, cfa); else cfa = pldraw_get_cfa(pldraw); if (cfa != PLDRAW_CFA_NONE) LOG("CFA: %s", pldraw_cfa_name[cfa]); if (rotation_angle < 0) rotation_angle = pldraw_get_rotation(pldraw); if (rotation_angle) LOG("rotation: %d", rotation_angle); if (do_log_info) pldraw_log_info(pldraw); sigint_original = signal(SIGINT, sigint_abort); if(onoff != -1){ LOG("POWER ONOFF:%i\n", onoff); if(onoff) plep_powerup(plep); else plep_powerdown(plep); exit(EXIT_SUCCESS); } if(display_enable != 0){ //LOG("DISPLAY ENABLE:%i\n", display_enable); if(display_enable>0){ plep_enable_display(plep, display_enable); }else{ plep_disable_display(plep, display_enable); } exit(EXIT_SUCCESS); } if (do_enumerate_waveforms) { ret = enumerate_waveforms(plep); } else { struct epdoc_opt opt; plep_set_opt(plep, PLEP_SYNC_UPDATE, do_synchro); if (do_wait_power_off) plep_set_opt(plep, PLEP_WAIT_POWER_OFF, 1); if(do_partial_update){ plep_set_opt(plep, PLEP_PARTIAL, 1); } if(use_manual_temperature){ plep_set_opt(plep, PLEP_TEMPERATURE, 1); plep_set_hw_opt(plep, PLEP_TEMPERATURE, manual_temperature); }else{ plep_set_opt(plep, PLEP_TEMPERATURE_AUTO, 1); } opt.dither_mode = dither_mode; opt.keep_power_on = keep_power_on; opt.do_auto_rotate = do_auto_rotate; opt.rotation_angle = rotation_angle; opt.wfid = waveform_id; opt.offset.x = offset.x; opt.offset.y = offset.y; opt.align_h = align_h; opt.align_v = align_v; memcpy(&opt.crop, &crop, sizeof opt.crop); opt.doc_type = doc_type; opt.use_alternative_vsource = use_alternative_vsource; if(do_fill){ pldraw_fill_rect(pldraw, pldraw_get_grey(pldraw, fill_color), &crop); plep_update_screen(plep, opt.wfid); }else{ ret = show_contents(pldraw, file_names, n_files, &opt, pause_ms, do_infinite_loop, background); } } signal(SIGINT, sigint_original); pldraw_free(pldraw); plep_free(plep); exit((ret < 0) ? EXIT_FAILURE : EXIT_SUCCESS); error_pldraw: plep_free(plep); error_plep: exit(EXIT_FAILURE); }
/* WARNING: all parameters MUST be valid, * NULL pointers lead to a crash. */ ret_t cherokee_socket_writev (cherokee_socket_t *socket, const struct iovec *vector, uint16_t vector_len, size_t *pcnt_written) { int re; int i; ret_t ret; size_t cnt; *pcnt_written = 0; /* There must be something to send, otherwise behaviour is undefined * and as we don't want this case, we have to enforce assertions. */ return_if_fail (vector != NULL && vector_len > 0, ret_error); if (likely (socket->is_tls != TLS)) { #ifdef _WIN32 int i; size_t total; for (i = 0, re = 0, total = 0; i < vector_len; i++) { if (vector[i].iov_len == 0) continue; re = send (SOCKET_FD(socket), vector[i].iov_base, vector[i].iov_len, 0); if (re < 0) break; total += re; /* if it is a partial send, then stop sending data */ if (re != vector[i].iov_len) break; } *pcnt_written = total; /* if we have sent at least one byte, * then return OK. */ if (likely (total > 0)) return ret_ok; if (re == 0) { int err = SOCK_ERRNO(); if (i == vector_len) return ret_ok; /* Retry later. */ return ret_eagain; } #else /* ! WIN32 */ re = writev (SOCKET_FD(socket), vector, vector_len); if (likely (re > 0)) { *pcnt_written = (size_t) re; return ret_ok; } if (re == 0) { int i; /* Find out whether there was something to send or not. */ for (i = 0; i < vector_len; i++) { if (vector[i].iov_base != NULL && vector[i].iov_len > 0) break; } if (i < vector_len) return ret_eagain; /* No, nothing to send, so return ok. */ return ret_ok; } #endif if (re < 0) { int err = SOCK_ERRNO(); switch (err) { #if defined(EWOULDBLOCK) && (EWOULDBLOCK != EAGAIN) case EWOULDBLOCK: #endif case EAGAIN: case EINTR: return ret_eagain; case EPIPE: #ifdef ENOTCONN case ENOTCONN: #endif case ECONNRESET: socket->status = socket_closed; case ETIMEDOUT: case EHOSTUNREACH: return ret_error; } LOG_ERRNO (errno, cherokee_err_error, CHEROKEE_ERROR_SOCKET_WRITEV, SOCKET_FD(socket)); } return ret_error; } /* TLS connection: Here we don't worry about sparing a few CPU * cycles, so we reuse the single send case for TLS. */ for (i = 0; i < vector_len; i++) { if ((vector[i].iov_len == 0) || (vector[i].iov_base == NULL)) continue; cnt = 0; ret = cherokee_socket_write (socket, vector[i].iov_base, vector[i].iov_len, &cnt); if (ret != ret_ok) { return ret; } *pcnt_written += cnt; if (cnt == vector[i].iov_len) continue; /* Unfinished */ return ret_ok; } /* Did send everything */ return ret_ok; }
int main(int argc, char **argv) { struct dt_dentry *probe; struct cfwk_dir curdir; int full = 0; int lookup = 0; char *host; int i; char *oldtree = NULL; FILE *oldfile; char *port = NULL; char *server_cp = NULL; CURLcode rcode; for (i = 1; i < argc; i++) { if (argv[i][0] != '-') break; if (argv[i][1] == '-' && argv[i][2] == 0) { i++; break; } switch (argv[i][1]) { case 'f': full = 1; break; case 'p': port = &argv[i][2]; break; case 'l': lookup = 1; break; case 'C': i++; if (i >= argc) usage(argv[0], ESTAT_FAILURE); server_cp = argv[i]; break; case 'u': i++; if (i >= argc) usage(argv[0], ESTAT_FAILURE); oldtree = argv[i]; break; case 'h': usage(argv[0], ESTAT_SUCCESS); default: usage(argv[0], ESTAT_FAILURE); } } if (i + 1 != argc) usage(argv[0], ESTAT_FAILURE); if ((rcode = curl_global_init(CURL_GLOBAL_NOTHING)) != CURLE_OK) { LOG_ERR("curl_global_init() returned non-zero: %s\n", curl_easy_strerror(rcode)); exit(ESTAT_FAILURE); } host = argv[i]; if (cfwk_open(&curdir, host, port, server_cp) < 0) exit(ESTAT_NOCONNECT); if (lookup) { probe = cfwk_walker.readdir(&curdir); cfwk_close(&curdir); if (probe != NULL) { dt_free(probe); exit(ESTAT_SUCCESS); } else exit(ESTAT_FAILURE); } if (full) dt_full(&cfwk_walker, &curdir); else if (oldtree) { if ((oldfile = fopen(oldtree, "r")) == NULL) { LOG_ERRNO("Can't open file %s\n", oldtree); exit(ESTAT_FAILURE); } dt_diff(oldfile, &cfwk_walker, &curdir); fclose(oldfile); } else dt_reverse(&cfwk_walker, &curdir); cfwk_close(&curdir); curl_global_cleanup(); return ESTAT_SUCCESS; }
/* WARNING: all parameters MUST be valid, * NULL pointers lead to a crash. */ ret_t cherokee_socket_write (cherokee_socket_t *socket, const char *buf, int buf_len, size_t *pcnt_written) { ret_t ret; ssize_t len; *pcnt_written = 0; /* There must be something to send, otherwise behaviour is undefined * and as we don't want this case, we have to enforce assertions. */ return_if_fail (buf != NULL && buf_len > 0, ret_error); if (likely (socket->is_tls != TLS)) { len = send (SOCKET_FD(socket), buf, buf_len, 0); if (likely (len > 0) ) { /* Return n. of bytes sent. */ *pcnt_written = len; return ret_ok; } if (len == 0) { /* Very strange, socket is ready but nothing * has been written, retry later. */ return ret_eagain; } /* else len < 0 */ { int err = SOCK_ERRNO(); switch (err) { #if defined(EWOULDBLOCK) && (EWOULDBLOCK != EAGAIN) case EWOULDBLOCK: #endif case EAGAIN: case EINTR: return ret_eagain; case EPIPE: #ifdef ENOTCONN case ENOTCONN: #endif case ECONNRESET: socket->status = socket_closed; case ETIMEDOUT: case EHOSTUNREACH: return ret_error; } LOG_ERRNO (errno, cherokee_err_error, CHEROKEE_ERROR_SOCKET_WRITE, SOCKET_FD(socket)); } return ret_error; } else if (socket->cryptor != NULL) { ret = cherokee_cryptor_socket_write (socket->cryptor, (char *)buf, buf_len, pcnt_written); switch (ret) { case ret_ok: case ret_error: case ret_eagain: return ret; case ret_eof: socket->status = socket_closed; return ret_eof; default: RET_UNKNOWN(ret); return ret; } } return ret_error; }
/* WARNING: all parameters MUST be valid, * NULL pointers lead to a crash. */ ret_t cherokee_socket_read (cherokee_socket_t *socket, char *buf, int buf_size, size_t *pcnt_read) { ret_t ret; ssize_t len; *pcnt_read = 0; /* There must be something to read, otherwise behaviour is undefined * and as we don't want this case, we have to enforce assertions. */ return_if_fail (buf != NULL && buf_size > 0, ret_error); if (unlikely (socket->status == socket_closed)) { TRACE(ENTRIES, "Reading a closed socket: fd=%d (TLS=%d)\n", SOCKET_FD(socket), (socket->is_tls == TLS)); return ret_eof; } if (likely (socket->is_tls != TLS)) { /* Plain read */ len = recv (SOCKET_FD(socket), buf, buf_size, 0); if (likely (len > 0)) { *pcnt_read = len; return ret_ok; } if (len == 0) { socket->status = socket_closed; return ret_eof; } { /* len < 0 */ int err = SOCK_ERRNO(); TRACE(ENTRIES",read", "Socket read error fd=%d: '%s'\n", SOCKET_FD(socket), strerror(errno)); switch (err) { #if defined(EWOULDBLOCK) && (EWOULDBLOCK != EAGAIN) case EWOULDBLOCK: #endif case EINTR: case EAGAIN: return ret_eagain; case EPIPE: #ifdef ENOTCONN case ENOTCONN: #endif case ECONNRESET: socket->status = socket_closed; case ETIMEDOUT: case EHOSTUNREACH: return ret_error; } LOG_ERRNO (errno, cherokee_err_error, CHEROKEE_ERROR_SOCKET_READ, SOCKET_FD(socket)); } return ret_error; } else if (socket->cryptor != NULL) { ret = cherokee_cryptor_socket_read (socket->cryptor, buf, buf_size, pcnt_read); switch (ret) { case ret_ok: case ret_error: case ret_eagain: return ret; case ret_eof: socket->status = socket_closed; return ret_eof; default: RET_UNKNOWN(ret); return ret; } } return ret_error; }
ret_t cherokee_socket_set_cork (cherokee_socket_t *socket, cherokee_boolean_t enable) { int re; int tmp = 0; int fd = socket->socket; if (enable) { tmp = 0; do { re = setsockopt (fd, IPPROTO_TCP, TCP_NODELAY, &tmp, sizeof(tmp)); } while ((re == -1) && (errno == EINTR)); if (unlikely (re < 0)) { LOG_ERRNO (errno, cherokee_err_error, CHEROKEE_ERROR_SOCKET_RM_NODELAY, fd); return ret_error; } TRACE(ENTRIES",cork,nodelay", "Set TCP_NODELAY on fd %d\n", fd); #ifdef TCP_CORK tmp = 1; do { re = setsockopt (fd, IPPROTO_TCP, TCP_CORK, &tmp, sizeof(tmp)); } while ((re == -1) && (errno == EINTR)); if (unlikely (re < 0)) { LOG_ERRNO (errno, cherokee_err_error, CHEROKEE_ERROR_SOCKET_SET_CORK, fd); return ret_error; } TRACE(ENTRIES",cork", "Set TCP_CORK on fd %d\n", fd); #endif return ret_ok; } #ifdef TCP_CORK tmp = 0; do { re = setsockopt (fd, IPPROTO_TCP, TCP_CORK, &tmp, sizeof(tmp)); } while ((re == -1) && (errno == EINTR)); if (unlikely (re < 0)) { LOG_ERRNO (errno, cherokee_err_error, CHEROKEE_ERROR_SOCKET_RM_CORK, fd); return ret_error; } TRACE(ENTRIES",cork", "Removed TCP_CORK on fd %d\n", fd); #endif tmp = 1; do { re = setsockopt (fd, IPPROTO_TCP, TCP_NODELAY, &tmp, sizeof(tmp)); } while ((re == -1) && (errno == EINTR)); if (unlikely (re < 0)) { LOG_ERRNO (errno, cherokee_err_error, CHEROKEE_ERROR_SOCKET_SET_NODELAY, fd); return ret_error; } TRACE(ENTRIES",cork,nodelay", "Removed TCP_NODELAY on fd %d\n", fd); return ret_ok; }
ret_t cherokee_socket_accept_fd (cherokee_socket_t *server_socket, int *new_fd, cherokee_sockaddr_t *sa) { ret_t ret; socklen_t len; int new_socket; /* Get the new connection */ len = sizeof (cherokee_sockaddr_t); do { new_socket = accept (server_socket->socket, &sa->sa, &len); } while ((new_socket == -1) && (errno == EINTR)); if (new_socket < 0) { return ret_error; } #if 0 /* DISABLED */ /* Deal with the FIN_WAIT2 state */ re = 1; re = setsockopt (new_socket, SOL_SOCKET, SO_KEEPALIVE, &re, sizeof(re)); if (re == -1) { LOG_ERRNO (errno, cherokee_err_warning, CHEROKEE_ERROR_SOCKET_SET_KEEPALIVE, new_socket); } linger.l_onoff = 1; linger.l_linger = SECONDS_TO_LINGER; re = setsockopt (new_socket, SOL_SOCKET, SO_LINGER, &linger, sizeof(linger)); if (re == -1) { LOG_ERRNO (errno, cherokee_err_warning, CHEROKEE_ERROR_SOCKET_SET_LINGER, new_socket); } #endif /* Close-on-exec: Child processes won't inherit this fd */ cherokee_fd_set_closexec (new_socket); /* Enables nonblocking I/O. */ ret = cherokee_fd_set_nonblocking (new_socket, true); if (ret != ret_ok) { LOG_WARNING (CHEROKEE_ERROR_SOCKET_NON_BLOCKING, new_socket); cherokee_fd_close (new_socket); return ret_error; } /* Disable Nagle's algorithm for this connection * so that there is no delay involved when sending data * which don't fill up a full IP datagram. */ ret = cherokee_fd_set_nodelay (new_socket, true); if (ret != ret_ok) { LOG_WARNING_S (CHEROKEE_ERROR_SOCKET_RM_NAGLES); cherokee_fd_close (new_socket); return ret_error; } *new_fd = new_socket; return ret_ok; }
ret_t fdpoll_epoll_new (cherokee_fdpoll_t **fdp, int sys_fd_limit, int fd_limit) { int re; cherokee_fdpoll_t *nfd; CHEROKEE_CNEW_STRUCT (1, n, fdpoll_epoll); nfd = FDPOLL(n); /* Init base class properties */ nfd->type = cherokee_poll_epoll; nfd->nfiles = fd_limit; nfd->system_nfiles = sys_fd_limit; nfd->npollfds = 0; /* Init base class virtual methods */ nfd->free = (fdpoll_func_free_t) _free; nfd->add = (fdpoll_func_add_t) _add; nfd->del = (fdpoll_func_del_t) _del; nfd->reset = (fdpoll_func_reset_t) _reset; nfd->set_mode = (fdpoll_func_set_mode_t) _set_mode; nfd->check = (fdpoll_func_check_t) _check; nfd->watch = (fdpoll_func_watch_t) _watch; /* Look for max fd limit */ n->ep_fd = -1; n->ep_nrevents = 0; n->ep_events = (struct epoll_event *) calloc (nfd->nfiles, sizeof(struct epoll_event)); n->epoll_fd2idx = (int *) calloc (nfd->system_nfiles, sizeof(int)); /* If anyone fails free all and return ret_nomem */ if (n->ep_events == NULL || n->epoll_fd2idx == NULL) { _free(n); return ret_nomem; } for (re = 0; re < nfd->system_nfiles; re++) { n->epoll_fd2idx[re] = -1; } n->ep_fd = epoll_create (nfd->nfiles); if (n->ep_fd < 0) { /* It may fail here if the glibc library supports epoll, * but the kernel doesn't. */ #if 0 LOG_ERRNO (errno, cherokee_err_error, CHEROKEE_ERROR_FDPOLL_EPOLL_CREATE, nfd->nfiles+1); #endif _free (n); return ret_error; } re = fcntl (n->ep_fd, F_SETFD, FD_CLOEXEC); if (re < 0) { LOG_ERRNO (errno, cherokee_err_error, CHEROKEE_ERROR_FDPOLL_EPOLL_CLOEXEC); _free (n); return ret_error; } /* Return the object */ *fdp = nfd; return ret_ok; }
netif_init_bpf(netif_t *netif, const char *name, uint16_t port, struct sock_filter *filter, int filter_len) #endif { bool result = true; struct ifaddrs *ifas; struct ifaddrs *ifa; #if __FreeBSD__ struct ifreq ifr; /* ioctl call to get VID */ struct vlanreq vreq; /* ioctl call to get VID */ #elif __linux__ struct ifreq ifr; /* ioctl call to get MAC address*/ struct rtnl_link_stats *stats; struct vlan_ioctl_args ifv; /* ioctl call to get VID */ struct sockaddr_ll addr; /* to bind packet socket to interface */ struct sockaddr_in dummy_addr; /* to bind dummy socket to interface */ struct sock_fprog prog; /* to attach to filter */ #endif /* string copy name */ strncpy(netif->name, name, NETIF_NAME_SIZE); /* set to zero */ memcpy(netif->mac.addr, MAC_ADDRESS_NULL.addr, MAC_ADDRESS_LEN); netif->vlan = NULL; netif->ipv4 = NULL; netif->ipv6 = NULL; /*** get the index of the interface ***/ netif->index = if_nametoindex(netif->name); if (netif->index == 0) { LOG_PRINTLN(LOG_NETWORK_INTERFACE, LOG_ERROR, ("interface '%s' is not known", netif->name)); return false; } /* create socket */ if ((netif->socket = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL))) < 0) { LOG_ERRNO(LOG_NETWORK_INTERFACE, LOG_ERROR, errno, ("socket failed")); return false; } /* get interface addresses */ if (getifaddrs(&ifas) != 0) { LOG_ERRNO(LOG_NETWORK_INTERFACE, LOG_ERROR, errno, ("getifaddrs failed")); return false; } for (ifa = ifas; ifa != NULL; ifa = ifa->ifa_next) { if ((ifa->ifa_addr) == NULL) continue; if ((ifa->ifa_flags & IFF_UP) == 0) continue; /* network interface name matches */ if (strcmp(name, ifa->ifa_name) == 0) { switch (ifa->ifa_addr->sa_family) { case AF_INET: netif_add_ipv4_address(netif, IPV4_ADDRESS(&(INADDR(ifa->ifa_addr)->sin_addr)), IPV4_ADDRESS(&(INADDR(ifa->ifa_netmask)->sin_addr)), IPV4_ADDRESS(&(INADDR(ifa->ifa_broadaddr)->sin_addr)), NULL); break; case AF_INET6: netif_add_ipv6_address(netif, IPV6_ADDRESS(&(INADDR6(ifa->ifa_addr)->sin6_addr)), IPV6_ADDRESS(&(INADDR6(ifa->ifa_netmask)->sin6_addr)), IPV6_STATE_VALID); break; #if __FreeBSD__ case AF_LINK: netif_add_mac_address(netif, MAC_ADDRESS(LLADDR(LADDR(ifa->ifa_addr)))); bzero((char *) &ifr, sizeof(ifr)); bzero((char *) &vreq, sizeof(vreq)); strncpy(ifr.ifr_name, netif->name, NETIF_NAME_SIZE); ifr.ifr_data = (caddr_t) &vreq; if (ioctl(sockfd, SIOCGETVLAN, &ifr) != -1) { netif_add_vid(netif, vreq.vlr_tag); } break; #elif __linux__ case AF_PACKET: stats = ifa->ifa_data; LOG_PRINTLN(LOG_NETWORK_INTERFACE, LOG_DEBUG, ("tx packet: %" PRIu32 " rx packet: %" PRIu32 " tx bytes: %" PRIu32 " rx bytes: %" PRIu32, stats->tx_packets, stats->rx_packets, stats->tx_bytes, stats->rx_bytes)); /* get MAC address, see netdevice(7) */ bzero((char *) &ifr, sizeof(ifr)); strncpy(ifr.ifr_name, netif->name, NETIF_NAME_SIZE); if (ioctl(netif->socket, SIOCGIFHWADDR, &ifr) != -1) { netif_add_mac_address(netif, MAC_ADDRESS(LLADDR(LADDR(ifr.ifr_hwaddr.sa_data)))); bzero((char *) &ifv, sizeof(ifv)); ifv.cmd = GET_VLAN_VID_CMD; strncpy(ifv.device1, netif->name, sizeof(ifv.device1)); if (ioctl(netif->socket, SIOCGIFVLAN, &ifv) != -1) { netif_add_vid(netif, ifv.u.VID); } } else { LOG_PRINTLN(LOG_NETWORK_INTERFACE, LOG_ERROR, ("couldn't get MAC address")); result = false; goto netif_init_exit; } break; #endif default: continue; } } } /* bind packet socket to interface */ bzero(&addr, sizeof(addr)); addr.sll_family = AF_PACKET; addr.sll_protocol = htons(ETH_P_ALL); addr.sll_ifindex = netif->index; if (bind(netif->socket, (struct sockaddr *) &addr, sizeof(addr)) < 0) { close(netif->socket); LOG_ERRNO(LOG_NETWORK_INTERFACE, LOG_ERROR, errno, ("can't bind packet socket to interface")); return false; } #if __FreeBSD__ #elif __linux__ if (filter != NULL) { prog.filter = filter; prog.len = filter_len; if (setsockopt(netif->socket, SOL_SOCKET, SO_ATTACH_FILTER, &prog, sizeof(prog)) < 0) { close(netif->socket); LOG_ERRNO(LOG_NETWORK_INTERFACE, LOG_ERROR, errno, ("can't add BPF filter")); return false; } } #endif if (netif->ipv4 != NULL && port > 0) { /* create dummy socket ***/ if ((netif->dummy_socket = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { close(netif->socket); LOG_ERRNO(LOG_NETWORK_INTERFACE, LOG_ERROR, errno, ("can't create dummy socket")); return false; } /* bind dummy socket to interface */ bzero(&dummy_addr, sizeof(dummy_addr)); dummy_addr.sin_family = AF_INET; dummy_addr.sin_addr.s_addr = netif->ipv4->address.addr32; dummy_addr.sin_port = htons(port); if (bind(netif->dummy_socket, (struct sockaddr *) &dummy_addr, sizeof(dummy_addr)) < 0) { close(netif->socket); close(netif->dummy_socket); LOG_ERRNO(LOG_NETWORK_INTERFACE, LOG_ERROR, errno, ("can't bind dummy socket to interface")); return false; } } /* clear receive buffer */ if (!netif_clear_receive_buffer(netif)) { return false; } netif_init_exit: freeifaddrs(ifas); return result; }
ret_t cherokee_source_connect (cherokee_source_t *src, cherokee_socket_t *sock) { ret_t ret; cherokee_resolv_cache_t *resolv; /* Short path: it's already connecting */ if (sock->socket >= 0) { return cherokee_socket_connect (sock); } /* Create the new socket and set the target IP info */ if (! cherokee_buffer_is_empty (&src->unix_socket)) { /* Create the socket descriptor */ ret = cherokee_socket_create_fd (sock, AF_UNIX); if (unlikely (ret != ret_ok)) { return ret; } ret = cherokee_socket_gethostbyname (sock, &src->unix_socket); if (unlikely (ret != ret_ok)) { return ret; } } else { cherokee_boolean_t tested_all; const struct addrinfo *addr; const struct addrinfo *addr_info = NULL; /* Query the resolv cache */ ret = cherokee_resolv_cache_get_default (&resolv); if (unlikely (ret!=ret_ok)) { return ret; } ret = cherokee_resolv_cache_get_addrinfo (resolv, &src->host, &addr_info); if ((ret != ret_ok) || (addr_info == NULL)) { return ret_error; } /* Current address */ if (src->addr_current) { tested_all = false; addr = src->addr_current; } else { tested_all = true; addr = addr_info; } /* Create the fd for the address family * * Iterates through the different addresses of the * host and stores a pointer to the first one with * a supported family. */ while (addr != NULL) { ret = cherokee_socket_create_fd (sock, addr->ai_family); #ifdef TRACE_ENABLED if (cherokee_trace_is_tracing()) { ret_t ret2; char ip[46]; ret2 = cherokee_ntop (addr->ai_family, addr->ai_addr, ip, sizeof(ip)); if (ret2 == ret_ok) { TRACE (ENTRIES, "Connecting to %s, ret=%d\n", ip, ret); } } #endif if (ret == ret_ok) { src->addr_current = addr; break; } addr = addr->ai_next; if (addr == NULL) { if (tested_all) { return ret_error; } tested_all = true; src->addr_current = NULL; addr = addr_info; continue; } cherokee_socket_close(sock); } /* Update the new socket with the address info */ switch (src->addr_current->ai_family) { case AF_INET: SOCKET_ADDR_IPv4(sock)->sin_port = htons(src->port); break; case AF_INET6: SOCKET_ADDR_IPv6(sock)->sin6_port = htons(src->port); break; default: SHOULDNT_HAPPEN; return ret_error; } ret = cherokee_socket_update_from_addrinfo (sock, src->addr_current, 0); if (unlikely (ret != ret_ok)) { return ret_error; } } /* Set non-blocking */ ret = cherokee_fd_set_nonblocking (sock->socket, true); if (unlikely (ret != ret_ok)) { LOG_ERRNO (errno, cherokee_err_error, CHEROKEE_ERROR_SOURCE_NONBLOCK, sock->socket); } /* Set close-on-exec and reuse-address */ cherokee_fd_set_closexec (sock->socket); cherokee_fd_set_reuseaddr (sock->socket); return cherokee_socket_connect (sock); }
static void init_seccomp(uint32_t def_action, bool main) { scmp_filter_ctx ctx = seccomp_init(def_action); if (ctx == NULL) { libreswan_log("seccomp_init() failed!"); exit_pluto(PLUTO_EXIT_SECCOMP_FAIL); } /* * read() and wait4() take the vast majority of syscall time * So we place these at the head of the list for performance * example strace -c -f output if pluto: * * % time seconds usecs/call calls errors syscall * ------ ----------- ----------- --------- --------- ---------------- * 73.70 41.137940 1202 34232 343 read * 20.77 11.595734 3549 3267 1176 wait4 * 1.47 0.819570 709 1156 epoll_wait * 0.60 0.332147 1 319902 rt_sigprocmask * 0.55 0.307552 5 61578 mmap * 0.41 0.230820 6 37788 2877 open * [...] */ LSW_SECCOMP_ADD(ctx, read); if (main) { LSW_SECCOMP_ADD(ctx, wait4); } #ifdef USE_EFENCE LSW_SECCOMP_ADD(ctx, madvise); #endif /* needed for pluto and updown, not helpers */ if (main) { LSW_SECCOMP_ADD(ctx, accept); LSW_SECCOMP_ADD(ctx, access); LSW_SECCOMP_ADD(ctx, bind); LSW_SECCOMP_ADD(ctx, brk); LSW_SECCOMP_ADD(ctx, chdir); LSW_SECCOMP_ADD(ctx, clone); LSW_SECCOMP_ADD(ctx, close); LSW_SECCOMP_ADD(ctx, connect); LSW_SECCOMP_ADD(ctx, dup); LSW_SECCOMP_ADD(ctx, dup2); LSW_SECCOMP_ADD(ctx, epoll_create); LSW_SECCOMP_ADD(ctx, epoll_ctl); LSW_SECCOMP_ADD(ctx, epoll_wait); LSW_SECCOMP_ADD(ctx, epoll_pwait); LSW_SECCOMP_ADD(ctx, execve); LSW_SECCOMP_ADD(ctx, faccessat); LSW_SECCOMP_ADD(ctx, fadvise64); LSW_SECCOMP_ADD(ctx, fcntl); LSW_SECCOMP_ADD(ctx, getcwd); LSW_SECCOMP_ADD(ctx, getdents); LSW_SECCOMP_ADD(ctx, getegid); LSW_SECCOMP_ADD(ctx, geteuid); LSW_SECCOMP_ADD(ctx, getgid); LSW_SECCOMP_ADD(ctx, getgroups); LSW_SECCOMP_ADD(ctx, getpgrp); LSW_SECCOMP_ADD(ctx, getpid); LSW_SECCOMP_ADD(ctx, getppid); LSW_SECCOMP_ADD(ctx, getrlimit); LSW_SECCOMP_ADD(ctx, getsockname); LSW_SECCOMP_ADD(ctx, getsockopt); LSW_SECCOMP_ADD(ctx, getuid); LSW_SECCOMP_ADD(ctx, ioctl); LSW_SECCOMP_ADD(ctx, lstat); LSW_SECCOMP_ADD(ctx, mkdir); LSW_SECCOMP_ADD(ctx, munmap); LSW_SECCOMP_ADD(ctx, newfstatat); LSW_SECCOMP_ADD(ctx, open); LSW_SECCOMP_ADD(ctx, openat); LSW_SECCOMP_ADD(ctx, pipe); LSW_SECCOMP_ADD(ctx, pipe2); LSW_SECCOMP_ADD(ctx, poll); LSW_SECCOMP_ADD(ctx, prctl); LSW_SECCOMP_ADD(ctx, pread64); LSW_SECCOMP_ADD(ctx, prlimit64); LSW_SECCOMP_ADD(ctx, readlink); LSW_SECCOMP_ADD(ctx, recvfrom); LSW_SECCOMP_ADD(ctx, recvmsg); LSW_SECCOMP_ADD(ctx, select); LSW_SECCOMP_ADD(ctx, sendmsg); LSW_SECCOMP_ADD(ctx, set_robust_list); LSW_SECCOMP_ADD(ctx, setsockopt); LSW_SECCOMP_ADD(ctx, socket); LSW_SECCOMP_ADD(ctx, socketcall); LSW_SECCOMP_ADD(ctx, socketpair); LSW_SECCOMP_ADD(ctx, sysinfo); LSW_SECCOMP_ADD(ctx, uname); LSW_SECCOMP_ADD(ctx, unlink); LSW_SECCOMP_ADD(ctx, unlinkat); } /* common to pluto and helpers */ LSW_SECCOMP_ADD(ctx, arch_prctl); LSW_SECCOMP_ADD(ctx, exit_group); LSW_SECCOMP_ADD(ctx, gettid); LSW_SECCOMP_ADD(ctx, gettimeofday); LSW_SECCOMP_ADD(ctx, fstat); LSW_SECCOMP_ADD(ctx, futex); LSW_SECCOMP_ADD(ctx, lseek); LSW_SECCOMP_ADD(ctx, mmap); LSW_SECCOMP_ADD(ctx, mprotect); LSW_SECCOMP_ADD(ctx, nanosleep); LSW_SECCOMP_ADD(ctx, rt_sigaction); LSW_SECCOMP_ADD(ctx, rt_sigprocmask); LSW_SECCOMP_ADD(ctx, rt_sigreturn); LSW_SECCOMP_ADD(ctx, sched_setparam); LSW_SECCOMP_ADD(ctx, sendto); LSW_SECCOMP_ADD(ctx, set_tid_address); LSW_SECCOMP_ADD(ctx, sigaltstack); LSW_SECCOMP_ADD(ctx, sigreturn); LSW_SECCOMP_ADD(ctx, stat); LSW_SECCOMP_ADD(ctx, statfs); LSW_SECCOMP_ADD(ctx, clock_gettime); LSW_SECCOMP_ADD(ctx, waitpid); LSW_SECCOMP_ADD(ctx, write); int rc = seccomp_load(ctx); if (rc < 0) { LOG_ERRNO(-rc, "seccomp_load() failed!"); seccomp_release(ctx); exit_pluto(PLUTO_EXIT_SECCOMP_FAIL); } libreswan_log("seccomp security enabled"); }
int main(int argc, char **argv) { struct dt_dentry *probe; struct wdwk_dir curdir; int full = 0; int lookup = 0; char *host; int i; char *oldtree = NULL; FILE *oldfile; int port = 0; for (i = 1; i < argc; i++) { if (argv[i][0] != '-') break; if (argv[i][1] == '-' && argv[i][2] == 0) { i++; break; } switch (argv[i][1]) { case 'f': full = 1; break; case 'p': port = atoi(&argv[i][2]); break; case 'l': lookup = 1; break; case 'u': i++; if (i >= argc) usage(argv[0], ESTAT_FAILURE); oldtree = argv[i]; break; case 'h': usage(argv[0], ESTAT_SUCCESS); default: usage(argv[0], ESTAT_FAILURE); } } if (i + 1 != argc) usage(argv[0], ESTAT_FAILURE); ne_debug_init(stderr, 0); if (ne_sock_init()) { LOG_ERR("ne_sock_init() returned non-zero\n"); exit(ESTAT_NOCONNECT); } host = argv[i]; if (wdwk_open(&curdir, host, port) < 0) exit(ESTAT_NOCONNECT); if (lookup) { probe = wdwk_walker.readdir(&curdir); wdwk_close(&curdir); if (probe != NULL) { dt_free(probe); exit(ESTAT_SUCCESS); } else exit(ESTAT_FAILURE); } if (full) dt_full(&wdwk_walker, &curdir); else if (oldtree) { if ((oldfile = fopen(oldtree, "r")) == NULL) { LOG_ERRNO("Can't open file %s\n", oldtree); exit(ESTAT_FAILURE); } dt_diff(oldfile, &wdwk_walker, &curdir); fclose(oldfile); } else dt_reverse(&wdwk_walker, &curdir); wdwk_close(&curdir); ne_sock_exit(); return ESTAT_SUCCESS; }
ret_t fdpoll_port_new (cherokee_fdpoll_t **fdp, int sys_limit, int limit) { int re; cuint_t i; cherokee_fdpoll_t *nfd; CHEROKEE_CNEW_STRUCT (1, n, fdpoll_port); nfd = FDPOLL(n); /* Init base class properties */ nfd->type = cherokee_poll_port; nfd->nfiles = limit; nfd->system_nfiles = sys_limit; nfd->npollfds = 0; /* Init base class virtual methods */ nfd->free = (fdpoll_func_free_t) _free; nfd->add = (fdpoll_func_add_t) _add; nfd->del = (fdpoll_func_del_t) _del; nfd->reset = (fdpoll_func_reset_t) _reset; nfd->set_mode = (fdpoll_func_set_mode_t) _set_mode; nfd->check = (fdpoll_func_check_t) _check; nfd->watch = (fdpoll_func_watch_t) _watch; /* Allocate data */ n->port = -1; n->port_readyfds = 0; n->port_events = (port_event_t *) calloc(nfd->nfiles, sizeof(port_event_t)); n->port_activefd = (int *) calloc(nfd->system_nfiles, sizeof(int)); if ( n->port_events == NULL || n->port_activefd == NULL ) { _free( n ); return ret_nomem; } for (i=0; i < nfd->system_nfiles; i++) { n->port_activefd[i] = -1; } n->port = port_create(); if (n->port == -1 ) { _free( n ); return ret_error; } re = fcntl (n->port, F_SETFD, FD_CLOEXEC); if (re < 0) { LOG_ERRNO (errno, cherokee_err_error, CHEROKEE_ERROR_FDPOLL_EPOLL_CLOEXEC); _free (n); return ret_error; } /* Return the object */ *fdp = nfd; return ret_ok; }
int main(int argc, char **argv) { static const char OPTIONS[] = "hvlpsjr:g:f::Ww:m:d:e:b:t:o:a:c:O:"; __sighandler_t sigint_original; char * const *file_names = NULL; size_t n_files = 0; const char *waveform_id_str = NULL; int waveform_id; int do_enumerate_waveforms = 0; int do_log_info = 0; int do_wait_power_off = 0; int do_synchro = 0; int do_infinite_loop = 0; int cfa = -1; int do_auto_rotate = 0; int rotation_angle = -1; unsigned long pause_ms = 2000; const char *mode = NULL; const char *fbdev = NULL; const char *epdev = NULL; const char *background = NULL; struct plep_point offset = { 0, 0 }; enum epdoc_align_h align_h = EPDOC_ALIGN_H_NONE; enum epdoc_align_v align_v = EPDOC_ALIGN_V_NONE; struct plep_rect crop = { { 0, 0 }, { INT_MAX, INT_MAX } }; const char *doc_type = NULL; const char *conf_file = NULL; struct plep *plep; struct pldraw *pldraw; int c; int ret; while ((c = getopt(argc, argv, OPTIONS)) != -1) { switch (c) { case 'h': print_usage(); exit(EXIT_SUCCESS); break; case 'v': printf("%s v%s - %s\n%s\n%s\n", APP_NAME, VERSION, DESCRIPTION, COPYRIGHT, LICENSE); exit(EXIT_SUCCESS); break; case 'l': do_log_info = 1; break; case 'p': do_wait_power_off = 1; break; case 's': do_synchro = 1; break; case 'j': do_infinite_loop = 1; break; case 'r': if (!strcmp(optarg, "auto")) { do_auto_rotate = 1; } else { unsigned long raw_angle; if (str2ul(optarg, &raw_angle) < 0) { LOG("failed to parse rotation angle"); print_usage(); exit(EXIT_FAILURE); } if ((raw_angle > 270) || (raw_angle % 90)) { LOG("invalid rotation angle"); print_usage(); exit(EXIT_FAILURE); } rotation_angle = raw_angle; } break; case 'g': if (str2ul(optarg, &pause_ms) < 0) { LOG("failed to parse pause duration"); print_usage(); exit(EXIT_FAILURE); } break; case 'f': if (optarg == NULL) { cfa = PLDRAW_CFA_GR_BW; } else { cfa = pldraw_get_cfa_id(optarg); if (cfa < 0) { LOG("Invalid CFA identifier: %s", optarg); print_usage(); exit(EXIT_FAILURE); } } break; case 'W': do_enumerate_waveforms = 1; break; case 'w': waveform_id_str = optarg; break; case 'm': mode = optarg; break; case 'd': fbdev = optarg; break; case 'e': epdev = optarg; break; case 'b': background = optarg; break; case 't': doc_type = optarg; break; case 'o': if (parse_offset(&offset, optarg) < 0) { print_usage(); exit(EXIT_FAILURE); } break; case 'a': if (parse_alignment(&align_h, &align_v, optarg) < 0) { print_usage(); exit(EXIT_FAILURE); } break; case 'c': if (parse_crop(&crop, optarg) < 0) { print_usage(); exit(EXIT_FAILURE); } break; case 'O': conf_file = optarg; if (access(conf_file, F_OK)) { LOG_ERRNO("Configuration file"); exit(EXIT_FAILURE); } break; case '?': default: LOG("Invalid arguments"); print_usage(); exit(EXIT_FAILURE); break; } } if (optind < argc) { file_names = &argv[optind]; n_files = argc - optind; } LOG("%s v%s", APP_NAME, VERSION); plep = plep_init(epdev, mode, conf_file); if (plep == NULL) { LOG("failed to initialise ePDC"); goto error_plep; } pldraw = pldraw_init(fbdev, conf_file); if (pldraw == NULL) { LOG("failed to initialise pldraw"); goto error_pldraw; } pldraw_set_plep(pldraw, plep); waveform_id = plep_get_wfid(plep, waveform_id_str); if (waveform_id < 0) { LOG("Invalid waveform path: %s", waveform_id_str); goto error_pldraw; } if (cfa >= 0) pldraw_set_cfa(pldraw, cfa); else cfa = pldraw_get_cfa(pldraw); if (cfa != PLDRAW_CFA_NONE) LOG("CFA: %s", pldraw_cfa_name[cfa]); if (rotation_angle < 0) rotation_angle = pldraw_get_rotation(pldraw); if (rotation_angle) LOG("rotation: %d", rotation_angle); if (do_log_info) pldraw_log_info(pldraw); sigint_original = signal(SIGINT, sigint_abort); if (do_enumerate_waveforms) { ret = enumerate_waveforms(plep); } else { struct epdoc_opt opt; plep_set_opt(plep, PLEP_SYNC_UPDATE, do_synchro); if (do_wait_power_off) plep_set_opt(plep, PLEP_WAIT_POWER_OFF, 1); opt.do_auto_rotate = do_auto_rotate; opt.rotation_angle = rotation_angle; opt.wfid = waveform_id; opt.offset.x = offset.x; opt.offset.y = offset.y; opt.align_h = align_h; opt.align_v = align_v; memcpy(&opt.crop, &crop, sizeof opt.crop); opt.doc_type = doc_type; ret = show_contents(pldraw, file_names, n_files, &opt, pause_ms, do_infinite_loop, background); } signal(SIGINT, sigint_original); pldraw_free(pldraw); plep_free(plep); exit((ret < 0) ? EXIT_FAILURE : EXIT_SUCCESS); error_pldraw: plep_free(plep); error_plep: exit(EXIT_FAILURE); }