sorta complicated
[munin-test.git] / server2.c
blobe42bb2da929d35faffceb054bf4389775a393703
1 /* A simple server in the internet domain using TCP */
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <sys/types.h>
5 #include <sys/socket.h>
6 #include <netinet/in.h>
7 #include <signal.h>
8 #include <string.h>
9 #include <sys/time.h>
11 #include <unistd.h>
12 #include <errno.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 */
18 void error(char *msg)
20 perror(msg);
21 exit(1);
24 int main()
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
32 * the child. */
34 signal(SIGCHLD,SIG_IGN);
36 int sockfd, newsockfd, portno, clilen, pid;
37 portno = 4949;
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);
55 if (sockfd < 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 */
76 listen(sockfd,5);
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);
85 while (1) {
86 newsockfd = accept(sockfd,
87 (struct sockaddr *) &cli_addr,
88 &clilen);
89 if (newsockfd < 0)
90 error("ERROR on accept");
91 pid = fork();
92 if (pid <0)
93 error("ERROR on fork");
94 if (pid == 0) {
95 close (sockfd);
96 dostuff(newsockfd);
97 exit(0);
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)
112 int n;
114 /* Server reads characters from the socket connection into
115 * this buffer */
116 char buffer[256];
118 char* nodemsg;
119 nodemsg = "birdbath.riseup.net\n.\n";
121 char* version;
122 version = "fakemunins node on birdbath.riseup.net version: 1.2.4\n";
124 char* timeoutmsg;
125 timeoutmsg = "Timeout!\n";
127 char* errormsg;
128 errormsg = "# Unknown command. Try list, nodes, config, fetch, version or quit\n";
130 char* greeting;
131 greeting = "# munin node at birdbath.riseup.net\n";
133 n = write(sock, greeting, strlen(greeting));
135 int loop;
136 loop=1;
138 while (loop) {
140 bzero(buffer,256);
141 n = read(sock,buffer,255);
142 buffer[n+1] = '\0';
144 if (n < 0) error("ERROR reading from socket");
146 if(strcmp(buffer, "list\r\n") == 0) {
147 FILE *fpipe;
148 char *command="ls /etc/munin/plugins";
149 char line[256];
150 if ( !(fpipe = (FILE*)popen(command,"r")) ) {
151 perror("Problems with pipe");
152 exit(1);
155 while ( fgets( line, sizeof line, fpipe))
157 n = write (sock, line, strlen(line));
159 pclose(fpipe);
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) {
168 /* spit configs */
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) {
180 exit(0);
183 else {
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");