#include #include #include #include #include #include #include #include #include #include #define PORT 8888 #define HOST_NAME "localhost" #define BUCKET_SIZE 1024 #define CHUNK_SIZE 128 #define OUT_FILE "./binary" void get_addr( struct sockaddr_in *addr, const char *host_name, int port ); int get_sock(); void initialize_connection(int sock, const struct sockaddr_in *addr); char *recv_data(int sock, size_t *len); char *clean_data(const char *data, size_t *len); void write_data(const char *path, const char *data, size_t len); inline void *xmalloc(size_t size); inline void *xrealloc(void *ptr, size_t size); int main(argc, argv) int argc; char **argv; { int sock; struct sockaddr_in peer; size_t data_len; char *data; char *clean; get_addr(&peer, HOST_NAME, PORT); sock = get_sock(); initialize_connection(sock, &peer); data = recv_data(sock, &data_len); clean = clean_data(data, &data_len); free(data); data = NULL; write_data(OUT_FILE, clean, data_len); exit(EXIT_SUCCESS); } void get_addr(addr, host_name, port) struct sockaddr_in *addr; const char *host_name; int port; { struct hostent *host; host = gethostbyname(host_name); if(!host) { fprintf(stderr, "Failed to lookup %s\n", host_name); exit(EXIT_FAILURE); } addr->sin_family = AF_INET; addr->sin_port = htons(port); addr->sin_addr = *((struct in_addr *)host->h_addr); memset(&addr->sin_zero, '\0', 8); } int get_sock() { int sock = socket(PF_INET, SOCK_STREAM, 0); if(sock == -1) { perror("Failed to get socket"); exit(EXIT_FAILURE); } return sock; } void initialize_connection(sock, addr) int sock; const struct sockaddr_in *addr; { int ret = connect(sock, (struct sockaddr *)addr, sizeof(struct sockaddr)); if(ret == -1) { perror("Connection failed"); exit(EXIT_FAILURE); } } char *recv_data(sock, len) int sock; size_t *len; { ssize_t received; char *data; size_t offset; size_t data_len; data = xmalloc(BUCKET_SIZE); offset = 0; data_len = BUCKET_SIZE; while(1) { received = recv(sock, (data + offset), CHUNK_SIZE, 0); if(received == -1) { perror("Receive failed"); exit(EXIT_FAILURE); } if(received == 0) break; offset += received; // Will we spill our bucket next time? if((data + data_len) - (data + offset) < CHUNK_SIZE) { data = xrealloc(data, data_len + BUCKET_SIZE); data_len += BUCKET_SIZE; } } *len = offset; data = xrealloc(data, *len); return data; } char *clean_data(data, len) const char *data; size_t *len; { char *clean; const char *ptr; register unsigned int i; register unsigned int j; size_t new_len; new_len = *len / 2; clean = xmalloc(new_len); ptr = data; i = 0; j = 0; while(ptr - data < *len) { if(i % 2) { clean[j++] = *ptr; } ptr++; i++; } *len = new_len; return clean; } void write_data(path, data, len) const char *path; const char *data; size_t len; { int file; size_t ret; file = creat(path, S_IRWXU); if(file == -1) { perror("Failed to open file"); exit(EXIT_FAILURE); } ret = write(file, data, len); if(ret != len) { perror("Failed to write to file"); exit(EXIT_FAILURE); } } inline void *xmalloc(size) size_t size; { void *tmp = malloc(size); if(!tmp) { fprintf(stderr, "Failed to allocate memory\n"); exit(EXIT_FAILURE); } return tmp; } inline void *xrealloc(ptr, size) void *ptr; size_t size; { void *tmp = realloc(ptr, size); if(!tmp) { fprintf(stderr, "Failed to allocate memory\n"); exit(EXIT_FAILURE); } return tmp; }