// // Name: Taylor Carr // Date: December 3, 2017 // CS4310: Project #2 // #include #include #include #include #include #include #include #include #include #include #include #define MAXBUF 1024 int main(int argc, const char * argv[]) { // Initialize log.txt file FILE *log, *reader; log = fopen("log.txt", "w+"); struct sockaddr_in my_addr; socklen_t arrdLen = sizeof(my_addr); short port = 0; int SIZE = 10; // Max number of agents char *agents[SIZE], // List of current connections *times[SIZE]; // List of connection times printf("Enter the port: "); scanf("%hu", &port); // store port from user // Set values for struct memset(&my_addr, '\0', arrdLen); // set everything to 0 my_addr.sin_family = AF_INET; my_addr.sin_port = htons(port); my_addr.sin_addr.s_addr = INADDR_ANY; memset(my_addr.sin_zero, '\0', sizeof(my_addr.sin_zero)); int sd; // Create a new socket if ((sd = socket (AF_INET, SOCK_STREAM, 0)) < 0) { fprintf (stderr, "ERROR: socket() failed\n"); exit (-1); } printf("\nSocket created\n"); // Bind socket if (bind (sd, (struct sockaddr *)&my_addr, arrdLen) < 0){ fprintf (stderr, "ERROR: bind() failed\n"); exit (-1); } printf("\nBind successful\n"); // Get listening IP and print it char szHostName[255]; gethostname(szHostName, 255); struct hostent *host_entry; host_entry= gethostbyname(szHostName); char * szLocalIP; szLocalIP = inet_ntoa (*(struct in_addr *)*host_entry->h_addr_list); printf("\nServer IP: %s\n", szLocalIP); // Listen for connection printf("\nListening for client\n"); if ((listen(sd, 1)) < 0){ fprintf (stderr, "ERROR: listen() failed\n"); exit (-1); } // Variable Declarations char buffer[MAXBUF]; int bytes_read = 0; int total_bytes_read = 0; int found = 0, // Bool flag i; struct tm ts; struct timeval connected[SIZE], current, difference; time_t TIME; // Initialize array to NULL for(i = 0; i < SIZE; i++) { agents[i] = NULL; } // Infinite Loop while (true) { // Client variables struct sockaddr_in client; int clientSocket; socklen_t clientLength = sizeof(client); memset(&client, 0, clientLength); // Accept connection clientSocket = accept(sd, (struct sockaddr *)&client, &clientLength); // Read command from client memset(buffer,0,MAXBUF); bytes_read = read(clientSocket, buffer, MAXBUF); if (bytes_read < 0) break; fprintf(stdout,"\nRead %d bytes: [%s]\r\n", bytes_read,buffer); // Store client's IP in string char *connectedIP = strdup(inet_ntoa(client.sin_addr)); // Option 1: if ((strcmp(buffer, "#JOIN")) == 0) { // Join list of connected agents found = 0; // Get current time for log TIME = time(NULL); ts = *localtime(&TIME); // Print message to log char buf[80]; strftime(buf, sizeof(buf), "%a %Y-%m-%d %H:%M:%S %Z", &ts); fprintf(log, "%s: Received a \"#JOIN\" action from agent \"%s\"", buf, connectedIP); fprintf(log, "\n\n"); fflush(log); // Handle #JOIN request appropriately for (i = 0; i < SIZE; i++) { if (agents[i] == NULL) { } else if (strcmp(agents[i], connectedIP) == 0){ // Agent found in list found = 1; // Write to agent char response[] = "#ALREADY MEMBER"; write (clientSocket, response, strlen(response)); // Get time for log TIME = time(NULL); ts = *localtime(&TIME); // Write to log char buf[80]; strftime(buf, sizeof(buf), "%a %Y-%m-%d %H:%M:%S %Z", &ts); fprintf(log, "%s: Responded to agent \"%s\" with \"#ALREADY MEMBER\"", buf, connectedIP); fprintf(log, "\n\n"); fflush(log); i = SIZE; } } if (found == 0) { // Save IP to list/queue for(i = 0; i < SIZE; i++) { if (agents[i] == NULL) { // Save IP to array agents[i] = connectedIP; // Save time to arrays gettimeofday(&connected[i], NULL); TIME = time(NULL); times[i] = TIME; ts = *localtime(&TIME); // Write to log char buf[80]; strftime(buf, sizeof(buf), "%a %Y-%m-%d %H:%M:%S %Z", &ts); fprintf(log, "%s: Responded to agent \"%s\" with \"#OK\"", buf, connectedIP); fprintf(log, "\n\n"); fflush(log); // Write to agent char response[] = "#OK"; write (clientSocket, response, strlen(response)); i = SIZE; } } } } // Option 2: Leave list of connected agents else if ((strcmp(buffer, "#LEAVE")) == 0) { found = 0; // Get time for log TIME = time(NULL); ts = *localtime(&TIME); // Write to log char buf[80]; strftime(buf, sizeof(buf), "%a %Y-%m-%d %H:%M:%S %Z", &ts); fprintf(log, "%s: Received a \"#LEAVE\" action from agent \"%s\"", buf, connectedIP); fprintf(log, "\n\n"); fflush(log); // Handle #LEAVE request apprpriately for (i = 0; i < SIZE; i++) { if (agents[i] == NULL){ } else if (!strcmp(agents[i], connectedIP)) { // Agent found in list found = 1; // Erase agent from arrays agents[i] = NULL; // Replace IP with NULL times[i] = NULL; // Write to agent char response[] = "#OK"; write (clientSocket, response, strlen(response)); // Get time for log TIME = time(NULL); ts = *localtime(&TIME); // Write to log char buf[80]; strftime(buf, sizeof(buf), "%a %Y-%m-%d %H:%M:%S %Z", &ts); fprintf(log, "%s: Responded to agent \"%s\" with \"#OK\"", buf, connectedIP); fprintf(log, "\n\n"); fflush(log); } } if (found == 0) { // Agent not found in list // Write to agent char response[] = "#NOT MEMBER"; write (clientSocket, response, strlen(response)); // Write to log char buf[80]; strftime(buf, sizeof(buf), "%a %Y-%m-%d %H:%M:%S %Z", &ts); fprintf(log, "%s: Responded to agent \"%s\" with \"#NOT MEMBER\"", buf, connectedIP); fprintf(log, "\n\n"); fflush(log); } } // Option 3: Share list of connected agents else if ((strcmp(buffer, "#LIST")) == 0) { int index = -1; found = 0; // Get time for log TIME = time(NULL); ts = *localtime(&TIME); // Write to log char buf[80]; strftime(buf, sizeof(buf), "%a %Y-%m-%d %H:%M:%S %Z", &ts); fprintf(log, "%s: Received a \"#LIST\" action from agent \"%s\"", buf, connectedIP); fprintf(log, "\n\n"); fflush(log); // See if requesting agent is currently in the list for(i = 0; i < SIZE; i++) { if (agents[i] == NULL){ } else if(strcmp(agents[i], connectedIP) == 0) { found = 1; index = i; i = SIZE; // Exit for loop } } if (found == 1){ // Agent found in list for(i = 0; i < SIZE; i++) { if(agents[i] != NULL) { // ensure slot in list is taken by an agent // Get the number of seconds that agent has been connected gettimeofday(¤t, NULL); timersub(¤t, &connected[i], &difference); // Write to agent char response[100]; sprintf(response, "<%s, %ld.%06ld>", agents[i], (long int)difference.tv_sec, (long int)difference.tv_usec); write(clientSocket, response, strlen(response)); } } // Get time for log TIME = time(NULL); ts = *localtime(&TIME); // Write to log char buf[80]; strftime(buf, sizeof(buf), "%a %Y-%m-%d %H:%M:%S %Z", &ts); fprintf(log, "%s: Responded to agent \"%s\" with current list", buf, connectedIP); fprintf(log, "\n\n"); fflush(log); } else { // Get time for log TIME = time(NULL); ts = *localtime(&TIME); // Write to log char buf[80]; strftime(buf, sizeof(buf), "%a %Y-%m-%d %H:%M:%S %Z", &ts); fprintf(log, "%s: No response supplied to agent \"%s\"", buf, connectedIP); fprintf(log, "\n\n"); fflush(log); } } // Option 4: Send log.txt to agent else if ((strcmp(buffer, "#LOG")) == 0) { found = 0; int index = -1; // Get time for log TIME = time(NULL); ts = *localtime(&TIME); // Write to log char buf[80]; strftime(buf, sizeof(buf), "%a %Y-%m-%d %H:%M:%S %Z", &ts); fprintf(log, "%s: Received a \"#LOG\" action from agent \"%s\"", buf, connectedIP); fprintf(log, "\n\n"); fflush(log); // See if requesting agent is currently in the list for(i = 0; i < SIZE; i++) { if (agents[i] == NULL){ } else if(strcmp(agents[i], connectedIP) == 0) { // Agent found in list found = 1; index = i; i = SIZE; // Exit for loop } } if (found == 0) { // Agent not in list, ignore request // Get time for log TIME = time(NULL); ts = *localtime(&TIME); // Write to log char buf[80]; strftime(buf, sizeof(buf), "%a %Y-%m-%d %H:%M:%S %Z", &ts); fprintf(log, "%s: No response supplied to agent \"%s\"", buf, connectedIP); fprintf(log, "\n\n"); fflush(log); } else { // Read from log and write to agent memset(buffer,0,MAXBUF); reader = fopen("log.txt", "r"); if (reader == NULL) perror ("Error opening file"); else { while ( ! feof (reader) ) { if ( fgets (buffer , MAXBUF , reader) == NULL ) break; write(clientSocket, buffer, strlen(buffer)); } fclose (reader); } // Get time for log TIME = time(NULL); ts = *localtime(&TIME); // Write to log char buf[80]; strftime(buf, sizeof(buf), "%a %Y-%m-%d %H:%M:%S %Z", &ts); fprintf(log, "%s: Responded to agent \"%s\" with current log", buf, connectedIP); fprintf(log, "\n\n"); fflush(log); } } // Option 5: Invalid request from agent else { printf("ERROR: Invalid command from agent\n"); // Write to agent char response[] = "#INVALID"; write (clientSocket, response, strlen(response)); // Get time for log TIME = time(NULL); ts = *localtime(&TIME); // Write to log char buf[80]; strftime(buf, sizeof(buf), "%a %Y-%m-%d %H:%M:%S %Z", &ts); fprintf(log, "%s: Received an \"#INVALID\" action from agent \"%s\"", buf, connectedIP); fprintf(log, "\n\n"); fflush(log); } // Close socket, flush log, close log close(clientSocket); memset(&client, 0, sizeof(client)); fflush(log); } return 0; }