/** * Send a string message through a socket. * \param sock Socket descriptor for the socket to send the message through. * \param buffer Buffer for buffering the message we send. */ void sendMessage(int sock, char* buffer) { int len = read(0,buffer,BUFFER_SIZE); exitIfError(len,"Error reading from console"); len = write(sock, buffer, len); exitIfError(len, "Error writing to socket"); }
Hashmap *newHashmap(size_t capacity) { Hashmap *map = malloc(sizeof(Hashmap)); exitIfError(map == NULL, "mallocing during hashmap creation"); map->capacity = capacity; map->entries = calloc(capacity, sizeof(MapEntry)); exitIfError(map->entries == NULL, "callocing during hashmap creation"); map->load = 0; return map; }
/** * Receive a string message through a socket. * \param sock Socket descriptor for the socket to receive the message through. * \param buffer Buffer for buffering the message we receive. */ int receiveMessage(int sock, char* buffer) { int len = read(sock,buffer,BUFFER_SIZE); exitIfError(len,"Error reading from socket"); if (len == 0) return -1; len = write(1, buffer, len); exitIfError(len, "Error writing to console"); return 0; }
void growHashmap(Hashmap *map, size_t newCapacity) { map->entries = realloc(map->entries, newCapacity * sizeof(MapEntry)); exitIfError(map->entries == NULL, "reallocing during hashmap resize"); memset(map->entries + map->capacity, 0, (newCapacity - map->capacity) * sizeof(MapEntry)); size_t currIndex; for (currIndex = 0; currIndex < map->capacity; currIndex++) { MapEntry *oldEntry = map->entries + currIndex; if (oldEntry->key == NULL) { continue; } size_t newIndex = *(size_t *)oldEntry->key % newCapacity; if (newIndex == currIndex) { continue; } MapEntry *newEntry = map->entries + newIndex; while (newEntry->key != NULL) { newEntry++; if (newEntry >= map->entries + newCapacity) { newEntry = map->entries; } } newEntry->key = oldEntry->key; newEntry->value = oldEntry->value; oldEntry->key = NULL; oldEntry->value = NULL; } map->capacity = newCapacity; }
void createIndex(Hashmap *map, DIR *directory) { if (directory == NULL) { printf("ERROR"); } struct dirent *ent; while ((ent = readdir(directory)) != NULL) { if (strcmp(ent->d_name, ".") == 0 || strcmp(ent->d_name, "..") == 0) { continue; } FILE *file = fopen(ent->d_name, "r"); exitIfError(ferror(file), "opening file during indexing"); char *hash = hashFile(file); exitIfError(fclose(file) == EOF, "closing file during indexing"); putInHashmap(map, hash, ent->d_name); } }
/** * Starts normal communication through global socket \a sock. */ void communicate() { char buffer[BUFFER_SIZE]; struct pollfd fds[FDCOUNT]; memset(fds, 0, sizeof(fds)); fds[0].fd = 0; fds[1].fd = sock; fds[0].events=fds[1].events = POLLIN; int result; for (;;) { result = poll(fds,FDCOUNT,-1); exitIfError(result, "Error on polling"); if (result>0) { if (fds[1].revents & POLLHUP) break; if (fds[0].revents & POLLIN) sendMessage(sock, buffer); if (fds[1].revents & POLLIN) if (-1 == receiveMessage(sock, buffer)) break; } } }
/** * Create a client and connect to localhost on the specified port. * \param host The host name or ip address to connect to. * \param port The port to connect to. */ void client(char * host, char* port) { #ifdef DEBUG puts("Client start requested."); #endif //resolve domain and port name and connect to target struct addrinfo hints, *res, *rp; memset(&hints, 0, sizeof(hints)); hints.ai_family = AF_INET; hints.ai_socktype = SOCK_STREAM; if (0 != getaddrinfo(host, port, &hints, &res)) { fprintf(stderr, "Error resolving address \"%s\". Exiting.\n", host); exit(1); } //evaluate results for (rp = res; rp != NULL; rp = rp->ai_next) { sock = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol); if (sock == -1) continue; if (connect(sock, rp->ai_addr, rp->ai_addrlen) == 0) break; /* Success */ close(sock); sock = -1; } freeaddrinfo(res); exitIfError(sock,"Error connecting to socket"); //send messages communicate(); }
char *hashFile(FILE *file) { unsigned char *md_value = malloc(HASH_LENGTH); exitIfError(md_value == NULL, "mallocing during file hashing"); EVP_MD_CTX mdctx; EVP_MD_CTX_init(&mdctx); const EVP_MD *md = EVP_sha256(); EVP_DigestInit_ex(&mdctx, md, NULL); int bytes; unsigned char data[4096]; while ((bytes = fread(data, 1, 4096, file)) != 0) { exitIfError(ferror(file), "reading data from file during hashing"); EVP_DigestUpdate(&mdctx, data, bytes); } EVP_DigestFinal_ex(&mdctx, md_value, NULL); EVP_MD_CTX_cleanup(&mdctx); return md_value; }
/** * The main function of the program. * \param argc The argument count * \param argv The command line arguments */ int main (int argc, char * argv[]) { //register signal handlers signal( SIGTERM, signalHandler); signal( SIGINT, signalHandler); //register cleanUp function int result = atexit(cleanUpOnExit); exitIfError(result, "Error registering exit function:"); parseCmdLineArguments(argc, argv); }
/** * Starts a server listing on a specified port * \param port_s The Port or service name to listen on */ void server(char * port_s) { int port = resolvePort(port_s); if (port == -1) exit(1); //create socket sock = socket(AF_INET,SOCK_STREAM, 0); exitIfError(sock, "Error creating socket"); //stop socket from blocking the port after disconnecting int sockopt = 1; int result = setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &sockopt, sizeof(sockopt)); exitIfError(result, "Error setting socket options"); //bind to port struct sockaddr_in localAddr, remoteAddr; localAddr.sin_family = AF_INET; localAddr.sin_port = port; //on all interfaces localAddr.sin_addr.s_addr = INADDR_ANY; result = bind(sock, (struct sockaddr*)&localAddr, sizeof(localAddr)); exitIfError(result, "Error binding to port"); //start listening result = listen(sock, 1); // only one client allowed exitIfError(result, "Error listening"); //accept connections socklen_t remoteAddrLength = sizeof(remoteAddr); int communicationSocket = accept(sock, (struct sockaddr*) &remoteAddr, &remoteAddrLength); exitIfError(communicationSocket, "Error accepting connection"); //replace listening socket with communicationSocket, so there is only one socket to close on catching signals etc. close(sock); sock = communicationSocket; communicate(); }