/* $Id: lcd4linux.c,v 1.79 2005/09/02 05:27:08 reinelt Exp $ * * LCD4Linux * * Copyright (C) 1999, 2000, 2001, 2002, 2003 Michael Reinelt * Copyright (C) 2004 The LCD4Linux Team * * 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: lcd4linux.c,v $ * Revision 1.79 2005/09/02 05:27:08 reinelt * double-fork daemonize patch from Petri Damsten * * Revision 1.78 2005/05/08 04:32:44 reinelt * CodingStyle added and applied * * Revision 1.77 2005/03/30 04:57:50 reinelt * Evaluator speedup: use bsearch for finding functions and variables * * Revision 1.76 2005/01/18 06:30:23 reinelt * added (C) to all copyright statements * * Revision 1.75 2004/09/24 21:41:00 reinelt * new driver for the BWCT USB LCD interface board. * * Revision 1.74 2004/06/26 12:04:59 reinelt * * uh-oh... the last CVS log message messed up things a lot... * * Revision 1.73 2004/06/26 09:27:21 reinelt * * added '-W' to CFLAGS * changed all C++ comments to C ones * cleaned up a lot of signed/unsigned mistakes * * Revision 1.72 2004/06/06 06:51:59 reinelt * * do not display end splash screen if quiet=1 * * Revision 1.71 2004/06/02 09:41:19 reinelt * * prepared support for startup splash screen * * Revision 1.70 2004/06/02 05:14:16 reinelt * * fixed models listing for Beckmann+Egle driver * some cosmetic changes * * Revision 1.69 2004/03/14 07:11:42 reinelt * parameter count fixed for plugin_dvb() * plugin_APM (battery status) ported * * Revision 1.68 2004/03/11 06:39:59 reinelt * big patch from Martin: * - reuse filehandles * - memory leaks fixed * - earlier busy-flag checking with HD44780 * - reuse memory for strings in RESULT and hash * - netdev_fast to wavid time-consuming regex * * Revision 1.67 2004/03/06 20:31:16 reinelt * Complete rewrite of the evaluator to get rid of the code * from mark Morley (because of license issues). * The new Evaluator does a pre-compile of expressions, and * stores them in trees. Therefore it should be reasonable faster... * * Revision 1.66 2004/03/03 04:44:16 reinelt * changes (cosmetics?) to the big patch from Martin * hash patch un-applied * * Revision 1.65 2004/03/03 03:47:04 reinelt * big patch from Martin Hejl: * - use qprintf() where appropriate * - save CPU cycles on gettimeofday() * - add quit() functions to free allocated memory * - fixed lots of memory leaks * * Revision 1.64 2004/02/27 07:06:25 reinelt * new function 'qprintf()' (simple but quick snprintf() replacement) * * Revision 1.63 2004/02/10 07:42:35 reinelt * cut off all old-style files which are no longer used with NextGeneration * * Revision 1.62 2004/01/30 20:57:56 reinelt * HD44780 patch from Martin Hejl * dmalloc integrated * * Revision 1.61 2004/01/14 11:33:00 reinelt * new plugin 'uname' which does what it's called * text widget nearly finished * first results displayed on MatrixOrbital * * Revision 1.60 2004/01/13 08:18:19 reinelt * timer queues added * liblcd4linux deactivated turing transformation to new layout * * Revision 1.59 2004/01/12 03:51:01 reinelt * evaluating the 'Variables' section in the config file * * Revision 1.58 2004/01/10 20:22:33 reinelt * added new function 'cfg_list()' (not finished yet) * added layout.c (will replace processor.c someday) * added widget_text.c (will be the first and most important widget) * modified lcd4linux.c so that old-style configs should work, too * * Revision 1.57 2004/01/10 17:45:26 reinelt * changed initialization order so cfg() gets initialized before plugins. * This way a plugin's init() can use cfg_get(). * Thanks to Xavier for reporting this one! * * Revision 1.56 2004/01/09 17:03:07 reinelt * initiated transfer to new driver architecture * new file 'drv.c' will someday replace 'display.c' * new file 'drv_MatrixOrbital.c' will replace 'MatrixOrbital.c' * due to this 'soft' transfer lcd4linux should stay usable during the switch * (at least I hope so) * * Revision 1.55 2004/01/09 04:16:06 reinelt * added 'section' argument to cfg_get(), but NULLed it on all calls by now. * * Revision 1.54 2004/01/08 05:28:12 reinelt * Luk Claes added to AUTHORS * cfg: group handling ('{}') added * * Revision 1.53 2003/12/19 05:35:14 reinelt * renamed 'client' to 'plugin' * * Revision 1.52 2003/12/01 07:08:50 reinelt * * Patches from Xavier: * - WiFi: make interface configurable * - "quiet" as an option from the config file * - ignore missing "MemShared" on Linux 2.6 * * Revision 1.51 2003/11/16 09:45:49 reinelt * Crystalfontz changes, small glitch in getopt() fixed * * Revision 1.50 2003/10/22 04:19:16 reinelt * Makefile.in for imon.c/.h, some MatrixOrbital clients * * Revision 1.49 2003/10/11 06:01:53 reinelt * * renamed expression.{c,h} to client.{c,h} * added config file client * new functions 'AddNumericVariable()' and 'AddStringVariable()' * new parameter '-i' for interactive mode * * Revision 1.48 2003/10/05 17:58:50 reinelt * libtool junk; copyright messages cleaned up * * Revision 1.47 2003/09/10 08:37:09 reinelt * icons: reorganized tick_* again... * * Revision 1.46 2003/09/09 06:54:43 reinelt * new function 'cfg_number()' * * Revision 1.45 2003/09/09 05:30:34 reinelt * even more icons stuff * * Revision 1.44 2003/08/24 05:17:58 reinelt * liblcd4linux patch from Patrick Schemitz * * Revision 1.43 2003/08/17 16:37:39 reinelt * more icon framework * * Revision 1.42 2003/08/14 03:47:40 reinelt * remove PID file if driver initialisation fails * * Revision 1.41 2003/08/08 08:05:23 reinelt * added PID file handling * * Revision 1.40 2003/08/08 06:58:06 reinelt * improved forking * * Revision 1.39 2003/07/24 04:48:09 reinelt * 'soft clear' needed for virtual rows * * Revision 1.38 2003/06/13 05:11:11 reinelt * error message cosmetics * * Revision 1.37 2003/04/07 06:03:01 reinelt * further parallel port abstraction * * Revision 1.36 2003/02/22 07:53:10 reinelt * cfg_get(key,defval) * * Revision 1.35 2003/02/13 10:40:17 reinelt * * changed "copyright" to "2003" * added slightly different protocol for MatrixOrbital "LK202" displays * * Revision 1.34 2002/04/29 11:00:28 reinelt * * added Toshiba T6963 driver * added ndelay() with nanosecond resolution * * Revision 1.33 2001/04/27 05:04:57 reinelt * * replaced OPEN_MAX with sysconf() * replaced mktemp() with mkstemp() * unlock serial port if open() fails * * Revision 1.32 2001/03/13 07:41:22 reinelt * * added NEWS file * * Revision 1.31 2001/03/12 12:39:36 reinelt * * reworked autoconf a lot: drivers may be excluded, #define's went to config.h * * Revision 1.30 2001/03/08 15:25:38 ltoetsch * improved exec * * Revision 1.29 2001/02/14 07:40:16 reinelt * * first (incomplete) GPO implementation * * Revision 1.28 2000/10/25 08:10:48 reinelt * * added restart funnctionality * (lots of this code was stolen from sendmail.c) * * Revision 1.27 2000/08/10 18:42:20 reinelt * * fixed some bugs with the new syslog code * * Revision 1.26 2000/08/10 09:44:09 reinelt * * new debugging scheme: error(), info(), debug() * uses syslog if in daemon mode * * Revision 1.25 2000/08/09 14:14:11 reinelt * * new switch -F (do not fork) * added automatic forking if -F not specified * * Revision 1.24 2000/08/09 09:50:29 reinelt * * opened 0.98 development * removed driver-specific signal-handlers * added 'quit'-function to driver structure * added global signal-handler * * Revision 1.23 2000/04/17 05:14:27 reinelt * * added README.44780 * * Revision 1.22 2000/04/15 16:56:52 reinelt * * moved delay loops to udelay.c * renamed -d (debugging) switch to -v (verbose) * new switch -d to calibrate delay loop * 'Delay' entry for HD44780 back again * delay loops will not calibrate automatically, because this will fail with hich CPU load * * Revision 1.21 2000/04/15 11:56:35 reinelt * * more debug messages * * Revision 1.20 2000/04/15 11:13:54 reinelt * * added '-d' (debugging) switch * added several debugging messages * removed config entry 'Delay' for HD44780 driver * delay loop for HD44780 will be calibrated automatically * * Revision 1.19 2000/04/10 04:40:53 reinelt * * minor changes and cleanups * * Revision 1.18 2000/04/07 05:42:20 reinelt * * UUCP style lockfiles for the serial port * * Revision 1.17 2000/04/03 17:31:52 reinelt * * suppress welcome message if display is smaller than 20x2 * change lcd4linux.ppm to 32 pixel high so KDE won't stretch the icon * * Revision 1.16 2000/04/03 04:46:38 reinelt * * added '-c key=val' option * * Revision 1.15 2000/04/01 22:40:42 herp * geometric correction (too many pixelgaps) * lcd4linux main should return int, not void * * Revision 1.14 2000/03/26 18:46:28 reinelt * * bug in pixmap.c that leaded to empty bars fixed * name conflicts with X11 resolved * * Revision 1.13 2000/03/26 12:55:03 reinelt * * enhancements to the PPM driver * * Revision 1.12 2000/03/25 05:50:43 reinelt * * memory leak in Raster_flush closed * driver family logic changed * * Revision 1.11 2000/03/24 11:36:56 reinelt * * new syntax for raster configuration * changed XRES and YRES to be configurable * PPM driver works nice * * Revision 1.10 2000/03/23 07:24:48 reinelt * * PPM driver up and running (but slow!) * * Revision 1.9 2000/03/22 15:36:21 reinelt * * added '-l' switch (list drivers) * generic pixmap driver added * X11 Framework done * * Revision 1.8 2000/03/22 07:33:50 reinelt * * FAQ added * new modules 'processor.c' contains all data processing * * Revision 1.7 2000/03/19 08:41:28 reinelt * * documentation available! README, README.MatrixOrbital, README.Drivers * added Skeleton.c as a starting point for new drivers * * Revision 1.6 2000/03/18 10:31:06 reinelt * * added sensor handling (for temperature etc.) * made data collecting happen only if data is used * (reading /proc/meminfo takes a lot of CPU!) * released lcd4linux-0.92 * * Revision 1.5 2000/03/18 08:07:04 reinelt * * vertical bars implemented * bar compaction improved * memory information implemented * * Revision 1.4 2000/03/17 09:21:42 reinelt * * various memory statistics added * * Revision 1.3 2000/03/13 15:58:24 reinelt * * release 0.9 * moved row parsing to parser.c * all basic work finished * * Revision 1.2 2000/03/10 17:36:02 reinelt * * first unstable but running release * */ #include "config.h" #include #include #include #include #include #include #include #include #include "cfg.h" #include "debug.h" #include "qprintf.h" #include "pid.h" #include "udelay.h" #include "drv.h" #include "timer.h" #include "layout.h" #include "plugin.h" #ifdef WITH_DMALLOC #include #endif #define PIDFILE "/var/run/lcd4linux.pid" static char *release = "LCD4Linux " VERSION; static char *copyright = "Copyright (C) 2005 The LCD4Linux Team "; static char **my_argv; extern char *output; int got_signal = 0; static void usage(void) { printf("%s\n", release); printf("%s\n", copyright); printf("usage: lcd4linux [-h]\n"); printf(" lcd4linux [-l]\n"); printf(" lcd4linux [-c key=value] [-i] [-f config-file] [-v]\n"); printf(" lcd4linux [-c key=value] [-F] [-f config-file] [-o output-file] [-q] [-v]\n"); } static void interactive_mode(void) { char line[1024]; void *tree; RESULT result = { 0, 0, 0, NULL }; printf("\neval> "); for (fgets(line, 1024, stdin); !feof(stdin); fgets(line, 1024, stdin)) { if (line[strlen(line) - 1] == '\n') line[strlen(line) - 1] = '\0'; if (strlen(line) > 0) { if (Compile(line, &tree) != -1) { Eval(tree, &result); if (result.type == R_NUMBER) { printf("%g\n", R2N(&result)); } else if (result.type == R_STRING) { printf("'%s'\n", R2S(&result)); } else if (result.type == (R_NUMBER | R_STRING)) { printf("'%s' (%g)\n", R2S(&result), R2N(&result)); } else { printf("internal error: unknown result type %d\n", result.type); } DelResult(&result); } DelTree(tree); } printf("eval> "); } printf("\n"); } void handler(int signal) { debug("got signal %d", signal); got_signal = signal; } static void daemonize(void) { /* thanks to Petri Damsten, we now follow the guidelines from the UNIX Programming FAQ */ /* 1.7 How do I get my program to act like a daemon? */ /* http://www.erlenstar.demon.co.uk/unix/faq_2.html#SEC16 */ /* especially the double-fork solved the 'lcd4linux dying when called from init' problem */ pid_t i; int fd; /* Step 1: fork() so that the parent can exit */ i = fork(); if (i < 0) { error("fork(#1) failed: %s", strerror(errno)); exit(1); } if (i != 0) exit(0); /* Step 2: setsid() to become a process group and session group leader */ setsid(); /* Step 3: fork() again so the parent (the session group leader) can exit */ i = fork(); if (i < 0) { error("fork(#2) failed: %s", strerror(errno)); exit(1); } if (i != 0) exit(0); /* Step 4: chdir("/") to ensure that our process doesn't keep any directory in use */ if (chdir("/") != 0) { error("chdir(\"/\") failed: %s", strerror(errno)); exit(1); } /* Step 5: umask(0) so that we have complete control over the permissions of anything we write */ umask(0); /* Step 6: Establish new open descriptors for stdin, stdout and stderr */ /* detach stdin */ if (freopen("/dev/null", "r", stdin) == NULL) { error("freopen (/dev/null) failed: %s", strerror(errno)); exit(1); } /* detach stdout and stderr */ fd = open("/dev/null", O_WRONLY, 0666); if (fd == -1) { error("open (/dev/null) failed: %s", strerror(errno)); exit(1); } fflush(stdout); dup2(fd, STDOUT_FILENO); fflush(stderr); dup2(fd, STDERR_FILENO); close(fd); } int main(int argc, char *argv[]) { char *cfg = "/etc/lcd4linux.conf"; char *display, *driver, *layout; char section[32]; int c; int quiet = 0; int interactive = 0; int pid; /* save arguments for restart */ my_argv = malloc(sizeof(char *) * (argc + 1)); for (c = 0; c < argc; c++) { my_argv[c] = strdup(argv[c]); } my_argv[c] = NULL; running_foreground = 0; running_background = 0; while ((c = getopt(argc, argv, "c:Ff:hilo:qv")) != EOF) { switch (c) { case 'c': if (cfg_cmd(optarg) < 0) { fprintf(stderr, "%s: illegal argument -c '%s'\n", argv[0], optarg); exit(2); } break; case 'F': running_foreground++; break; case 'f': cfg = optarg; break; case 'h': usage(); exit(0); case 'i': interactive++; break; case 'l': printf("%s\n", release); printf("%s\n", copyright); drv_list(); exit(0); case 'o': output = optarg; break; case 'q': quiet++; break; case 'v': verbose_level++; break; default: exit(2); } } if (optind < argc) { fprintf(stderr, "%s: illegal option %s\n", argv[0], argv[optind]); exit(2); } /* do not fork in interactive mode */ if (interactive) { running_foreground = 1; } info("Version " VERSION " starting"); if (!running_foreground && (my_argv[0] == NULL || my_argv[0][0] != '/')) { info("invoked without full path; restart may not work!"); } if (cfg_init(cfg) == -1) exit(1); if (plugin_init() == -1) exit(1); display = cfg_get(NULL, "Display", NULL); if (display == NULL || *display == '\0') { error("missing 'Display' entry in %s!", cfg_source()); exit(1); } qprintf(section, sizeof(section), "Display:%s", display); free(display); driver = cfg_get(section, "Driver", NULL); if (driver == NULL || *driver == '\0') { error("missing '%s.Driver' entry in %s!", section, cfg_source()); exit(1); } if (!running_foreground) { debug("going background..."); daemonize(); /* ignore nasty signals */ signal(SIGINT, SIG_IGN); signal(SIGQUIT, SIG_IGN); /* create PID file */ if ((pid = pid_init(PIDFILE)) != 0) { error("lcd4linux already running as process %d", pid); exit(1); } /* now we are a daemon */ running_background = 1; } /* go into interactive mode before display initialization */ if (interactive >= 2) { interactive_mode(); pid_exit(PIDFILE); cfg_exit(); exit(0); } /* check the conf to see if quiet startup is wanted */ if (!quiet) { cfg_number(NULL, "Quiet", 0, 0, 1, &quiet); } debug("initializing driver %s", driver); if (drv_init(section, driver, quiet) == -1) { pid_exit(PIDFILE); exit(1); } free(driver); /* go into interactive mode (display has been initialized) */ if (interactive >= 1) { interactive_mode(); drv_quit(quiet); pid_exit(PIDFILE); cfg_exit(); exit(0); } /* check for new-style layout */ layout = cfg_get(NULL, "Layout", NULL); if (layout == NULL || *layout == '\0') { error("missing 'Layout' entry in %s!", cfg_source()); exit(1); } layout_init(layout); free(layout); debug("starting main loop"); /* now install our own signal handler */ signal(SIGHUP, handler); signal(SIGINT, handler); signal(SIGQUIT, handler); signal(SIGTERM, handler); while (got_signal == 0) { struct timespec delay; if (timer_process(&delay) < 0) break; nanosleep(&delay, NULL); } debug("leaving main loop"); drv_quit(quiet); pid_exit(PIDFILE); cfg_exit(); plugin_exit(); timer_exit(); if (got_signal == SIGHUP) { long fd; debug("restarting..."); /* close all files on exec */ for (fd = sysconf(_SC_OPEN_MAX); fd > 2; fd--) { int flag; if ((flag = fcntl(fd, F_GETFD, 0)) != -1) fcntl(fd, F_SETFD, flag | FD_CLOEXEC); } execv(my_argv[0], my_argv); error("execv() failed: %s", strerror(errno)); exit(1); } for (c = 0; my_argv[c] != NULL; c++) { free(my_argv[c]); } free(my_argv); exit(0); } -color: #e3d2d2 } /* Error */ .highlight .k { color: #008800; font-weight: bold } /* Keyword */ .highlight .ch { color: #888888 } /* Comment.Hashbang */ .highlight .cm { color: #888888 } /* Comment.Multiline */ .highlight .cp { color: #cc0000; font-weight: bold } /* Comment.Preproc */ .highlight .cpf { color: #888888 } /* Comment.PreprocFile */ .highlight .c1 { color: #888888 } /* Comment.Single */ .highlight .cs { color: #cc0000; font-weight: bold; background-color: #fff0f0 } /* Comment.Special */ .highlight .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */ .highlight .ge { font-style: italic } /* Generic.Emph */ .highlight .gr { color: #aa0000 } /* Generic.Error */ .highlight .gh { color: #333333 } /* Generic.Heading */ .highlight .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */ .highlight .go { color: #888888 } /* Generic.Output */ .highlight .gp { color: #555555 } /* Generic.Prompt */ .highlight .gs { font-weight: bold } /* Generic.Strong */ .highlight .gu { color: #666666 } /* Generic.Subheading */ .highlight .gt { color: #aa0000 } /* Generic.Traceback */ .highlight .kc { color: #008800; font-weight: bold } /* Keyword.Constant */ .highlight .kd { color: #008800; font-weight: bold } /* Keyword.Declaration */ .highlight .kn { color: #008800; font-weight: bold } /* Keyword.Namespace */ .highlight .kp { color: #008800 } /* Keyword.Pseudo */ .highlight .kr { color: #008800; font-weight: bold } /* Keyword.Reserved */ .highlight .kt { color: #888888; font-weight: bold } /* Keyword.Type */ .highlight .m { color: #0000DD; font-weight: bold } /* Literal.Number */ .highlight .s { color: #dd2200; background-color: #fff0f0 } /* Literal.String */ .highlight .na { color: #336699 } /* Name.Attribute */ .highlight .nb { color: #003388 } /* Name.Builtin */ .highlight .nc { color: #bb0066; font-weight: bold } /* Name.Class */ .highlight .no { color: #003366; font-weight: bold } /* Name.Constant */ .highlight .nd { color: #555555 } /* Name.Decorator */ .highlight .ne { color: #bb0066; font-weight: bold } /* Name.Exception */ .highlight .nf { color: #0066bb; font-weight: bold } /* Name.Function */ .highlight .nl { color: #336699; font-style: italic } /* Name.Label */ .highlight .nn { color: #bb0066; font-weight: bold } /* Name.Namespace */ .highlight .py { color: #336699; font-weight: bold } /* Name.Property */ .highlight .nt { color: #bb0066; font-weight: bold } /* Name.Tag */ .highlight .nv { color: #336699 } /* Name.Variable */ .highlight .ow { color: #008800 } /* Operator.Word */ .highlight .w { color: #bbbbbb } /* Text.Whitespace */ .highlight .mb { color: #0000DD; font-weight: bold } /* Literal.Number.Bin */ .highlight .mf { color: #0000DD; font-weight: bold } /* Literal.Number.Float */ .highlight .mh { color: #0000DD; font-weight: bold } /* Literal.Number.Hex */ .highlight .mi { color: #0000DD; font-weight: bold } /* Literal.Number.Integer */ .highlight .mo { color: #0000DD; font-weight: bold } /* Literal.Number.Oct */ .highlight .sa { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Affix */ .highlight .sb { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Backtick */ .highlight .sc { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Char */ .highlight .dl { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Delimiter */ .highlight .sd { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Doc */ .highlight .s2 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Double */ .highlight .se { color: #0044dd; background-color: #fff0f0 } /* Literal.String.Escape */ .highlight .sh { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Heredoc */ .highlight .si { color: #3333bb; background-color: #fff0f0 } /* Literal.String.Interpol */ .highlight .sx { color: #22bb22; background-color: #f0fff0 } /* Literal.String.Other */ .highlight .sr { color: #008800; background-color: #fff0ff } /* Literal.String.Regex */ .highlight .s1 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Single */ .highlight .ss { color: #aa6600; background-color: #fff0f0 } /* Literal.String.Symbol */ .highlight .bp { color: #003388 } /* Name.Builtin.Pseudo */ .highlight .fm { color: #0066bb; font-weight: bold } /* Name.Function.Magic */ .highlight .vc { color: #336699 } /* Name.Variable.Class */ .highlight .vg { color: #dd7700 } /* Name.Variable.Global */ .highlight .vi { color: #3333bb } /* Name.Variable.Instance */ .highlight .vm { color: #336699 } /* Name.Variable.Magic */ .highlight .il { color: #0000DD; font-weight: bold } /* Literal.Number.Integer.Long */
/* $Id: plugin.c,v 1.45 2006/08/13 18:14:03 harbaum Exp $
 *
 * plugin handler for the Evaluator
 *
 * Copyright (C) 2003 Michael Reinelt <reinelt@eunet.at>
 * Copyright (C) 2004 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.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
 *
 * Revision 1.43  2006/07/30 11:29:02  lfcorreia
 * Make changes suggested by Michael, only one init function is needed
 *
 * Revision 1.42  2006/07/29 21:12:31  lfcorreia
 * Add UPPERCASE string plugin function
 *
 * Revision 1.41  2006/04/15 05:22:52  reinelt
 * mpd plugin from Stefan Kuhne
 *
 * Revision 1.40  2006/02/19 15:42:19  reinelt
 * file plugin from Chris Maj
 *
 * Revision 1.39  2005/11/04 04:53:10  reinelt
 * sample plugin activated
 *
 * Revision 1.38  2005/05/08 04:32:44  reinelt
 * CodingStyle added and applied
 *
 * Revision 1.37  2005/05/02 10:29:20  reinelt
 * preparations for python bindings and python plugin
 *
 * Revision 1.36  2005/04/03 07:07:51  reinelt
 * added statfs plugin
 *
 * Revision 1.35  2005/01/18 06:30:23  reinelt
 * added (C) to all copyright statements
 *
 * Revision 1.34  2004/06/26 12:04:59  reinelt
 *
 * uh-oh... the last CVS log message messed up things a lot...
 *
 * Revision 1.33  2004/06/26 09:27:21  reinelt
 *
 * added '-W' to CFLAGS
 * changed all C++ comments to C ones
 * cleaned up a lot of signed/unsigned mistakes
 *
 * Revision 1.32  2004/06/07 06:56:55  reinelt
 *
 * added test plugin from Andy Baxter
 *
 * Revision 1.31  2004/05/29 00:27:23  reinelt
 *
 * added plugin_diskstats.c
 *
 * Revision 1.30  2004/05/22 18:30:02  reinelt
 *
 * added plugin 'uptime'
 *
 * Revision 1.29  2004/05/20 07:47:51  reinelt
 * added plugin_time
 *
 * Revision 1.28  2004/04/12 11:12:26  reinelt
 * added plugin_isdn, removed old ISDN client
 * fixed some real bad bugs in the evaluator
 *
 * Revision 1.27  2004/04/09 06:09:55  reinelt
 * big configure rework from Xavier
 *
 * Revision 1.25  2004/04/07 08:29:05  hejl
 * New plugin for wireless info
 *
 * Revision 1.24  2004/03/19 06:37:47  reinelt
 * asynchronous thread handling started
 *
 * Revision 1.23  2004/03/14 07:11:42  reinelt
 * parameter count fixed for plugin_dvb()
 * plugin_APM (battery status) ported
 *
 * Revision 1.22  2004/03/13 06:49:20  reinelt
 * seti@home plugin ported to NextGeneration
 *
 * Revision 1.21  2004/03/10 07:16:15  reinelt
 * MySQL plugin from Javier added
 *
 * Revision 1.20  2004/03/03 03:47:04  reinelt
 * big patch from Martin Hejl:
 * - use qprintf() where appropriate
 * - save CPU cycles on gettimeofday()
 * - add quit() functions to free allocated memory
 * - fixed lots of memory leaks
 *
 * Revision 1.19  2004/02/18 14:45:42  nicowallmeier
 * Imon/Telmon plugin ported
 *
 * Revision 1.18  2004/02/10 07:42:35  reinelt
 * cut off all old-style files which are no longer used with NextGeneration
 *
 * Revision 1.17  2004/02/10 06:54:39  reinelt
 * DVB plugin ported
 *
 * Revision 1.16  2004/01/29 04:40:02  reinelt
 * every .c file includes "config.h" now
 *
 * Revision 1.15  2004/01/27 08:13:39  reinelt
 * ported PPP token to plugin_ppp
 *
 * Revision 1.14  2004/01/25 05:30:09  reinelt
 * plugin_netdev for parsing /proc/net/dev added
 *
 * Revision 1.13  2004/01/16 05:04:53  reinelt
 * started plugin proc_stat which should parse /proc/stat
 * which again is a paint in the a**
 * thinking over implementation methods of delta functions
 * (CPU load, ...)
 *
 * Revision 1.12  2004/01/15 04:29:45  reinelt
 * moved lcd4linux.conf.sample to *.old
 * lcd4linux.conf.sample with new layout
 * new plugins 'loadavg' and 'meminfo'
 * text widget have pre- and postfix
 *
 * Revision 1.11  2004/01/14 11:33:00  reinelt
 * new plugin 'uname' which does what it's called
 * text widget nearly finished
 * first results displayed on MatrixOrbital
 *
 * Revision 1.10  2004/01/13 10:03:01  reinelt
 * new util 'hash' for associative arrays
 * new plugin 'cpuinfo'
 *
 * Revision 1.9  2004/01/11 18:26:02  reinelt
 * further widget and layout processing
 *
 * Revision 1.8  2004/01/10 20:22:33  reinelt
 * added new function 'cfg_list()' (not finished yet)
 * added layout.c (will replace processor.c someday)
 * added widget_text.c (will be the first and most important widget)
 * modified lcd4linux.c so that old-style configs should work, too
 *
 * Revision 1.7  2004/01/10 17:45:26  reinelt
 * changed initialization order so cfg() gets initialized before plugins.
 * This way a plugin's init() can use cfg_get().
 * Thanks to Xavier for reporting this one!
 *
 * Revision 1.6  2004/01/10 17:36:56  reinelt
 *
 * I2C Sensors plugin from Xavier added
 *
 * Revision 1.5  2004/01/06 17:33:45  reinelt
 *
 * Evaluator: functions with variable argument lists
 * Evaluator: plugin_sample.c and README.Plugins added
 *
 * Revision 1.4  2004/01/06 15:19:16  reinelt
 * Evaluator rearrangements...
 *
 * Revision 1.3  2003/12/19 06:27:33  reinelt
 * added XMMS plugin from Markus Keil
 *
 * Revision 1.2  2003/12/19 05:49:23  reinelt
 * extracted plugin_math and plugin_string into extra files
 *
 * Revision 1.1  2003/12/19 05:35:14  reinelt
 * renamed 'client' to 'plugin'
 *
 * Revision 1.1  2003/10/11 06:01:52  reinelt
 *
 * renamed expression.{c,h} to client.{c,h}
 * added config file client
 * new functions 'AddNumericVariable()' and 'AddStringVariable()'
 * new parameter '-i' for interactive mode
 *
 * Revision 1.3  2003/10/06 05:51:15  reinelt
 * functions: min(), max()
 *
 * Revision 1.2  2003/10/06 05:47:27  reinelt
 * operators: ==, \!=, <=, >=
 *
 * Revision 1.1  2003/10/06 04:34:06  reinelt
 * expression evaluator added
 *
 */

