Advertisement
Guest User

Untitled

a guest
Mar 5th, 2015
195
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.16 KB | None | 0 0
  1. #include <stdlib.h>
  2. #include <stdio.h>
  3. #include <unistd.h>
  4. #include <string.h>
  5. #include <strings.h>
  6. #include <signal.h>
  7. #include <sys/types.h>
  8. #include <sys/socket.h>
  9. #include <sys/un.h>
  10. #include <errno.h>
  11. #include <netdb.h>
  12. #include <netinet/in.h>
  13. #include <arpa/inet.h>
  14. #include <sys/param.h>
  15.  
  16. #define MAXQUEUE 5 /* maximum number of pending connections */
  17. #define PORTNUMBER 2225 /* arbitrary portnumber in range we may use */
  18. #define MAXOUTPUT 500 /* outout buffer size */
  19.  
  20. static void print_ip_and_port(void);
  21. static void clean_up(int);
  22. static void set_up_server(void);
  23. static void server_loop(void);
  24. static void server_handler(void);
  25.  
  26. /* global variables so they are accessible in signalhandler */
  27.  
  28. static int serverFD = -1, clientFD = -1; /* fd for server and client socket */
  29.  
  30.  
  31. int main(int argc, char *argv[]) {
  32.  
  33. /* TODO install signalhandler clean_up for clean termination */
  34.  
  35. if (signal(SIGTERM, clean_up) == SIG_ERR) { // subscribe clean_up to SIGTERM
  36. printf("\ncan't catch SIGINT\n");
  37. }
  38.  
  39. set_up_server();
  40.  
  41. print_ip_and_port(); /* inform user of where we are running */
  42.  
  43. server_loop();
  44.  
  45. }
  46.  
  47.  
  48. static void set_up_server(void) {
  49. struct sockaddr_in serverINETAdress;
  50.  
  51. /* TODO create a socket to listen to in serverFD, with default protocol for stream (TCP) */
  52.  
  53. serverFD = socket(AF_INET, SOCK_STREAM, 0);
  54.  
  55. /* initialize adresses of server */
  56. bzero((void *) &serverINETAdress, sizeof(serverINETAdress));
  57.  
  58. /* Internet domain */
  59. serverINETAdress.sin_family = AF_INET;
  60. /* Accept connectionsfrom any IP adress */
  61. serverINETAdress.sin_addr.s_addr = htonl(INADDR_ANY);
  62. serverINETAdress.sin_port = htons((u_short)PORTNUMBER);
  63. /* set reuse address so you don't have to wait for the port to be free again */
  64. int on = 1;
  65. setsockopt(serverFD, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
  66.  
  67. /* TODO bind socket to address */
  68. bind(serverFD, (struct sockaddr *)&serverINETAdress, sizeof(serverINETAdress));
  69.  
  70. /* TODO listen to socket */
  71.  
  72. listen(serverFD, MAXQUEUE);
  73. }
  74.  
  75. static void server_loop(void) {
  76. for (;/* EVER */;) {
  77. struct sockaddr_in clientINETAdress;
  78. socklen_t clientLen = sizeof(clientINETAdress);
  79.  
  80. /* TODO accept connection from serverFD into clientFD */
  81.  
  82. clientFD = accept(serverFD, (struct sockaddr*)NULL, NULL);
  83.  
  84. fprintf(stdout, "connected clientFD %d from IPadress %s\n",
  85. clientFD, inet_ntoa(clientINETAdress.sin_addr));
  86.  
  87. /* Create new child to deal with this connection */
  88. pid_t cpid = fork();
  89. if (cpid == 0) { // child
  90. serverFD = -1; // avoid cleaning this up
  91. server_handler();
  92. exit(0);
  93. } else { // parent
  94. clientFD = -1; // reset so it doesn't get closed twice
  95. }
  96. }
  97. }
  98.  
  99. static void server_handler(void) {
  100. unsigned long bufferlen = 0;
  101. for (;/* EVER */;) {
  102. /* TODO receive message length...remember to check for errors! */
  103.  
  104.  
  105. if((read(clientFD, &bufferlen, sizeof(unsigned long)))<0){
  106. printf("Could not read from client");
  107. bufferlen = 0;
  108. return;
  109. }
  110.  
  111.  
  112.  
  113. fprintf(stdout, "reading %lu bytes\n", bufferlen);
  114. if (bufferlen > 0) {
  115.  
  116. /* TODO receive message contents...remember to check for errors! */
  117.  
  118. char *buffer = malloc(bufferlen * sizeof(char));
  119. read(clientFD, buffer, bufferlen);
  120.  
  121. /* TODO deal with command "exit"
  122. or deal with command "cd"
  123. or deal with anything else using popen
  124.  
  125. forward responses to the client and terminate with a bufferlength 0
  126. */
  127.  
  128. if (strncmp(buffer, "exit", 4) == 0) {
  129. free(buffer);
  130. return;
  131. }
  132. FILE *pf;
  133. pf = popen(buffer, "r");
  134. char data[MAXOUTPUT];
  135.  
  136. fgets(data, MAXOUTPUT, pf);
  137.  
  138.  
  139. unsigned long len = strlen(data);
  140. write(clientFD, &len, sizeof(data));
  141.  
  142. write(clientFD, data, sizeof(data));
  143. pclose(pf);
  144.  
  145.  
  146. /* TODO remember to allocate and free the receive buffer */
  147. free(buffer);
  148. bufferlen = 0; // reset bufferlen
  149. }
  150. }
  151. }
  152.  
  153. static void print_ip_and_port(void) {
  154. char hostname[121];
  155. struct hostent *hostPtr;
  156.  
  157. gethostname(hostname, 120);
  158. hostPtr = gethostbyname(hostname);
  159.  
  160. printf("Server is running on\n%s (",
  161. hostname);
  162. if (hostPtr != NULL) {
  163. int i = 0;
  164. while (hostPtr->h_addr_list[i] != NULL) {
  165. struct sockaddr_in server;
  166. memcpy(&server.sin_addr, hostPtr->h_addr_list[0], hostPtr->h_length);
  167. printf(" %s ", inet_ntoa(server.sin_addr));
  168. i++;
  169. }
  170. }
  171. printf(") : %d\n", PORTNUMBER);
  172. }
  173.  
  174. static void clean_up(int sign) {
  175. fprintf(stderr, "Server is shutting down....\n");
  176. if (serverFD != -1) {
  177. fprintf(stderr, "Closing serverFD %d\n", serverFD);
  178. close(serverFD);
  179. }
  180. if (clientFD != -1) {
  181. fprintf(stderr, "Closing clientFD %d\n", clientFD);
  182. close(clientFD);
  183. }
  184. _exit(0);
  185. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement