/[svn]/liblscp/trunk/examples/server.c
ViewVC logotype

Diff of /liblscp/trunk/examples/server.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 962 by capela, Sun Sep 24 12:55:48 2006 UTC revision 963 by capela, Sun Dec 3 18:30:04 2006 UTC
# Line 50  static void _lscp_connect_list_init ( ls Line 50  static void _lscp_connect_list_init ( ls
50  {  {
51  //  fprintf(stderr, "_lscp_connect_list_init: pList=%p.\n", pList);  //  fprintf(stderr, "_lscp_connect_list_init: pList=%p.\n", pList);
52    
53      pList->first = NULL;          pList->first = NULL;
54      pList->last  = NULL;          pList->last  = NULL;
55      pList->count = 0;          pList->count = 0;
56    
57      lscp_mutex_init(pList->mutex);          lscp_mutex_init(pList->mutex);
58  }  }
59    
60    
# Line 62  static void _lscp_connect_list_append ( Line 62  static void _lscp_connect_list_append (
62  {  {
63  //  fprintf(stderr, "_lscp_connect_list_append: pList=%p pItem=%p.\n", pList, pItem);  //  fprintf(stderr, "_lscp_connect_list_append: pList=%p pItem=%p.\n", pList, pItem);
64    
65      lscp_mutex_lock(pList->mutex);          lscp_mutex_lock(pList->mutex);
66    
67      pItem->prev = pList->last;          pItem->prev = pList->last;
68      pItem->next = NULL;          pItem->next = NULL;
69    
70      if (pList->last)          if (pList->last)
71          (pList->last)->next = pItem;                  (pList->last)->next = pItem;
72      else          else
73          pList->first = pItem;                  pList->first = pItem;
74    
75      pList->last = pItem;          pList->last = pItem;
76    
77      pList->count++;          pList->count++;
78    
79      lscp_mutex_unlock(pList->mutex);          lscp_mutex_unlock(pList->mutex);
80  }  }
81    
82    
# Line 84  static void _lscp_connect_list_remove ( Line 84  static void _lscp_connect_list_remove (
84  {  {
85  //  fprintf(stderr, "_lscp_connect_list_remove: pList=%p pItem=%p.\n", pList, pItem);  //  fprintf(stderr, "_lscp_connect_list_remove: pList=%p pItem=%p.\n", pList, pItem);
86    
87      if (pItem->next)          if (pItem->next)
88          (pItem->next)->prev = pItem->prev;                  (pItem->next)->prev = pItem->prev;
89      else          else
90          pList->last = pItem->prev;                  pList->last = pItem->prev;
91    
92      if (pItem->prev)          if (pItem->prev)
93          (pItem->prev)->next = pItem->next;                  (pItem->prev)->next = pItem->next;
94      else          else
95          pList->first = pItem->next;                  pList->first = pItem->next;
96    
97      pItem->next = NULL;          pItem->next = NULL;
98      pItem->prev = NULL;          pItem->prev = NULL;
99    
100      pList->count--;          pList->count--;
101  }  }
102    
103    
104  static void _lscp_connect_list_remove_safe ( lscp_connect_list_t *pList, lscp_connect_t *pItem )  static void _lscp_connect_list_remove_safe ( lscp_connect_list_t *pList, lscp_connect_t *pItem )
105  {  {
106      lscp_connect_t *p;          lscp_connect_t *p;
107    
108  //  fprintf(stderr, "_lscp_connect_list_remove_safe: pList=%p pItem=%p.\n", pList, pItem);  //  fprintf(stderr, "_lscp_connect_list_remove_safe: pList=%p pItem=%p.\n", pList, pItem);
109    
110      lscp_mutex_lock(pList->mutex);          lscp_mutex_lock(pList->mutex);
111    
112      for (p = pList->first; p; p = p->next) {          for (p = pList->first; p; p = p->next) {
113          if (p == pItem) {                  if (p == pItem) {
114              _lscp_connect_list_remove(pList, pItem);                          _lscp_connect_list_remove(pList, pItem);
115              break;                          break;
116          }                  }
117      }          }
118    
119      lscp_mutex_unlock(pList->mutex);          lscp_mutex_unlock(pList->mutex);
120  }  }
121    
122    
123  static void _lscp_connect_list_free ( lscp_connect_list_t *pList )  static void _lscp_connect_list_free ( lscp_connect_list_t *pList )
124  {  {
125      lscp_connect_t *p, *pNext;          lscp_connect_t *p, *pNext;
126    
127  //  fprintf(stderr, "_lscp_connect_list_free: pList=%p.\n", pList);  //  fprintf(stderr, "_lscp_connect_list_free: pList=%p.\n", pList);
128    
129      lscp_mutex_lock(pList->mutex);          lscp_mutex_lock(pList->mutex);
130    
131      for (p = pList->first; p; p = pNext) {          for (p = pList->first; p; p = pNext) {
132          pNext = p->next;                  pNext = p->next;
133          _lscp_connect_list_remove(pList, p);                  _lscp_connect_list_remove(pList, p);
134          _lscp_connect_destroy(p);                  _lscp_connect_destroy(p);
135      }          }
136    
137      lscp_mutex_unlock(pList->mutex);          lscp_mutex_unlock(pList->mutex);
138                
139      lscp_mutex_destroy(pList->mutex);          lscp_mutex_destroy(pList->mutex);
140  }  }
141    
142    
143  static lscp_connect_t *_lscp_connect_list_find_sock ( lscp_connect_list_t *pList, lscp_socket_t sock )  static lscp_connect_t *_lscp_connect_list_find_sock ( lscp_connect_list_t *pList, lscp_socket_t sock )
144  {  {
145      lscp_connect_t *p;          lscp_connect_t *p;
146    
147  //  fprintf(stderr, "_lscp_connect_list_find_sock: pList=%p sock=%d.\n", pList, sock);  //  fprintf(stderr, "_lscp_connect_list_find_sock: pList=%p sock=%d.\n", pList, sock);
148    
149      for (p = pList->first; p; p = p->next) {          for (p = pList->first; p; p = p->next) {
150          if (sock == p->client.sock)                  if (sock == p->client.sock)
151              return p;                          return p;
152      }          }
153    
154      return NULL;          return NULL;
155  }  }
156    
157  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
# Line 159  static lscp_connect_t *_lscp_connect_lis Line 159  static lscp_connect_t *_lscp_connect_lis
159    
160  static void _lscp_connect_proc ( void *pvConnect )  static void _lscp_connect_proc ( void *pvConnect )
161  {  {
162      lscp_connect_t *pConnect = (lscp_connect_t *) pvConnect;          lscp_connect_t *pConnect = (lscp_connect_t *) pvConnect;
163      lscp_server_t  *pServer  = pConnect->server;          lscp_server_t  *pServer  = pConnect->server;
164    
165      while (pServer->agent.iState && pConnect->client.iState) {          while (pServer->agent.iState && pConnect->client.iState) {
166          if (_lscp_connect_recv(pConnect) != LSCP_OK)                  if (_lscp_connect_recv(pConnect) != LSCP_OK)
167              pConnect->client.iState = 0;                          pConnect->client.iState = 0;
168      }          }
169    
170      (*pServer->pfnCallback)(pConnect, NULL, LSCP_CONNECT_CLOSE, pServer->pvData);          (*pServer->pfnCallback)(pConnect, NULL, LSCP_CONNECT_CLOSE, pServer->pvData);
171      _lscp_connect_list_remove_safe(&(pServer->connects), pConnect);          _lscp_connect_list_remove_safe(&(pServer->connects), pConnect);
172      closesocket(pConnect->client.sock);          closesocket(pConnect->client.sock);
173  }  }
174    
175  static lscp_connect_t *_lscp_connect_create ( lscp_server_t *pServer, lscp_socket_t sock, struct sockaddr_in *pAddr, int cAddr )  static lscp_connect_t *_lscp_connect_create ( lscp_server_t *pServer, lscp_socket_t sock, struct sockaddr_in *pAddr, int cAddr )
176  {  {
177      lscp_connect_t *pConnect;          lscp_connect_t *pConnect;
178    
179      if (pServer == NULL || sock == INVALID_SOCKET || pAddr == NULL) {          if (pServer == NULL || sock == INVALID_SOCKET || pAddr == NULL) {
180          fprintf(stderr, "_lscp_connect_create: Invalid connection arguments.\n");                  fprintf(stderr, "_lscp_connect_create: Invalid connection arguments.\n");
181          return NULL;                  return NULL;
182      }          }
183    
184      pConnect = (lscp_connect_t *) malloc(sizeof(lscp_connect_t));          pConnect = (lscp_connect_t *) malloc(sizeof(lscp_connect_t));
185      if (pConnect == NULL) {          if (pConnect == NULL) {
186          fprintf(stderr, "_lscp_connect_create: Out of memory.\n");                  fprintf(stderr, "_lscp_connect_create: Out of memory.\n");
187          closesocket(sock);                  closesocket(sock);
188          return NULL;                  return NULL;
189      }          }
190      memset(pConnect, 0, sizeof(lscp_connect_t));          memset(pConnect, 0, sizeof(lscp_connect_t));
191    
192      pConnect->server = pServer;          pConnect->server = pServer;
193      pConnect->events = LSCP_EVENT_NONE;          pConnect->events = LSCP_EVENT_NONE;
194    
195  #ifdef DEBUG  #ifdef DEBUG
196      fprintf(stderr, "_lscp_connect_create: pConnect=%p: sock=%d addr=%s port=%d.\n", pConnect, sock, inet_ntoa(pAddr->sin_addr), ntohs(pAddr->sin_port));          fprintf(stderr, "_lscp_connect_create: pConnect=%p: sock=%d addr=%s port=%d.\n", pConnect, sock, inet_ntoa(pAddr->sin_addr), ntohs(pAddr->sin_port));
197  #endif  #endif
198    
199      lscp_socket_agent_init(&(pConnect->client), sock, pAddr, cAddr);          lscp_socket_agent_init(&(pConnect->client), sock, pAddr, cAddr);
200    
201      if (pServer->mode == LSCP_SERVER_THREAD) {          if (pServer->mode == LSCP_SERVER_THREAD) {
202          if (lscp_socket_agent_start(&(pConnect->client), _lscp_connect_proc, pConnect, 0) != LSCP_OK) {                  if (lscp_socket_agent_start(&(pConnect->client), _lscp_connect_proc, pConnect, 0) != LSCP_OK) {
203              closesocket(sock);                          closesocket(sock);
204              free(pConnect);                          free(pConnect);
205              return NULL;                          return NULL;
206          }                  }
207      }          }
208    
209      return pConnect;          return pConnect;
210  }  }
211    
212    
213  static lscp_status_t _lscp_connect_destroy ( lscp_connect_t *pConnect )  static lscp_status_t _lscp_connect_destroy ( lscp_connect_t *pConnect )
214  {  {
215      lscp_status_t ret = LSCP_FAILED;          lscp_status_t ret = LSCP_FAILED;
216    
217      if (pConnect == NULL)          if (pConnect == NULL)
218          return ret;                  return ret;
219    
220  #ifdef DEBUG  #ifdef DEBUG
221      fprintf(stderr, "_lscp_connect_destroy: pConnect=%p.\n", pConnect);          fprintf(stderr, "_lscp_connect_destroy: pConnect=%p.\n", pConnect);
222  #endif  #endif
223    
224      lscp_socket_agent_free(&(pConnect->client));          lscp_socket_agent_free(&(pConnect->client));
225    
226      free(pConnect);          free(pConnect);
227    
228      return ret;          return ret;
229  }  }
230    
231    
232  lscp_status_t _lscp_connect_recv ( lscp_connect_t *pConnect )  lscp_status_t _lscp_connect_recv ( lscp_connect_t *pConnect )
233  {  {
234      lscp_status_t ret = LSCP_FAILED;          lscp_status_t ret = LSCP_FAILED;
235      lscp_server_t *pServer;          lscp_server_t *pServer;
236      char achBuffer[LSCP_BUFSIZ];          char achBuffer[LSCP_BUFSIZ];
237      int cchBuffer;          int cchBuffer;
238    
239      if (pConnect == NULL)          if (pConnect == NULL)
240          return ret;                  return ret;
241    
242      pServer = pConnect->server;          pServer = pConnect->server;
243      if (pServer == NULL)          if (pServer == NULL)
244          return ret;                  return ret;
245    
246      cchBuffer = recv(pConnect->client.sock, achBuffer, sizeof(achBuffer), 0);          cchBuffer = recv(pConnect->client.sock, achBuffer, sizeof(achBuffer), 0);
247      if (cchBuffer > 0)          if (cchBuffer > 0)
248          ret = (*pServer->pfnCallback)(pConnect, achBuffer, cchBuffer, pServer->pvData);                  ret = (*pServer->pfnCallback)(pConnect, achBuffer, cchBuffer, pServer->pvData);
249      else if (cchBuffer < 0)          else if (cchBuffer < 0)
250          lscp_socket_perror("_lscp_connect_recv: recv");                  lscp_socket_perror("_lscp_connect_recv: recv");
251    
252      return ret;          return ret;
253  }  }
254    
255    
# Line 258  lscp_status_t _lscp_connect_recv ( lscp_ Line 258  lscp_status_t _lscp_connect_recv ( lscp_
258    
259  static void _lscp_server_thread_proc ( lscp_server_t *pServer )  static void _lscp_server_thread_proc ( lscp_server_t *pServer )
260  {  {
261      lscp_socket_t sock;          lscp_socket_t sock;
262      struct sockaddr_in addr;          struct sockaddr_in addr;
263      socklen_t cAddr;          socklen_t cAddr;
264      lscp_connect_t *pConnect;          lscp_connect_t *pConnect;
265    
266  #ifdef DEBUG  #ifdef DEBUG
267      fprintf(stderr, "_lscp_server_thread_proc: Server listening for connections.\n");          fprintf(stderr, "_lscp_server_thread_proc: Server listening for connections.\n");
268  #endif  #endif
269    
270      while (pServer->agent.iState) {          while (pServer->agent.iState) {
271          cAddr = sizeof(struct sockaddr_in);                  cAddr = sizeof(struct sockaddr_in);
272          sock = accept(pServer->agent.sock, (struct sockaddr *) &addr, &cAddr);                  sock = accept(pServer->agent.sock, (struct sockaddr *) &addr, &cAddr);
273          if (sock == INVALID_SOCKET) {                  if (sock == INVALID_SOCKET) {
274              lscp_socket_perror("_lscp_server_thread_proc: accept");                          lscp_socket_perror("_lscp_server_thread_proc: accept");
275              pServer->agent.iState = 0;                          pServer->agent.iState = 0;
276          } else {                  } else {
277              pConnect = _lscp_connect_create(pServer, sock, &addr, cAddr);                          pConnect = _lscp_connect_create(pServer, sock, &addr, cAddr);
278              if (pConnect) {                          if (pConnect) {
279                  _lscp_connect_list_append(&(pServer->connects), pConnect);                                  _lscp_connect_list_append(&(pServer->connects), pConnect);
280                  (*pServer->pfnCallback)(pConnect, NULL, LSCP_CONNECT_OPEN, pServer->pvData);                                  (*pServer->pfnCallback)(pConnect, NULL, LSCP_CONNECT_OPEN, pServer->pvData);
281              }                          }
282          }                  }
283      }          }
284    
285  #ifdef DEBUG  #ifdef DEBUG
286      fprintf(stderr, "_lscp_server_thread_proc: Server closing.\n");          fprintf(stderr, "_lscp_server_thread_proc: Server closing.\n");
287  #endif  #endif
288  }  }
289    
290    
291  static void _lscp_server_select_proc ( lscp_server_t *pServer )  static void _lscp_server_select_proc ( lscp_server_t *pServer )
292  {  {
293      fd_set master_fds;  // Master file descriptor list.          fd_set master_fds;  // Master file descriptor list.
294      fd_set select_fds;  // temp file descriptor list for select().          fd_set select_fds;  // temp file descriptor list for select().
295      int fd, fdmax;      // Maximum file descriptor number.          int fd, fdmax;      // Maximum file descriptor number.
296      struct timeval tv;  // For specifying a timeout value.          struct timeval tv;  // For specifying a timeout value.
297      int iSelect;        // Holds select return status.          int iSelect;        // Holds select return status.
298    
299      lscp_socket_t sock;          lscp_socket_t sock;
300      struct sockaddr_in addr;          struct sockaddr_in addr;
301      socklen_t cAddr;          socklen_t cAddr;
302      lscp_connect_t *pConnect;          lscp_connect_t *pConnect;
303    
304  #ifdef DEBUG  #ifdef DEBUG
305      fprintf(stderr, "_lscp_server_select_proc: Server listening for connections.\n");          fprintf(stderr, "_lscp_server_select_proc: Server listening for connections.\n");
306  #endif  #endif
307      FD_ZERO(&master_fds);          FD_ZERO(&master_fds);
308      FD_ZERO(&select_fds);          FD_ZERO(&select_fds);
309    
310      // Add the listener to the master set          // Add the listener to the master set
311      FD_SET((unsigned int) pServer->agent.sock, &master_fds);          FD_SET((unsigned int) pServer->agent.sock, &master_fds);
312    
313      // Keep track of the biggest file descriptor;          // Keep track of the biggest file descriptor;
314      // So far, it's ourself, the listener.          // So far, it's ourself, the listener.
315      fdmax = (int) pServer->agent.sock;          fdmax = (int) pServer->agent.sock;
316    
317      // Main loop...          // Main loop...
318      while (pServer->agent.iState) {          while (pServer->agent.iState) {
319    
320          // Use a copy of the master.                  // Use a copy of the master.
321          select_fds = master_fds;                  select_fds = master_fds;
322          // Use the timeout feature for watchdoggin.                  // Use the timeout feature for watchdoggin.
323          tv.tv_sec = LSCP_SERVER_SLEEP;                  tv.tv_sec = LSCP_SERVER_SLEEP;
324          tv.tv_usec = 0;                  tv.tv_usec = 0;
325          // Wait for events...                  // Wait for events...
326          iSelect = select(fdmax + 1, &select_fds, NULL, NULL, &tv);                  iSelect = select(fdmax + 1, &select_fds, NULL, NULL, &tv);
327    
328          if (iSelect < 0) {                  if (iSelect < 0) {
329              lscp_socket_perror("_lscp_server_select_proc: select");                          lscp_socket_perror("_lscp_server_select_proc: select");
330              pServer->agent.iState = 0;                          pServer->agent.iState = 0;
331          }                  }
332          else if (iSelect > 0) {                  else if (iSelect > 0) {
333              // Run through the existing connections looking for data to read...                          // Run through the existing connections looking for data to read...
334              for (fd = 0; fd < fdmax + 1; fd++) {                          for (fd = 0; fd < fdmax + 1; fd++) {
335                  if (FD_ISSET(fd, &select_fds)) {    // We got one!!                                  if (FD_ISSET(fd, &select_fds)) {    // We got one!!
336                      // Is it ourselves, the command listener?                                          // Is it ourselves, the command listener?
337                      if (fd == (int) pServer->agent.sock) {                                          if (fd == (int) pServer->agent.sock) {
338                          // Accept the connection...                                                  // Accept the connection...
339                          cAddr = sizeof(struct sockaddr_in);                                                  cAddr = sizeof(struct sockaddr_in);
340                          sock = accept(pServer->agent.sock, (struct sockaddr *) &addr, &cAddr);                                                  sock = accept(pServer->agent.sock, (struct sockaddr *) &addr, &cAddr);
341                          if (sock == INVALID_SOCKET) {                                                  if (sock == INVALID_SOCKET) {
342                              lscp_socket_perror("_lscp_server_select_proc: accept");                                                          lscp_socket_perror("_lscp_server_select_proc: accept");
343                              pServer->agent.iState = 0;                                                          pServer->agent.iState = 0;
344                          } else {                                                  } else {
345                              // Add to master set.                                                          // Add to master set.
346                              FD_SET((unsigned int) sock, &master_fds);                                                          FD_SET((unsigned int) sock, &master_fds);
347                              // Keep track of the maximum.                                                          // Keep track of the maximum.
348                              if ((int) sock > fdmax)                                                          if ((int) sock > fdmax)
349                                  fdmax = (int) sock;                                                                  fdmax = (int) sock;
350                              // And do create the client connection entry.                                                          // And do create the client connection entry.
351                              pConnect = _lscp_connect_create(pServer, sock, &addr, cAddr);                                                          pConnect = _lscp_connect_create(pServer, sock, &addr, cAddr);
352                              if (pConnect) {                                                          if (pConnect) {
353                                  _lscp_connect_list_append(&(pServer->connects), pConnect);                                                                  _lscp_connect_list_append(&(pServer->connects), pConnect);
354                                  (*pServer->pfnCallback)(pConnect, NULL, LSCP_CONNECT_OPEN, pServer->pvData);                                                                  (*pServer->pfnCallback)(pConnect, NULL, LSCP_CONNECT_OPEN, pServer->pvData);
355                              }                                                          }
356                          }                                                  }
357                          // Done with one new connection.                                                  // Done with one new connection.
358                      } else {                                          } else {
359                          // Otherwise it's trivial transaction...                                                  // Otherwise it's trivial transaction...
360                          lscp_mutex_lock(pServer->connects.mutex);                                                  lscp_mutex_lock(pServer->connects.mutex);
361                          // Find the connection on our cache...                                                  // Find the connection on our cache...
362                          pConnect = _lscp_connect_list_find_sock(&(pServer->connects), (lscp_socket_t) fd);                                                  pConnect = _lscp_connect_list_find_sock(&(pServer->connects), (lscp_socket_t) fd);
363                          // Handle data from a client.                                                  // Handle data from a client.
364                          if (_lscp_connect_recv(pConnect) != LSCP_OK) {                                                  if (_lscp_connect_recv(pConnect) != LSCP_OK) {
365                              // Say bye bye!                                                          // Say bye bye!
366                              if (pConnect) {                                                          if (pConnect) {
367                                  (*pServer->pfnCallback)(pConnect, NULL, LSCP_CONNECT_CLOSE, pServer->pvData);                                                                  (*pServer->pfnCallback)(pConnect, NULL, LSCP_CONNECT_CLOSE, pServer->pvData);
368                                  _lscp_connect_list_remove(&(pServer->connects), pConnect);                                                                  _lscp_connect_list_remove(&(pServer->connects), pConnect);
369                                  _lscp_connect_destroy(pConnect);                                                                  _lscp_connect_destroy(pConnect);
370                              }                                                          }
371                              // Remove from master set.                                                          // Remove from master set.
372                              FD_CLR((unsigned int) fd, &master_fds);                                                          FD_CLR((unsigned int) fd, &master_fds);
373                          }                                                  }
374                          lscp_mutex_unlock(pServer->connects.mutex);                                                  lscp_mutex_unlock(pServer->connects.mutex);
375                      }                                          }
376                  }                                  }
377              }                          }
378              // Done (iSelect > 0)                          // Done (iSelect > 0)
379          }                  }
380      }          }
381    
382  #ifdef DEBUG  #ifdef DEBUG
383      fprintf(stderr, "_lscp_server_select_proc: Server closing.\n");          fprintf(stderr, "_lscp_server_select_proc: Server closing.\n");
384  #endif  #endif
385  }  }
386    
387    
388  static void _lscp_server_agent_proc ( void *pvServer )  static void _lscp_server_agent_proc ( void *pvServer )
389  {  {
390      lscp_server_t *pServer = (lscp_server_t *) pvServer;          lscp_server_t *pServer = (lscp_server_t *) pvServer;
391    
392      if (pServer->mode == LSCP_SERVER_THREAD)          if (pServer->mode == LSCP_SERVER_THREAD)
393          _lscp_server_thread_proc(pServer);                  _lscp_server_thread_proc(pServer);
394      else          else
395          _lscp_server_select_proc(pServer);                  _lscp_server_select_proc(pServer);
396  }  }
397    
398    
# Line 427  const char* lscp_server_build   (void) { Line 427  const char* lscp_server_build   (void) {
427   */   */
428  lscp_server_t* lscp_server_create ( int iPort, lscp_server_proc_t pfnCallback, void *pvData )  lscp_server_t* lscp_server_create ( int iPort, lscp_server_proc_t pfnCallback, void *pvData )
429  {  {
430      return lscp_server_create_ex(iPort, pfnCallback, pvData, LSCP_SERVER_SELECT);          return lscp_server_create_ex(iPort, pfnCallback, pvData, LSCP_SERVER_SELECT);
431  }  }
432    
433    
# Line 452  lscp_server_t* lscp_server_create ( int Line 452  lscp_server_t* lscp_server_create ( int
452   */   */
453  lscp_server_t* lscp_server_create_ex ( int iPort, lscp_server_proc_t pfnCallback, void *pvData, lscp_server_mode_t mode )  lscp_server_t* lscp_server_create_ex ( int iPort, lscp_server_proc_t pfnCallback, void *pvData, lscp_server_mode_t mode )
454  {  {
455      lscp_server_t *pServer;          lscp_server_t *pServer;
456      lscp_socket_t sock;          lscp_socket_t sock;
457      struct sockaddr_in addr;          struct sockaddr_in addr;
458      socklen_t cAddr;          socklen_t cAddr;
459      int iSockOpt = (-1);          int iSockOpt = (-1);
460    
461      if (pfnCallback == NULL) {          if (pfnCallback == NULL) {
462          fprintf(stderr, "lscp_server_create: Invalid server callback function.\n");                  fprintf(stderr, "lscp_server_create: Invalid server callback function.\n");
463          return NULL;                  return NULL;
464      }          }
465    
466      // Allocate server descriptor...          // Allocate server descriptor...
467    
468      pServer = (lscp_server_t *) malloc(sizeof(lscp_server_t));          pServer = (lscp_server_t *) malloc(sizeof(lscp_server_t));
469      if (pServer == NULL) {          if (pServer == NULL) {
470          fprintf(stderr, "lscp_server_create: Out of memory.\n");                  fprintf(stderr, "lscp_server_create: Out of memory.\n");
471          return NULL;                  return NULL;
472      }          }
473      memset(pServer, 0, sizeof(lscp_server_t));          memset(pServer, 0, sizeof(lscp_server_t));
474    
475      _lscp_connect_list_init(&(pServer->connects));          _lscp_connect_list_init(&(pServer->connects));
476    
477      pServer->mode = mode;          pServer->mode = mode;
478      pServer->pfnCallback = pfnCallback;          pServer->pfnCallback = pfnCallback;
479      pServer->pvData = pvData;          pServer->pvData = pvData;
480    
481  #ifdef DEBUG  #ifdef DEBUG
482      fprintf(stderr, "lscp_server_create: pServer=%p: iPort=%d.\n", pServer, iPort);          fprintf(stderr, "lscp_server_create: pServer=%p: iPort=%d.\n", pServer, iPort);
483  #endif  #endif
484    
485      // Prepare the command stream server socket...          // Prepare the command stream server socket...
486    
487      sock = socket(AF_INET, SOCK_STREAM, 0);          sock = socket(AF_INET, SOCK_STREAM, 0);
488      if (sock == INVALID_SOCKET) {          if (sock == INVALID_SOCKET) {
489          lscp_socket_perror("lscp_server_create: socket");                  lscp_socket_perror("lscp_server_create: socket");
490          free(pServer);                  free(pServer);
491          return NULL;                  return NULL;
492      }          }
493    
494      if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *) &iSockOpt, sizeof(int)) == SOCKET_ERROR)          if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *) &iSockOpt, sizeof(int)) == SOCKET_ERROR)
495          lscp_socket_perror("lscp_server_create: setsockopt(SO_REUSEADDR)");                  lscp_socket_perror("lscp_server_create: setsockopt(SO_REUSEADDR)");
496  #if defined(WIN32)  #if defined(WIN32)
497      if (setsockopt(sock, SOL_SOCKET, SO_DONTLINGER, (char *) &iSockOpt, sizeof(int)) == SOCKET_ERROR)          if (setsockopt(sock, SOL_SOCKET, SO_DONTLINGER, (char *) &iSockOpt, sizeof(int)) == SOCKET_ERROR)
498          lscp_socket_perror("lscp_server_create: setsockopt(SO_DONTLINGER)");                  lscp_socket_perror("lscp_server_create: setsockopt(SO_DONTLINGER)");
499  #endif  #endif
500    
501  #ifdef DEBUG  #ifdef DEBUG
502      lscp_socket_getopts("lscp_server_create", sock);          lscp_socket_getopts("lscp_server_create", sock);
503  #endif  #endif
504    
505      cAddr = sizeof(struct sockaddr_in);          cAddr = sizeof(struct sockaddr_in);
506      memset((char *) &addr, 0, cAddr);          memset((char *) &addr, 0, cAddr);
507      addr.sin_family = AF_INET;          addr.sin_family = AF_INET;
508      addr.sin_addr.s_addr = htonl(INADDR_ANY);          addr.sin_addr.s_addr = htonl(INADDR_ANY);
509      addr.sin_port = htons((short) iPort);          addr.sin_port = htons((short) iPort);
510    
511      if (bind(sock, (const struct sockaddr *) &addr, cAddr) == SOCKET_ERROR) {          if (bind(sock, (const struct sockaddr *) &addr, cAddr) == SOCKET_ERROR) {
512          lscp_socket_perror("lscp_server_create: bind");                  lscp_socket_perror("lscp_server_create: bind");
513          closesocket(sock);                  closesocket(sock);
514          free(pServer);                  free(pServer);
515          return NULL;                  return NULL;
516      }          }
517    
518      if (listen(sock, 10) == SOCKET_ERROR) {          if (listen(sock, 10) == SOCKET_ERROR) {
519          lscp_socket_perror("lscp_server_create: listen");                  lscp_socket_perror("lscp_server_create: listen");
520          closesocket(sock);                  closesocket(sock);
521          free(pServer);                  free(pServer);
522          return NULL;                  return NULL;
523      }          }
524    
525      if (iPort == 0) {          if (iPort == 0) {
526          if (getsockname(sock, (struct sockaddr *) &addr, &cAddr) == SOCKET_ERROR) {                  if (getsockname(sock, (struct sockaddr *) &addr, &cAddr) == SOCKET_ERROR) {
527              lscp_socket_perror("lscp_server_create: getsockname");                          lscp_socket_perror("lscp_server_create: getsockname");
528              closesocket(sock);                          closesocket(sock);
529              free(pServer);                          free(pServer);
530          }                  }
531      }          }
532    
533      lscp_socket_agent_init(&(pServer->agent), sock, &addr, cAddr);          lscp_socket_agent_init(&(pServer->agent), sock, &addr, cAddr);
534    
535  #ifdef DEBUG  #ifdef DEBUG
536      fprintf(stderr, "lscp_server_create: sock=%d addr=%s port=%d.\n", pServer->agent.sock, inet_ntoa(pServer->agent.addr.sin_addr), ntohs(pServer->agent.addr.sin_port));          fprintf(stderr, "lscp_server_create: sock=%d addr=%s port=%d.\n", pServer->agent.sock, inet_ntoa(pServer->agent.addr.sin_addr), ntohs(pServer->agent.addr.sin_port));
537  #endif  #endif
538    
539      // Now's finally time to startup threads...          // Now's finally time to startup threads...
540    
541      // Command service thread...          // Command service thread...
542      if (lscp_socket_agent_start(&(pServer->agent), _lscp_server_agent_proc, pServer, 0) != LSCP_OK) {          if (lscp_socket_agent_start(&(pServer->agent), _lscp_server_agent_proc, pServer, 0) != LSCP_OK) {
543          lscp_socket_agent_free(&(pServer->agent));                  lscp_socket_agent_free(&(pServer->agent));
544          free(pServer);                  free(pServer);
545          return NULL;                  return NULL;
546      }          }
547    
548      // Finally we've some success...          // Finally we've some success...
549      return pServer;          return pServer;
550  }  }
551    
552    
# Line 557  lscp_server_t* lscp_server_create_ex ( i Line 557  lscp_server_t* lscp_server_create_ex ( i
557   */   */
558  lscp_status_t lscp_server_join ( lscp_server_t *pServer )  lscp_status_t lscp_server_join ( lscp_server_t *pServer )
559  {  {
560      if (pServer == NULL)          if (pServer == NULL)
561          return LSCP_FAILED;                  return LSCP_FAILED;
562    
563  #ifdef DEBUG  #ifdef DEBUG
564      fprintf(stderr, "lscp_server_join: pServer=%p.\n", pServer);          fprintf(stderr, "lscp_server_join: pServer=%p.\n", pServer);
565  #endif  #endif
566    
567      lscp_socket_agent_join(&(pServer->agent));          lscp_socket_agent_join(&(pServer->agent));
568    
569      return LSCP_OK;          return LSCP_OK;
570  }  }
571    
572    
# Line 577  lscp_status_t lscp_server_join ( lscp_se Line 577  lscp_status_t lscp_server_join ( lscp_se
577   */   */
578  lscp_status_t lscp_server_destroy ( lscp_server_t *pServer )  lscp_status_t lscp_server_destroy ( lscp_server_t *pServer )
579  {  {
580      if (pServer == NULL)          if (pServer == NULL)
581          return LSCP_FAILED;                  return LSCP_FAILED;
582    
583  #ifdef DEBUG  #ifdef DEBUG
584      fprintf(stderr, "lscp_server_destroy: pServer=%p.\n", pServer);          fprintf(stderr, "lscp_server_destroy: pServer=%p.\n", pServer);
585  #endif  #endif
586    
587      _lscp_connect_list_free(&(pServer->connects));          _lscp_connect_list_free(&(pServer->connects));
588      lscp_socket_agent_free(&(pServer->agent));          lscp_socket_agent_free(&(pServer->agent));
589    
590      free(pServer);          free(pServer);
591    
592      return LSCP_OK;          return LSCP_OK;
593  }  }
594    
595    
# Line 605  lscp_status_t lscp_server_destroy ( lscp Line 605  lscp_status_t lscp_server_destroy ( lscp
605   */   */
606  lscp_status_t lscp_server_broadcast ( lscp_server_t *pServer, lscp_event_t event, const char *pchData, int cchData )  lscp_status_t lscp_server_broadcast ( lscp_server_t *pServer, lscp_event_t event, const char *pchData, int cchData )
607  {  {
608      lscp_connect_t *p;          lscp_connect_t *p;
609      const char *pszEvent;          const char *pszEvent;
610      char  achBuffer[LSCP_BUFSIZ];          char  achBuffer[LSCP_BUFSIZ];
611      int   cchBuffer;          int   cchBuffer;
612    
613      if (pServer == NULL)          if (pServer == NULL)
614          return LSCP_FAILED;                  return LSCP_FAILED;
615      if (pchData == NULL || cchData < 1)          if (pchData == NULL || cchData < 1)
616          return LSCP_FAILED;                  return LSCP_FAILED;
617    
618      // Which (single) event?          // Which (single) event?
619      pszEvent = lscp_event_to_text(event);          pszEvent = lscp_event_to_text(event);
620      if (pszEvent == NULL)          if (pszEvent == NULL)
621          return LSCP_FAILED;                  return LSCP_FAILED;
622    
623      // Build the event message string...          // Build the event message string...
624      cchBuffer = sprintf(achBuffer, "NOTIFY:%s:", pszEvent);          cchBuffer = sprintf(achBuffer, "NOTIFY:%s:", pszEvent);
625      if (pchData) {          if (pchData) {
626          if (cchData > LSCP_BUFSIZ - cchBuffer - 2)                  if (cchData > LSCP_BUFSIZ - cchBuffer - 2)
627              cchData = LSCP_BUFSIZ - cchBuffer - 2;                          cchData = LSCP_BUFSIZ - cchBuffer - 2;
628          strncpy(&achBuffer[cchBuffer], pchData, cchData);                  strncpy(&achBuffer[cchBuffer], pchData, cchData);
629          cchBuffer += cchData;                  cchBuffer += cchData;
630      }          }
631      achBuffer[cchBuffer++] = '\r';          achBuffer[cchBuffer++] = '\r';
632      achBuffer[cchBuffer++] = '\n';          achBuffer[cchBuffer++] = '\n';
633    
634      // And do the direct broadcasting...          // And do the direct broadcasting...
635                
636      lscp_mutex_lock(pServer->connects.mutex);          lscp_mutex_lock(pServer->connects.mutex);
637    
638      for (p = pServer->connects.first; p; p = p->next) {          for (p = pServer->connects.first; p; p = p->next) {
639          if (p->events & event)                  if (p->events & event)
640              send(p->client.sock, achBuffer, cchBuffer, 0);                          send(p->client.sock, achBuffer, cchBuffer, 0);
641      }          }
642    
643      lscp_mutex_unlock(pServer->connects.mutex);          lscp_mutex_unlock(pServer->connects.mutex);
644    
645      return LSCP_OK;          return LSCP_OK;
646  }  }
647    
648    
# Line 657  lscp_status_t lscp_server_broadcast ( ls Line 657  lscp_status_t lscp_server_broadcast ( ls
657   */   */
658  lscp_status_t lscp_server_result ( lscp_connect_t *pConnect, const char *pchBuffer, int cchBuffer )  lscp_status_t lscp_server_result ( lscp_connect_t *pConnect, const char *pchBuffer, int cchBuffer )
659  {  {
660      lscp_status_t ret = LSCP_FAILED;          lscp_status_t ret = LSCP_FAILED;
661    
662      if (pConnect == NULL)          if (pConnect == NULL)
663          return ret;                  return ret;
664      if (pchBuffer == NULL || cchBuffer < 1)          if (pchBuffer == NULL || cchBuffer < 1)
665          return ret;                  return ret;
666    
667      if (send(pConnect->client.sock, pchBuffer, cchBuffer, 0) != cchBuffer)          if (send(pConnect->client.sock, pchBuffer, cchBuffer, 0) != cchBuffer)
668          lscp_socket_perror("lscp_server_result");                  lscp_socket_perror("lscp_server_result");
669      else          else
670          ret = LSCP_OK;                  ret = LSCP_OK;
671    
672      return ret;          return ret;
673  }  }
674    
675    
# Line 683  lscp_status_t lscp_server_result ( lscp_ Line 683  lscp_status_t lscp_server_result ( lscp_
683   */   */
684  lscp_status_t lscp_server_subscribe ( lscp_connect_t *pConnect, lscp_event_t event )  lscp_status_t lscp_server_subscribe ( lscp_connect_t *pConnect, lscp_event_t event )
685  {  {
686      if (pConnect == NULL)          if (pConnect == NULL)
687          return LSCP_FAILED;                  return LSCP_FAILED;
688      if (event == LSCP_EVENT_NONE)          if (event == LSCP_EVENT_NONE)
689          return LSCP_FAILED;                  return LSCP_FAILED;
690    
691      pConnect->events |= event;          pConnect->events |= event;
692    
693      return LSCP_OK;          return LSCP_OK;
694  }  }
695    
696    
# Line 701  lscp_status_t lscp_server_subscribe ( ls Line 701  lscp_status_t lscp_server_subscribe ( ls
701   *  @param event    Event type flag of the requesting client unsubscription.   *  @param event    Event type flag of the requesting client unsubscription.
702   *   *
703   *  @returns LSCP_OK on success, LSCP_FAILED otherwise.   *  @returns LSCP_OK on success, LSCP_FAILED otherwise.
704  */   */
705  lscp_status_t lscp_server_unsubscribe ( lscp_connect_t *pConnect, lscp_event_t event )  lscp_status_t lscp_server_unsubscribe ( lscp_connect_t *pConnect, lscp_event_t event )
706  {  {
707      if (pConnect == NULL)          if (pConnect == NULL)
708          return LSCP_FAILED;                  return LSCP_FAILED;
709      if (event == LSCP_EVENT_NONE)          if (event == LSCP_EVENT_NONE)
710          return LSCP_FAILED;                  return LSCP_FAILED;
711    
712      pConnect->events &= ~event;          pConnect->events &= ~event;
713    
714      return LSCP_OK;          return LSCP_OK;
715  }  }
716    
717    

Legend:
Removed from v.962  
changed lines
  Added in v.963

  ViewVC Help
Powered by ViewVC