/* 
 * exported functions:
 *
 * int plugin_init (void)
 *  initializes the expression evaluator
 *  adds some handy constants and functions
 *
 */


#include "config.h"

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#include "debug.h"
#include "plugin.h"


/* Prototypes */
int plugin_init_cfg(void);
void plugin_exit_cfg(void);
int plugin_init_math(void);
void plugin_exit_math(void);
int plugin_init_string(void);
void plugin_exit_string(void);
int plugin_init_test(void);
void plugin_exit_test(void);
int plugin_init_time(void);
void plugin_exit_time(void);

int plugin_init_apm(void);
void plugin_exit_apm(void);
int plugin_init_cpuinfo(void);
void plugin_exit_cpuinfo(void);
int plugin_init_diskstats(void);
void plugin_exit_diskstats(void);
int plugin_init_dvb(void);
void plugin_exit_dvb(void);
int plugin_init_exec(void);
void plugin_exit_exec(void);
int plugin_init_file(void);
void plugin_exit_file(void);
int plugin_init_i2c_sensors(void);
void plugin_exit_i2c_sensors(void);
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);
void plugin_exit_meminfo(void);
int plugin_init_mpd(void);
void plugin_exit_mpd(void);
int plugin_init_mysql(void);
void plugin_exit_mysql(void);
int plugin_init_netdev(void);
void plugin_exit_netdev(void);
int plugin_init_pop3(void);
void plugin_exit_pop3(void);
int plugin_init_ppp(void);
void plugin_exit_ppp(void);
int plugin_init_proc_stat(void);
void plugin_exit_proc_stat(void);
int plugin_init_python(void);
void plugin_exit_python(void);
int plugin_init_sample(void);
void plugin_exit_sample(void);
int plugin_init_seti(void);
void plugin_exit_seti(void);
int plugin_init_statfs(void);
void plugin_exit_statfs(void);
int plugin_init_uname(void);
void plugin_exit_uname(void);
int plugin_init_uptime(void);
void plugin_exit_uptime(void);
int plugin_init_wireless(void);
void plugin_exit_wireless(void);
int plugin_init_xmms(void);
void plugin_exit_xmms(void);


