void spray(int s, const struct sockaddr *cli, int cli_len, const char *file_path, __u16 padding, unsigned int fr) { char *filename = basename(file_path); char *encoded_file_path; int size; int num_blocks; size = asprintf(&encoded_file_path, "%s/%s", ENCODED_DIR, filename); if (size == -1) { fprintf(stderr, "asprintf: cannot allocate encoded file path\n"); return; } /* Check if a directory for that name exists. */ if (!dir_exists(encoded_file_path)) { fprintf(stderr, "invalid request; %s encoding does not exist\n", filename); return; } num_blocks = get_num_blocks(filename); if (num_blocks == -1) { fprintf(stderr, "get_num_blocks: cannot find number of blocks\n"); return; } send_data_files(s, cli, cli_len, filename, num_blocks, padding, fr); send_code_files(s, cli, cli_len, filename, num_blocks, padding, fr); }
int main( int argc, char ** argv ) { /* Vars */ uint i, j, k; node block; /* check to make sure an input file was supplied */ /* get the number of blocks (the first line of input) */ /* I am just assuming that the input will always be */ /* correct since this is for a competition */ if( argc == 2) get_num_blocks(argv[1]); else exit(EXIT_FAILURE); /* Initialize the graph and cycles arrays */ /* The graph array is an incidence matrix */ /* if graph(i,j) is true, then there is a */ /* directed edge from i -> j */ for( i = 0; i < SIZE; ++i ) { for( j = 0; j < SIZE; ++j ) { graph[i][j] = NO_CONN; } } /* Get the input blocks */ for( i = 0; i < num_blocks; ++i ) { /* for each block... */ if( get_block( &block ) > 2 ) { /* if the block has more than 2 '00' terms then just skip it */ /* if the block has 3 or 4 sides with '00' terms then it */ /* cannot connect to anything so it doesn't matter */ continue; } /* else // block has less than 2 zeros */ /* if a block matches itself, then the structure is unbounded */ /* We wouldn't have to do this, but it is a simple enough check */ /* and as n -> 40,000 it can save a lot of time */ for( k = 0; k < 4; ++k ) { for( j = 0; j < 4; ++j ) { if( block[k*2] == block[j*2] && block[k*2+1] != block[j*2+1] ) goto unbounded; } } /* else // block does not match itself */ /* add links to the graph */ for( j = 0; j < 4; ++j ) { /* For each side... */ /* assume correct formatting so only need to test first block for if 0 */ if( block[j*2] == '0' ) { /* no links can be added */ continue; } else { for( k = 0; k < 4; ++k ) { /* for every other side on the block... */ if( j == k ) /* same side we are already on, so continue */ continue; else if( block[k*2] == '0' ) /* side is 00 so continue */ continue; /* else add link */ /* The basic idea for the links is, add a directed edge */ /* between the opposite of that side (i.d. opposite of */ /* P- is P+) to each of the other sides on the block. */ /* This is because if you can connect to the current */ /* side of the block (i.d. block[j*2]) then you will */ /* connect with the opposite of this block, and it will */ /* connect you to any of the other sides of the current */ /* block. */ /* The problem is actually pretty nice since you can */ /* rotate and reflect, the geometry of the block doesnt */ /* actually matter. */ if( block[j*2+1] == '+' ) graph[ NEGATIVE( block[j*2] ) ][ to_index( &block[k*2] ) ] = 1; /* else the block is negative */ else graph[ POSITIVE( block[j*2] ) ][ to_index( &block[k*2] ) ] = 1; } } } /* turn on __DEBUG__ if you want to see the graph */ print_graph(); } /* graph is all set up, just check for cycles */ if( traverse() ) goto unbounded; /* U mad bro? */ /* if we made it here then it is a bounded structure */ printf("bounded\n"); exit(EXIT_SUCCESS); unbounded: printf("unbounded\n"); exit(EXIT_SUCCESS); } /**~ end main ~**/