/* Handles a printf flag. Returns the number of chars printed */ int handle_flag(char** current_char, va_list args, int chars_printed) { char* to_print; char buf[256] = {0}; int printed = 0; int field_width = 0; char padding = ' '; (*current_char)++; if(!is_flag(**current_char)) { if(**current_char == '0') /* Handle 0 flag */ { (*current_char)++; padding = '0'; } char dig[10]; int i = 0; if(!is_flag(**current_char)) /* Handle width */ { while(!is_flag(**current_char)) { dig[i++] = **current_char; (*current_char)++; } field_width = atoi(dig); } } switch(**current_char) { case 'd': to_print = pad(itoa(va_arg(args, int), buf, 10), field_width, padding); printed += strlen(to_print); fputs(to_print, stdout); break; case 's': to_print = va_arg(args, char*); printed += strlen(to_print); fputs(to_print, stdout); break; case 'u': to_print = pad(itoa(va_arg(args, unsigned int), buf, 10), field_width, padding); printed += strlen(to_print); fputs(to_print, stdout); break; case 'c': putchar(va_arg(args, int)); printed++; break; case 'x': to_print = pad(itoa(va_arg(args, int), buf, 16), field_width, padding); printed += strlen(to_print); fputs(to_print, stdout); break; case '%': putchar('%'); printed++; break; case 'n': *(va_arg(args, int*)) = printed + chars_printed; break; } return printed; }
int main( int argc, char *argv[] ) { struct sockaddr_storage myaddr,remote; struct server_ctx ctx; int cli_fd, ret; socklen_t addrlen; char peer[INET6_ADDRSTRLEN]; void *ptr; if ( signal( SIGTERM, sighandler ) == SIG_ERR ) { fprintf(stderr, "Unable to set signal handler\n"); return EXIT_FAILURE; } if ( signal( SIGINT, sighandler ) == SIG_ERR ) { fprintf(stderr, "Unable to set signal handler\n"); return EXIT_FAILURE; } if ( signal( SIGPIPE, sighandler ) == SIG_ERR ) { fprintf(stderr, "Unable to set signal handler\n"); return EXIT_FAILURE; } memset( &ctx, 0, sizeof( ctx )); ctx.port = DEFAULT_PORT; ctx.recvbuf_size = RECVBUF_SIZE; partial_store_init(&ctx.partial); ret = parse_args( argc, argv, &ctx ); if ( ret < 0 ) { WARN("Error while parsing command line\n" ); return EXIT_FAILURE; } else if ( ret == 0 ) { return EXIT_SUCCESS; } memset( &myaddr, 0, sizeof( myaddr)); myaddr.ss_family = AF_INET6; if ( is_flag( ctx.options, SEQ_FLAG )) { DBG("Using SEQPKT socket\n"); ctx.sock = socket( PF_INET6, SOCK_SEQPACKET, IPPROTO_SCTP ); } else { DBG("Using STREAM socket\n"); ctx.sock = socket( PF_INET6, SOCK_STREAM, IPPROTO_SCTP ); } if ( ctx.sock < 0 ) { fprintf(stderr, "Unable to create socket: %s \n", strerror(errno)); return EXIT_FAILURE; } if (ctx.initmsg != NULL ) { TRACE("Requesting for %d output streams and at max %d input streams\n", ctx.initmsg->sinit_num_ostreams, ctx.initmsg->sinit_max_instreams); if (setsockopt( ctx.sock, SOL_SCTP, SCTP_INITMSG, ctx.initmsg, sizeof(*ctx.initmsg)) < 0) { fprintf(stderr,"Warning: unable to set the association parameters: %s\n", strerror(errno)); } } if ( bind_and_listen( &ctx ) < 0 ) { fprintf(stderr, "Error while initializing the server\n" ); close(ctx.sock); return EXIT_FAILURE; } if ( is_flag( ctx.options, VERBOSE_FLAG )) subscribe_to_events(ctx.sock); /* to err is not fatal */ memset( &remote, 0, sizeof(remote)); addrlen = sizeof( struct sockaddr_in6); TRACE("Allocating %d bytes for recv buffer \n", ctx.recvbuf_size ); ctx.recvbuf = mem_alloc( ctx.recvbuf_size * sizeof( uint8_t )); printf("Listening on port %d \n", ctx.port ); while ( !close_req ) { if ( is_flag( ctx.options, SEQ_FLAG ) ) { ret = do_server( &ctx, ctx.sock ); if ( ret == SERVER_ERROR ) break; } else { cli_fd = do_accept( &ctx, &remote, &addrlen ); if ( cli_fd < 0 ) { if ( errno == EINTR ) break; close( ctx.sock ); mem_free( ctx.recvbuf); WARN( "Error in accept!\n"); return EXIT_FAILURE; } else if ( cli_fd == 0 ) { break; } if ( remote.ss_family == AF_INET ) { ptr = &(((struct sockaddr_in *)&remote)->sin_addr); } else { ptr = &(((struct sockaddr_in6 *)&remote)->sin6_addr); } if ( inet_ntop(remote.ss_family, ptr, peer, INET6_ADDRSTRLEN ) != NULL ) { printf("Connection from %s \n", peer ); } else { printf("Connection from unknown\n"); } if( do_server( &ctx, cli_fd ) == SERVER_ERROR ) { close( cli_fd); break; } close( cli_fd ); } } mem_free( ctx.recvbuf); if (ctx.initmsg != NULL ) { mem_free( ctx.initmsg); } close( ctx.sock ); return EXIT_SUCCESS; }
void get_clustering(char * fname, int offset) { // read the clustering for sequences i to j // in the input file the sequence number will be give as 0..j-i FILE * cfn; char tmp[4095]; int res,curr,the_next,last,cnum,prev,validcurr; cfn = fopen(fname,"r"); if (cfn == NULL) { perror(fname); exit(1); } // Are we restoring from a checkpoint if (prog_opts.restore) { // first line of file will contain cnum=num_seqs; // round numbers. Find the min value for(res=1; res<numprocs; res++) { fscanf(cfn,"%d\n",&the_next); if(the_next<cnum) cnum = the_next; } prog_opts.restore= cnum; //printf("Restore value is %d",prog_opts.restore); } // Read the clusters do { res = fscanf(cfn, "%d", &cnum); cnum = cnum+offset; validcurr = cnum; if (res != 1) break; prev=cnum; while (fscanf(cfn, "%d", &curr)==1) { validcurr = curr+offset; tree[validcurr].cluster=cnum; tree[prev].next = validcurr; prev = validcurr; if (IS_FLAG(FIX,validcurr)) SET_FLAG(FIX,cnum); } tree[validcurr].next = -1; // now deal with resetting // find the first sequencein cluster that should NOT be reset // --- reset all sequences up to that point res = is_flag(RESET,cnum); for(curr=cnum; (curr != -1) && (is_flag(RESET,curr)); curr=the_next) { the_next = tree[curr].next; tree[curr].next=-1; tree[curr].rank=1; tree[curr].cluster=curr; tree[curr].last=curr; } prev=-1; cnum=last=curr; // Now find the last non-reset sequence for(curr=cnum; curr != -1; curr=tree[curr].next) last = curr; // Now go through the rest -- eithe reset or link up for(curr=cnum; curr != -1; curr=tree[curr].next) { if (IS_FLAG(RESET,curr)) { tree[curr].next=-1; tree[curr].rank=1; tree[curr].cluster=curr; tree[curr].last=curr; } else { // link up if (prev != -1) tree[prev].next = curr; tree[curr].cluster=cnum; tree[curr].last = last; tree[cnum].rank++; prev = curr; } } res = fscanf(cfn,"%[.]",tmp); assert(res==1); } while (1); }
/** * Server loop. * * Wait for incoming data from remote peer and if echo mode is on, echo it * back. * * @param ctx Pointer to main context. * @param fd The socket to the remote peer (in SOCK_STREAM mode) or the "server * socket" in SOCK_SEQPKT mode. * @return SERVER_USER_CLOSE if user requested stop (ctrl+c was pressed), * SERVER_ERROR if there was error when receiving data, SERVER_OK if the remote * end closed connetion. */ int do_server( struct server_ctx *ctx, int fd ) { struct sockaddr_storage peer_ss; socklen_t peerlen; struct sctp_sndrcvinfo info; int ret,flags; while( ! close_req ) { memset( &peer_ss, 0, sizeof( peer_ss )); memset( &info, 0, sizeof( peer_ss )); peerlen = sizeof( struct sockaddr_in6); flags = 0; ret = recv_wait( fd, ACCEPT_TIMEOUT_MS, ctx->recvbuf, ctx->recvbuf_size, (struct sockaddr *)&peer_ss, &peerlen, &info, &flags ); if ( ret == -1 ) { if ( errno == EINTR ) continue; print_error("Unable to read data", errno); return SERVER_ERROR; } else if ( ret == -2 ) { printf("Connection closed by remote host\n" ); return SERVER_REMOTE_CLOSED; } else if ( ret > 0 ) { DBG("Received %d bytes \n", ret ); partial_store_collect(&ctx->partial, ctx->recvbuf, ret); if ( flags & MSG_NOTIFICATION ) { TRACE("Received SCTP event\n"); if ( flags & MSG_EOR ) { handle_event(partial_store_dataptr(&ctx->partial)); partial_store_flush(&ctx->partial); } continue; } if (is_flag(ctx->options, VERBOSE_FLAG)) print_input( &peer_ss, ret, flags, &info); else print_input( &peer_ss, ret, flags, NULL); if (is_flag(ctx->options, XDUMP_FLAG)) xdump_data( stdout, ctx->recvbuf, ret, "Received data" ); if ( is_flag( ctx->options, ECHO_FLAG ) && (flags & MSG_EOR) ) { if ( sendit( fd, info.sinfo_ppid, info.sinfo_stream, (struct sockaddr *)&peer_ss, peerlen, partial_store_dataptr( &ctx->partial), partial_store_len( &ctx->partial) ) < 0) { WARN("Error while echoing data!\n"); } else { if (is_flag(ctx->options, VERBOSE_FLAG)) print_output_verbose(&peer_ss, partial_store_len(&ctx->partial), info.sinfo_ppid, info.sinfo_stream); else print_output( &peer_ss, partial_store_len(&ctx->partial)); } } if ( flags & MSG_EOR ) partial_store_flush( &ctx->partial ); } } return SERVER_USER_CLOSE; }