int plugin_init(void)
{
    plugin_init_cfg();
    plugin_init_math();
    plugin_init_string();
    plugin_init_test();
    plugin_init_time();

#ifdef PLUGIN_APM
    plugin_init_apm();
#endif
#ifdef PLUGIN_CPUINFO
    plugin_init_cpuinfo();
#endif
#ifdef PLUGIN_DISKSTATS
    plugin_init_diskstats();
#endif
#ifdef PLUGIN_DVB
    plugin_init_dvb();
#endif
#ifdef PLUGIN_EXEC
    plugin_init_exec();
#endif
#ifdef PLUGIN_FILE
    plugin_init_file();
#endif
#ifdef PLUGIN_I2C_SENSORS
    plugin_init_i2c_sensors();
#endif
#ifdef PLUGIN_IMON
    plugin_init_imon();
#endif
#ifdef PLUGIN_ISDN
    plugin_init_isdn();
#endif
#ifdef PLUGIN_KVV
    plugin_init_kvv();
#endif
#ifdef PLUGIN_LOADAVG
    plugin_init_loadavg();
#endif
#ifdef PLUGIN_MEMINFO
    plugin_init_meminfo();
#endif
#ifdef PLUGIN_MPD
    plugin_init_mpd();
#endif

#ifdef PLUGIN_MYSQL
    plugin_init_mysql();
#endif
#ifdef PLUGIN_NETDEV
    plugin_init_netdev();
#endif
#ifdef PLUGIN_POP3
    plugin_init_pop3();
#endif
#ifdef PLUGIN_PPP
    plugin_init_ppp();
#endif
#ifdef PLUGIN_PROC_STAT
    plugin_init_proc_stat();
#endif
#ifdef PLUGIN_PYTHON
    plugin_init_python();
#endif
#ifdef PLUGIN_SAMPLE
    plugin_init_sample();
#endif
#ifdef PLUGIN_SETI
    plugin_init_seti();
#endif
#ifdef PLUGIN_STATFS
    plugin_init_statfs();
#endif
#ifdef PLUGIN_UNAME
    plugin_init_uname();
#endif
#ifdef PLUGIN_UPTIME
    plugin_init_uptime();
#endif
#ifdef PLUGIN_WIRELESS
    plugin_init_wireless();
#endif
#ifdef PLUGIN_XMMS
    plugin_init_xmms();
#endif

    return 0;
}


