static FILE *open_config_file(char **filename) { assert(filename != NULL); char *config = getenv("MACSPOOF_CONFIG"); if (config != NULL) { *filename = "<none>"; FILE *file = fmemopen(config, strlen(config), "r"); if (file == NULL) perror_die("fmemopen"); return file; } *filename = getenv("MACSPOOF_CONFIG_FILE"); if (*filename != NULL) { FILE *file = fopen(*filename, "r"); if (file == NULL) perror_die("fopen"); return file; } *filename = "~/.macspoofrc"; FILE *file = fopen(*filename, "r"); if (file != NULL) return file; *filename = MACSPOOF_ETCDIR "/macspoof.conf"; file = fopen(*filename, "r"); if (file == NULL) { perror("fopen"); die("Cannot open any config file."); } return file; }
int main(int argc, const char** argv) { setvbuf(stdout, NULL, _IONBF, 0); int portnum = 9988; if (argc >= 2) { portnum = atoi(argv[1]); } printf("Listening on port %d\n", portnum); int sockfd = listen_inet_socket(portnum); struct sockaddr_in peer_addr; socklen_t peer_addr_len = sizeof(peer_addr); int newsockfd = accept(sockfd, (struct sockaddr*)&peer_addr, &peer_addr_len); if (newsockfd < 0) { perror_die("ERROR on accept"); } report_peer_connected(&peer_addr, peer_addr_len); // Set nonblocking mode on the socket. int flags = fcntl(newsockfd, F_GETFL, 0); if (flags == -1) { perror_die("fcntl F_GETFL"); } if (fcntl(newsockfd, F_SETFL, flags | O_NONBLOCK) == -1) { perror_die("fcntl F_SETFL O_NONBLOCK"); } while (1) { uint8_t buf[1024]; printf("Calling recv...\n"); int len = recv(newsockfd, buf, sizeof buf, 0); if (len < 0) { if (errno == EAGAIN || errno == EWOULDBLOCK) { // No data on the socket; sleep a bit and re-try recv(). usleep(200 * 1000); continue; } perror_die("recv"); } else if (len == 0) { printf("Peer disconnected; I'm done.\n"); break; } printf("recv returned %d bytes\n", len); } close(newsockfd); close(sockfd); return 0; }
xmlelf_t * xmlelf_create_info( elf_t * elf , char * name ) { xmlDocPtr doc; xmlelf_t * ret; if(!elf||!name) error_ret("null args",NULL); if(!(ret = calloc(1,sizeof(*ret)))) perror_die("calloc()",1); if(!(doc = xmlNewDoc("1.0"))){ free(ret); error_ret("can't get doc",NULL); } if(!(doc->root= xmlNewDocNode(doc,NULL,"elf",NULL))){ xmlFreeDoc(doc); free(ret); error_ret("Can't create node",NULL); } xmlelf_set_elf( ret , elf ); ret->name = strdup(name); ret->doc = doc; return(ret); }
static void install_term_and_int_handlers() { struct sigaction sa; sa.sa_handler = on_signal; sa.sa_flags = 0; sigemptyset(&sa.sa_mask); if (sigaction(SIGINT, &sa, NULL)) perror_die("could not catch SIGINT"); if (sigaction(SIGTERM, &sa, NULL)) perror_die("could not catch SIGTERM"); sa.sa_handler = on_alarm; if (sigaction(SIGALRM, &sa, NULL)) perror_die("could not catch SIGALRM"); }
void *my_realloc(void *ptr, size_t size) { void *result; if ((result = realloc(ptr, size)) == NULL) perror_die("malloc"); return result; }
void *my_malloc(size_t size) { void *result; if ((result = malloc(size)) == NULL) perror_die("malloc"); bzero(result, size); return result; }
static char *mkconfig(const char *fmt, ...) { char *name = strdup("macspoof_test.XXXXXXXX"); if (name == NULL) perror_die("strdup"); int fd = mkstemp(name); if (fd == -1) perror_die("mkstemp"); tempfiles = g_slist_prepend(tempfiles, name); FILE *file = fdopen(fd, "r+"); if (file == NULL) perror_die("fdopen"); va_list ap; va_start(ap, fmt); if (vfprintf(file, fmt, ap) == -1) perror_die("vfprintf"); va_end(ap); if (fclose(file) == EOF) perror_die("fclose"); return name; }
static void read_config(void) { char *filename = NULL; FILE *file = open_config_file(&filename); if (config_read(config, file) != CONFIG_TRUE) die("%s:%d %s", filename, config_error_line(config), config_error_text(config)); if (fclose(file) == EOF) perror_die("fclose"); }
int main(int argc, const char** argv) { setvbuf(stdout, NULL, _IONBF, 0); int portnum = 9988; if (argc >= 2) { portnum = atoi(argv[1]); } printf("Listening on port %d\n", portnum); int sockfd = listen_inet_socket(portnum); struct sockaddr_in peer_addr; socklen_t peer_addr_len = sizeof(peer_addr); int newsockfd = accept(sockfd, (struct sockaddr*)&peer_addr, &peer_addr_len); if (newsockfd < 0) { perror_die("ERROR on accept"); } report_peer_connected(&peer_addr, peer_addr_len); while (1) { uint8_t buf[1024]; printf("Calling recv...\n"); int len = recv(newsockfd, buf, sizeof buf, 0); if (len < 0) { perror_die("recv"); } else if (len == 0) { printf("Peer disconnected; I'm done.\n"); break; } printf("recv returned %d bytes\n", len); } close(newsockfd); close(sockfd); return 0; }
xmlelf_t * xmlelf_open_info( elf_t * elf , char * name ) { xmlDocPtr doc; xmlelf_t * ret; if(!elf||!name) error_ret("null args",NULL); if(!(ret = calloc(1,sizeof(*ret)))) perror_die("calloc()",1); if(!(doc = xmlParseDoc("1.0"))){ free(ret); error_ret("can't get doc",NULL); } return(ret); }
/* * Open an existing info file. */ xmlelf_t * xmlelf_open_info( elf_t * elf , char * name ) { xmlDocPtr doc; xmlelf_t * ret; if(!elf||!name) error_ret("null args",NULL); if(!(ret = calloc(1,sizeof(*ret)))) perror_die("calloc()",1); if(!(doc = xmlParseFile(name))){ free(ret); error_ret("can't get doc",NULL); } ret->elf = elf; ret->doc = doc; ret->root = doc->children; ret->name = strdup(name); return(ret); }
fd_status_t on_peer_ready_recv(int sockfd) { assert(sockfd < MAXFDs); peer_state_t* peerstate = &global_state[sockfd]; if (peerstate->state == INITIAL_ACK || peerstate->sendptr < peerstate->sendbuf_end) { // Until the initial ACK has been sent to the peer, there's nothing we // want to receive. Also, wait until all data staged for sending is sent to // receive more data. return fd_status_W; } uint8_t buf[1024]; int nbytes = recv(sockfd, buf, sizeof buf, 0); if (nbytes == 0) { // The peer disconnected. return fd_status_NORW; } else if (nbytes < 0) { if (errno == EAGAIN || errno == EWOULDBLOCK) { // The socket is not *really* ready for recv; wait until it is. return fd_status_R; } else { perror_die("recv"); } } bool ready_to_send = false; for (int i = 0; i < nbytes; ++i) { switch (peerstate->state) { case INITIAL_ACK: assert(0 && "can't reach here"); break; case WAIT_FOR_MSG: if (buf[i] == '^') { peerstate->state = IN_MSG; } break; case IN_MSG: if (buf[i] == '$') { peerstate->state = WAIT_FOR_MSG; } else { assert(peerstate->sendbuf_end < SENDBUF_SIZE); peerstate->sendbuf[peerstate->sendbuf_end++] = buf[i] + 1; ready_to_send = true; } break; } } // Report reading readiness iff there's nothing to send to the peer as a // result of the latest recv. return (fd_status_t){.want_read = !ready_to_send, .want_write = ready_to_send}; } fd_status_t on_peer_ready_send(int sockfd) { assert(sockfd < MAXFDs); peer_state_t* peerstate = &global_state[sockfd]; if (peerstate->sendptr >= peerstate->sendbuf_end) { // Nothing to send. return fd_status_RW; } int sendlen = peerstate->sendbuf_end - peerstate->sendptr; int nsent = send(sockfd, peerstate->sendbuf, sendlen, 0); if (nsent == -1) { if (errno == EAGAIN || errno == EWOULDBLOCK) { return fd_status_W; } else { perror_die("send"); } } if (nsent < sendlen) { peerstate->sendptr += nsent; return fd_status_W; } else { // Everything was sent successfully; reset the send queue. peerstate->sendptr = 0; peerstate->sendbuf_end = 0; // Special-case state transition in if we were in INITIAL_ACK until now. if (peerstate->state == INITIAL_ACK) { peerstate->state = WAIT_FOR_MSG; } return fd_status_R; } }
int main(int argc, const char** argv) { setvbuf(stdout, NULL, _IONBF, 0); int portnum = 9090; if (argc >= 2) { portnum = atoi(argv[1]); } printf("Serving on port %d\n", portnum); int listener_sockfd = listen_inet_socket(portnum); make_socket_non_blocking(listener_sockfd); int epollfd = epoll_create1(0); if (epollfd < 0) { perror_die("epoll_create1"); } struct epoll_event accept_event; accept_event.data.fd = listener_sockfd; accept_event.events = EPOLLIN; if (epoll_ctl(epollfd, EPOLL_CTL_ADD, listener_sockfd, &accept_event) < 0) { perror_die("epoll_ctl EPOLL_CTL_ADD"); } struct epoll_event* events = calloc(MAXFDS, sizeof(struct epoll_event)); if (events == NULL) { die("Unable to allocate memory for epoll_events"); } while (1) { int nready = epoll_wait(epollfd, events, MAXFDS, -1); for (int i = 0; i < nready; i++) { if (events[i].events & EPOLLERR) { perror_die("epoll_wait returned EPOLLERR"); } if (events[i].data.fd == listener_sockfd) { // The listening socket is ready; this means a new peer is connecting. struct sockaddr_in peer_addr; socklen_t peer_addr_len = sizeof(peer_addr); int newsockfd = accept(listener_sockfd, (struct sockaddr*)&peer_addr, &peer_addr_len); if (newsockfd < 0) { if (errno == EAGAIN || errno == EWOULDBLOCK) { // This can happen due to the nonblocking socket mode; in this // case don't do anything, but print a notice (since these events // are extremely rare and interesting to observe...) printf("accept returned EAGAIN or EWOULDBLOCK\n"); } else { perror_die("accept"); } } else { make_socket_non_blocking(newsockfd); if (newsockfd >= MAXFDS) { die("socket fd (%d) >= MAXFDS (%d)", newsockfd, MAXFDS); } fd_status_t status = on_peer_connected(newsockfd, &peer_addr, peer_addr_len); struct epoll_event event = {0}; event.data.fd = newsockfd; if (status.want_read) { event.events |= EPOLLIN; } if (status.want_write) { event.events |= EPOLLOUT; } if (epoll_ctl(epollfd, EPOLL_CTL_ADD, newsockfd, &event) < 0) { perror_die("epoll_ctl EPOLL_CTL_ADD"); } } } else { // A peer socket is ready. if (events[i].events & EPOLLIN) { // Ready for reading. int fd = events[i].data.fd; fd_status_t status = on_peer_ready_recv(fd); struct epoll_event event = {0}; event.data.fd = fd; if (status.want_read) { event.events |= EPOLLIN; } if (status.want_write) { event.events |= EPOLLOUT; } if (event.events == 0) { printf("socket %d closing\n", fd); if (epoll_ctl(epollfd, EPOLL_CTL_DEL, fd, NULL) < 0) { perror_die("epoll_ctl EPOLL_CTL_DEL"); } close(fd); } else if (epoll_ctl(epollfd, EPOLL_CTL_MOD, fd, &event) < 0) { perror_die("epoll_ctl EPOLL_CTL_MOD"); } } else if (events[i].events & EPOLLOUT) { // Ready for writing. int fd = events[i].data.fd; fd_status_t status = on_peer_ready_send(fd); struct epoll_event event = {0}; event.data.fd = fd; if (status.want_read) { event.events |= EPOLLIN; } if (status.want_write) { event.events |= EPOLLOUT; } if (event.events == 0) { printf("socket %d closing\n", fd); if (epoll_ctl(epollfd, EPOLL_CTL_DEL, fd, NULL) < 0) { perror_die("epoll_ctl EPOLL_CTL_DEL"); } close(fd); } else if (epoll_ctl(epollfd, EPOLL_CTL_MOD, fd, &event) < 0) { perror_die("epoll_ctl EPOLL_CTL_MOD"); } } } } } return 0; }
static void set_text(YYSTYPE *yylval, const char *text) { if ((yylval->text = strdup(text)) == NULL) perror_die("strdup"); }