mirror of
https://github.com/netfun2000/lcd4linux.git
synced 2026-02-27 09:44:34 +08:00
[lcd4linux @ 2006-08-13 18:14:03 by harbaum]
Added KVV plugin git-svn-id: https://ssl.bulix.org/svn/lcd4linux/trunk@692 3ae390bd-cb1e-0410-b409-cd5a39f66f1f
This commit is contained in:
@@ -104,6 +104,7 @@ plugin_file.c \
|
||||
plugin_i2c_sensors.c \
|
||||
plugin_imon.c \
|
||||
plugin_isdn.c \
|
||||
plugin_kvv.c \
|
||||
plugin_loadavg.c \
|
||||
plugin_meminfo.c \
|
||||
plugin_mpd.c \
|
||||
|
||||
@@ -279,6 +279,7 @@ plugin_file.c \
|
||||
plugin_i2c_sensors.c \
|
||||
plugin_imon.c \
|
||||
plugin_isdn.c \
|
||||
plugin_kvv.c \
|
||||
plugin_loadavg.c \
|
||||
plugin_meminfo.c \
|
||||
plugin_mpd.c \
|
||||
@@ -458,6 +459,7 @@ distclean-compile:
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/plugin_i2c_sensors.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/plugin_imon.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/plugin_isdn.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/plugin_kvv.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/plugin_loadavg.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/plugin_math.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/plugin_meminfo.Po@am__quote@
|
||||
|
||||
@@ -281,6 +281,9 @@
|
||||
/* ISDN plugin */
|
||||
#undef PLUGIN_ISDN
|
||||
|
||||
/* kvv plugin */
|
||||
#undef PLUGIN_KVV
|
||||
|
||||
/* loadavg plugin */
|
||||
#undef PLUGIN_LOADAVG
|
||||
|
||||
|
||||
@@ -8245,6 +8245,7 @@ echo "$as_me: error: run ./configure --with-plugins=..." >&2;}
|
||||
PLUGIN_I2C_SENSORS="yes"
|
||||
PLUGIN_IMON="yes"
|
||||
PLUGIN_ISDN="yes"
|
||||
PLUGIN_KVV="yes"
|
||||
PLUGIN_LOADAVG="yes"
|
||||
PLUGIN_MEMINFO="yes"
|
||||
PLUGIN_MPD="yes"
|
||||
@@ -8289,6 +8290,9 @@ echo "$as_me: error: run ./configure --with-plugins=..." >&2;}
|
||||
isdn)
|
||||
PLUGIN_ISDN=$val
|
||||
;;
|
||||
kvv)
|
||||
PLUGIN_KVV=$val
|
||||
;;
|
||||
loadavg)
|
||||
PLUGIN_LOADAVG=$val
|
||||
;;
|
||||
@@ -8770,6 +8774,14 @@ cat >>confdefs.h <<\_ACEOF
|
||||
#define PLUGIN_ISDN 1
|
||||
_ACEOF
|
||||
|
||||
fi
|
||||
if test "$PLUGIN_KVV" = "yes"; then
|
||||
PLUGINS="$PLUGINS plugin_kvv.o"
|
||||
|
||||
cat >>confdefs.h <<\_ACEOF
|
||||
#define PLUGIN_KVV 1
|
||||
_ACEOF
|
||||
|
||||
fi
|
||||
if test "$PLUGIN_LOADAVG" = "yes"; then
|
||||
PLUGINS="$PLUGINS plugin_loadavg.o"
|
||||
|
||||
+47
-5
@@ -1,4 +1,4 @@
|
||||
/* $Id: drv_LEDMatrix.c,v 1.5 2006/08/13 09:53:10 reinelt Exp $
|
||||
/* $Id: drv_LEDMatrix.c,v 1.6 2006/08/13 18:14:03 harbaum Exp $
|
||||
*
|
||||
* LED matrix driver for LCD4Linux
|
||||
* (see http://www.harbaum.org/till/ledmatrix for hardware)
|
||||
@@ -23,6 +23,9 @@
|
||||
*
|
||||
*
|
||||
* $Log: drv_LEDMatrix.c,v $
|
||||
* Revision 1.6 2006/08/13 18:14:03 harbaum
|
||||
* Added KVV plugin
|
||||
*
|
||||
* Revision 1.5 2006/08/13 09:53:10 reinelt
|
||||
* dynamic properties added (used by 'style' of text widget)
|
||||
*
|
||||
@@ -106,7 +109,13 @@ static int port = DSP_DEFAULT_PORT;
|
||||
|
||||
static void drv_LEDMatrix_blit(const int row, const int col, const int height, const int width)
|
||||
{
|
||||
int r, c;
|
||||
int r, c, i;
|
||||
fd_set rfds;
|
||||
struct timeval tv;
|
||||
unsigned char reply[256];
|
||||
struct sockaddr_in cli_addr;
|
||||
int fromlen, ack = 0;
|
||||
int timeout = 10;
|
||||
|
||||
for (r = row; r < row + height; r++) {
|
||||
for (c = col; c < col + width; c++) {
|
||||
@@ -127,8 +136,42 @@ static void drv_LEDMatrix_blit(const int row, const int col, const int height, c
|
||||
|
||||
// scan entire display
|
||||
tx_buffer[0] = DSP_CMD_IMAGE;
|
||||
if ((sendto(sock, tx_buffer, DSP_MEM + 1, 0, (struct sockaddr *) &dsp_addr, sizeof(dsp_addr))) != DSP_MEM + 1)
|
||||
error("%s: sendto error on socket", Name);
|
||||
|
||||
do {
|
||||
|
||||
if ((sendto(sock, tx_buffer, DSP_MEM + 1, 0, (struct sockaddr *) &dsp_addr, sizeof(dsp_addr))) != DSP_MEM + 1)
|
||||
error("%s: sendto error on socket", Name);
|
||||
|
||||
/* now wait for reply */
|
||||
|
||||
FD_ZERO(&rfds);
|
||||
FD_SET(sock, &rfds);
|
||||
tv.tv_sec = 0;
|
||||
tv.tv_usec = 100000;
|
||||
|
||||
// wait 1 sec for ack
|
||||
if ((i = select(FD_SETSIZE, &rfds, NULL, NULL, &tv)) < 0) {
|
||||
perror("select");
|
||||
}
|
||||
|
||||
if (FD_ISSET(sock, &rfds)) {
|
||||
// wait for ack
|
||||
fromlen = sizeof(dsp_addr);
|
||||
i = recvfrom(sock, reply, sizeof(reply), 0, (struct sockaddr *) &cli_addr, &fromlen);
|
||||
if (i < 0) {
|
||||
perror("recvfrom");
|
||||
} else {
|
||||
if ((i == 2) && (reply[0] == DSP_CMD_ACK) && (reply[1] == DSP_CMD_IMAGE)) {
|
||||
ack = 1;
|
||||
// } else if((i > 1) && (reply[0] == DSP_CMD_IR)) {
|
||||
// ir_receive(reply+1, i-1);
|
||||
} else {
|
||||
fprintf(stderr, "Unexpected reply message\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
timeout--;
|
||||
} while ((!ack) && (timeout > 0));
|
||||
}
|
||||
|
||||
static int drv_LEDMatrix_start(const char *section)
|
||||
@@ -137,7 +180,6 @@ static int drv_LEDMatrix_start(const char *section)
|
||||
struct sockaddr_in cli_addr;
|
||||
struct hostent *hp;
|
||||
int val;
|
||||
char *attr;
|
||||
|
||||
IPAddress = cfg_get(section, "IPAddress", NULL);
|
||||
if (IPAddress == NULL || *IPAddress == '\0') {
|
||||
|
||||
+12
-9
@@ -1,4 +1,4 @@
|
||||
/* $Id: font_6x8_bold.h,v 1.1 2006/08/09 17:25:34 harbaum Exp $
|
||||
/* $Id: font_6x8_bold.h,v 1.2 2006/08/13 18:14:03 harbaum Exp $
|
||||
*
|
||||
* 6x8 bold font
|
||||
*
|
||||
@@ -23,6 +23,9 @@
|
||||
*
|
||||
*
|
||||
* $Log: font_6x8_bold.h,v $
|
||||
* Revision 1.2 2006/08/13 18:14:03 harbaum
|
||||
* Added KVV plugin
|
||||
*
|
||||
* Revision 1.1 2006/08/09 17:25:34 harbaum
|
||||
* Better bar color support and new bold font
|
||||
*
|
||||
@@ -175,11 +178,11 @@ unsigned char Font_6x8_bold[256][8] = {
|
||||
_OO___,
|
||||
______},
|
||||
[0x2a] {______,
|
||||
__OO__,
|
||||
O_OO_O,
|
||||
_OOOO_,
|
||||
O_OO_O,
|
||||
__OO__,
|
||||
___O__,
|
||||
_O_O_O,
|
||||
__OOO_,
|
||||
_O_O_O,
|
||||
___O__,
|
||||
______,
|
||||
______},
|
||||
[0x2b] {______,
|
||||
@@ -230,12 +233,12 @@ unsigned char Font_6x8_bold[256][8] = {
|
||||
_OO_OO,
|
||||
__OOO_,
|
||||
______},
|
||||
[0x31] {____O_,
|
||||
___OO_,
|
||||
[0x31] {___OO_,
|
||||
__OOO_,
|
||||
___OO_,
|
||||
___OO_,
|
||||
___OO_,
|
||||
___OO_,
|
||||
__OOOO,
|
||||
______},
|
||||
[0x32] {__OOO_,
|
||||
@@ -767,8 +770,8 @@ unsigned char Font_6x8_bold[256][8] = {
|
||||
_OOOO_,
|
||||
______},
|
||||
[0x74] {__OO__,
|
||||
_OOOO_,
|
||||
__OO__,
|
||||
_OOOO_,
|
||||
__OO__,
|
||||
__OO__,
|
||||
__OO__,
|
||||
|
||||
@@ -420,6 +420,14 @@ Display Image {
|
||||
Basecolor '80d000'
|
||||
}
|
||||
|
||||
Plugin KVV {
|
||||
StationID '12_701'
|
||||
Refresh 30
|
||||
|
||||
Proxy 'igate'
|
||||
Port 8080;
|
||||
}
|
||||
|
||||
Plugin Seti {
|
||||
Directory '/root/setiathome-3.08.i686-pc-linux-gnu'
|
||||
}
|
||||
@@ -877,6 +885,28 @@ Widget ImageTest {
|
||||
inverted 0
|
||||
}
|
||||
|
||||
Widget KVV {
|
||||
class 'Text'
|
||||
expression kvv::line(0).' '.kvv::station(0)
|
||||
width 11
|
||||
|
||||
align 'L'
|
||||
update tick
|
||||
Foreground 'ffff00'
|
||||
style 'bold'
|
||||
}
|
||||
|
||||
Widget KVV_TIME {
|
||||
class 'Text'
|
||||
expression kvv::time_str(0)
|
||||
width 2
|
||||
|
||||
align 'R'
|
||||
update tick
|
||||
foreground kvv::time(0) < 2 ? 'FF0000' : ( kvv::time(0) < 5 ? 'FFFF00' : '00FF00' )
|
||||
style 'bold'
|
||||
}
|
||||
|
||||
Layout Default {
|
||||
Row1 {
|
||||
Col1 'OS'
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $Id: plugin.c,v 1.44 2006/07/31 03:48:09 reinelt Exp $
|
||||
/* $Id: plugin.c,v 1.45 2006/08/13 18:14:03 harbaum Exp $
|
||||
*
|
||||
* plugin handler for the Evaluator
|
||||
*
|
||||
@@ -23,6 +23,9 @@
|
||||
*
|
||||
*
|
||||
* $Log: plugin.c,v $
|
||||
* Revision 1.45 2006/08/13 18:14:03 harbaum
|
||||
* Added KVV plugin
|
||||
*
|
||||
* Revision 1.44 2006/07/31 03:48:09 reinelt
|
||||
* preparations for scrolling
|
||||
*
|
||||
@@ -250,6 +253,8 @@ int plugin_init_imon(void);
|
||||
void plugin_exit_imon(void);
|
||||
int plugin_init_isdn(void);
|
||||
void plugin_exit_isdn(void);
|
||||
int plugin_init_kvv(void);
|
||||
void plugin_exit_kvv(void);
|
||||
int plugin_init_loadavg(void);
|
||||
void plugin_exit_loadavg(void);
|
||||
int plugin_init_meminfo(void);
|
||||
@@ -319,6 +324,9 @@ int plugin_init(void)
|
||||
#ifdef PLUGIN_ISDN
|
||||
plugin_init_isdn();
|
||||
#endif
|
||||
#ifdef PLUGIN_KVV
|
||||
plugin_init_kvv();
|
||||
#endif
|
||||
#ifdef PLUGIN_LOADAVG
|
||||
plugin_init_loadavg();
|
||||
#endif
|
||||
@@ -402,6 +410,9 @@ void plugin_exit(void)
|
||||
#ifdef PLUGIN_ISDN
|
||||
plugin_exit_isdn();
|
||||
#endif
|
||||
#ifdef PLUGIN_KVV
|
||||
plugin_exit_kvv();
|
||||
#endif
|
||||
#ifdef PLUGIN_LOADAVG
|
||||
plugin_exit_loadavg();
|
||||
#endif
|
||||
|
||||
+714
@@ -0,0 +1,714 @@
|
||||
/* $Id: plugin_kvv.c,v 1.1 2006/08/13 18:14:03 harbaum Exp $
|
||||
*
|
||||
* plugin kvv (karlsruher verkehrsverbund)
|
||||
*
|
||||
* Copyright (C) 2006 Till Harbaum <till@harbaum.org>
|
||||
* Copyright (C) 2006 The LCD4Linux Team <lcd4linux-devel@users.sourceforge.net>
|
||||
*
|
||||
* This file is part of LCD4Linux.
|
||||
*
|
||||
* LCD4Linux is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* LCD4Linux is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
*
|
||||
* $Log: plugin_kvv.c,v $
|
||||
* Revision 1.1 2006/08/13 18:14:03 harbaum
|
||||
* Added KVV plugin
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* exported functions:
|
||||
*
|
||||
* int plugin_init_kvv (void)
|
||||
* adds various functions
|
||||
* void plugin_exit_kvv (void)
|
||||
*
|
||||
*/
|
||||
|
||||
/* define the include files you need */
|
||||
#include "config.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <signal.h>
|
||||
|
||||
/* network specific includes */
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netdb.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
/* these should always be included */
|
||||
#include "debug.h"
|
||||
#include "plugin.h"
|
||||
#include "cfg.h"
|
||||
#include "thread.h"
|
||||
|
||||
/* these can't be configured as it doesn't make sense to change them */
|
||||
#define HTTP_SERVER "www.init-ka.de"
|
||||
#define HTTP_REQUEST "/webfgi/StopInfoInplace.aspx?ID=%s"
|
||||
|
||||
#define DEFAULT_STATION_ID "89" // Hauptbahnhof
|
||||
|
||||
/* example ids:
|
||||
* 89 = Hauptbahnhof
|
||||
* 12_701 = Berufsakademie
|
||||
*/
|
||||
|
||||
/* total max values to calculate shm size */
|
||||
#define MAX_LINES 4
|
||||
#define MAX_LINE_LENGTH 8
|
||||
#define MAX_STATION_LENGTH 32
|
||||
|
||||
typedef struct {
|
||||
char line[MAX_LINE_LENGTH + 1];
|
||||
char station[MAX_STATION_LENGTH + 1];
|
||||
int time;
|
||||
} kvv_entry_t;
|
||||
|
||||
typedef struct {
|
||||
int entries;
|
||||
kvv_entry_t entry[MAX_LINES];
|
||||
} kvv_shm_t;
|
||||
|
||||
static char *station_id = NULL;
|
||||
static char *proxy_name = NULL;
|
||||
static int port = 80;
|
||||
static pid_t pid = -1;
|
||||
static int refresh = 60;
|
||||
static int stringlen = 16;
|
||||
|
||||
static int mutex = 0;
|
||||
static int shmid;
|
||||
static kvv_shm_t *shm;
|
||||
|
||||
#define SECTION "Plugin:KVV"
|
||||
|
||||
#define TIMEOUT_SHORT 1 /* wait this long for additional data */
|
||||
#define TIMEOUT_LONG 10 /* wait this long for initial data */
|
||||
|
||||
/* search an element in the result string */
|
||||
static int get_element(char *input, char *name, char **data)
|
||||
{
|
||||
int skip = 0;
|
||||
int len = 0;
|
||||
int state = 0; // nothing found yet
|
||||
|
||||
// search entire string
|
||||
while (*input) {
|
||||
if (skip == 0) {
|
||||
switch (state) {
|
||||
case 0:
|
||||
if (*input == '<')
|
||||
state = 1;
|
||||
else
|
||||
state = 0;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
// ignore white spaces
|
||||
if (*input != ' ') {
|
||||
if (strncasecmp(input, name, strlen(name)) == 0) {
|
||||
state = 2;
|
||||
skip = strlen(name) - 1;
|
||||
} else
|
||||
state = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case 2:
|
||||
if (*input == ' ') {
|
||||
*data = ++input;
|
||||
while (*input++ != '>')
|
||||
len++;
|
||||
|
||||
return len;
|
||||
} else
|
||||
state = 0;
|
||||
break;
|
||||
}
|
||||
} else if (skip)
|
||||
skip--;
|
||||
|
||||
input++;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* serach an attribute within an element */
|
||||
static int get_attrib(char *input, char *name, char **data)
|
||||
{
|
||||
int skip = 0;
|
||||
int len = 0;
|
||||
int state = 0; // nothing found
|
||||
|
||||
// search in this element
|
||||
while (*input != '>') {
|
||||
// ignore white spaces
|
||||
if (((*input != ' ') && (*input != '\t')) && (skip == 0)) {
|
||||
switch (state) {
|
||||
case 0:
|
||||
if (strncasecmp(input, name, strlen(name)) == 0) {
|
||||
state = 1;
|
||||
skip = strlen(name) - 1;
|
||||
}
|
||||
break;
|
||||
|
||||
case 1:
|
||||
if (*input == '=')
|
||||
state = 2;
|
||||
else
|
||||
state = 0;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
if (*input == '\"') {
|
||||
*data = ++input;
|
||||
while (*input++ != '\"')
|
||||
len++;
|
||||
|
||||
return len;
|
||||
} else
|
||||
state = 0;
|
||||
|
||||
break;
|
||||
}
|
||||
} else if (skip)
|
||||
skip--;
|
||||
|
||||
input++;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int http_open(char *name)
|
||||
{
|
||||
struct sockaddr_in server;
|
||||
struct hostent *host_info;
|
||||
unsigned long addr;
|
||||
int sock;
|
||||
|
||||
/* create socket */
|
||||
sock = socket(PF_INET, SOCK_STREAM, 0);
|
||||
if (sock < 0) {
|
||||
perror("failed to create socket");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Erzeuge die Socketadresse des Servers
|
||||
* Sie besteht aus Typ, IP-Adresse und Portnummer */
|
||||
memset(&server, 0, sizeof(server));
|
||||
if ((addr = inet_addr(name)) != INADDR_NONE) {
|
||||
memcpy((char *) &server.sin_addr, &addr, sizeof(addr));
|
||||
} else {
|
||||
/* Wandle den Servernamen in eine IP-Adresse um */
|
||||
host_info = gethostbyname(name);
|
||||
if (NULL == host_info) {
|
||||
error("[KVV] Unknown server: %s", name);
|
||||
return -1;
|
||||
}
|
||||
memcpy((char *) &server.sin_addr, host_info->h_addr, host_info->h_length);
|
||||
}
|
||||
|
||||
server.sin_family = AF_INET;
|
||||
server.sin_port = htons(port);
|
||||
|
||||
/* Baue die Verbindung zum Server auf */
|
||||
if (connect(sock, (struct sockaddr *) &server, sizeof(server)) < 0) {
|
||||
perror("can't connect to server");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return sock;
|
||||
}
|
||||
|
||||
static void get_text(char *input, char *end, char *dest, int dlen)
|
||||
{
|
||||
int state = 0; // nothing yet, outside any element
|
||||
int cnt = 0;
|
||||
|
||||
while (*input) {
|
||||
switch (state) {
|
||||
case 0:
|
||||
if (*input == '<')
|
||||
state = 1;
|
||||
else {
|
||||
if (cnt < (dlen - 1))
|
||||
dest[cnt++] = *input;
|
||||
}
|
||||
break;
|
||||
|
||||
case 1:
|
||||
if (*input == '/')
|
||||
state = 2;
|
||||
else if (*input == '>')
|
||||
state = 0;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
if (strncasecmp(input, end, strlen(end)) == 0) {
|
||||
dest[cnt++] = 0;
|
||||
return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
input++;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void process_station_string(char *str)
|
||||
{
|
||||
char *p, *q;
|
||||
int last, i;
|
||||
char *repl[] = {
|
||||
"Hauptbahnhof", "Hbf.",
|
||||
"Bahnhof", "Bhf.",
|
||||
"Karlsruhe", "KA",
|
||||
"Schienenersatzverkehr", "Ersatzv.",
|
||||
"Marktplatz", "Marktpl.",
|
||||
};
|
||||
|
||||
/* erase multiple spaces */
|
||||
p = q = str;
|
||||
last = 1; // no leading spaces
|
||||
while (*p) {
|
||||
if ((!last) || (*p != ' '))
|
||||
*q++ = *p;
|
||||
|
||||
last = (*p == ' ');
|
||||
p++;
|
||||
}
|
||||
*q++ = 0;
|
||||
|
||||
/* decode utf8 */
|
||||
p = q = str;
|
||||
last = 0;
|
||||
while (*p) {
|
||||
if (last) {
|
||||
*q++ = (last << 6) | (*p & 0x3f);
|
||||
last = 0;
|
||||
} else if ((*p & 0xe0) == 0xc0) {
|
||||
last = *p & 3;
|
||||
} else
|
||||
*q++ = *p;
|
||||
|
||||
p++;
|
||||
}
|
||||
*q++ = 0;
|
||||
|
||||
/* replace certain (long) words with e.g. abbreviations */
|
||||
for (i = 0; i < (int) (sizeof(repl) / (2 * sizeof(char *))); i++) {
|
||||
if ((p = strstr(str, repl[2 * i])) != NULL) {
|
||||
|
||||
/* move new string */
|
||||
memcpy(p, repl[2 * i + 1], strlen(repl[2 * i + 1]));
|
||||
/* move rest of string down */
|
||||
memmove(p + strlen(repl[2 * i + 1]),
|
||||
p + strlen(repl[2 * i]), strlen(str) - (p - str) - strlen(repl[2 * i]) + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void kvv_client(void)
|
||||
{
|
||||
char ibuffer[8192];
|
||||
char obuffer[8192];
|
||||
int count, i, sock;
|
||||
|
||||
char server_name[] = HTTP_SERVER;
|
||||
char *connect_to;
|
||||
|
||||
/* connect to proxy if given, to server otherwise */
|
||||
if ((proxy_name != NULL) && (strlen(proxy_name) != 0))
|
||||
connect_to = proxy_name;
|
||||
else
|
||||
connect_to = server_name;
|
||||
|
||||
info("[KVV] Connecting to %s", connect_to);
|
||||
|
||||
while (1) {
|
||||
|
||||
sock = http_open(connect_to);
|
||||
if (sock < 0) {
|
||||
error("[KVV] Error accessing server/proxy: %s", strerror(errno));
|
||||
return;
|
||||
}
|
||||
// create and set get request
|
||||
sprintf(obuffer, "GET http://%s" HTTP_REQUEST " HTTP/1.1\n" "Host: %s\n\n", server_name, station_id,
|
||||
server_name);
|
||||
|
||||
info("[KVV] Sending first (GET) request ...");
|
||||
send(sock, obuffer, strlen(obuffer), 0);
|
||||
|
||||
count = 0;
|
||||
do {
|
||||
fd_set rfds;
|
||||
struct timeval tv;
|
||||
|
||||
FD_ZERO(&rfds);
|
||||
FD_SET(sock, &rfds);
|
||||
|
||||
tv.tv_sec = count ? TIMEOUT_SHORT : TIMEOUT_LONG;
|
||||
tv.tv_usec = 0;
|
||||
|
||||
i = select(FD_SETSIZE, &rfds, NULL, NULL, &tv);
|
||||
if (i < 0) {
|
||||
perror("select");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (i != 0) {
|
||||
i = recv(sock, ibuffer + count, sizeof(ibuffer) - count, 0);
|
||||
count += i;
|
||||
}
|
||||
}
|
||||
while (i > 0);
|
||||
|
||||
ibuffer[count] = 0; // terminate string
|
||||
close(sock);
|
||||
|
||||
if (count > 0) {
|
||||
char *input, *cookie, *name, *value;
|
||||
int input_len, cookie_len, name_len, value_len;
|
||||
|
||||
// buffer to html encode value
|
||||
char value_enc[512];
|
||||
int value_enc_len;
|
||||
|
||||
// find cookie
|
||||
cookie_len = 0;
|
||||
cookie = strstr(ibuffer, "Set-Cookie:");
|
||||
if (cookie) {
|
||||
cookie += strlen("Set-Cookie:");
|
||||
|
||||
while (*cookie == ' ')
|
||||
cookie++;
|
||||
|
||||
while (cookie[cookie_len] != ';')
|
||||
cookie_len++;
|
||||
}
|
||||
// find input element
|
||||
input_len = get_element(ibuffer, "input", &input);
|
||||
|
||||
|
||||
if (input_len > 0) {
|
||||
char *input_end = input;
|
||||
while (*input_end != '>')
|
||||
input_end++;
|
||||
while (*input_end != '\"')
|
||||
input_end--;
|
||||
*(input_end + 1) = 0;
|
||||
|
||||
name_len = get_attrib(input, "name", &name);
|
||||
value_len = get_attrib(input, "value", &value);
|
||||
|
||||
for (value_enc_len = 0, i = 0; i < value_len; i++) {
|
||||
if (isalnum(value[i]))
|
||||
value_enc[value_enc_len++] = value[i];
|
||||
else {
|
||||
sprintf(value_enc + value_enc_len, "%%%02X", 0xff & value[i]);
|
||||
value_enc_len += 3;
|
||||
}
|
||||
}
|
||||
|
||||
if (cookie_len >= 0)
|
||||
cookie[cookie_len] = 0;
|
||||
if (name_len >= 0)
|
||||
name[name_len] = 0;
|
||||
if (value_len >= 0)
|
||||
value[value_len] = 0;
|
||||
if (value_enc_len >= 0)
|
||||
value_enc[value_enc_len] = 0;
|
||||
|
||||
sock = http_open(connect_to);
|
||||
|
||||
// send POST
|
||||
sprintf(obuffer,
|
||||
"POST http://%s" HTTP_REQUEST " HTTP/1.1\n"
|
||||
"Host: %s\n"
|
||||
"Cookie: %s\n"
|
||||
"Content-Type: application/x-www-form-urlencoded\n"
|
||||
"Content-Length: %d\n"
|
||||
"\n%s=%s",
|
||||
server_name, station_id, server_name, cookie, name_len + value_enc_len + 1, name, value_enc);
|
||||
|
||||
info("[KVV] Sending second (POST) request ...");
|
||||
send(sock, obuffer, strlen(obuffer), 0);
|
||||
|
||||
count = 0;
|
||||
do {
|
||||
fd_set rfds;
|
||||
struct timeval tv;
|
||||
|
||||
FD_ZERO(&rfds);
|
||||
FD_SET(sock, &rfds);
|
||||
|
||||
tv.tv_sec = count ? TIMEOUT_SHORT : TIMEOUT_LONG;
|
||||
tv.tv_usec = 0;
|
||||
|
||||
i = select(FD_SETSIZE, &rfds, NULL, NULL, &tv);
|
||||
if (i > 0) {
|
||||
i = recv(sock, ibuffer + count, sizeof(ibuffer) - count, 0);
|
||||
count += i;
|
||||
}
|
||||
}
|
||||
while (i > 0); /* leave on select or read error */
|
||||
|
||||
ibuffer[count] = 0;
|
||||
|
||||
/* close connection */
|
||||
close(sock);
|
||||
|
||||
if (count > 0) {
|
||||
int last_was_stop = 0;
|
||||
char *td = ibuffer;
|
||||
char str[32];
|
||||
int td_len, i, overflow = 0;
|
||||
|
||||
/* lock shared memory */
|
||||
mutex_lock(mutex);
|
||||
|
||||
/* free allocated memory */
|
||||
shm->entries = 0;
|
||||
|
||||
/* scan through all <td> entries and search the line nums */
|
||||
do {
|
||||
if ((td_len = get_element(td, "td", &td)) > 0) {
|
||||
char *attr, *p;
|
||||
int attr_len;
|
||||
|
||||
/* time does not have a class but comes immediately after stop :-( */
|
||||
if (last_was_stop) {
|
||||
td += td_len + 1;
|
||||
get_text(td, "td", str, sizeof(str));
|
||||
|
||||
/* time needs special treatment */
|
||||
if (strncasecmp(str, "sofort", strlen("sofort")) == 0)
|
||||
i = 0;
|
||||
else {
|
||||
/* skip everything that is not a number */
|
||||
p = str;
|
||||
while (!isdigit(*p))
|
||||
p++;
|
||||
|
||||
/* and convert remaining to number */
|
||||
i = atoi(p);
|
||||
}
|
||||
|
||||
/* save time */
|
||||
if (!overflow)
|
||||
shm->entry[shm->entries - 1].time = i;
|
||||
|
||||
last_was_stop = 0;
|
||||
}
|
||||
|
||||
/* linenum and stopname fields have proper classes */
|
||||
if ((attr_len = get_attrib(td, "class", &attr)) > 0) {
|
||||
|
||||
if (strncasecmp(attr, "lineNum", strlen("lineNum")) == 0) {
|
||||
td += td_len + 1;
|
||||
get_text(td, "td", str, sizeof(str));
|
||||
|
||||
if (shm->entries < MAX_LINES) {
|
||||
// allocate a new slot
|
||||
shm->entries++;
|
||||
shm->entry[shm->entries - 1].time = -1;
|
||||
memset(shm->entry[shm->entries - 1].line, 0, MAX_LINE_LENGTH + 1);
|
||||
memset(shm->entry[shm->entries - 1].station, 0, MAX_STATION_LENGTH + 1);
|
||||
|
||||
// add new lines entry
|
||||
strncpy(shm->entry[shm->entries - 1].line, str, MAX_LINE_LENGTH);
|
||||
} else
|
||||
overflow = 1; /* don't add further entries */
|
||||
}
|
||||
|
||||
if (strncasecmp(attr, "stopname", strlen("stopname")) == 0) {
|
||||
td += td_len + 1;
|
||||
get_text(td, "td", str, sizeof(str));
|
||||
|
||||
/* stopname may need further tuning */
|
||||
process_station_string(str);
|
||||
|
||||
if (!overflow)
|
||||
strncpy(shm->entry[shm->entries - 1].station, str, MAX_STATION_LENGTH);
|
||||
|
||||
last_was_stop = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
} while (td_len >= 0);
|
||||
|
||||
mutex_unlock(mutex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sleep(refresh);
|
||||
}
|
||||
}
|
||||
|
||||
static void kvv_line(RESULT * result, RESULT * arg1)
|
||||
{
|
||||
int index = (int) R2N(arg1);
|
||||
|
||||
mutex_lock(mutex);
|
||||
|
||||
if (index < shm->entries) {
|
||||
SetResult(&result, R_STRING, shm->entry[index].line);
|
||||
} else
|
||||
SetResult(&result, R_STRING, "---");
|
||||
|
||||
mutex_unlock(mutex);
|
||||
}
|
||||
|
||||
static void kvv_station(RESULT * result, RESULT * arg1)
|
||||
{
|
||||
int index = (int) R2N(arg1);
|
||||
|
||||
mutex_lock(mutex);
|
||||
|
||||
if (index < shm->entries)
|
||||
SetResult(&result, R_STRING, shm->entry[index].station);
|
||||
else
|
||||
SetResult(&result, R_STRING, "---");
|
||||
|
||||
mutex_unlock(mutex);
|
||||
}
|
||||
|
||||
static void kvv_time(RESULT * result, RESULT * arg1)
|
||||
{
|
||||
int index = (int) R2N(arg1);
|
||||
double value = -1.0;
|
||||
|
||||
mutex_lock(mutex);
|
||||
|
||||
if (index < shm->entries)
|
||||
value = shm->entry[index].time;
|
||||
|
||||
SetResult(&result, R_NUMBER, &value);
|
||||
|
||||
mutex_unlock(mutex);
|
||||
}
|
||||
|
||||
static void kvv_time_str(RESULT * result, RESULT * arg1)
|
||||
{
|
||||
int index = (int) R2N(arg1);
|
||||
|
||||
mutex_lock(mutex);
|
||||
|
||||
if (index < shm->entries) {
|
||||
char str[8];
|
||||
sprintf(str, "%d", shm->entry[index].time);
|
||||
SetResult(&result, R_STRING, str);
|
||||
} else
|
||||
SetResult(&result, R_STRING, "---");
|
||||
|
||||
mutex_unlock(mutex);
|
||||
}
|
||||
|
||||
/* plugin initialization */
|
||||
int plugin_init_kvv(void)
|
||||
{
|
||||
int val;
|
||||
char *p;
|
||||
|
||||
/* register all our cool functions */
|
||||
AddFunction("kvv::line", 1, kvv_line);
|
||||
AddFunction("kvv::station", 1, kvv_station);
|
||||
AddFunction("kvv::time", 1, kvv_time);
|
||||
AddFunction("kvv::time_str", 1, kvv_time_str);
|
||||
|
||||
/* parse parameter */
|
||||
if ((p = cfg_get(SECTION, "StationID", DEFAULT_STATION_ID)) != NULL) {
|
||||
station_id = malloc(strlen(p) + 1);
|
||||
strcpy(station_id, p);
|
||||
}
|
||||
info("[KVV] Using station %s", station_id);
|
||||
|
||||
if ((p = cfg_get(SECTION, "Proxy", NULL)) != NULL) {
|
||||
proxy_name = malloc(strlen(p) + 1);
|
||||
strcpy(proxy_name, p);
|
||||
info("[KVV] Using proxy \"%s\"", proxy_name);
|
||||
}
|
||||
|
||||
if (cfg_number(SECTION, "Port", 0, 0, 65535, &val) > 0) {
|
||||
port = val;
|
||||
info("[KVV] Using port %d", port);
|
||||
} else {
|
||||
info("[KVV] Using default port %d", port);
|
||||
}
|
||||
|
||||
if (cfg_number(SECTION, "Refresh", 0, 0, 65535, &val) > 0) {
|
||||
refresh = val;
|
||||
info("[KVV] Using %d seconds refresh interval", refresh);
|
||||
} else {
|
||||
info("[KVV] Using default refresh interval of %d seconds", refresh);
|
||||
}
|
||||
|
||||
if (cfg_number(SECTION, "Stringlen", 0, 0, 65535, &val) > 0) {
|
||||
stringlen = val;
|
||||
info("[KVV] Using %d character string length", stringlen);
|
||||
} else {
|
||||
info("[KVV] Using %d characters default string length", stringlen);
|
||||
}
|
||||
|
||||
/* create communication buffer */
|
||||
shmid = shm_create((void **) &shm, sizeof(kvv_shm_t));
|
||||
|
||||
/* catch error */
|
||||
if (shmid < 0) {
|
||||
error("[KVV] Shared memory allocation failed!");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* attach client thread */
|
||||
mutex = mutex_create();
|
||||
pid = fork();
|
||||
if (pid < 0) {
|
||||
error("[KVV] Unable to fork client: %s", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (pid == 0)
|
||||
kvv_client();
|
||||
else
|
||||
info("[KVV] forked client with pid %d", pid);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void plugin_exit_kvv(void)
|
||||
{
|
||||
if (pid != -1)
|
||||
kill(pid, SIGTERM);
|
||||
|
||||
if (station_id)
|
||||
free(station_id);
|
||||
if (proxy_name)
|
||||
free(proxy_name);
|
||||
|
||||
mutex_destroy(mutex);
|
||||
|
||||
if (shm)
|
||||
shm_destroy(shmid, shm);
|
||||
}
|
||||
@@ -58,6 +58,7 @@ for plugin in $plugins; do
|
||||
PLUGIN_I2C_SENSORS="yes"
|
||||
PLUGIN_IMON="yes"
|
||||
PLUGIN_ISDN="yes"
|
||||
PLUGIN_KVV="yes"
|
||||
PLUGIN_LOADAVG="yes"
|
||||
PLUGIN_MEMINFO="yes"
|
||||
PLUGIN_MPD="yes"
|
||||
@@ -102,6 +103,9 @@ for plugin in $plugins; do
|
||||
isdn)
|
||||
PLUGIN_ISDN=$val
|
||||
;;
|
||||
kvv)
|
||||
PLUGIN_KVV=$val
|
||||
;;
|
||||
loadavg)
|
||||
PLUGIN_LOADAVG=$val
|
||||
;;
|
||||
@@ -203,6 +207,10 @@ if test "$PLUGIN_ISDN" = "yes"; then
|
||||
PLUGINS="$PLUGINS plugin_isdn.o"
|
||||
AC_DEFINE(PLUGIN_ISDN,1,[ISDN plugin])
|
||||
fi
|
||||
if test "$PLUGIN_KVV" = "yes"; then
|
||||
PLUGINS="$PLUGINS plugin_kvv.o"
|
||||
AC_DEFINE(PLUGIN_KVV,1,[kvv plugin])
|
||||
fi
|
||||
if test "$PLUGIN_LOADAVG" = "yes"; then
|
||||
PLUGINS="$PLUGINS plugin_loadavg.o"
|
||||
AC_DEFINE(PLUGIN_LOADAVG,1,[loadavg plugin])
|
||||
|
||||
+13
-11
@@ -1,4 +1,4 @@
|
||||
/* $Id: property.c,v 1.2 2006/08/13 11:38:20 reinelt Exp $
|
||||
/* $Id: property.c,v 1.3 2006/08/13 18:14:03 harbaum Exp $
|
||||
*
|
||||
* dynamic properties
|
||||
*
|
||||
@@ -23,6 +23,9 @@
|
||||
*
|
||||
*
|
||||
* $Log: property.c,v $
|
||||
* Revision 1.3 2006/08/13 18:14:03 harbaum
|
||||
* Added KVV plugin
|
||||
*
|
||||
* Revision 1.2 2006/08/13 11:38:20 reinelt
|
||||
* text widget uses dynamic properties
|
||||
*
|
||||
@@ -93,32 +96,31 @@ int property_eval(PROPERTY * prop)
|
||||
{
|
||||
RESULT old;
|
||||
int update = 1;
|
||||
|
||||
|
||||
/* this is a bit ugly: we need to remember the old value */
|
||||
|
||||
|
||||
old.type = prop->result.type;
|
||||
old.size = prop->result.size;
|
||||
old.number = prop->result.number;
|
||||
old.string = prop->result.string != NULL ? strdup(prop->result.string) : NULL;
|
||||
|
||||
old.string = prop->result.string != NULL ? strdup(prop->result.string) : NULL;
|
||||
|
||||
DelResult(&prop->result);
|
||||
Eval(prop->compiled, &prop->result);
|
||||
|
||||
|
||||
if (prop->result.type & R_NUMBER && old.type & R_NUMBER && prop->result.number == old.number) {
|
||||
update = 0;
|
||||
}
|
||||
|
||||
|
||||
if (prop->result.type & R_STRING && old.type & R_STRING && prop->result.size == old.size) {
|
||||
if (prop->result.string == NULL && old.string == NULL) {
|
||||
update = 0;
|
||||
}
|
||||
else if (prop->result.string != NULL && old.string != NULL && strcmp(prop->result.string, old.string) == 0) {
|
||||
} else if (prop->result.string != NULL && old.string != NULL && strcmp(prop->result.string, old.string) == 0) {
|
||||
update = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (old.string)
|
||||
free (old.string);
|
||||
free(old.string);
|
||||
|
||||
return update;
|
||||
}
|
||||
|
||||
+6
-3
@@ -1,4 +1,4 @@
|
||||
/* $Id: widget_text.c,v 1.26 2006/08/13 11:38:20 reinelt Exp $
|
||||
/* $Id: widget_text.c,v 1.27 2006/08/13 18:14:03 harbaum Exp $
|
||||
*
|
||||
* simple text widget handling
|
||||
*
|
||||
@@ -21,6 +21,9 @@
|
||||
*
|
||||
*
|
||||
* $Log: widget_text.c,v $
|
||||
* Revision 1.27 2006/08/13 18:14:03 harbaum
|
||||
* Added KVV plugin
|
||||
*
|
||||
* Revision 1.26 2006/08/13 11:38:20 reinelt
|
||||
* text widget uses dynamic properties
|
||||
*
|
||||
@@ -172,7 +175,7 @@ void widget_text_scroll(void *Self)
|
||||
char *postfix = P2S(&T->postfix);
|
||||
|
||||
char *string = T->string;
|
||||
|
||||
|
||||
int num, len, width, pad;
|
||||
char *src, *dst;
|
||||
|
||||
@@ -325,7 +328,7 @@ void widget_text_update(void *Self)
|
||||
|
||||
/* text style */
|
||||
update += property_eval(&T->style);
|
||||
|
||||
|
||||
/* something has changed and should be updated */
|
||||
if (update) {
|
||||
/* reset marquee counter if content has changed */
|
||||
|
||||
+6
-3
@@ -1,4 +1,4 @@
|
||||
/* $Id: widget_text.h,v 1.9 2006/08/13 11:38:20 reinelt Exp $
|
||||
/* $Id: widget_text.h,v 1.10 2006/08/13 18:14:03 harbaum Exp $
|
||||
*
|
||||
* simple text widget handling
|
||||
*
|
||||
@@ -23,6 +23,9 @@
|
||||
*
|
||||
*
|
||||
* $Log: widget_text.h,v $
|
||||
* Revision 1.10 2006/08/13 18:14:03 harbaum
|
||||
* Added KVV plugin
|
||||
*
|
||||
* Revision 1.9 2006/08/13 11:38:20 reinelt
|
||||
* text widget uses dynamic properties
|
||||
*
|
||||
@@ -77,9 +80,9 @@ typedef enum { ALIGN_LEFT, ALIGN_CENTER, ALIGN_RIGHT, ALIGN_MARQUEE } TEXT_ALIGN
|
||||
typedef struct WIDGET_TEXT {
|
||||
PROPERTY prefix; /* label on the left side */
|
||||
PROPERTY postfix; /* label on the right side */
|
||||
PROPERTY value; /* value of text widget */
|
||||
PROPERTY value; /* value of text widget */
|
||||
PROPERTY style; /* text style (plain/bold/slant) */
|
||||
char *string; /* formatted value */
|
||||
char *string; /* formatted value */
|
||||
char *buffer; /* string with 'width+1' bytes allocated */
|
||||
int width; /* field width */
|
||||
int precision; /* number of digits after the decimal point */
|
||||
|
||||
Reference in New Issue
Block a user