/* * Actually swap something out. * block - the memory to swap out * size - how big it is * locp - the swap location is written to the int this points to */ static int swap_out(char * block, int size, int * locp) { if (!block || time_to_swap == 0) return 0; if (!assert_swap_file()) return 0; if (*locp == -1) { /* needs data written out */ *locp = alloc_swap(size + sizeof size); swap_seek(*locp, 0); #ifdef SWAP_USE_FD if ((write(swap_file, &size, sizeof size) != sizeof size) || write(swap_file, block, size) != size) { debug_perror("swap_out", swap_file); *locp = -1; return 0; } #else if (fwrite((char *) &size, sizeof size, 1, swap_file) != 1 || fwrite(block, size, 1, swap_file) != 1) { debug_perror("swap_out:swap file", 0); *locp = -1; return 0; } #endif if (*locp >= last_data) last_data = *locp + sizeof size + size; } total_bytes_swapped += size;/* also count sizeof int?? */ return 1; }
static struct uiomux_state * create_shared_state (void) { struct uiomux_state * state; int shm_descr; size_t size; size = sizeof(struct uiomux_state) + init_owners_table(NULL); shm_descr = shm_open (UIOMUX_SHM_NAME, O_CREAT | O_EXCL | O_RDWR, S_IRWXU); if (shm_descr == -1) { debug_perror ("create_shared_state: shm_open"); return NULL; } if (ftruncate (shm_descr, size) < 0 ) { debug_perror ("create_shared_state: ftruncate"); } state = (struct uiomux_state *) mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, shm_descr, (long)0); if (state == MAP_FAILED) { debug_perror ("create_shared_state: mmap"); return NULL; } close (shm_descr); state->proper_address = (void *)state; state->version = UIOMUX_STATE_VERSION; state->size = size; return state; }
static struct uiomux_state * map_shared_state (void) { struct uiomux_state * state; int shm_descr; void * exact_address; size_t size; debug_info ("map_shared_state: IN"); size = sizeof(struct uiomux_state) + init_owners_table(NULL); shm_descr = shm_open (UIOMUX_SHM_NAME, O_RDWR, S_IRWXU); if (shm_descr == -1) { debug_perror ("map_shared_state: shm_open"); return NULL; } debug_info ("map_shared_state: mmap ..."); state = (struct uiomux_state *) mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, shm_descr, (long)0); if (state == MAP_FAILED) { debug_perror ("map_shared_state: mmap"); close (shm_descr); return NULL; } if (state->proper_address != (void *)state) { debug_info ("map_shared_state: Not mapped at proper address, trying with MAP_FIXED ..."); exact_address = state->proper_address; #ifdef DEBUG fprintf (stderr, "%s: exact_address %p\n", __func__, exact_address); #endif munmap ((void *)state, size); state = (struct uiomux_state *) mmap(exact_address, size, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_FIXED, shm_descr, (long)0); if (state == MAP_FAILED) { debug_perror ("map_shared_state: mmap (MAP_FIXED)"); close (shm_descr); return NULL; } } if (state->version != UIOMUX_STATE_VERSION || state->num_blocks < UIOMUX_BLOCK_MAX) { debug_info ("map_shared_state: Incorrect version or num_blocks, unmapping and closing ..."); munmap ((void *)state, size); close (shm_descr); /* XXX: Set error code for incorrect UIOMux version */ return NULL; } close (shm_descr); return state; }
int destroy_shared_state (struct uiomux_state * state) { pthread_mutex_t * mutex; int i, ret; size_t size; if (state == NULL) return -1; if (state->proper_address != state) return -1; for (i = 0; i < UIOMUX_BLOCK_MAX; i++) { /* Destroy mutex */ mutex = &state->mutex[i].mutex; ret = pthread_mutex_destroy (mutex); if (ret == EBUSY) { #ifdef DEBUG perror ("pthread_mutex_destroy"); #endif } } if (state->version == 1) { size = sizeof (struct uiomux_state); } else { size = state->size; } munmap ((void *)state, size); if (shm_unlink (UIOMUX_SHM_NAME) < 0) { debug_perror ("shm_unlink"); } return 0; }
/* transmit and free message */ void cann_transmit(cann_conn_t *conn, rs232can_msg *msg) { // sanity if (conn->error) { debug(5, "cann_transmit: not transmiting on errorous connection fd=%d", conn->fd); return; } debug(9, "Transmitting message fd=%d", conn->fd); /* copy this into another buffer, convert to cantcp and send it with a single write to avoid multiple tcp packets */ unsigned char txbuf[sizeof(rs232can_msg)], swap; memcpy((void *) txbuf, (void *) msg, sizeof(rs232can_msg)); swap = txbuf[0]; txbuf[0] = txbuf[1]; txbuf[1] = swap; if (send(conn->fd, txbuf, 2 + msg->len, MSG_NOSIGNAL) != msg->len + 2) goto error; return; error: conn->error = 1; debug_perror(5, "Error sending fd %d", conn->fd); return; }
/* * I/O handler. */ INLINE void aserv_process_io (int nb) { int i; switch (nb) { case -1: debug_perror("sigio_handler: select", 0); break; case 0: break; default: /* * check for new connection. */ if (FD_ISSET(conn_fd, &readmask)) { DBG(("sigio_handler: NEW_CONN")); enqueue_datapending(conn_fd, NEW_CONN); } /* * check for data pending on established connections. */ for (i = 0; i < MAX_CONNS; i++) { if (FD_ISSET(all_conns[i].fd, &readmask)) { DBG(("sigio_handler: CONN")); enqueue_datapending(all_conns[i].fd, CONN); } } break; } }
void cache_add_hosts_entries(FILE *cache_file) { FILE *hosts_fp; char line[BUF_SIZE]; char *ip, *name; debug("cache_add_hosts_entreies()\n"); hosts_fp = fopen( config.hosts_file , "r"); if( !hosts_fp ) { debug_perror("can not open 'hosts'-file "); return; } while( fgets(line, BUF_SIZE, hosts_fp) ){ line[strlen(line) - 1] = 0; /* get rid of '\n' */ ip = strtok( line, " \t"); if( ip == NULL ) continue; /* ignore blank lines */ if( ip[0] == '#' )continue; /* ignore comments */ while( (name = strtok( NULL, " \t" )) ){ if(name[0] == '#')break; #if 0//defined(AEI_VDSL_CUSTOMER_NCS) if(strstr(name,config.domain_name)==NULL) fprintf( cache_file, "%s.%s %s %ld\n", name,config.domain_name, ip, 0L ); else #endif fprintf( cache_file, "%s %s %ld\n", name, ip, 0L ); } } fclose(hosts_fp); debug("cache_add_hosts_entreies(): done\n"); }
int dns_read_packet(int sock, dns_request_t *m) { struct sockaddr_in sa; int salen; /* Read in the actual packet */ salen = sizeof(sa); m->numread = recvfrom(sock, m->original_buf, sizeof(m->original_buf), 0, (struct sockaddr *)&sa, &salen); if ( m->numread < 0) { debug_perror("dns_read_packet: recvfrom\n"); return -1; } /* TODO: check source addr against list of allowed hosts */ /* record where it came from */ memcpy( (void *)&m->src_addr, (void *)&sa.sin_addr, sizeof(struct in_addr)); m->src_port = ntohs( sa.sin_port ); /* check that the message is long enough */ if( m->numread < sizeof (m->message.header) ){ debug("dns_read_packet: packet from '%s' to short to be dns packet", inet_ntoa (sa.sin_addr) ); return -1; } /* pass on for full decode */ dns_decode_request( m ); return 0; }
int main(int argc, char **argv) { /* get commandline options, load config if needed. */ if(get_options( argc, argv ) < 0 ) { exit(1); } signal(SIGHUP, sig_hup); dns_init(); if (config.daemon_mode) { /* Standard fork and background code */ switch (fork()) { case -1: /* Oh shit, something went wrong */ debug_perror("fork"); exit(-1); case 0: /* Child: close off stdout, stdin and stderr */ close(0); close(1); close(2); break; default: /* Parent: Just exit */ exit(0); } } dns_main_loop(); return 0; }
int dns_init() { struct sockaddr_in sa; struct in_addr ip; /* Clear it out */ memset((void *)&sa, 0, sizeof(sa)); dns_sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); /* Error */ if( dns_sock < 0 ){ debug_perror("Could not create socket"); exit(1); } ip.s_addr = INADDR_ANY; sa.sin_family = AF_INET; memcpy((void *)&sa.sin_addr, (void *)&ip, sizeof(struct in_addr)); sa.sin_port = htons(PORT); /* bind() the socket to the interface */ if (bind(dns_sock, (struct sockaddr *)&sa, sizeof(struct sockaddr)) < 0){ debug_perror("dns_init: bind: Could not bind to port"); exit(1); } dns_main_quit = 0; FD_ZERO( &rfds ); FD_SET( dns_sock, &rfds ); dns_request_list = NULL; cache_purge( config.purge_time ); return 1; }
INLINE int set_socket_nonblocking P2(int, fd, int, which) { #if !defined(OLD_ULTRIX) && !defined(_SEQUENT_) int result; #endif #ifdef OLD_ULTRIX if (which) return fcntl(fd, F_SETFL, FNDELAY); else return fcntl(fd, F_SETFL, FNBLOCK); #else #ifdef _SEQUENT_ int flags = fcntl(fd, F_GETFL, 0); if (flags == -1) return (-1); if (which) flags |= O_NONBLOCK; else flags &= ~O_NONBLOCK; return fcntl(fd, F_SETFL, flags); #else result = OS_socket_ioctl(fd, FIONBIO, &which); if (result == -1) debug_perror("set_socket_nonblocking: ioctl", 0); #if 0 /* boggle ... someone track down an errno for this */ if (result == -1) { XXX("Try using cc instead of gcc to correct this error.\n"); } #endif return result; #endif #endif }
int dns_write_packet(int sock, struct in_addr in, int port, dns_request_t *m) { struct sockaddr_in sa; int retval; /* Zero it out */ memset((void *)&sa, 0, sizeof(sa)); /* Fill in the information */ //inet_aton( "203.12.160.35", &in ); memcpy( &sa.sin_addr.s_addr, &in, sizeof(in) ); sa.sin_port = htons(port); sa.sin_family = AF_INET; retval = sendto(sock, m->original_buf, m->numread, 0, (struct sockaddr *)&sa, sizeof(sa)); if( retval < 0 ){ debug_perror("dns_write_packet: sendto"); } return retval; }
int copy_file (const char * from, const char * to) { char buf[128]; int from_fd, to_fd; int num_read, num_written; char *write_ptr; extern svalue_t apply_ret_value; from = check_valid_path(from, current_object, "move_file", 0); assign_svalue(&from_sv, &apply_ret_value); to = check_valid_path(to, current_object, "move_file", 1); assign_svalue(&to_sv, &apply_ret_value); if (from == 0) return -1; if (to == 0) return -2; if (lstat(from, &from_stats) != 0) { error("/%s: lstat failed\n", from); return 1; } if (lstat(to, &to_stats) == 0) { #ifdef WIN32 if (!strcmp(from, to)) #else if (from_stats.st_dev == to_stats.st_dev && from_stats.st_ino == to_stats.st_ino) #endif { error("`/%s' and `/%s' are the same file", from, to); return 1; } } else if (errno != ENOENT) { error("/%s: unknown error\n", to); return 1; } from_fd = open(from, OPEN_READ); if (from_fd < 0) return -1; if (file_size(to) == -2) { /* Target is a directory; build full target filename. */ const char *cp; char newto[MAX_FNAME_SIZE + MAX_PATH_LEN + 2]; cp = strrchr(from, '/'); if (cp) cp++; else cp = from; sprintf(newto, "%s/%s", to, cp); close(from_fd); return copy_file(from, newto); } to_fd = open(to, OPEN_WRITE | O_CREAT | O_TRUNC, 0666); if (to_fd < 0) { close(from_fd); return -2; } while ((num_read = read(from_fd, buf, 128)) != 0) { if (num_read < 0) { debug_perror("copy_file: read", from); close(from_fd); close(to_fd); return -3; } write_ptr = buf; while (write_ptr != (buf + num_read)) { num_written = write(to_fd, write_ptr, num_read); if (num_written < 0) { debug_perror("copy_file: write", to); close(from_fd); close(to_fd); return -3; } write_ptr += num_written; } } close(from_fd); close(to_fd); return 1; }
void cache_purge(int older_than) { FILE /**in_fp, */*out_fp; // char line[BUF_SIZE]; // char old_cache[1024]; // char *name, *ip, *time_made; debug("enter cache_purge()\n"); #if 0 //BRCM in_fp = fopen( config.cache_file , "r"); if(!in_fp){ debug_perror("Could not open old cache file"); /*return;*/ } if( in_fp ) { sprintf( old_cache, "%s.old", config.cache_file ); if( rename( config.cache_file, old_cache ) < 0 ){ debug_perror("Could not move cache file"); fclose(in_fp); return; } } #endif out_fp = fopen( config.cache_file , "w"); if(!out_fp){ #if 0 //BRCM if( in_fp ) { fclose(in_fp); } #endif debug_perror("Could not open new cache file"); return; } cache_add_hosts_entries(out_fp); /* No need to add dhcp entries any more, It seems that all dhcp * entries now will be added to the host entries */ #if !defined(AEI_VDSL_DNS_CACHE) cache_add_dhcp_entries(out_fp); #endif #if 0 //BRCM if( in_fp ) { while( fgets(line, BUF_SIZE, in_fp) ){ name = strtok( line, " "); ip = strtok( NULL, " "); time_made = strtok( NULL, " "); if(!time_made)continue; if( time(NULL) - atoi( time_made ) < older_than ) fprintf( out_fp, "%s %s %s", name, ip, time_made ); } fclose(in_fp); unlink(old_cache); } #endif fclose(out_fp); }
/* open connection to cand */ cann_conn_t *cann_connect(char *server, char *port) { struct addrinfo hints; struct addrinfo *result, *rp; int s; cann_conn_t *client; char buf[INET6_ADDRSTRLEN]; // initialize client struct client = malloc(sizeof(cann_conn_t)); if (client == NULL) { debug(0, "Could not allocate client buffer!\n"); free(client); exit(EXIT_FAILURE); } client->state = CANN_LEN; client->missing_bytes = 0; client->error = 0; #ifdef USE_WINSOCK WSADATA wsaData; int err; err = WSAStartup(0x0202, &wsaData); if (err != 0) { /* Tell the user that we could not find a usable */ /* Winsock DLL. */ printf("WSAStartup failed with error: %d\n", err); exit(EXIT_FAILURE); } #endif /* Obtain address(es) matching host/port */ memset(&hints, 0, sizeof(struct addrinfo)); hints.ai_family = AF_UNSPEC; /* Allow IPv4 or IPv6 */ hints.ai_socktype = SOCK_STREAM; /* Datagram socket */ hints.ai_flags = AI_ADDRCONFIG | AI_NUMERICSERV; // hints.ai_protocol = 0; /* Any protocol */ s = getaddrinfo(server, port, &hints, &result); if (s != 0) { debug_perror(0, "getaddrinfo: %s\n", gai_strerror(s)); free(client); exit(EXIT_FAILURE); } /* getaddrinfo() returns a list of address structures. Try each address until we successfully connect(2). If socket(2) (or connect(2)) fails, we (close the socket and) try the next address. */ for (rp = result; rp != NULL; rp = rp->ai_next) { client->fd = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol); if (client->fd == -1) continue; if (connect(client->fd, rp->ai_addr, rp->ai_addrlen) != -1) break; /* Success */ close(client->fd); } if (rp == NULL) { /* No address succeeded */ debug_perror(0, "Could not connect\n"); free(client); exit(EXIT_FAILURE); } debug(4, "Connected to %s.", get_ip_str((struct sockaddr *)rp->ai_addr, buf, sizeof(buf))); freeaddrinfo(result); /* No longer needed */ listen_socket = client->fd; #ifdef USE_WINSOCK u_long option = 1; ioctlsocket(client->fd, FIONBIO, &option); #else // set some options on socket fcntl(client->fd, F_SETFL, O_NONBLOCK); #endif int flag = 1; setsockopt(client->fd, IPPROTO_TCP, /* set option at TCP level */ TCP_NODELAY, /* name of option */ (char *) &flag, /* the cast is historical cruft */ sizeof(int)); /* length of option value */ debug(9, "connected to server, fd=%d\r\n", client->fd); return client; }
/* open listening socket and initialize */ void cann_listen(char *port) { struct addrinfo hints; struct addrinfo *result, *rp; int sfd, s; char buf[200]; int ret, one = 1; signal(SIGPIPE, SIG_IGN); memset(&hints, 0, sizeof(struct addrinfo)); hints.ai_family = AF_UNSPEC; // Allow IPv4 or IPv6 - ipv4 is mapped into an v6 addr -> ai_v4mapped hints.ai_socktype = SOCK_STREAM; // Datagram socket hints.ai_flags = AI_PASSIVE | AI_V4MAPPED | AI_NUMERICSERV | AI_ALL; // For wildcard IP address s = getaddrinfo(NULL, port, &hints, &result); if (s != 0) { fprintf(stderr, "No listening addresses available(getaddrinfo: %s)\n", gai_strerror(s)); exit(EXIT_FAILURE); } //dump address info for (rp = result; rp != NULL; rp = rp->ai_next) debug(5, "Found Address %s\t\t(family: %s, socktype %i: protocol %i)", get_ip_str((struct sockaddr *)rp->ai_addr, buf, sizeof(buf)), (rp->ai_family == AF_INET) ? "IPv4" : ((rp->ai_family == AF_INET6) ? "IPv6" : ((snprintf(buf, sizeof(buf), "%i", rp->ai_family) != 0) ? buf : "")), rp->ai_socktype, rp->ai_protocol); /* getaddrinfo() returns a list of address structures. Try each address until we successfully bind(2). If socket(2) (or bind(2)) fails, we (close the socket and) try the next address. */ for (rp = result; rp != NULL; rp = rp->ai_next) { sfd = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol); if (sfd == -1) continue; debug(5, "Trying to bind to %s (%s)", get_ip_str((struct sockaddr *)rp->ai_addr, buf, sizeof(buf)), (rp->ai_family == AF_INET) ? "IPv4" : ((rp->ai_family == AF_INET6) ? "IPv6" : ((snprintf(buf, sizeof(buf), "%i", rp->ai_family) != 0) ? buf : "")), rp->ai_socktype, rp->ai_protocol); //set reuseaddr to avoid address in use (b/c if close_wait) when restarting ret = setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one)); if (ret != 0) debug_perror(0, "Could not set socket options: "); if (bind(sfd, rp->ai_addr, rp->ai_addrlen) == 0) break; /* Success */ debug_perror(0, "Could not bind to %s.", get_ip_str((struct sockaddr *)rp->ai_addr, buf, sizeof(buf))); close(sfd); } if (rp == NULL) { /* No address succeeded */ debug_perror(0, "All addresses in use"); exit(EXIT_FAILURE); } else debug(5, "Bind succeeded!"); freeaddrinfo(result); /* No longer needed */ listen_socket = sfd; int flags = 0; flags = fcntl(listen_socket, F_GETFL, 0); fcntl(listen_socket, F_SETFL, flags | O_NDELAY); /* specify queue */ ret = listen(listen_socket, SOMAXCONN); debug_assert(ret >= 0, "Could listen() listening socket"); }
/* nonblocking read on netwok -- returns msg if complete msg arrived */ rs232can_msg *cann_get_nb(cann_conn_t *client) { int ret; unsigned char val; // sanity if (client->error) { debug( 0, "cann_get_nb() with error %d on %d", client->error, client->fd); return NULL; } // XXX das alles geht auch einfacher XXX if (client->state == CANN_LEN) { ret = read(client->fd, &val, 1); if (ret == 0) goto eof; if (ret < 0) goto error; // check msg length if (val > sizeof(client->msg.data)) { debug( 2, "Protocol error on fd %d: message too big (size=%d)", client->fd, val ); client->error = 1; return NULL; } debug(10, "Next packet on %d: length=%d", client->fd, val); client->msg.len = val; client->missing_bytes = val; client->rcv_ptr = client->msg.data; client->state = CANN_CMD; } if (client->state == CANN_CMD) { ret = read(client->fd, &(client->msg.cmd), 1); if (ret == 0) goto eof; if (ret < 0) goto error; debug(10, "Next packet on %d: cmd=%d", client->fd, client->msg.cmd); client->state = CANN_PAYLOAD; } if (client->missing_bytes > 0) { // read data ret = read(client->fd, client->rcv_ptr, client->missing_bytes); if (ret == 0) goto eof; if (ret < 0) goto error; client->missing_bytes -= ret; client->rcv_ptr += ret; debug(10, "fd %d: recived %d bytes, %d missing", client->fd, ret, client->missing_bytes); } // message complete? if (client->missing_bytes == 0) { rs232can_msg *rmsg = malloc(sizeof(rs232can_msg)); if (rmsg == NULL) { debug(0, "Could not allocate rmsg buffer, exiting!\n"); exit(EXIT_FAILURE); } memcpy(rmsg, &(client->msg), sizeof(rs232can_msg)); client->state = CANN_LEN; return rmsg; } return NULL; error: if ((errno == EAGAIN) || (errno == 0)) return NULL; eof: debug_perror(5, "Error readig fd %d (ret==%d)", client->fd, ret); client->error = 1; return NULL; }