summaryrefslogtreecommitdiffstats
path: root/oncology/dpfhack_display/lcd4linux/.svn/text-base/plugin_kvv.c.svn-base
diff options
context:
space:
mode:
Diffstat (limited to 'oncology/dpfhack_display/lcd4linux/.svn/text-base/plugin_kvv.c.svn-base')
-rw-r--r--oncology/dpfhack_display/lcd4linux/.svn/text-base/plugin_kvv.c.svn-base814
1 files changed, 0 insertions, 814 deletions
diff --git a/oncology/dpfhack_display/lcd4linux/.svn/text-base/plugin_kvv.c.svn-base b/oncology/dpfhack_display/lcd4linux/.svn/text-base/plugin_kvv.c.svn-base
deleted file mode 100644
index 2291af14..00000000
--- a/oncology/dpfhack_display/lcd4linux/.svn/text-base/plugin_kvv.c.svn-base
+++ /dev/null
@@ -1,814 +0,0 @@
-/* $Id$
- * $URL$
- *
- * 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.
- *
- */
-
-/*
- * 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 USER_AGENT "lcd4linux - KVV plugin (http://ssl.bulix.org/projects/lcd4linux/wiki/plugin_kvv)"
-
-#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 40
-
-typedef struct {
- char line[MAX_LINE_LENGTH + 1];
- char station[MAX_STATION_LENGTH + 1];
- int time;
-} kvv_entry_t;
-
-typedef struct {
- int entries, error;
- 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 abbreviate = 0;
-
-static int initialized = 0;
-static int mutex = 0;
-static int shmid = -1;
-static kvv_shm_t *shm = NULL;
-
-#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 && (*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;
-
- /* some strings to replace */
- char *repl[] = {
- "Hauptbahnhof", "Hbf.",
- "Bahnhof", "Bhf.",
- "Karlsruhe", "KA",
- "Schienenersatzverkehr", "Ersatzv.",
- "Marktplatz", "Marktpl.",
- };
-
- /* 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;
-
- /* erase multiple spaces and replace umlauts */
- p = q = str;
- last = 1; /* no leading spaces */
- while (*p) {
- if ((!last) || (*p != ' ')) {
-
- /* translate from latin1 to hd44780 */
- if (*p == (char) 228) /* lower a umlaut */
- *q++ = (char) 0xe1;
- else if (*p == (char) 223) /* sz ligature */
- *q++ = (char) 0xe2;
- else if (*p == (char) 246) /* lower o umlaut */
- *q++ = (char) 0xef;
- else if (*p == (char) 252) /* lower u umlaut */
- *q++ = (char) 0xf5;
- else
- *q++ = *p;
- }
-
- last = (*p == ' ');
- p++;
- }
- *q++ = 0;
-
- /* replace certain (long) words with e.g. abbreviations if enabled */
- if (abbreviate) {
-
- 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( __attribute__ ((unused))
- void *dummy)
-{
- char ibuffer[8192];
- char obuffer[1024];
- 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 */
- if (snprintf(obuffer, sizeof(obuffer),
- "GET http://%s" HTTP_REQUEST " HTTP/1.1\n"
- "Host: %s\n" "User-Agent: " USER_AGENT "\n\n", server_name, station_id,
- server_name) >= (int) sizeof(obuffer)) {
-
- info("[KVV] Warning, request has been truncated!");
- }
-
- 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 - 1, 0);
- count += i;
- }
- }
- while (i > 0);
-
- ibuffer[count] = 0; /* terminate string */
- close(sock);
-
- if (!count)
- info("[KVV] empty/no reply");
-
- if (count > 0) {
- char *input, *cookie, *name = NULL, *value = NULL;
- 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 */
- if (snprintf(obuffer, sizeof(obuffer),
- "POST http://%s" HTTP_REQUEST " HTTP/1.1\n"
- "Host: %s\n"
- "User-Agent: " USER_AGENT "\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) >= (int) sizeof(obuffer)) {
-
- info("[KVV] Warning, request has been truncated!");
- }
-
- 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 - 1, 0);
- count += i;
- }
- }
- while (i > 0); /* leave on select or read error */
-
- ibuffer[count] = 0;
-
- /* printf("Result (%d):\n%s\n", count, ibuffer); */
-
- /* close connection */
- close(sock);
-
- if (!count)
- info("[KVV] empty/no reply");
-
- 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;
-
- if (strstr(ibuffer, "Die Daten konnten nicht abgefragt werden.") != NULL) {
- info("[KVV] Server returned error!");
- /* printf("%s\n", ibuffer); */
- shm->error = 1;
- } else
- shm->error = 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 int kvv_fork(void)
-{
- if (initialized)
- return 0;
-
- info("[KVV] creating client thread");
-
- /* set this here to prevent continous retries if init fails */
- initialized = 1;
-
- /* 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 = thread_create("plugin_kvv", kvv_client, NULL);
-
- if (pid < 0) {
- error("[KVV] Unable to fork client: %s", strerror(errno));
- return -1;
- }
-
- info("[KVV] forked client with pid %d", pid);
- return 0;
-}
-
-static void kvv_start(void)
-{
- static int started = 0;
- int val;
- char *p;
-
-
- if (started)
- return;
-
- started = 1;
-
- /* 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, "Abbreviate", 0, 0, 65535, &val) > 0) {
- abbreviate = val;
- info("[KVV] Abbreviation enabled: %s", abbreviate ? "on" : "off");
- } else {
- info("[KVV] Default abbreviation setting: %s", abbreviate ? "on" : "off");
- }
-
-}
-
-static void kvv_line(RESULT * result, RESULT * arg1)
-{
- int index = (int) R2N(arg1);
-
- kvv_start();
-
- if (kvv_fork() != 0) {
- SetResult(&result, R_STRING, "");
- return;
- }
-
- 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);
-
- kvv_start();
-
- if (kvv_fork() != 0) {
- SetResult(&result, R_STRING, "");
- return;
- }
-
- mutex_lock(mutex);
-
- if (shm->error && index == 0)
- SetResult(&result, R_STRING, "Server Err");
- else {
- 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;
-
- kvv_start();
-
- if (kvv_fork() != 0) {
- SetResult(&result, R_STRING, "");
- return;
- }
-
- 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);
-
- kvv_start();
-
- if (kvv_fork() != 0) {
- SetResult(&result, R_STRING, "");
- return;
- }
-
- 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)
-{
- /* 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);
- return 0;
-}
-
-void plugin_exit_kvv(void)
-{
- /* kill client thread if it's running */
- if (initialized) {
- /* kill client */
- if (pid != -1)
- thread_destroy(pid);
-
- /* free shared mem and its mutex */
- if (shm) {
- shm_destroy(shmid, shm);
- mutex_destroy(mutex);
- }
- }
-
- if (station_id)
- free(station_id);
- if (proxy_name)
- free(proxy_name);
-}