Files
lcdproc/server/clients.c
T

268 lines
5.3 KiB
C
Raw Normal View History

1999-12-09 23:15:14 +00:00
/*
* clients.c
* This file is part of LCDd, the lcdproc server.
*
* This file is released under the GNU General Public License. Refer to the
* COPYING file distributed with this package.
*
* Copyright (c) 1999, William Ferrell, Scott Scriven
*
*
* Inits/shuts down client system,
* creates/destroys individual clients,
* enqueues/dequeues messages from clients,
* and searches for clients in the list.
*
* :)
*
1999-12-09 23:15:14 +00:00
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include "sock.h"
1999-12-09 23:15:14 +00:00
#include "clients.h"
#include "client_data.h"
2001-11-29 14:09:13 +00:00
#include "shared/report.h"
#include "render.h"
1999-12-09 23:15:14 +00:00
LinkedList *clients;
1999-12-09 23:15:14 +00:00
2001-12-30 00:15:25 +00:00
/* Initialize and kill client list...*/
int
client_init ()
1999-12-09 23:15:14 +00:00
{
2001-11-29 14:09:13 +00:00
debug(RPT_INFO, "client_init()");
2000-04-03 22:13:57 +00:00
clients = LL_new ();
if (!clients) {
2001-11-29 14:09:13 +00:00
report( RPT_ERR, "client_init: Unable to create client list");
2000-04-03 22:13:57 +00:00
return -1;
}
1999-12-09 23:15:14 +00:00
2000-04-03 22:13:57 +00:00
return 0;
1999-12-09 23:15:14 +00:00
}
int
client_shutdown ()
1999-12-09 23:15:14 +00:00
{
2000-04-03 22:13:57 +00:00
client *c;
1999-12-09 23:15:14 +00:00
2001-11-29 14:09:13 +00:00
debug (RPT_INFO, "client_shutdown()");
2001-12-30 00:15:25 +00:00
/* Free all client structures...
* Note that the regular list loop doesn't work here, because
* client_destroy() calls LL_Remove()
*/
2000-04-03 22:13:57 +00:00
for (c = LL_Pop (clients); c; c = LL_Pop (clients)) {
2001-11-29 14:09:13 +00:00
debug (RPT_DEBUG, "client_shutdown: ...");
2000-04-03 22:13:57 +00:00
if (c) {
2001-11-29 14:09:13 +00:00
debug (RPT_DEBUG, "client_shutdown: ... %i ...", c->sock);
if (client_destroy (c) != 0) {
2001-11-29 14:09:13 +00:00
report (RPT_ERR, "client_shutdown: Error freeing client");
2000-04-03 22:13:57 +00:00
} else {
2001-11-29 14:09:13 +00:00
debug (RPT_DEBUG, "client_shutdown: Freed client...");
2000-04-03 22:13:57 +00:00
}
} else {
2001-11-29 14:09:13 +00:00
debug (RPT_DEBUG, "client_shutdown: No client!");
2000-04-03 22:13:57 +00:00
}
}
1999-12-09 23:15:14 +00:00
2001-12-30 00:15:25 +00:00
/* Then, free the list...*/
2000-04-03 22:13:57 +00:00
LL_Destroy (clients);
2001-11-29 14:09:13 +00:00
debug (RPT_DEBUG, "client_shutdown: done");
1999-12-09 23:15:14 +00:00
2000-04-03 22:13:57 +00:00
return 0;
1999-12-09 23:15:14 +00:00
}
2001-12-30 00:15:25 +00:00
/* A client is identified by the file descriptor
+ associated with it.
*
* Create and destroy clients....
*/
client *
client_create (int sock)
1999-12-09 23:15:14 +00:00
{
2000-04-03 22:13:57 +00:00
client *c;
1999-12-09 23:15:14 +00:00
2001-11-29 14:09:13 +00:00
debug (RPT_DEBUG, "client_create(%i)", sock);
1999-12-09 23:15:14 +00:00
2001-12-30 00:15:25 +00:00
/* Allocate new client...*/
2000-04-03 22:13:57 +00:00
c = malloc (sizeof (client));
if (!c) {
2001-11-29 14:09:13 +00:00
report (RPT_ERR, "client_create: error allocating new client");
2000-04-03 22:13:57 +00:00
return NULL;
}
2001-12-30 00:15:25 +00:00
/* Init struct members*/
2000-04-03 22:13:57 +00:00
c->sock = 0;
c->data = NULL;
c->messages = NULL;
1999-12-09 23:15:14 +00:00
2000-04-03 22:13:57 +00:00
c->sock = sock;
2001-12-30 00:15:25 +00:00
c->backlight_state = backlight; /*By default we get the server setting*/
1999-12-09 23:15:14 +00:00
2001-12-30 00:15:25 +00:00
/*Set up message list...*/
2000-04-03 22:13:57 +00:00
c->messages = LL_new ();
if (!c->messages) {
2001-11-29 14:09:13 +00:00
report (RPT_ERR, "client_create: error allocating message list");
2000-04-03 22:13:57 +00:00
free (c);
return NULL;
}
2001-12-30 00:15:25 +00:00
/*TODO: allocate and init client data...*/
2000-04-03 22:13:57 +00:00
c->data = malloc (sizeof (client_data));
if (!c->data) {
2001-11-29 14:09:13 +00:00
report (RPT_ERR, "client_create: error allocating client data");
2000-04-03 22:13:57 +00:00
free (c->messages);
free (c);
return NULL;
} else if (client_data_init (c->data) < 0) {
return NULL;
}
2001-12-30 00:15:25 +00:00
/*TODO: Check for errors while adding the client to the list?*/
2000-04-03 22:13:57 +00:00
LL_Push (clients, (void *) c);
2000-04-03 22:13:57 +00:00
return c;
1999-12-09 23:15:14 +00:00
}
int
client_destroy (client * c)
1999-12-09 23:15:14 +00:00
{
2000-04-03 22:13:57 +00:00
int err;
2000-04-03 22:13:57 +00:00
char *str;
1999-12-09 23:15:14 +00:00
2001-11-29 14:09:13 +00:00
debug (RPT_INFO, "client_destroy()");
2000-04-03 22:13:57 +00:00
if (!c)
return -1;
1999-12-09 23:15:14 +00:00
2001-12-30 00:15:25 +00:00
/*Eat the rest of the incoming requests...*/
2001-11-29 14:09:13 +00:00
debug (RPT_DEBUG, "client_destroy: get_messages");
2000-04-03 22:13:57 +00:00
while ((str = client_get_message (c))) {
if (str) {
2001-11-29 14:09:13 +00:00
debug (RPT_DEBUG, "client_destroy: kill message %s", str);
2000-04-03 22:13:57 +00:00
free (str);
}
}
1999-12-09 23:15:14 +00:00
2001-12-30 00:15:25 +00:00
/*close socket...*/
if (c->sock) {
2001-12-30 00:15:25 +00:00
/*sock_send_string (c->sock, "bye\n");*/
close(c->sock);
2001-11-29 14:09:13 +00:00
report(RPT_NOTICE, "closed socket for #%d", c->sock);
}
2000-04-03 22:13:57 +00:00
err = LL_Destroy (c->messages);
1999-12-09 23:15:14 +00:00
2001-12-30 00:15:25 +00:00
/*Free client's other data*/
2000-04-03 22:13:57 +00:00
client_data_destroy (c->data);
2001-12-30 00:15:25 +00:00
/*Remove the client from the clients list...*/
2000-04-03 22:13:57 +00:00
LL_Remove (clients, c);
2000-04-03 22:13:57 +00:00
free (c);
1999-12-09 23:15:14 +00:00
2000-04-03 22:13:57 +00:00
return 0;
1999-12-09 23:15:14 +00:00
}
2001-12-30 00:15:25 +00:00
/*Add and remove messages from the client's queue...*/
int
client_add_message (client * c, char *message)
1999-12-09 23:15:14 +00:00
{
2000-04-03 22:13:57 +00:00
int err = 0;
char *dup;
char *str, *cp;
char delimiters[] = "\n\r\0";
2001-12-30 00:15:25 +00:00
/* int len;*/
1999-12-09 23:15:14 +00:00
2001-11-29 14:09:13 +00:00
debug(RPT_DEBUG, "client_add_message(%s)", message);
2000-04-03 22:13:57 +00:00
if (!c)
return -1;
if (!message)
return -1;
1999-12-09 23:15:14 +00:00
2001-12-30 00:15:25 +00:00
/* len = strlen(message);
* if(len < 1) return 0;
*/
2001-12-30 00:15:25 +00:00
/* Copy the string to avoid overwriting the original...*/
2000-04-03 22:13:57 +00:00
dup = strdup (message);
if (!dup) {
2001-11-29 14:09:13 +00:00
report(RPT_ERR, "client_add_message: Error allocating new string");
2000-04-03 22:13:57 +00:00
return -1;
}
2001-12-30 00:15:25 +00:00
/* Now split the string into lines and enqueue each one...*/
2000-04-03 22:13:57 +00:00
for (str = strtok (dup, delimiters); str; str = strtok (NULL, delimiters)) {
cp = strdup (str);
2001-11-29 14:09:13 +00:00
debug (RPT_DEBUG, "client_add_message: %s", cp);
2000-04-03 22:13:57 +00:00
err += LL_Enqueue (c->messages, (void *) cp);
}
1999-12-09 23:15:14 +00:00
2001-12-30 00:15:25 +00:00
/*debug(RPT_DEBUG, "client_add_message(%s): %i errors", message, err);*/
free (dup); /* Fixed memory leak...*/
2001-12-30 00:15:25 +00:00
/* Err is the number of errors encountered...*/
2000-04-03 22:13:57 +00:00
return err;
1999-12-09 23:15:14 +00:00
}
2001-12-30 00:15:25 +00:00
/* Woo-hoo! A simple function. :)*/
char *
client_get_message (client * c)
1999-12-09 23:15:14 +00:00
{
2000-04-03 22:13:57 +00:00
char *str;
1999-12-09 23:15:14 +00:00
2001-11-29 14:09:13 +00:00
debug(RPT_DEBUG, "client_get_message()");
1999-12-09 23:15:14 +00:00
2000-04-03 22:13:57 +00:00
if (!c)
return NULL;
2000-04-03 22:13:57 +00:00
str = (char *) LL_Dequeue (c->messages);
1999-12-09 23:15:14 +00:00
2001-12-30 00:15:25 +00:00
/*debug(RPT_DEBUG, "client_get_message: \"%s\"", str);*/
2000-04-03 22:13:57 +00:00
return str;
1999-12-09 23:15:14 +00:00
}
2001-12-30 00:15:25 +00:00
/* Get and set the client's data...*/
int
client_set (client * c, void *data)
1999-12-09 23:15:14 +00:00
{
2001-12-30 00:15:25 +00:00
/* You know, I really doubt this function will be useful...*/
2000-04-03 22:13:57 +00:00
return 0;
1999-12-09 23:15:14 +00:00
}
void *
client_get (client * c)
1999-12-09 23:15:14 +00:00
{
2001-12-30 00:15:25 +00:00
/* But this one might be handy...*/
1999-12-09 23:15:14 +00:00
2000-04-03 22:13:57 +00:00
return NULL;
1999-12-09 23:15:14 +00:00
}
client *
client_find_sock (int sock)
1999-12-09 23:15:14 +00:00
{
2000-04-03 22:13:57 +00:00
client *c;
1999-12-09 23:15:14 +00:00
2001-12-30 00:15:25 +00:00
/* debug(RPT_INFO, "client_find_sock(%i)", sock);*/
1999-12-09 23:15:14 +00:00
2000-04-03 22:13:57 +00:00
LL_Rewind (clients);
do {
c = (client *) LL_Get (clients);
2001-12-30 00:15:25 +00:00
/* debug(RPT_DEBUG, "client_find_sock: ... %i ...", c->sock);*/
2000-04-03 22:13:57 +00:00
if (c->sock == sock) {
2001-12-30 00:15:25 +00:00
/* debug(RPT_DEBUG, "client_find_sock: ..! %i !..", c->sock);*/
2000-04-03 22:13:57 +00:00
return c;
}
} while (LL_Next (clients) == 0);
2001-11-29 14:09:13 +00:00
debug (RPT_ERR, "client_find_sock: failed");
1999-12-09 23:15:14 +00:00
2000-04-03 22:13:57 +00:00
return NULL;
1999-12-09 23:15:14 +00:00
}