void plugin_exit(void)
{
#ifdef PLUGIN_APM
    plugin_exit_apm();
#endif
#ifdef PLUGIN_CPUINFO
    plugin_exit_cpuinfo();
#endif
#ifdef PLUGIN_DISKSTATS
    plugin_exit_diskstats();
#endif
#ifdef PLUGIN_DVB
    plugin_exit_dvb();
#endif
#ifdef PLUGIN_EXEC
    plugin_exit_exec();
#endif
#ifdef PLUGIN_FILE
    plugin_exit_file();
#endif
#ifdef PLUGIN_I2C_SENSORS
    plugin_exit_i2c_sensors();
#endif
#ifdef PLUGIN_IMON
    plugin_exit_imon();
#endif
#ifdef PLUGIN_ISDN
    plugin_exit_isdn();
#endif
#ifdef PLUGIN_KVV
    plugin_exit_kvv();
#endif
#ifdef PLUGIN_LOADAVG
    plugin_exit_loadavg();
#endif
#ifdef PLUGIN_MEMINFO
    plugin_exit_meminfo();
#endif
#ifdef PLUGIN_MPD
    plugin_exit_mpd();
#endif
#ifdef PLUGIN_MYSQL
    plugin_exit_mysql();
#endif
#ifdef PLUGIN_NETDEV
    plugin_exit_netdev();
#endif
#ifdef PLUGIN_POP3
    plugin_exit_pop3();
#endif
#ifdef PLUGIN_PPP
    plugin_exit_ppp();
#endif
#ifdef PLUGIN_PROC_STAT
    plugin_exit_proc_stat();
#endif
#ifdef PLUGIN_PYTHON
    plugin_exit_python();
#endif
#ifdef PLUGIN_SAMPLE
    plugin_exit_sample();
#endif
#ifdef PLUGIN_SETI
    plugin_exit_seti();
#endif
#ifdef PLUGIN_STATFS
    plugin_exit_statfs();
#endif
#ifdef PLUGIN_UNAME
    plugin_exit_uname();
#endif
#ifdef PLUGIN_UPTIME
    plugin_exit_uptime();
#endif
#ifdef PLUGIN_WIRELESS
    plugin_exit_wireless();
#endif
#ifdef PLUGIN_XMMS
    plugin_exit_xmms();
#endif

    plugin_exit_cfg();
    plugin_exit_math();
    plugin_exit_string();
    plugin_exit_test();
    plugin_exit_time();

    DeleteFunctions();
    DeleteVariables();
}