source: npl/mediabox/lcdproc_edwin/src/server/sock.c

Last change on this file was c5c522c, checked in by Edwin Eefting <edwin@datux.nl>, 8 years ago

initial commit, transferred from cleaned syn3 svn tree

  • Property mode set to 100644
File size: 6.0 KB
Line 
1#include <unistd.h>
2#include <stddef.h>
3#include <stdio.h>
4#include <errno.h>
5#include <stdlib.h>
6#include <sys/socket.h>
7#include <sys/un.h>
8#include <sys/time.h>
9#include <sys/types.h>
10#include <netinet/in.h>
11#include <netdb.h>
12#include <sys/socket.h>
13#include <arpa/inet.h>
14#include <fcntl.h>
15
16#include "../shared/sockets.h"
17#include "sock.h"
18#include "clients.h"
19#include "../shared/debug.h"
20
21
22/**************************************************
23  LCDproc sockets code...
24
25  This is messy, and needs to be finished.
26**************************************************/
27
28fd_set active_fd_set, read_fd_set;
29int orig_sock;
30
31// Length of longest transmission allowed at once...
32#define MAXMSG 8192
33
34
35int read_from_client (int filedes);
36
37
38// Creates a socket in internet space
39int sock_create_inet_socket(unsigned short int port)
40{
41  struct sockaddr_in name;
42  int sock;
43
44  debug("sock_create_inet_socket(%i)\n", port);
45 
46  /* Create the socket. */
47  //debug("Creating Inet Socket\n");
48  sock = socket (PF_INET, SOCK_STREAM, 0);
49  if (sock < 0)
50  {
51     perror("Error creating socket");
52     return -1;
53  }
54     
55  /* Give the socket a name. */
56  //debug("Binding Inet Socket\n");
57  name.sin_family = AF_INET;
58  name.sin_port = htons (port);
59  name.sin_addr.s_addr = htonl (INADDR_ANY);
60  if (bind (sock, (struct sockaddr *) &name, sizeof (name)) < 0)
61  {
62     perror("Error binding socket");
63     return -1;
64  }
65     
66  return sock;
67 
68}
69
70//int StartSocketServer()
71int sock_create_server()
72{
73   int sock;
74     
75  debug("sock_create_server()\n");
76 
77  /* Create the socket and set it up to accept connections. */
78  sock = sock_create_inet_socket(LCDPORT);
79  if(sock < 0)
80    {
81      perror("sock_create_server: Error creating socket");
82      return -1;
83    }
84 
85 
86  if (listen (sock, 1) < 0)
87    {
88      perror("sock_create_server: Listen error");
89      return -1;
90    }
91 
92  /* Initialize the set of active sockets. */
93  FD_ZERO (&active_fd_set);
94  FD_SET (sock, &active_fd_set);
95
96  orig_sock = sock;
97 
98/*
99  {
100     int val, len, sock;
101     sock = new;
102     
103     len = sizeof(int);
104     getsockopt(sock, SOL_SOCKET, SO_SNDBUF, &val, &len);
105     printf("SEND buffer: %i bytes\n", val);
106
107     len = sizeof(int);
108     getsockopt(sock, SOL_SOCKET, SO_RCVBUF, &val, &len);
109     printf("RECV buffer: %i bytes\n", val);
110  }
111*/
112
113  return sock;
114}
115
116
117int sock_poll_clients()
118{
119   int i;
120   int err;
121   struct sockaddr_in clientname;
122   size_t size;
123   struct timeval t;
124   client *c;
125   
126   //debug("sock_poll_clients()\n");
127   
128   t.tv_sec = 0;
129   t.tv_usec = 0;
130
131   /* Block until input arrives on one or more active sockets. */
132   read_fd_set = active_fd_set;
133   
134   if (select (FD_SETSIZE, &read_fd_set, NULL, NULL, &t) < 0)
135   {
136      perror("sock_poll_clients: Select error");
137      return -1;
138   }
139
140   /* Service all the sockets with input pending. */
141   for (i = 0; i < FD_SETSIZE; ++i)
142   {
143      if (FD_ISSET (i, &read_fd_set))
144      {
145         if (i == orig_sock)
146         {
147            /* Connection request on original socket. */
148            int new;
149            size = sizeof (clientname);
150            new = accept (orig_sock,
151                          (struct sockaddr *) &clientname,
152                          &size);
153            if (new < 0)
154            {
155               perror("sock_poll_clients: Accept error");
156               return -1;
157            }
158            debug("sock_poll_clients: connect from host %s, port %hd.\n",
159                     inet_ntoa (clientname.sin_addr),
160                     ntohs (clientname.sin_port));
161            FD_SET (new, &active_fd_set);
162
163            fcntl(new, F_SETFL, O_NONBLOCK);
164           
165
166            // TODO:  Create new "client" here...  (done?)
167            if ( client_create(new) == NULL)
168            {
169               fprintf(stderr,
170                       "sock_poll_clients: error creating client %i\n",
171                       i);
172               return -1;
173            }
174         }
175         else
176         {
177            /* Data arriving on an already-connected socket. */
178            err = 0;
179            do {
180               debug("sock_poll_clients: reading...\n");
181               err = read_from_client(i);
182               debug("sock_poll_clients: ...done\n");
183               if (err < 0)
184               {
185                  // TODO:  Destroy a "client" here... (done?)
186                  c = client_find_sock(i);
187                  if(c)
188                  {
189                     //sock_send_string(i, "bye\n");
190                     client_destroy(c);
191                     close (i);
192                     FD_CLR (i, &active_fd_set);
193                     debug("sock_poll_clients: Closed connection %i\n", i);
194                  }
195                  else fprintf(stderr,
196                               "sock_poll_clients: Can't find client %i\n",
197                               i);
198               }
199            } while (err > 0);
200           
201         }
202      }
203   }
204   return 0;
205}
206
207
208int read_from_client (int filedes)
209{
210   char buffer[MAXMSG];
211   int nbytes, i;
212   client *c;
213   
214//   nbytes = read (filedes, buffer, MAXMSG);
215   //debug("read_from_client(%i): reading...\n", filedes);
216   nbytes = sock_recv (filedes, buffer, MAXMSG);
217   //debug("read_from_client(%i): ...done\n", filedes);
218   debug("read_from_client(%i): %i bytes\n", filedes, nbytes);
219   
220 
221   if (nbytes < 0)  // Read error?  No data available?
222   {
223      // TODO:  check errno here!
224      //fprintf (stderr,"read_from_client: Read error\n");
225      return 0;
226   }
227   else if (nbytes == 0)  // EOF
228      return -1;
229   else if (nbytes > (MAXMSG - (MAXMSG / 8)))  // Very noisy client...
230   {
231      sock_send_string(filedes, "huh? Shut up!\n");
232      return -1;
233   }
234   else         // Data Read
235   {
236      buffer[nbytes] = 0;
237      // Now, replace zeros with linefeeds...
238      for(i=0; i<nbytes; i++)
239         if(buffer[i] == 0) buffer[i] = '\n';
240      // Enqueue a "client message" here...
241      c = client_find_sock(filedes);
242      if(c)
243      {
244         client_add_message(c, buffer);
245      }
246      else fprintf(stderr, "read_from_client:  Can't find client %i\n",
247                   filedes);
248     
249      debug("read_from_client: got message: `%s'\n", buffer);
250      return nbytes;
251   }
252   return nbytes;
253}
254
255// FIXME: This talks to all open files, including
256// stdin, stdout, stderr, the LCD, etc...
257// BUT it should only talk to sockets!
258int sock_close_all()
259{
260   int i;
261
262   debug("sock_close_all()\n");
263   
264   for (i = 0; i < FD_SETSIZE; i++)
265   {
266      // TODO:  Destroy a "client" here...?  Nope.
267      sock_send_string(i, "bye\n");
268      close (i);
269      FD_CLR (i, &active_fd_set);
270      debug("sock_close_all: Closed connection %i\n", i);
271   }
272
273   return 0;
274 
275}
Note: See TracBrowser for help on using the repository browser.