1 /* A simple server in the internet domain using TCP */
5 #include <sys/socket.h>
6 #include <netinet/in.h>
14 void dostuff(int); /* function prototype */
16 /* This function is called when a system call fails,
17 * it will display on stderr and then abort */
26 /* The following keeps zombies at bay.
27 * When children die and the parent doesn't wait() on
28 * them then their SIGCHLD handler is not happy because
29 * the process is not permitted to fully die because at
30 * some point in the future, the parent of the process might
31 * want to execute a wait and would want info on the death of
34 signal(SIGCHLD
,SIG_IGN
);
36 int sockfd
, newsockfd
, portno
, clilen
, pid
;
39 /* sockfd and newsockfd are file descriptors containing
40 * the values returned by the socket and accept syscall
41 * portno stores the port number the server will accept
42 * connections, clilen stores the size of the address of
43 * the client, this is needed for the accept syscall,
44 * n is the return value for the read() and write() calls,
45 * which will be the number of characters read or written.
48 /* serv_addr will contain the address of the server, and
49 * cli_addr will contain the address of the client connecting */
51 struct sockaddr_in serv_addr
, cli_addr
;
53 /* Create a new socket */
54 sockfd
= socket(AF_INET
, SOCK_STREAM
, 0);
56 error("ERROR opening socket");
58 /* zero out the serv_addr buffer */
59 bzero((char *) &serv_addr
, sizeof(serv_addr
));
61 /* set serv_addr structure fields:
62 * sin_family = code for the address family
63 * sin_port = contains the port number (converted to network byte order)
64 * in_addr = contains s_addr = IP address of the server */
65 serv_addr
.sin_family
= AF_INET
;
66 serv_addr
.sin_port
= htons(portno
);
67 serv_addr
.sin_addr
.s_addr
= INADDR_ANY
;
69 /* bind() binds a socket to an address, takes socket fd, address to bind
70 * size of the address to which it is bound */
71 if (bind(sockfd
, (struct sockaddr
*) &serv_addr
,
72 sizeof(serv_addr
)) < 0)
73 error("ERROR on binding");
75 /* listen on the socket for connections */
78 /* accept() causes the process to block until client connects, wakes up
79 * when a connection from a client has succeeded and then returns a new
80 * file descriptor, and all communications should be done on this fd.
81 * The second argument is a reference pointer to the address of the client
82 * on the other end of the connection, third arg is the size of the structure. */
83 clilen
= sizeof(cli_addr
);
86 newsockfd
= accept(sockfd
,
87 (struct sockaddr
*) &cli_addr
,
90 error("ERROR on accept");
93 error("ERROR on fork");
99 else close (newsockfd
);
100 } /* end of while loop */
101 return 0; /* never gets here */
104 /******** DOSTUFF() *********************
105 * There is a separate instance of this function
106 * for each connection. It handles all communication
107 * once a connnection has been established.
108 ******************************************/
110 void dostuff (int sock
)
114 /* Server reads characters from the socket connection into
119 nodemsg
= "birdbath.riseup.net\n.\n";
122 version
= "fakemunins node on birdbath.riseup.net version: 1.2.4\n";
125 timeoutmsg
= "Timeout!\n";
128 errormsg
= "# Unknown command. Try list, nodes, config, fetch, version or quit\n";
131 greeting
= "# munin node at birdbath.riseup.net\n";
133 n
= write(sock
, greeting
, strlen(greeting
));
141 n
= read(sock
,buffer
,255);
144 if (n
< 0) error("ERROR reading from socket");
146 if(strcmp(buffer
, "list\r\n") == 0) {
148 char *command
="ls /etc/munin/plugins";
150 if ( !(fpipe
= (FILE*)popen(command
,"r")) ) {
151 perror("Problems with pipe");
155 while ( fgets( line
, sizeof line
, fpipe
))
157 n
= write (sock
, line
, strlen(line
));
163 else if(strcmp(buffer
, "nodes\r\n") == 0) {
164 n
= write (sock
, nodemsg
, strlen(nodemsg
));
167 else if(strcmp(buffer
, "config\r\n") == 0) {
171 else if(strcmp(buffer
, "help\r\n") == 0) {
172 n
= write (sock
, errormsg
, strlen(errormsg
));
175 else if(strcmp(buffer
, "version\r\n") == 0) {
176 n
= write (sock
, version
, strlen(version
));
179 else if(strcmp(buffer
, "quit\r\n") == 0) {
184 n
= write(sock
, errormsg
, strlen(errormsg
));
188 /* n = write(sock,"I got your message",18); */
189 if (n
< 0) error("ERROR writing to socket");