Exemplo n.º 1
0
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");
}
Exemplo n.º 4
0
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;
}
Exemplo n.º 6
0
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);

	}

}
Exemplo n.º 7
0
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");
}
Exemplo n.º 8
0
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;
}
Exemplo n.º 9
0
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");
	}

}
Exemplo n.º 10
0
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");
	}

}
Exemplo n.º 11
0
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;
}
Exemplo n.º 12
0
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;
}
Exemplo n.º 13
0
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;
    }
}
Exemplo n.º 14
0
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;

}
Exemplo n.º 15
0
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;
}
Exemplo n.º 16
0
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;
}
Exemplo n.º 17
0
//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);
	}
}
Exemplo n.º 18
0
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;
}
Exemplo n.º 19
0
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;
        }
      }
    }
  }
}
Exemplo n.º 20
0
// 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");
	}
}
Exemplo n.º 21
0
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;
}
Exemplo n.º 22
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");
	}
}
Exemplo n.º 23
0
static void flush_()
{
	if ( buf_pos && !fwrite( buf, buf_pos, 1, file ) )
		exit_with_error( "Couldn't write WAVE data" );
	buf_pos = 0;
}
Exemplo n.º 24
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;
}
Exemplo n.º 25
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;
}
Exemplo n.º 26
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;
}
Exemplo n.º 27
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(&current_line[16]) + CONTENT_PADDING, SEEK_CUR);
					reading_node = 0;
				}
				else if (starts_with(current_line,"Node-action: ")) {
					if (strcmp(&current_line[13],"add") == 0) {
						current_node[nod_len].action = ADD;
					}
					else if (strcmp(&current_line[13],"delete") == 0) {
						current_node[nod_len].action = DELETE;
					}
					else if (strcmp(&current_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(&current_line[19]));
					strcpy(current_node[nod_len].copyfrom, &current_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(&current_line[10]));
				strcpy(current_node[nod_len].path, &current_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(&current_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, &current_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(&current_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, &current_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(&current_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;
}