#remove next line for liblcd4linux
lcd4linux_DEPENDENCIES = @DRIVERS@
-lcd4linux_SOURCES = lcd4linux.c cfg.c cfg.h debug.c debug.h drv.c drv.h evaluator.c evaluator.h hash.c hash.h layout.c layout.h lock.c lock.h pid.c pid.h timer.c timer.h thread.c thread.h udelay.c udelay.h qprintf.c qprintf.h widget.c widget.h widget_text.c widget_text.h widget_bar.c widget_bar.h widget_icon.c widget_icon.h plugin.c plugin.h plugin_math.c plugin_string.c plugin_cfg.c plugin_uname.c plugin_loadavg.c plugin_proc_stat.c plugin_cpuinfo.c plugin_meminfo.c plugin_netdev.c plugin_ppp.c plugin_dvb.c plugin_apm.c plugin_i2c_sensors.c plugin_imon.c plugin_exec.c plugin_xmms.c plugin_mysql.c plugin_seti.c
+lcd4linux_SOURCES = lcd4linux.c cfg.c cfg.h debug.c debug.h drv.c drv.h evaluator.c evaluator.h hash.c hash.h layout.c layout.h lock.c lock.h pid.c pid.h timer.c timer.h thread.c thread.h udelay.c udelay.h qprintf.c qprintf.h widget.c widget.h widget_text.c widget_text.h widget_bar.c widget_bar.h widget_icon.c widget_icon.h plugin.c plugin.h plugin_math.c plugin_string.c plugin_cfg.c plugin_uname.c plugin_loadavg.c plugin_proc_stat.c plugin_cpuinfo.c plugin_meminfo.c plugin_netdev.c plugin_ppp.c plugin_dvb.c plugin_apm.c plugin_i2c_sensors.c plugin_imon.c plugin_exec.c plugin_xmms.c plugin_mysql.c plugin_wireless.c plugin_seti.c
#liblcd4linux_la_DEPENDENCIES = @DRIVERS@
plugin_string.o plugin_cfg.o plugin_uname.o plugin_loadavg.o \
plugin_proc_stat.o plugin_cpuinfo.o plugin_meminfo.o plugin_netdev.o \
plugin_ppp.o plugin_dvb.o plugin_apm.o plugin_i2c_sensors.o \
-plugin_imon.o plugin_exec.o plugin_xmms.o plugin_mysql.o plugin_seti.o
+plugin_imon.o plugin_exec.o plugin_xmms.o plugin_mysql.o \
+plugin_wireless.o plugin_seti.o
CFLAGS = @CFLAGS@
COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
CCLD = $(CC)
.deps/plugin_math.P .deps/plugin_meminfo.P .deps/plugin_mysql.P \
.deps/plugin_netdev.P .deps/plugin_ppp.P .deps/plugin_proc_stat.P \
.deps/plugin_seti.P .deps/plugin_string.P .deps/plugin_uname.P \
-.deps/plugin_xmms.P .deps/qprintf.P .deps/thread.P .deps/timer.P \
-.deps/udelay.P .deps/widget.P .deps/widget_bar.P .deps/widget_icon.P \
-.deps/widget_text.P
+.deps/plugin_wireless.P .deps/plugin_xmms.P .deps/qprintf.P \
+.deps/thread.P .deps/timer.P .deps/udelay.P .deps/widget.P \
+.deps/widget_bar.P .deps/widget_icon.P .deps/widget_text.P
SOURCES = $(lcd4linux_SOURCES) $(EXTRA_lcd4linux_SOURCES)
OBJECTS = $(lcd4linux_OBJECTS)
# Checks for X11
-echo "$as_me:$LINENO: checking for X" >&5
+
+if test "x$ac_path_x_has_been_run" != xyes; then
+ echo "$as_me:$LINENO: checking for X" >&5
echo $ECHO_N "checking for X... $ECHO_C" >&6
+ac_path_x_has_been_run=yes
# Check whether --with-x or --without-x was given.
if test "${with_x+set}" = set; then
/usr/openwin/share/include'
if test "$ac_x_includes" = no; then
- # Guess where to find include files, by looking for Intrinsic.h.
+ # Guess where to find include files, by looking for a specified header file.
# First, try using that file with no special directory specified.
cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
# Update the cache value to reflect the command line values.
ac_cv_have_x="have_x=yes \
ac_x_includes=$x_includes ac_x_libraries=$x_libraries"
- echo "$as_me:$LINENO: result: libraries $x_libraries, headers $x_includes" >&5
-echo "${ECHO_T}libraries $x_libraries, headers $x_includes" >&6
+ # It might be that x_includes is empty (headers are found in the
+ # standard search path. Then output the corresponding message
+ ac_out_x_includes=$x_includes
+ test "x$x_includes" = x && ac_out_x_includes="in standard search path"
+ echo "$as_me:$LINENO: result: libraries $x_libraries, headers $ac_out_x_includes" >&5
+echo "${ECHO_T}libraries $x_libraries, headers $ac_out_x_includes" >&6
fi
+fi
if test "$no_x" = yes; then
# Not all programs may use this symbol, but it does not hurt to define it.
-/* $Id: plugin_exec.c,v 1.1 2004/03/20 11:49:40 reinelt Exp $
+/* $Id: plugin_exec.c,v 1.2 2004/04/08 10:48:25 reinelt Exp $
*
* plugin for external processes
*
*
*
* $Log: plugin_exec.c,v $
+ * Revision 1.2 2004/04/08 10:48:25 reinelt
+ * finished plugin_exec
+ * modified thread handling
+ * added '%x' format to qprintf (hexadecimal)
+ *
* Revision 1.1 2004/03/20 11:49:40 reinelt
* forgot to add plugin_exec.c ...
*
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
-
-// #include <string.h>
-// #include <ctype.h>
-// #include <errno.h>
-
-#include <sys/ipc.h>
-#include <sys/sem.h>
-#include <sys/shm.h>
+#include <string.h>
+#include <errno.h>
#include "debug.h"
#include "plugin.h"
#include "hash.h"
#include "cfg.h"
#include "thread.h"
+#include "qprintf.h"
+
+
+#define NUM_THREADS 16
+#define SHM_SIZE 256
+
+typedef struct {
+ int delay;
+ int mutex;
+ pid_t pid;
+ int shmid;
+ char *cmd;
+ char *key;
+ char *ret;
+} EXEC_THREAD;
+
+static EXEC_THREAD Thread[NUM_THREADS];
+static int max_thread = -1;
static HASH EXEC = { 0, };
-static int fatal = 0;
-static int do_exec (void)
+
+// x^0 + x^5 + x^12
+#define CRCPOLY 0x8408
+
+static unsigned short CRC (unsigned char *s)
+{
+ int i;
+ unsigned short crc;
+
+ // seed value
+ crc=0xffff;
+
+ while (*s!='\0') {
+ crc ^= *s++;
+ for (i = 0; i < 8; i++)
+ crc = (crc >> 1) ^ ((crc & 1) ? CRCPOLY : 0);
+ }
+ return crc;
+}
+
+
+static void exec_thread (void *data)
+{
+ EXEC_THREAD *Thread = (EXEC_THREAD*)data;
+ FILE *pipe;
+ char buffer[SHM_SIZE];
+ int len;
+
+ // use a safe path
+ putenv ("PATH=/usr/local/bin:/usr/bin:/bin");
+
+ // forever...
+ while (1) {
+ pipe = popen(Thread->cmd, "r");
+ if (pipe == NULL) {
+ error("exec error: could not run pipe '%s': %s", Thread->cmd, strerror(errno));
+ len = 0;
+ } else {
+ len = fread(buffer, 1, SHM_SIZE-1, pipe);
+ if (len <= 0) {
+ error("exec error: could not read from pipe '%s': %s", Thread->cmd, strerror(errno));
+ len = 0;
+ }
+ pclose(pipe);
+ }
+
+ // force trailing zero
+ buffer[len] = '\0';
+
+ // remove trailing CR/LF
+ while (len>0 && (buffer[len-1]=='\n' || buffer[len-1]=='\r')) {
+ buffer[--len]='\0';
+ }
+
+ // lock shared memory
+ mutex_lock(Thread->mutex);
+ // write data
+ strncpy(Thread->ret, buffer, SHM_SIZE);
+ // unlock shared memory
+ mutex_unlock(Thread->mutex);
+ usleep (Thread->delay);
+ }
+}
+
+
+static void destroy_exec_thread (int n)
+{
+ if (Thread[n].mutex != 0) mutex_destroy(Thread[n].mutex);
+ if (Thread[n].cmd) free (Thread[n].cmd);
+ if (Thread[n].key) free (Thread[n].key);
+ if (Thread[n].ret) shm_destroy (Thread[n].shmid, Thread[n].ret);
+
+ Thread[n].delay = 0;
+ Thread[n].mutex = 0;
+ Thread[n].pid = 0;
+ Thread[n].shmid = 0;
+ Thread[n].cmd = NULL;
+ Thread[n].key = NULL;
+ Thread[n].ret = NULL;
+}
+
+
+static int create_exec_thread (char *cmd, char *key, int delay)
{
- int age;
+ char name[10];
+
+ if (max_thread >= NUM_THREADS) {
+ error ("cannot create exec thread <%s>: thread buffer full!", cmd);
+ return -1;
+ }
+
+ max_thread++;
+ Thread[max_thread].delay = delay;
+ Thread[max_thread].mutex = mutex_create();
+ Thread[max_thread].pid = -1;
+ Thread[max_thread].cmd = strdup(cmd);
+ Thread[max_thread].key = strdup(key);
+ Thread[max_thread].ret = NULL;
+
+ // create communication buffer
+ Thread[max_thread].shmid = shm_create ((void**)&Thread[max_thread].ret, SHM_SIZE);
+
+ // catch error
+ if (Thread[max_thread].shmid < 0) {
+ error ("cannot create exec thread <%s>: shared memory allocation failed!", cmd);
+ destroy_exec_thread (max_thread--);
+ return -1;
+ }
- // if a fatal error occured, do nothing
- if (fatal != 0) return -1;
+ // create thread
+ qprintf(name, sizeof(name), "exec-%s", key);
+ Thread[max_thread].pid = thread_create (name, exec_thread, &Thread[max_thread]);
+
+ // catch error
+ if (Thread[max_thread].pid < 0) {
+ error ("cannot create exec thread <%s>: fork failed?!", cmd);
+ destroy_exec_thread (max_thread--);
+ return -1;
+ }
- // reread every 100 msec only
- age=hash_age(&EXEC, NULL, NULL);
- if (age>0 && age<=100) return 0;
return 0;
-}
+}
-static void my_junk (char *name)
+
+static int do_exec (char *cmd, char *key, int delay)
{
- int i;
+ int i, age;
+
+ age = hash_age(&EXEC, key, NULL);
- debug ("junk thread starting!");
+ if (age < 0) {
+ hash_set (&EXEC, key, "");
+ // first-time call: create thread
+ if (delay < 10) {
+ error ("exec(%s): delay %d is too short! using 10 msec", cmd, delay);
+ delay = 10;
+ }
+ if (create_exec_thread (cmd, key, 1000*delay)) {
+ return -1;
+ }
+ return 0;
+ }
+
+ // reread every 10 msec only
+ if (age > 0 && age <= 10) return 0;
- for (i=0; i<10; i++) {
- debug ("junk look %d", i);
- sleep (1);
+ // find thread
+ for (i = 0; i <= max_thread; i++) {
+ if (strcmp(key, Thread[i].key) == 0) {
+ // lock shared memory
+ mutex_lock(Thread[i].mutex);
+ // copy data
+ hash_set (&EXEC, key, Thread[i].ret);
+ // unlock shared memory
+ mutex_unlock(Thread[i].mutex);
+ return 0;
+ }
}
- debug ("junk thread done!");
+
+ error ("internal error: could not find thread exec-%s", key);
+ return -1;
}
-
-static void my_exec (RESULT *result, int argc, RESULT *argv[])
+static void my_exec (RESULT *result, RESULT *arg1, RESULT *arg2)
{
- char *key, *val;
+ char *cmd, key[5], *val;
+ int delay;
- if (do_exec()<0) {
+ cmd = R2S(arg1);
+ delay = (int)R2N(arg2);
+
+ qprintf (key, sizeof(key), "%x", CRC(cmd));
+
+ if (do_exec(cmd, key, delay) < 0) {
SetResult(&result, R_STRING, "");
return;
}
- // key=R2S(arg1);
- val=hash_get(&EXEC, key);
- if (val==NULL) val="";
+ val = hash_get(&EXEC, key);
+ if (val == NULL) val = "";
SetResult(&result, R_STRING, val);
}
int plugin_init_exec (void)
{
- int junk;
-
- AddFunction ("exec", -1, my_exec);
-
- // junk=thread_create ("Junk", my_junk);
- // debug ("junk=%d", junk);
-
+ AddFunction ("exec", 2, my_exec);
return 0;
}
void plugin_exit_exec(void)
{
+ int i;
+
+ for (i=0; i<=max_thread; i++) {
+ destroy_exec_thread(i);
+ }
+
hash_destroy(&EXEC);
}