void prepare_generic_socket(int argc, char *argv[], int family, int flags, int type, int protocol) { struct addrinfo lookup_addr; memset(&lookup_addr, 0, sizeof(struct addrinfo)); lookup_addr.ai_family = family; lookup_addr.ai_flags = flags; lookup_addr.ai_socktype = type; lookup_addr.ai_protocol = protocol; if (getaddrinfo(NULL, argv[1], &lookup_addr, &listen_addr) != 0) { exit_with_error("getaddrinfo failed"); } sock = socket(listen_addr->ai_family, listen_addr->ai_socktype, listen_addr->ai_protocol); if (sock < 0) { exit_with_error("socket failed"); } if (bind(sock, listen_addr->ai_addr, listen_addr->ai_addrlen) < 0) { exit_with_error("bind failed"); } }
/** * get_todo - retrieve a single todo and send it in the response * * @client_socket: client socket to send information back to * @todo_list: todo list to search through * @id: ID of todo item we're searching for * * Return: 0 if success, else HTTP error code */ int get_todo(int client_socket, list_t *todo_list, int id) { char *ok_msg; int clen, l1, l2, l3, l4; list_t *walk; if (id == -1) return (404); for (walk = todo_list; walk != NULL; walk = walk->next) { if (walk->id == id) break; } if (walk == NULL) return (404); l1 = strlen("{\"id\":,\"title\":\"\",\"description\":\"\"}"); l2 = int_len(walk->id); l3 = strlen(walk->title); l4 = strlen(walk->description); clen = l1 + l2 + l3 + l4; ok_msg = malloc(clen + 72); if (ok_msg == NULL) exit_with_error("malloc() failed"); sprintf( ok_msg, "HTTP/1.1 200 OK\r\n" "Content-Length: %d\r\n" "Content-Type: application/json\r\n\r\n" "{\"id\":%d,\"title\":\"%s\",\"description\":\"%s\"}", clen, walk->id, walk->title, walk->description ); printf("200 OK\n"); if (send(client_socket, ok_msg, strlen(ok_msg), 0) < 0) exit_with_error("send() failed"); }
/** * post_todo_success - send the client back the proper response * * @todo_list: todo list holding (possibly) newly created data * @client_socket: socket fd of client */ void post_todo_success(list_t *todo_list, int client_socket) { char *ok_msg; int clen, l1, l2, l3, l4; l1 = strlen("{\"id\":,\"title\":\"\",\"description\":\"\"}"); l2 = int_len(todo_list->id); l3 = strlen(todo_list->title); l4 = strlen(todo_list->description); clen = l1 + l2 + l3 + l4; ok_msg = malloc(clen + 77); if (ok_msg == NULL) exit_with_error("malloc() failed"); sprintf( ok_msg, "HTTP/1.1 201 Created\r\n" "Content-Length: %d\r\n" "Content-Type: application/json\r\n\r\n" "{\"id\":%d,\"title\":\"%s\",\"description\":\"%s\"}", clen, todo_list->id, todo_list->title, todo_list->description ); printf("201 Created\n"); if (send(client_socket, ok_msg, strlen(ok_msg), 0) < 0) exit_with_error("send() failed"); }
int main(int argc, char *argv[]) { mode_t mask = umask(0); mode_t mode = 0777&~mask; int verboseflag = 0; int parentflag = 0; int option; int i; while ((option = getopt(argc, argv, "pvm:")) != -1) switch (option) { case 'm': mode = strtol(optarg,NULL,8); break; case 'p': parentflag = 1; break; case 'v': verboseflag = 1; break; case '?': exit(EXIT_FAILURE); default: abort (); // this shouldn't happen! } // Handle other command line arguments for (i = optind; i < argc; ++i) { errno = 0; if (parentflag) { /* Important: Don't delete *gargv until while loop * finishes, rest's content overlaps with it. */ struct Gstring rest; struct Gstring *gargv = togstring(argv[i]); struct Gstring *path_so_far = gstrtoken(gargv,"/",&rest); while(rest.length > 0) { struct Gstring *next_part; if(mkdir(path_so_far->content, mode) == -1 && errno != EEXIST) exit_with_error(argv[0], argv[i]); next_part = gstrtoken(&rest,"/",&rest); appendstr2gstring(path_so_far,"/"); combinegstr(path_so_far,next_part); } freegstring (gargv); freegstring (path_so_far); } if (mkdir(argv[i],mode) == -1) if (!parentflag || errno != EEXIST) exit_with_error(argv[0], argv[i]); if (verboseflag && errno != EEXIST) printf("%s created.\n",argv[i]); } return 0; }
char* str_malloc(size_t sz) { char* str; if ((str = (char*)malloc(sz)) == NULL) { exit_with_error("malloc failed", 2); } return str; }
void receive_tcp_clients(char *argv[]) { while (!stop) { struct sockaddr_storage client_addr; socklen_t addr_len = sizeof(struct sockaddr_storage); int client = accept(sock, (struct sockaddr *) &client_addr, &addr_len); if (stop) { break; } if (client < 0) { exit_with_error("accept failed"); } handle_tcp_client(client, argv); } }
int main(int argc, char* argv[]) { struct arg_struct arg_data; arg_data = handle_args(argc, argv); if (setup(arg_data.file_path)!=0) exit_with_error("Fail to setup"); if (setup(arg_data.file_path)!=0) exit_with_error("Fail to setup"); if (parse_pb()!=0) exit_with_error("Fail to parse_pb"); if (teardown()!=0) exit_with_error("Fail to teardown"); }
rtntype main(uint argc, char *argv[]) { FILE *fp = NULL; MYSQL *conn = NULL; MYSQL_RES *res = NULL; MYSQL_ROW row = NULL; uint num_fields = 0; schar sql[SQL_MAX_LEN]; schar error_type[ERR_STR_MAX_LEN]; char buf[READ_LENGTH_EACH_TIME + 1] = { 0 }; int read_times = 0; conn = mysql_init(NULL); if (conn == NULL) { exit_with_error(conn); } if (mysql_real_connect(conn, host_name, user_name, password, database, port, NULL, 0) == NULL) { exit_with_error(conn); } /* show databases */ strcpy(sql, "show databases;"); mysql_exe_query(conn, sql); show_all_select_results(conn); printf("Initializing data ......\n"); fp = fopen(english_char_source, "r"); read_times = 0; /* read times from file */ while (fp != EOF) { fread(buf, sizeof(char), READ_LENGTH_EACH_TIME, fp); printf("%s\n", buf); read_times++; if (read_times > READ_TOTAL_TIMES) { break; } } fclose(fp); mysql_close(conn); getchar(); EC_SUCCESS; }
void send_eoe(int socket, void *buffer, size_t size, int flags) { int bytes_sent; bytes_sent = send(socket, buffer, size, flags); if (bytes_sent != size) { exit_with_error("send() failed"); } }
void bind_eoe(int socket, struct sockaddr *addr, socklen_t length) { int success; success = bind (socket, addr, length); if (success < 0) { exit_with_error("bind() failed"); } }
int socket_eoe(int domain, int style, int protocol) { int ssocket; ssocket = socket(domain, style, protocol); if (ssocket < 0) { exit_with_error("socket() failed"); } return ssocket; }
int recv_eoe(int socket, void *buffer, size_t size, int flags) { int message_size; message_size = recv(socket, buffer, size, flags); if (message_size < 0) { exit_with_error("recv() failed"); } return message_size; }
void * write_last(size_t fd, re_buf_t *buf) { size_t r; if (buf->last > buf->start){ r = write(fd, buf->start, buf->last - buf->start); if(r == RE_ERROR){ exit_with_error("write fd error"); } buf->last = buf->start; } }
int accept_eoe (int socket, struct sockaddr *addr, socklen_t *length_ptr) { int client_socket; client_socket = accept(socket, addr, length_ptr); if (client_socket < 0) { exit_with_error("accept() failed"); } return client_socket; }
FILE* wave_open( long sample_rate, const char* filename ) { sample_count_ = 0; sample_rate_ = sample_rate; buf_pos = header_size; chan_count = 1; buf = (unsigned char*) malloc( buf_size * sizeof *buf ); if ( !buf ) exit_with_error( "Out of memory" ); if ( strcmp( filename, "-" ) == 0 ) file = tmpfile(); else file = fopen( filename, "wb" ); if ( !file ) exit_with_error( "Couldn't open WAVE file for writing" ); setvbuf( file, 0, _IOFBF, 32 * 1024L ); return file; }
int main(int argc, char *argv[]) { int rc = 0; struct arg_struct arg_data; arg_data = handle_args(argc, argv); struct metaparse__pb pbf_obj; struct mmbuf__obj out_obj; if (metaparse__setup(&pbf_obj, arg_data.pb_path, "r")!=0) exit_with_error("Fail to setup playback\n"); if (mmbuf__setup(&out_obj, arg_data.out_path, "w")!=0) exit_with_error("Fail to setup outfile\n"); if (test(&pbf_obj, &out_obj)!=0) exit_with_error("Fail to test\n"); if (mmbuf__teardown(&out_obj)!=0) exit_with_error("Fail to outfile\n"); if (metaparse__teardown(&pbf_obj)!=0) exit_with_error("Fail to teardown\n"); return rc; }
//this function sends a generic data buffer via tcp void send_tcp_data(FILE* rx, FILE *tx, void *data, int datalen) { if (tx) { size_t bytes_sent = fwrite(data, 1, datalen, tx); if (errno == EPIPE) { fclose(tx); fclose(rx); exit_with_error("pipe error\n"); } else if (bytes_sent < 0) { fclose(tx); fclose(rx); exit_with_error("send failed"); } fflush(tx); } else { sprint_hex((uint8_t *)data, datalen); } }
size_t write_buf(size_t fd, re_buf_t *buf, u_char *src, size_t len) { size_t r; if (buf->end - buf->last < len) { r = write(fd, buf->start, buf->last - buf->start); if(r == RE_ERROR){ return exit_with_error("write fd error"); } buf->last = buf->start; } re_cpybuf(buf->last, src, len); buf->last +=len; return RE_OK; }
void AliveCollection_c::report( std::ostream& out ) const { for (int i=0; i<256; i++) { for (Category_e categoryIter = categoryBegin; categoryIter != categoryEnd; categoryIter = nextCategory(categoryIter)) { const int32_t ci32_alivePeriod = alivePeriod(categoryIter); if (alives(categoryIter, static_cast<uint8_t>( i )).size()>0) { if (ci32_alivePeriod > 0) { // we have a periodic event! out << std::endl << "ISOBUS node with SA="<<std::hex<<i<<std::dec<<" had the following alive-times for ["<<name(categoryIter)<<"] with alive-periods of "<<alivePeriod(categoryIter)<<" ms:"<<std::endl; } else if (ci32_alivePeriod < 0) { // we have a handshaking event! out << std::endl << "ISOBUS node with SA="<<std::hex<<i<<std::dec<<" had the following alive-times for ["<<name(categoryIter)<<"] with alive-periods of "<<(-alivePeriod(categoryIter))<<" ms:"<<std::endl; } else { // single events!! "== 0" out << std::endl << "ISOBUS node with SA="<<std::hex<<i<<std::dec<<" sent out ["<<name(categoryIter)<<"] at the following times:"<<std::endl; } std::vector<std::pair<msgType_e,std::string> >::const_iterator type_iter=response(categoryIter, static_cast<uint8_t>( i ) ).begin(); for (std::vector<uint64_t>::const_iterator iter=alives(categoryIter, static_cast<uint8_t>( i )).begin(); iter != alives(categoryIter, static_cast<uint8_t>( i )).end(); iter++) { out << std::setfill (' '); out << "absolute time: "<<std::setw(10)<<(*iter/1000)<<"."<<std::setw(3)<<std::setfill('0')<<(*iter%1000)<<std::setfill(' '); if (iter != alives(categoryIter, static_cast<uint8_t>( i )).begin()) { const uint64_t cui32_delta = ( *(iter) - *(iter-1) ); out<< " relative time: "<<std::setw(10)<<cui32_delta; if (ci32_alivePeriod > 0) { // print out the alivePeriod-deviation! out<<" deviation: "; int deviation = int ((double (int32_t (cui32_delta)-ci32_alivePeriod) / ci32_alivePeriod) * 100); uint8_t deviation_bias = (deviation > 0) ? '+' : '-'; deviation = (deviation < 0) ? -deviation : deviation; if (deviation > 100) { out << "EXTREME DEVIATION(!!) OF " << std::setw(10) << deviation << "0"; } else { while (deviation > 10) { out << deviation_bias; deviation -= 10; } } } else if (ci32_alivePeriod < 0) { // Handshaking if (type_iter == response(categoryIter,static_cast<uint8_t>( i )).end()) exit_with_error("No direction/msgType set but is expected. System failure."); int32_t i32_alivePeriodSpecial; switch ((*type_iter).first) { case msgTypeResponse: out << " Response "; i32_alivePeriodSpecial = -ci32_alivePeriod; break; case msgTypeCommand: out << " Command "; i32_alivePeriodSpecial = 0; break; // no timing-requirement here! case msgTypeRTS: out << " (E)TP-CONN: Request to Send (RTS) "; i32_alivePeriodSpecial = 0; break; // no timing-requirement here! case msgTypeCTS: out << " (E)TP-CONN: Clear to Send (CTS) "; i32_alivePeriodSpecial = 1250; break; case msgTypeDPO: out << " (E)TP-CONN: Data Packet Offset (DPO) "; i32_alivePeriodSpecial = 1250; break; /// @todo SOON-260: set the correct values here! case msgTypeEOMACK: out << " (E)TP-CONN: End of Message ACK (EoMACK) "; i32_alivePeriodSpecial = 1250; break; case msgTypeDATA: out << " (E)TP-DATA "; i32_alivePeriodSpecial = 250; break; case msgTypeCONNABORT: out << " (E)TP-CONN: Connection Abort (CONNABORT) "; i32_alivePeriodSpecial = -1; break; // doesn't come normally! case msgTypeSetpoint: out << " (TC->Client) Setpoint "; i32_alivePeriodSpecial = 0; break; case msgTypeMeasurement:out << " (Client->TC) Measrmnt "; i32_alivePeriodSpecial = 0; break; default: out << " ??? "; i32_alivePeriodSpecial = 0; break; } if ( ((*type_iter).first == msgTypeResponse) && ((*(type_iter-1)).first == msgTypeResponse) ) out << " - RESPONSE FOLLOWING A RESPONSE! (check if there was a TP command though)"; if ( ((*type_iter).first == msgTypeCommand) && ((*(type_iter-1)).first == msgTypeCommand) ) out << " - COMMAND FOLLOWING A COMMAND! (check if there was a TP response though)"; if (i32_alivePeriodSpecial > 0) { // print out the time it took! if (cui32_delta > (unsigned int) (i32_alivePeriodSpecial)) out << " *** !!! TIMEOUT - Check relative time!!!! ***"; else { int32_t time = int32_t ((cui32_delta*100) / i32_alivePeriodSpecial); out <<std::setw(2)<<time<< " percent of timeout ("<<std::setw(4)<<i32_alivePeriodSpecial<<"): (one '%' shows 10%) "; while (time > 10) { out << "%"; time -= 10; } } } else if (i32_alivePeriodSpecial < 0) { // unsolicited messages (like CONNABORT) out << "*** UNEXPECTED/UNSOLICITED MESSAGE ***"; } out << (*type_iter).second; } } out << std::endl; if (type_iter != response(categoryIter, static_cast<uint8_t>( i )).end()) ++type_iter; } } } } }
// Establish a connection to the server void connect_eoe(int sock, struct sockaddr *addr, int size) { if (connect(sock, addr, size) < 0) { exit_with_error("connect() failed"); } }
int main(int argc, char *argv[]) { int c, index; double dist = 0.0; int finish = -1, pace = -1; double finishd = -1.0, paced = -1.0; int mode = MODE_NONE; while ((c = getopt_long(argc, argv, "hd:f:p:", options, &index)) != -1) { switch (c) { case 'h': print_help(); return 0; case 'd': if (strcmp("h", optarg) == 0) dist = DIST_HALF; else if (strcmp("f", optarg) == 0) dist = DIST_FULL; else dist = atof(optarg); break; case 'f': finish = str_to_time(optarg); mode = mode | MODE_FTOP; break; case 'p': pace = str_to_time(optarg); mode = mode | MODE_PTOF; break; default: break; } } /* main proc */ /* more than 1 mode are on */ if (1 < countbits(mode)) exit_with_error("Selected more than 1 mode."); /* calc and prepare result */ char finish_str[128], pace_str[128]; if (mode == MODE_FTOP) { paced = (double)finish / dist; dtime_to_str(paced, pace_str); time_to_str(finish, finish_str); } else if (mode == MODE_PTOF) { finishd = (double)pace * dist; time_to_str(pace, pace_str); dtime_to_str(finishd, finish_str); } /* disp results */ cout << "Results:" << endl; cout << " mode " << mode_str[mode] << endl; cout << " dist " << dist << " km" << endl; cout << " finish-time " << finish_str << endl; cout << " pace-time " << pace_str << " /km" << endl; return 0; }
/* Start listening on the socket. If there is an error, exit the * program.*/ void listen_eoe(int socket, int n) { if (listen(socket, n) < 0) { exit_with_error("listen() failed"); } }
static void flush_() { if ( buf_pos && !fwrite( buf, buf_pos, 1, file ) ) exit_with_error( "Couldn't write WAVE data" ); buf_pos = 0; }
int main(int argc, const char **argv) { size_t in_size = 0, enc_bytes, rgb_bytes; ssize_t written; struct RGB_Info ri; srt_string *iobuf = NULL, *rgb_buf = NULL; int exit_code = 1; FILE *fin = NULL, *fout = NULL; const char *exit_msg = "not enough parameters"; int filter = F_None; enum ImgTypes t_in, t_out; srt_bool ro; #define IMGC_XTEST(test, m, c) \ if (test) { \ exit_msg = m; \ exit_code = c; \ break; \ } for (;;) { if (argc < 2) break; if (argc > 3) { filter = atoi(argv[3]); IMGC_XTEST(filter >= F_NumElems, "invalid filter", 10); } ro = argc < 3 ? S_TRUE : S_FALSE; t_in = file_type(argv[1]); t_out = ro ? IMG_none : file_type(argv[2]); IMGC_XTEST(t_in == IMG_error || t_out == IMG_error, "invalid parameters", t_in == IMG_error ? 2 : 3); fin = fopen(argv[1], "rb"); iobuf = ss_dup_read(fin, MAX_FILE_SIZE); in_size = ss_size(iobuf); IMGC_XTEST(!in_size, "input read error", 4); rgb_bytes = any2rgb(&rgb_buf, &ri, iobuf, t_in); IMGC_XTEST(!rgb_bytes, "can not process input file", 5); if (ro) printf("%s: ", argv[1]); enc_bytes = rgb2type(&iobuf, t_out, rgb_buf, &ri, filter); IMGC_XTEST(!enc_bytes, "output file encoding error", 6); fout = fopen(argv[2], "wb+"); written = ro ? 0 : ss_write(fout, iobuf, 0, ss_size(iobuf)); IMGC_XTEST(!ro && (written < 0 || (size_t)written != ss_size(iobuf)), "write error", 7); exit_code = 0; if (!ro) IF_DEBUG_IMGC(fprintf( stderr, "%s (%ix%i %ibpp %ich) %u bytes" " > %s %u bytes\n", argv[1], (int)ri.width, (int)ri.height, (int)ri.bpp, (int)ri.chn, (unsigned)in_size, argv[2], (unsigned)ss_size(iobuf))); break; } #ifdef S_USE_VA_ARGS ss_free(&iobuf, &rgb_buf); #else ss_free(&iobuf); ss_free(&rgb_buf); #endif if (fin) fclose(fin); if (fout) fclose(fout); return exit_code ? exit_with_error(argv, exit_msg, exit_code) : 0; }
int main(int argc, const char **argv) { size_t in_size = 0, enc_bytes, rgb1_bytes, rgb2_bytes; ssize_t written; struct RGB_Info ri1, ri2; srt_string *iobuf = NULL, *rgb1_buf = NULL, *rgb2_buf = NULL, *rgb3_buf = NULL; int exit_code = 2; FILE *fin = NULL, *fout = NULL; const char *exit_msg = "not enough parameters"; srt_bool ro; enum ImgTypes t_in1, t_in2, t_out; #define IMGC_XTEST(test, m, c) \ if (test) { \ exit_msg = m; \ exit_code = c; \ break; \ } for (;;) { if (argc < 2) break; ro = argc < 3 ? S_TRUE : S_FALSE; t_in1 = file_type(argv[1]); t_in2 = file_type(argv[2]); t_out = argc < 4 ? IMG_none : file_type(argv[3]); IMGC_XTEST(t_in1 == IMG_error || t_in2 == IMG_error || t_out == IMG_error, "invalid parameters", t_in1 == IMG_error || t_in2 == IMG_error ? 3 : 4); fin = fopen(argv[1], "rb"); iobuf = ss_dup_read(fin, MAX_FILE_SIZE); in_size = ss_size(iobuf); IMGC_XTEST(!in_size, "input #1 read error", 5); rgb1_bytes = any2rgb(&rgb1_buf, &ri1, iobuf, t_in1); IMGC_XTEST(!rgb1_bytes, "can not process input file #1", 6); fclose(fin); fin = fopen(argv[2], "rb"); ss_read(&iobuf, fin, MAX_FILE_SIZE); in_size = ss_size(iobuf); IMGC_XTEST(!in_size, "input #2 read error", 7); rgb2_bytes = any2rgb(&rgb2_buf, &ri2, iobuf, t_in2); IMGC_XTEST(!rgb2_bytes, "can not process input file #2", 8); IMGC_XTEST(ss_size(rgb1_buf) != ss_size(rgb2_buf), "can not process input file #2", 9); exit_code = rgbdiff(&rgb3_buf, rgb1_buf, &ri1, rgb2_buf, &ri2) ? 1 : 0; if (exit_code == 1) fprintf(stderr, "Image files %s and %s differ\n", argv[1], argv[2]); if (t_out != IMG_none) { enc_bytes = rgb2type(&iobuf, t_out, rgb3_buf, &ri1, F_None); IMGC_XTEST(!enc_bytes, "output file encoding error", 10); fout = fopen(argv[3], "wb+"); written = ss_write(fout, iobuf, 0, ss_size(iobuf)); IMGC_XTEST(!ro && (written < 0 || (size_t)written != ss_size(iobuf)), "write error", 11); } break; } #ifdef S_USE_VA_ARGS ss_free(&iobuf, &rgb1_buf, &rgb2_buf, &rgb3_buf); #else ss_free(&iobuf); ss_free(&rgb1_buf); ss_free(&rgb2_buf); ss_free(&rgb3_buf); #endif if (fin) fclose(fin); if (fout) fclose(fout); return exit_code > 1 ? exit_with_error(argv, exit_msg, exit_code) : 0; }
int main (int argc, char** argv) { int opt = 0; const char* short_options = "hrb:"; const struct option long_options[] = { { "help", no_argument, NULL, 'h' }, { "recursive", no_argument, NULL, 'r' }, { "block-size", required_argument, NULL, 'b' }, { NULL, no_argument, NULL, 0 } }; do { opt = getopt_long(argc, argv, short_options, long_options, NULL); //printf("optarg: %s\n", optarg); switch (opt) { case 'r': arg_found = true; recursive = true; break; case 'b': arg_found = true; block_size = optarg ? (atoi(optarg) > 0 ? atoi(optarg) : DEFAULT_BLOCK_SIZE) : DEFAULT_BLOCK_SIZE; break; case 'h': print_help(true); return 0; break; default: if (argc == 1) { print_help(false); return -1; } } } while (opt != -1); if (argc >= 3) { sprintf(inputpath, "%s", argv[argc-1]); sprintf(outputpath, "%s", argv[argc-2]); } if (!(strlen(inputpath) && strlen(outputpath))) exit_with_error("No paths."); struct stat filestat; if (stat(inputpath, &filestat) < 0) exit_with_error("Not a valid input path."); if (stat(outputpath, &filestat) < 0) exit_with_error("Not a valid output path."); // Start ncurses here init_nc(); for (int i = 1; i < 80; ++i) { mvwprintw (my_window, 2, i, "=>"); wrefresh(my_window); usleep(1000 * 10); } refresh(); getchar(); return 0; }
int main(int argc, char **argv) { // Misc temporary variables int i, j, k, l, ch, want_by_default, should_do, new_number, empty, temp_int; off_t offset,con_len; time_t rawtime; struct tm *ptm; char *temp_str = NULL; char *temp_str2 = NULL; char *tok_str = NULL; int steps = 6; int cur_step = 1; int delete_needed = 0; int to_file = 1; // Variables to help analyze user input int in = 0; int out = 0; int incl = 0; int excl = 0; int drop = 0; int redef = 0; // Variables related to files and paths FILE *infile = NULL; FILE *outfile = NULL; FILE *messages = stdout; char **include = NULL; // Holds the paths the user wants to keep char **exclude = NULL; // Holds the paths the user wants to discard char **mustkeep = NULL; // For storing the paths the user wants to discard, but must be kept char **relevant_paths = NULL; char **no_longer_relevant = NULL; char *redefined_root = NULL; // Variables to hold the size of 2D pseudoarrays int inc_len = 0; int exc_len = 0; int must_len = 0; int rel_len = 0; int no_len = 0; int cur_len = 0; int cur_max = 80; // File reading & writing variables char *current_line; if ((current_line = (char*)calloc(cur_max, 1)) == NULL) { exit_with_error("calloc failed", 2); } int reading_node = 0; int writing = 1; int toggle = 0; // Variables related to revisions and nodes int drop_empty = 0; int rev_len = -1; int rev_max = 10; int rev = -1; revision *revisions; if ((revisions = (revision*)malloc(rev_max * sizeof(revision))) == NULL) { exit_with_error("malloc failed", 2); } int nod_len = -1; int nod = -1; node *current_node = NULL; // Analyze the given parameters for (i = 1 ; i < argc ; ++i) { if (starts_with(argv[i], "-")) { if (strcmp(argv[i], "--help") == 0 || strcmp(argv[i], "-h") == 0) { free(current_line); free(revisions); free(include); free(exclude); show_help_and_exit(); } in = (!strcmp(argv[i], "--infile") || !strcmp(argv[i], "-i")); out = (!strcmp(argv[i], "--outfile") || !strcmp(argv[i], "-o")); incl = (!strcmp(argv[i], "--include") || !strcmp(argv[i], "-n")); excl = (!strcmp(argv[i], "--exclude") || !strcmp(argv[i], "-e")); drop = (!strcmp(argv[i], "--drop-empty") || !strcmp(argv[i], "-d")); redef = (!strcmp(argv[i], "--redefine-root") || !strcmp(argv[i], "-r")); if (!(in || out || incl || excl || drop || redef)) { exit_with_error(strcat(argv[i], " is not a valid parameter. Use -h for help."), 1); } else if (drop) { drop_empty = 1; steps = 7; } } else if (in && infile == NULL) { infile = fopen(argv[i],"rb"); if (infile == NULL) { exit_with_error(strcat(argv[i], " can not be opened as infile") , 3); } } else if (out && outfile == NULL) { outfile = fopen(argv[i],"wb"); if (outfile == NULL) { exit_with_error(strcat(argv[i], " can not be opened as outfile") , 3); } } else if (incl) { if ((include = (char**)realloc(include, (inc_len + 1) * sizeof(char*))) == NULL) { exit_with_error("realloc failed", 2); } // Allow the user to escape a directory in the repository root, that starts with a // hyphen, using a slash. if (starts_with(argv[i], "/")) { include[inc_len] = &argv[i][1]; } else { include[inc_len] = argv[i]; } ++inc_len; } else if (excl) { if ((exclude = (char**)realloc(exclude, (exc_len + 1) * sizeof(char*))) == NULL) { exit_with_error("realloc failed", 2); } if (starts_with(argv[i], "/")) { exclude[exc_len] = &argv[i][1]; } else { exclude[exc_len] = argv[i]; } ++exc_len; } else if (redef && redefined_root == NULL) { redefined_root = argv[i]; } else { exit_with_error(strcat(argv[i], " is not a valid parameter. Use -h for help."), 1); } } if (infile == NULL) { exit_with_error("You must specify an infile", 1); } if (outfile == NULL) { to_file = 0; outfile = stdout; messages = stderr; } if (include == NULL && exclude == NULL) { fclose(infile); if (to_file) { fclose(outfile); } exit_with_error("You must specify something to either include or exclude", 1); } if (include != NULL && exclude != NULL) { fclose(infile); if (to_file) { fclose(outfile); } exit_with_error("You may not specify both includes and excludes", 1); } if (exclude != NULL && redefined_root != NULL) { fclose(infile); if (to_file) { fclose(outfile); } exit_with_error("You may not redefine root when using excludes", 1); } if (redefined_root != NULL) { temp_str = str_malloc(strlen(redefined_root) + 2); strcpy(temp_str, redefined_root); strcat(temp_str, "/"); for (i = 0; i < inc_len; ++i) { if (!(strcmp(include[i], redefined_root) == 0 || starts_with(include[i], temp_str))) { fclose(infile); if (outfile != NULL) { fclose(outfile); } strcat(redefined_root, " can not be redefined as root for include "); exit_with_error(strcat(redefined_root, include[i]), 1); } } free(temp_str); } want_by_default = (include == NULL); fprintf(messages, "Step %d/%d: Reading the infile... ", cur_step, steps); fflush(messages); ++cur_step; // Read the metadata from all nodes. while ((ch = fgetc(infile)) != EOF) { // Once we reach a newline character we need to analyze the data. if (ch == NEWLINE) { // Data inside nodes needs special treatment. if (reading_node) { // An empty line while reading a node, means the node stops here. if (strlen(current_line) == 0) { reading_node = 0; } // A line starting with "Content-lenth: " means that the content // of the node is the only thing left of it. else if (starts_with(current_line,"Content-length: ")) { // The content is irrelevant (and might mess things up). Skip it. fseeko(infile, (off_t)atol(¤t_line[16]) + CONTENT_PADDING, SEEK_CUR); reading_node = 0; } else if (starts_with(current_line,"Node-action: ")) { if (strcmp(¤t_line[13],"add") == 0) { current_node[nod_len].action = ADD; } else if (strcmp(¤t_line[13],"delete") == 0) { current_node[nod_len].action = DELETE; } else if (strcmp(¤t_line[13],"change") == 0) { current_node[nod_len].action = CHANGE; } else { current_node[nod_len].action = REPLACE; } } else if (starts_with(current_line,"Node-copyfrom-path: ")) { current_node[nod_len].copyfrom = str_malloc(strlen(¤t_line[19])); strcpy(current_node[nod_len].copyfrom, ¤t_line[20]); } } // End of "if (reading_node)" else if (starts_with(current_line,"Node-path: ")) { ++nod_len; ++revisions[rev_len].size; if (nod_len == 0) { if ((current_node = (node*)malloc(sizeof(node))) == NULL) { exit_with_error("malloc failed", 2); } } else if ((current_node = (node*)realloc(current_node, (nod_len + 1) * sizeof(node))) == NULL) { exit_with_error("realloc failed", 2); } current_node[nod_len].path = str_malloc(strlen(¤t_line[10])); strcpy(current_node[nod_len].path, ¤t_line[11]); current_node[nod_len].copyfrom = NULL; current_node[nod_len].wanted = want_by_default; reading_node = 1; } else if (starts_with(current_line,"Revision-number: ")) { if (rev_len >= 0) { revisions[rev_len].nodes = current_node; } ++rev_len; if (rev_len == rev_max) { rev_max += INCREMENT; if ((revisions = (revision*)realloc(revisions, (rev_max * sizeof(revision)))) == NULL) { exit_with_error("realloc failed", 2); } } current_node = NULL; revisions[rev_len].nodes = NULL; revisions[rev_len].size = 0; revisions[rev_len].number = -1; nod_len = -1; } current_line[0] = '\0'; cur_len = 0; } // End of "if (ch != NEWLINE)" else { if (cur_len == cur_max - 1) { cur_max += INCREMENT; if ((current_line = (char*)realloc(current_line, cur_max)) == NULL) { exit_with_error("realloc failed", 2); } } current_line[cur_len] = ch; ++cur_len; current_line[cur_len] = '\0'; } } // End of "while ((ch = fgetc(infile)) != EOF)" if (rev_len >= 0) { revisions[rev_len].nodes = current_node; } ++rev_len; current_line[0] = '\0'; cur_len = 0; fprintf(messages, "OK\nStep %d/%d: Removing unwanted nodes... ", cur_step, steps); fflush(messages); ++cur_step; // Analyze the metadata in order to decide which nodes to keep. // If the user specified excludes, mark nodes in the exclude paths as unwanted. // (By default all nodes are wanted when using excludes.) if (exclude != NULL) { for (i = rev_len - 1; i >= 0; --i) { for (j = 0; j < revisions[i].size; ++j) { for (k = 0; k < exc_len; ++k) { temp_str = str_malloc(strlen(exclude[k]) + 2); strcpy(temp_str, exclude[k]); strcat(temp_str, "/"); if (strcmp(revisions[i].nodes[j].path, exclude[k]) == 0 || starts_with(revisions[i].nodes[j].path, temp_str)) { revisions[i].nodes[j].wanted = 0; } free(temp_str); } // Check whether the node has been marked as a "must keep". Keep it if it has. for (k = 0; k < must_len; ++k) { if ((temp_str = (char*)calloc(strlen(mustkeep[k]) + 2, 1)) == NULL) { exit_with_error("calloc failed", 2); } temp_str2 = str_malloc(strlen(mustkeep[k]) + 1); strcpy(temp_str2, mustkeep[k]); tok_str = strtok(temp_str2, "/"); while (tok_str != NULL) { strcat(temp_str,tok_str); if (strcmp(revisions[i].nodes[j].path, temp_str) == 0) { revisions[i].nodes[j].wanted = 1; } strcat(temp_str,"/"); tok_str = strtok(NULL, "/"); } if (starts_with(revisions[i].nodes[j].path, temp_str)) { revisions[i].nodes[j].wanted = 1; } free(temp_str); free(temp_str2); } // Check whether the path should be added as a "must keep". if (revisions[i].nodes[j].wanted && revisions[i].nodes[j].copyfrom != NULL) { should_do = 0; for (k = 0; k < exc_len; ++k) { temp_str = str_malloc(strlen(exclude[k]) + 2); strcpy(temp_str, exclude[k]); strcat(temp_str, "/"); if (strcmp(revisions[i].nodes[j].copyfrom, exclude[k]) == 0 || starts_with(revisions[i].nodes[j].copyfrom, temp_str)) { should_do = 1; } free(temp_str); } if (should_do) { if ((mustkeep = (char**)realloc(mustkeep, (must_len + 1) * sizeof(char*))) == NULL) { exit_with_error("realloc failed", 2); } mustkeep[must_len] = str_malloc(strlen(revisions[i].nodes[j].copyfrom) + 1); strcpy(mustkeep[must_len], revisions[i].nodes[j].copyfrom); ++must_len; } } } } } // If the user specified includes, mark nodes in the include paths as wanted. // (By default all nodes are unwanted when using includes.) else { for (i = rev_len - 1; i >= 0; --i) { for (j = 0 ; j < revisions[i].size ; ++j) { for (k = 0; k < inc_len; ++k) { temp_str = str_malloc(strlen(include[k]) + 2); strcpy(temp_str, include[k]); strcat(temp_str, "/"); temp_str2 = str_malloc(strlen(revisions[i].nodes[j].path) + 2); strcpy(temp_str2, revisions[i].nodes[j].path); strcat(temp_str2, "/"); if (strcmp(revisions[i].nodes[j].path, include[k]) == 0 || starts_with(revisions[i].nodes[j].path, temp_str) || starts_with(include[k], temp_str2)) { revisions[i].nodes[j].wanted = 1; } free(temp_str); free(temp_str2); } // Check whether the node has been marked as a "must keep". for (k = 0; k < must_len; ++k) { if ((temp_str = (char*)calloc(strlen(mustkeep[k]) + 2, 1)) == NULL) { exit_with_error("calloc failed", 2); } temp_str2 = str_malloc(strlen(mustkeep[k]) + 1); strcpy(temp_str2, mustkeep[k]); tok_str = strtok(temp_str2, "/"); while (tok_str != NULL) { strcat(temp_str,tok_str); if (strcmp(revisions[i].nodes[j].path, temp_str) == 0) { revisions[i].nodes[j].wanted = 1; } strcat(temp_str,"/"); tok_str = strtok(NULL, "/"); } if (starts_with(revisions[i].nodes[j].path, temp_str)) { revisions[i].nodes[j].wanted = 1; } free(temp_str); free(temp_str2); } // Check whether the path should be added as a "must keep". if (revisions[i].nodes[j].wanted && revisions[i].nodes[j].copyfrom != NULL) { should_do = 1; for (k = 0; k < inc_len; ++k) { temp_str = str_malloc(strlen(include[k]) + 2); strcpy(temp_str, include[k]); strcat(temp_str, "/"); if (strcmp(revisions[i].nodes[j].copyfrom, include[k]) == 0 || starts_with(revisions[i].nodes[j].copyfrom, temp_str)) { should_do = 0; } free(temp_str); } if (should_do) { if ((mustkeep = (char**)realloc(mustkeep, (must_len + 1) * sizeof(char*))) == NULL) { exit_with_error("realloc failed", 2); } mustkeep[must_len] = str_malloc(strlen(revisions[i].nodes[j].copyfrom) + 1); strcpy(mustkeep[must_len], revisions[i].nodes[j].copyfrom); ++must_len; } } } } } fprintf(messages, "OK\nStep %d/%d: Bringing back necessary delete operations... ", cur_step, steps); fflush(messages); ++cur_step; // Parse through the metadata again - this time bringing back any // possible delete instructions for the nodes we were forced to keep // but actually don't want any more. for (i = 0; i < rev_len; ++i) { for (j = 0; j < revisions[i].size; ++j) { if (revisions[i].nodes[j].wanted && revisions[i].nodes[j].action != DELETE) { should_do = 1; for (k = 0; k < rel_len; ++k) { if (relevant_paths[k] != NULL && strcmp(revisions[i].nodes[j].path, relevant_paths[k]) == 0) { should_do = 0; } } if (should_do) { if ((relevant_paths = (char**)realloc(relevant_paths, (rel_len + 1) * sizeof(char*))) == NULL) { exit_with_error("realloc failed", 2); } relevant_paths[rel_len] = str_malloc(strlen(revisions[i].nodes[j].path) + 1); strcpy(relevant_paths[rel_len], revisions[i].nodes[j].path); ++rel_len; } } if (revisions[i].nodes[j].action == DELETE) { for (k = 0; k < rel_len; ++k) { if (relevant_paths[k] != NULL && strcmp(revisions[i].nodes[j].path, relevant_paths[k]) == 0) { revisions[i].nodes[j].wanted = 1; for (l = 0; l < rel_len; ++l) { temp_str = str_malloc(strlen(revisions[i].nodes[j].path) + 2); strcpy(temp_str, revisions[i].nodes[j].path); strcat(temp_str, "/"); if (relevant_paths[l] != NULL && (strcmp(relevant_paths[l], revisions[i].nodes[j].path) == 0 || starts_with(relevant_paths[l], temp_str))) { free(relevant_paths[l]); relevant_paths[l] = NULL; } free(temp_str); } } } } } } fprintf(messages, "OK\nStep %d/%d: Identifying lingering unwanted nodes... ", cur_step, steps); fflush(messages); ++cur_step; // Find paths which are not relevant as specified by the user, but still lingers // due to dependency includes. (So that we can deal with them later.) for (i = 0; i < rel_len; ++i) { if (include == NULL && relevant_paths[i] != NULL) { for (j = 0; j < exc_len; ++j) { temp_str = str_malloc(strlen(exclude[j]) + 2); strcpy(temp_str, exclude[j]); strcat(temp_str, "/"); if (strcmp(relevant_paths[i], exclude[j]) == 0 || starts_with(relevant_paths[i], temp_str)) { if ((no_longer_relevant = (char**)realloc(no_longer_relevant, (no_len + 1) * sizeof(char*))) == NULL) { exit_with_error("realloc failed", 2); } no_longer_relevant[no_len] = str_malloc(strlen(relevant_paths[i]) + 1); strcpy(no_longer_relevant[no_len], relevant_paths[i]); ++no_len; } free(temp_str); } } else if (exclude == NULL && relevant_paths[i] != NULL) { temp_str = str_malloc(strlen(relevant_paths[i]) + 2); strcpy(temp_str, relevant_paths[i]); strcat(temp_str, "/"); for (j = 0; j < inc_len; ++j) { temp_str2 = str_malloc(strlen(include[j]) + 2); strcpy(temp_str2, include[j]); strcat(temp_str2, "/"); if (!(strcmp(relevant_paths[i], include[j]) == 0 || starts_with(relevant_paths[i], temp_str2) || starts_with(include[j], temp_str))) { if ((no_longer_relevant = (char**)realloc(no_longer_relevant, (no_len + 1) * sizeof(char*))) == NULL) { exit_with_error("realloc failed", 2); } no_longer_relevant[no_len] = str_malloc(strlen(relevant_paths[i]) + 1); strcpy(no_longer_relevant[no_len], relevant_paths[i]); ++no_len; } free(temp_str2); } free(temp_str); } } // Check that we don't have anything specifically included in our "no_longer_relevant"-section. for (i = 0; i < no_len; ++i) { if (no_longer_relevant[i] != NULL) { for (j = 0; j < inc_len ; ++j) { temp_str = str_malloc(strlen(include[j]) + 2); strcpy(temp_str, include[j]); strcat(temp_str, "/"); if (strcmp(no_longer_relevant[i], include[j]) == 0 || starts_with(no_longer_relevant[i], temp_str)) { free(no_longer_relevant[i]); no_longer_relevant[i] = NULL; break; } free(temp_str); } } } // Remove any directory entries that should no longer exist with the redefined root if (redefined_root != NULL) { for (i = 0; i < rev_len ; ++i) { for (j = 0; j < revisions[i].size; ++j) { if (revisions[i].nodes[j].wanted) { temp_str = str_malloc(strlen(redefined_root) + 2); strcpy(temp_str, redefined_root); strcat(temp_str, "/"); for (k = strlen(temp_str) - 1; k > 0; --k) { if (temp_str[k] == '/') { temp_str[k] = '\0'; if (strcmp(temp_str, revisions[i].nodes[j].path) == 0) { revisions[i].nodes[j].wanted = 0; for (l = 0; l < no_len; ++l) { if (strcmp(revisions[i].nodes[j].path, no_longer_relevant[l]) == 0) { free(no_longer_relevant[l]); no_longer_relevant[l] = NULL; } } } } } free(temp_str); } } } // Reduce the paths of deletion candidates, so that we delete the correct paths for (i = 0; i < no_len; ++i) { if (no_longer_relevant[i] != NULL) { temp_str = reduce_path(redefined_root, no_longer_relevant[i]); strcpy(no_longer_relevant[i], temp_str); free(temp_str); } } } // Remove redundant entries (i.e. delete only "trunk" instead of "trunk", "trunk/foo", "trunk/bar", et.c.) for (i = 0; i < no_len; ++i) { if (no_longer_relevant[i] != NULL) { delete_needed = 1; temp_str = str_malloc(strlen(no_longer_relevant[i]) + 2); strcpy(temp_str, no_longer_relevant[i]); strcat(temp_str, "/"); for (j = 0; j < no_len; ++j) { if (i != j && no_longer_relevant[j] != NULL && (starts_with(no_longer_relevant[j], temp_str) || strcmp(no_longer_relevant[i], no_longer_relevant[j]) == 0)) { free(no_longer_relevant[j]); no_longer_relevant[j] = NULL; } } for (j = 0; j < inc_len ; ++j) { if (strcmp(no_longer_relevant[i], include[j]) == 0 || starts_with(include[j], temp_str)) { free(no_longer_relevant[i]); no_longer_relevant[i] = NULL; break; } } free(temp_str); } } // Renumber the revisions if the empty ones are to be dropped if (drop_empty) { fprintf(messages, "OK\nStep %d/%d: Renumbering revisions... ", cur_step, steps); fflush(messages); ++cur_step; revisions[0].number = 0; // Revision 0 is special, and should never be dropped. new_number = 1; for (i = 1; i < rev_len; ++i) { empty = 1; for (j = 0; j < revisions[i].size; ++j) { if (revisions[i].nodes[j].wanted) { empty = 0; break; } } if (!empty) { revisions[i].number = new_number; ++new_number; } } } fprintf(messages, "OK\nStep %d/%d: Writing the outfile... ", cur_step, steps); fflush(messages); ++cur_step; // Copy the infile to the outfile skipping the undesireable parts. reading_node = 0; rewind(infile); while ((ch = fgetc(infile)) != EOF) { if (ch == NEWLINE) { if (reading_node) { if (strlen(current_line) == 0) { reading_node = 0; writing = 1; } else if (drop_empty && writing && starts_with(current_line, "Node-copyfrom-rev: ")) { temp_int = atoi(¤t_line[19]); // It's possible for the copyfrom-rev argument to point to a revision that is being removed. // If this is the case we change it to point to the first revision prior to it, that remains. while (revisions[temp_int].number < 0) { --temp_int; } fprintf(outfile, "Node-copyfrom-rev: %d\n", revisions[temp_int].number); toggle = 1; } else if(writing && redefined_root != NULL && starts_with(current_line, "Node-copyfrom-path: ")) { temp_str = reduce_path(redefined_root, ¤t_line[20]); fprintf(outfile, "Node-copyfrom-path: %s\n", temp_str); toggle = 1; free(temp_str); } else if (starts_with(current_line, "Content-length: ")) { con_len = (off_t)atol(¤t_line[16]); if (writing) { fprintf(outfile, "%s\n", current_line); for (offset = 0; offset < con_len + CONTENT_PADDING; ++offset) { fputc(fgetc(infile), outfile); } } else { fseeko(infile, con_len + CONTENT_PADDING, SEEK_CUR); } reading_node = 0; writing = 1; toggle = 1; } } else if (starts_with(current_line, "Node-path: ")) { reading_node = 1; ++nod; writing = revisions[rev].nodes[nod].wanted; if (writing && redefined_root != NULL) { temp_str = reduce_path(redefined_root, ¤t_line[11]); fprintf(outfile, "Node-path: %s\n", temp_str); toggle = 1; free(temp_str); } } else if (starts_with(current_line, "Revision-number: ")) { ++rev; nod = -1; writing = (!drop_empty || revisions[rev].number >= 0); if (drop_empty && writing) { temp_int = atoi(¤t_line[17]); fprintf(outfile, "Revision-number: %d\n", revisions[temp_int].number); toggle = 1; } } if (writing && !toggle) { fprintf(outfile, "%s\n", current_line); } else { toggle = 0; } current_line[0] = '\0'; cur_len = 0; } else { current_line[cur_len] = ch; ++cur_len; current_line[cur_len] = '\0'; } } fprintf(messages, "OK\nStep %d/%d: Adding revision deleting surplus nodes... ", cur_step, steps); fflush(messages); ++cur_step; // Now we deal with any surplus nodes by adding a revision that deletes them. if (delete_needed) { time(&rawtime); ptm = gmtime(&rawtime); if (drop_empty) { i = 1; do { temp_int = revisions[rev_len - i].number + 1; ++i; } while (temp_int == 0); } else { temp_int = rev_len; } fprintf(outfile, "Revision-number: %d\n", temp_int); fprintf(outfile, "Prop-content-length: 133\n"); fprintf(outfile, "Content-length: 133\n\n"); fprintf(outfile, "K 7\nsvn:log\nV 22\n"); fprintf(outfile, "Deleted unwanted nodes\n"); fprintf(outfile, "K 10\nsvn:author\nV 16\nsvndumpsanitizer\nK 8\nsvn:date\nV 27\n"); fprintf(outfile, "%d-%.2d-%.2dT%.2d:%.2d:%.2d.000000Z\n", ptm->tm_year + 1900, ptm->tm_mon + 1, ptm->tm_mday, ptm->tm_hour, ptm->tm_min, ptm->tm_sec); fprintf(outfile, "PROPS-END\n\n"); for (i = 0; i < no_len; ++i) { if (no_longer_relevant[i] != NULL) { fprintf(outfile, "Node-path: %s\n", no_longer_relevant[i]); fprintf(outfile, "Node-action: delete\n\n\n"); } } fprintf(messages, "OK\n"); } else { fprintf(messages, "NOT NEEDED\n"); } // Clean everything up fclose(infile); if (to_file) { fclose(outfile); } for (i = 0; i < rev_len; ++i) { for (j = 0; j < revisions[i].size; ++j) { free(revisions[i].nodes[j].path); free(revisions[i].nodes[j].copyfrom); } free(revisions[i].nodes); } for (i = 0; i < rel_len; ++i) { free(relevant_paths[i]); } for (i = 0; i < no_len; ++i) { free(no_longer_relevant[i]); } for (i = 0; i < must_len; ++i) { free(mustkeep[i]); } free(revisions); free(relevant_paths); free(no_longer_relevant); free(include); free(exclude); free(mustkeep); free(current_line); return 0; }