Advertisement
Guest User

Untitled

a guest
Nov 12th, 2019
124
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.29 KB | None | 0 0
  1. /*
  2. * ser6.c - (Topic 11, HX 22/5/1995)
  3. * An improved version of "ser5.c". This version handles the message boundaries
  4. * which are not preserved by the TCP. Each message transmitted between the
  5. * client and the server is preceeded by a two byte value which is the length
  6. * of the message. The handling of the message length is done in routines readn
  7. * and writen.
  8. * revised: 22/05/1996
  9. * revised: 18/10/2006
  10. */
  11.  
  12. #include <stdlib.h> /* strlen(), strcmp() etc */
  13. #include <stdio.h> /* printf() */
  14. #include <string.h> /* strlen(), strcmp() etc */
  15. #include <errno.h> /* extern int errno, EINTR, perror() */
  16. #include <signal.h> /* SIGCHLD, sigaction() */
  17. #include <syslog.h>
  18. #include <sys/stat.h>
  19. #include <sys/types.h> /* pid_t, u_long, u_short */
  20. #include <sys/socket.h> /* struct sockaddr, socket(), etc */
  21. #include <sys/wait.h> /* waitpid(), WNOHAND */
  22. #include <netinet/in.h> /* struct sockaddr_in, htons(), htonl(), */
  23. /* and INADDR_ANY */
  24. #include <unistd.h>
  25. #include "stream.h" /* MAX_BLOCK_SIZE, readn(), writen() */
  26. #include "stream.c"
  27.  
  28.  
  29.  
  30.  
  31. #define SERV_TCP_PORT 40005 /* default server listening port */
  32.  
  33.  
  34. void claim_children()
  35. {
  36. pid_t pid=1;
  37.  
  38. while (pid>0) { /* claim as many zombies as we can */
  39. pid = waitpid(0, (int *)0, WNOHANG);
  40. }
  41. }
  42.  
  43.  
  44. void daemon_init(void)
  45. {
  46. pid_t pid;
  47. struct sigaction act;
  48.  
  49. if ( (pid = fork()) < 0) {
  50. perror("fork"); exit(1);
  51. } else if (pid > 0) {
  52. printf("Hay, you'd better remember my PID: %d\n", pid);
  53. exit(0); /* parent goes bye-bye */
  54. }
  55.  
  56. /* child continues */
  57. setsid(); /* become session leader */
  58. chdir("/"); /* change working directory */
  59. umask(0); /* clear file mode creation mask */
  60.  
  61. /* catch SIGCHLD to remove zombies from system */
  62. act.sa_handler = claim_children; /* use reliable signal */
  63. sigemptyset(&act.sa_mask); /* not to block other signals */
  64. act.sa_flags = SA_NOCLDSTOP; /* not catch stopped children */
  65. sigaction(SIGCHLD,(struct sigaction *)&act,(struct sigaction *)0);
  66. /* note: a less than perfect method is to use
  67. signal(SIGCHLD, claim_children);
  68. */
  69. }
  70.  
  71.  
  72.  
  73. void reverse(char *s)
  74. {
  75. char c;
  76. int i, j;
  77.  
  78. for (i=0, j = strlen(s)-1; i<j; i++, j--) {
  79. c = s[i]; s[i] = s[j]; s[j] = c;
  80. }
  81. }
  82.  
  83.  
  84. void serve_a_client(int sd)
  85. { int nr, nw;
  86. char buf[MAX_BLOCK_SIZE];
  87.  
  88. while (1){
  89. /* read data from client */
  90. if ((nr = readn(sd, buf, sizeof(buf))) <= 0)
  91. return; /* connection broken down */
  92.  
  93. /* process data */
  94. buf[nr] = '\0'; reverse(buf);
  95.  
  96. /* send results to client */
  97. nw = writen(sd, buf, nr);
  98. }
  99. }
  100.  
  101.  
  102. int main(int argc, char *argv[])
  103. {
  104. string theDirectory = argv[1];
  105. printf("thiss %s", theDirectory);
  106.  
  107. int sd, nsd, n;
  108. pid_t pid;
  109. unsigned short port; // server listening port
  110. socklen_t cli_addrlen;
  111. struct sockaddr_in ser_addr, cli_addr;
  112.  
  113. /* get the port number */
  114. if (argc == 1) {
  115. port = SERV_TCP_PORT;
  116. } else if (argc == 2) {
  117. int n = atoi(argv[1]);
  118. if (n >= 1024 && n < 65536)
  119. port = n;
  120. else {
  121. printf("Error: port number must be between 1024 and 65535\n");
  122. exit(1);
  123. }
  124. } else {
  125. printf("Usage: %s [ server listening port ]\n", argv[0]);
  126. exit(1);
  127. }
  128.  
  129. /* turn the program into a daemon */
  130. daemon_init();
  131.  
  132. /* set up listening socket sd */
  133. if ((sd = socket(PF_INET, SOCK_STREAM, 0)) < 0) {
  134. perror("server:socket"); exit(1);
  135. }
  136.  
  137. /* build server Internet socket address */
  138. bzero((char *)&ser_addr, sizeof(ser_addr));
  139. ser_addr.sin_family = AF_INET;
  140. ser_addr.sin_port = htons(port);
  141. ser_addr.sin_addr.s_addr = htonl(INADDR_ANY);
  142. /* note: accept client request sent to any one of the
  143. network interface(s) on this host.
  144. */
  145.  
  146. /* bind server address to socket sd */
  147. if (bind(sd, (struct sockaddr *) &ser_addr, sizeof(ser_addr))<0){
  148. perror("server bind"); exit(1);
  149. }
  150.  
  151. /* become a listening socket */
  152. listen(sd, 5);
  153.  
  154. while (1) {
  155.  
  156. /* wait to accept a client request for connection */
  157. cli_addrlen = sizeof(cli_addr);
  158. nsd = accept(sd, (struct sockaddr *) &cli_addr, &cli_addrlen);
  159. if (nsd < 0) {
  160. if (errno == EINTR) /* if interrupted by SIGCHLD */
  161. continue;
  162. perror("server:accept"); exit(1);
  163. }
  164.  
  165. /* create a child process to handle this client */
  166. if ((pid=fork()) <0) {
  167. perror("fork"); exit(1);
  168. } else if (pid > 0) {
  169. close(nsd);
  170. continue; /* parent to wait for next client */
  171. }
  172.  
  173. /* now in child, serve the current client */
  174. close(sd);
  175. serve_a_client(nsd);
  176. exit(0);
  177. }
  178. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement