2008-11-30 22:31:20 +00:00
|
|
|
/** \file server/client.c
|
2008-11-30 15:30:28 +00:00
|
|
|
* Define all the client data and actions.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
/* This file is part of LCDd, the lcdproc server.
|
2002-04-26 00:00:31 +00:00
|
|
|
*
|
2008-11-30 22:31:20 +00:00
|
|
|
* This file is released under the GNU General Public License.
|
|
|
|
|
* Refer to the COPYING file distributed with this package.
|
2002-04-26 00:00:31 +00:00
|
|
|
*
|
2011-01-05 23:34:37 +00:00
|
|
|
* Copyright (c) 1999, William Ferrell, Selene Scriven
|
2002-04-26 00:00:31 +00:00
|
|
|
* 2002, Joris Robijn
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
#include <unistd.h>
|
|
|
|
|
#include <string.h>
|
|
|
|
|
|
2007-06-17 10:20:55 +00:00
|
|
|
#ifdef HAVE_CONFIG_H
|
|
|
|
|
# include "config.h"
|
|
|
|
|
#endif
|
2002-04-26 00:00:31 +00:00
|
|
|
|
|
|
|
|
#include "client.h"
|
2012-02-22 22:25:32 +00:00
|
|
|
#include "screen.h"
|
2002-04-26 00:00:31 +00:00
|
|
|
#include "screenlist.h"
|
|
|
|
|
#include "render.h"
|
2002-06-28 23:35:55 +00:00
|
|
|
#include "input.h"
|
2002-07-09 22:56:05 +00:00
|
|
|
#include "menuscreens.h"
|
2002-04-26 00:00:31 +00:00
|
|
|
#include "shared/report.h"
|
|
|
|
|
#include "shared/LL.h"
|
|
|
|
|
|
2007-04-02 21:29:53 +00:00
|
|
|
Client *client_create(int sock)
|
2002-04-26 00:00:31 +00:00
|
|
|
{
|
|
|
|
|
Client *c;
|
|
|
|
|
|
2007-04-02 21:29:53 +00:00
|
|
|
debug(RPT_DEBUG, "%s(sock=%i)", __FUNCTION__, sock);
|
2002-04-26 00:00:31 +00:00
|
|
|
|
|
|
|
|
/* Allocate new client...*/
|
2007-04-02 21:29:53 +00:00
|
|
|
c = malloc(sizeof(Client));
|
2002-04-26 00:00:31 +00:00
|
|
|
if (!c) {
|
2007-04-02 21:29:53 +00:00
|
|
|
report(RPT_ERR, "%s: Error allocating", __FUNCTION__);
|
2002-04-26 00:00:31 +00:00
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
/* Init struct members*/
|
|
|
|
|
c->sock = sock;
|
|
|
|
|
c->messages = NULL;
|
|
|
|
|
c->backlight = BACKLIGHT_OPEN;
|
|
|
|
|
c->heartbeat = HEARTBEAT_OPEN;
|
|
|
|
|
|
|
|
|
|
/*Set up message list...*/
|
2007-04-02 21:29:53 +00:00
|
|
|
c->messages = LL_new();
|
2002-04-26 00:00:31 +00:00
|
|
|
if (!c->messages) {
|
2007-04-02 21:29:53 +00:00
|
|
|
report(RPT_ERR, "%s: Error allocating", __FUNCTION__);
|
|
|
|
|
free(c);
|
2002-04-26 00:00:31 +00:00
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
2008-11-28 18:34:10 +00:00
|
|
|
c->state = NEW;
|
2002-04-26 00:00:31 +00:00
|
|
|
c->name = NULL;
|
2002-06-28 23:35:55 +00:00
|
|
|
c->menu = NULL;
|
2002-04-26 00:00:31 +00:00
|
|
|
|
|
|
|
|
c->screenlist = LL_new();
|
|
|
|
|
|
|
|
|
|
if (!c->screenlist) {
|
2007-04-02 21:29:53 +00:00
|
|
|
report(RPT_ERR, "%s: Error allocating", __FUNCTION__);
|
2002-04-26 00:00:31 +00:00
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
return c;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int
|
2007-04-02 21:29:53 +00:00
|
|
|
client_destroy(Client *c)
|
2002-04-26 00:00:31 +00:00
|
|
|
{
|
|
|
|
|
Screen *s;
|
2012-02-22 22:25:32 +00:00
|
|
|
Menu *m;
|
2007-04-02 21:29:53 +00:00
|
|
|
char *str;
|
2002-04-26 00:00:31 +00:00
|
|
|
|
|
|
|
|
if (!c)
|
|
|
|
|
return -1;
|
|
|
|
|
|
2007-04-02 21:29:53 +00:00
|
|
|
debug(RPT_DEBUG, "%s(c=[%d])", __FUNCTION__, c->sock);
|
2002-07-14 20:30:33 +00:00
|
|
|
|
|
|
|
|
/* Close the socket */
|
2007-04-02 21:29:53 +00:00
|
|
|
close(c->sock);
|
2002-07-14 20:30:33 +00:00
|
|
|
|
|
|
|
|
/* Eat messages */
|
2007-04-02 21:29:53 +00:00
|
|
|
while ((str = client_get_message(c))) {
|
|
|
|
|
free(str);
|
2002-07-14 20:30:33 +00:00
|
|
|
}
|
2007-04-02 21:29:53 +00:00
|
|
|
LL_Destroy(c->messages);
|
2002-04-26 00:00:31 +00:00
|
|
|
|
|
|
|
|
/* Clean up the screenlist...*/
|
2007-04-02 21:29:53 +00:00
|
|
|
debug(RPT_DEBUG, "%s: Cleaning screenlist", __FUNCTION__);
|
2002-04-26 00:00:31 +00:00
|
|
|
|
2007-04-02 21:29:53 +00:00
|
|
|
for (s = LL_GetFirst(c->screenlist); s; s = LL_GetNext(c->screenlist)) {
|
2002-04-26 00:00:31 +00:00
|
|
|
/* Free its memory...*/
|
2007-04-02 21:29:53 +00:00
|
|
|
screen_destroy(s);
|
2002-04-26 00:00:31 +00:00
|
|
|
/* Note that the screen is not removed from the list because
|
|
|
|
|
* the list will be destroyed anyway...
|
|
|
|
|
*/
|
|
|
|
|
}
|
2007-04-02 21:29:53 +00:00
|
|
|
LL_Destroy(c->screenlist);
|
2002-04-26 00:00:31 +00:00
|
|
|
|
2012-02-22 22:25:32 +00:00
|
|
|
m = (Menu *) c->menu;
|
2002-06-28 23:35:55 +00:00
|
|
|
/* Destroy the client's menu, if it exists */
|
2012-02-22 22:25:32 +00:00
|
|
|
if (m) {
|
|
|
|
|
menuscreen_inform_item_destruction(m);
|
|
|
|
|
menu_remove_item(m->parent, m);
|
|
|
|
|
menuscreen_inform_item_modified(m->parent);
|
|
|
|
|
menuitem_destroy(m);
|
2002-07-09 22:56:05 +00:00
|
|
|
}
|
2002-06-28 23:35:55 +00:00
|
|
|
|
|
|
|
|
/* Forget client's key reservations */
|
2007-04-02 21:29:53 +00:00
|
|
|
input_release_client_keys(c);
|
2002-06-28 23:35:55 +00:00
|
|
|
|
|
|
|
|
/* Free client's other data */
|
2008-11-28 18:34:10 +00:00
|
|
|
c->state = GONE;
|
2002-06-28 23:35:55 +00:00
|
|
|
|
|
|
|
|
/* Clean up the name...*/
|
|
|
|
|
if (c->name)
|
2007-04-02 21:29:53 +00:00
|
|
|
free(c->name);
|
2002-06-28 23:35:55 +00:00
|
|
|
|
2002-04-26 00:00:31 +00:00
|
|
|
/* Remove structure */
|
2007-04-02 21:29:53 +00:00
|
|
|
free(c);
|
2002-04-26 00:00:31 +00:00
|
|
|
|
2007-04-02 21:29:53 +00:00
|
|
|
debug(RPT_DEBUG, "%s: Client data removed", __FUNCTION__);
|
2002-04-26 00:00:31 +00:00
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*Add and remove messages from the client's queue...*/
|
|
|
|
|
int
|
2007-04-02 21:29:53 +00:00
|
|
|
client_add_message(Client *c, char *message)
|
2002-04-26 00:00:31 +00:00
|
|
|
{
|
|
|
|
|
int err = 0;
|
|
|
|
|
|
|
|
|
|
if (!c)
|
|
|
|
|
return -1;
|
|
|
|
|
if (!message)
|
|
|
|
|
return -1;
|
|
|
|
|
|
2010-01-19 22:49:51 +00:00
|
|
|
if (strlen(message) > 0) {
|
|
|
|
|
debug(RPT_DEBUG, "%s(c=[%d], message=\"%s\")", __FUNCTION__,
|
|
|
|
|
c->sock, message);
|
|
|
|
|
err = LL_Enqueue(c->messages, (void *) message);
|
2002-04-26 00:00:31 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return err;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Woo-hoo! A simple function. :)*/
|
|
|
|
|
char *
|
2007-04-02 21:29:53 +00:00
|
|
|
client_get_message(Client *c)
|
2002-04-26 00:00:31 +00:00
|
|
|
{
|
|
|
|
|
char *str;
|
|
|
|
|
|
2007-04-02 21:29:53 +00:00
|
|
|
debug(RPT_DEBUG, "%s(c=[%d])", __FUNCTION__, c->sock);
|
2002-04-26 00:00:31 +00:00
|
|
|
|
|
|
|
|
if (!c)
|
|
|
|
|
return NULL;
|
|
|
|
|
|
2007-04-02 21:29:53 +00:00
|
|
|
str = (char *) LL_Dequeue(c->messages);
|
2002-04-26 00:00:31 +00:00
|
|
|
|
|
|
|
|
return str;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Screen *
|
2007-04-02 21:29:53 +00:00
|
|
|
client_find_screen(Client *c, char *id)
|
2002-04-26 00:00:31 +00:00
|
|
|
{
|
|
|
|
|
Screen *s;
|
|
|
|
|
|
|
|
|
|
if (!c)
|
|
|
|
|
return NULL;
|
|
|
|
|
if (!id)
|
|
|
|
|
return NULL;
|
|
|
|
|
|
2007-04-02 21:29:53 +00:00
|
|
|
debug(RPT_DEBUG, "%s(c=[%d], id=\"%s\")", __FUNCTION__, c->sock, id);
|
2002-04-26 00:00:31 +00:00
|
|
|
|
2007-04-02 21:29:53 +00:00
|
|
|
LL_Rewind(c->screenlist);
|
2002-04-26 00:00:31 +00:00
|
|
|
do {
|
2007-04-02 21:29:53 +00:00
|
|
|
s = LL_Get(c->screenlist);
|
|
|
|
|
if ((s) && (0 == strcmp(s->id, id))) {
|
|
|
|
|
debug(RPT_DEBUG, "%s: Found %s", __FUNCTION__, id);
|
2002-04-26 00:00:31 +00:00
|
|
|
return s;
|
|
|
|
|
}
|
2007-04-02 21:29:53 +00:00
|
|
|
} while (LL_Next(c->screenlist) == 0);
|
2002-04-26 00:00:31 +00:00
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int
|
2007-04-02 21:29:53 +00:00
|
|
|
client_add_screen(Client *c, Screen *s)
|
2002-04-26 00:00:31 +00:00
|
|
|
{
|
2002-07-14 20:30:33 +00:00
|
|
|
if (!c)
|
|
|
|
|
return -1;
|
|
|
|
|
if (!s)
|
|
|
|
|
return -1;
|
|
|
|
|
|
2007-04-02 21:29:53 +00:00
|
|
|
debug(RPT_DEBUG, "%s(c=[%d], s=[%s])", __FUNCTION__, c->sock, s->id);
|
2002-07-14 20:30:33 +00:00
|
|
|
|
2007-04-02 21:29:53 +00:00
|
|
|
LL_Push(c->screenlist, (void *) s);
|
2002-04-26 00:00:31 +00:00
|
|
|
|
|
|
|
|
/* Now, add it to the screenlist...*/
|
2007-04-02 21:29:53 +00:00
|
|
|
screenlist_add(s);
|
2002-04-26 00:00:31 +00:00
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int
|
2007-04-02 21:29:53 +00:00
|
|
|
client_remove_screen(Client *c, Screen *s)
|
2002-04-26 00:00:31 +00:00
|
|
|
{
|
|
|
|
|
if (!c)
|
|
|
|
|
return -1;
|
|
|
|
|
if (!s)
|
|
|
|
|
return -1;
|
|
|
|
|
|
2007-04-02 21:29:53 +00:00
|
|
|
debug(RPT_DEBUG, "%s(c=[%d], s=[%s])", __FUNCTION__, c->sock, s->id);
|
2002-07-14 20:30:33 +00:00
|
|
|
|
2002-04-26 00:00:31 +00:00
|
|
|
/* TODO: Check for errors here?*/
|
2008-11-30 15:30:28 +00:00
|
|
|
LL_Remove(c->screenlist, (void *) s, NEXT);
|
2002-04-26 00:00:31 +00:00
|
|
|
|
|
|
|
|
/* Now, remove it from the screenlist...*/
|
2007-04-02 21:29:53 +00:00
|
|
|
screenlist_remove(s);
|
2003-02-27 21:20:20 +00:00
|
|
|
|
2002-04-26 00:00:31 +00:00
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
2007-04-02 21:29:53 +00:00
|
|
|
int client_screen_count(Client *c)
|
2002-04-26 00:00:31 +00:00
|
|
|
{
|
|
|
|
|
return LL_Length(c->screenlist);
|
2002-05-26 19:21:23 +00:00
|
|
|
}
|