aboutsummaryrefslogtreecommitdiffstats
path: root/widget.c (follow)
AgeCommit message (Expand)AuthorFilesLines
2005-05-08[lcd4linux @ 2005-05-08 04:32:43 by reinelt]reinelt1-100/+107
2005-01-18[lcd4linux @ 2005-01-18 06:30:21 by reinelt]reinelt1-3/+6
2004-06-26[lcd4linux @ 2004-06-26 12:04:59 by reinelt]reinelt1-2/+6
2004-06-26[lcd4linux @ 2004-06-26 09:27:20 by reinelt]reinelt1-12/+18
2004-06-20[lcd4linux @ 2004-06-20 10:09:52 by reinelt]reinelt1-3/+7
2004-05-26[lcd4linux @ 2004-05-26 11:37:35 by reinelt]reinelt1-3/+8
2004-03-03[lcd4linux @ 2004-03-03 03:47:04 by reinelt]reinelt1-2/+21
2004-02-18[lcd4linux @ 2004-02-18 06:39:20 by reinelt]reinelt1-2/+5
2004-01-30[lcd4linux @ 2004-01-30 20:57:55 by reinelt]reinelt1-1/+9
2004-01-29[lcd4linux @ 2004-01-29 04:40:02 by reinelt]reinelt1-1/+6
2004-01-23[lcd4linux @ 2004-01-23 04:53:23 by reinelt]reinelt1-2/+5
2004-01-14[lcd4linux @ 2004-01-14 11:33:00 by reinelt]reinelt1-2/+11
2004-01-13[lcd4linux @ 2004-01-13 08:18:07 by reinelt]reinelt1-4/+37
2004-01-11[lcd4linux @ 2004-01-11 18:26:02 by reinelt]reinelt1-4/+45
2004-01-11[lcd4linux @ 2004-01-11 09:26:15 by reinelt]reinelt1-3/+6
2004-01-10[lcd4linux @ 2004-01-10 20:22:33 by reinelt]reinelt1-2/+41
2004-01-10[lcd4linux @ 2004-01-10 17:34:40 by reinelt]reinelt1-58/+8
2003-10-05[lcd4linux @ 2003-10-05 17:58:50 by reinelt]reinelt1-2/+5
2003-09-19[lcd4linux @ 2003-09-19 03:51:29 by reinelt]reinelt1-0/+102
209'>209 210 211 212 213 214 215 216 217 218 219 220 221 222
/* $Id$
 * $URL$
 *
 * plugin template
 *
 * Copyright (C) 2008 Michael Vogt <michu@neophob.com>
 * Copyright (C) 2004, 2005, 2006, 2007, 2008 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.
 *
 */

/* 
 * Quick fifo hack for lcd4linux
 * 
 * most code is ripped ...
 *
 */

/* define the include files you need */
#include "config.h"

#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <errno.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <signal.h>

/* these should always be included */
#include "debug.h"
#include "plugin.h"
#include "cfg.h"

#ifdef WITH_DMALLOC
#include <dmalloc.h>
#endif

#define FIFO_BUFFER_SIZE 80

typedef struct _FifoData {
    char *path;
    int input;
    int created;
} FifoData;

static char Section[] = "Plugin:FIFO";
static FifoData fd;
static char msg[FIFO_BUFFER_SIZE];
static char fifopath[1024];


static void configure_fifo(void)
{
    char *s;
    memset(fifopath, 0, 1024);
    s = cfg_get(Section, "fifopath", "/tmp/lcd4linux.fifo");
    if (*s == '\0') {
	info("[FIFO] empty '%s.fifopath' entry from %s, assuming '/tmp/lcd4linux.fifo'", Section, cfg_source());
	strcpy(fifopath, "/tmp/lcd4linux.fifo");
    } else {
	strcpy(fifopath, s);
	info("[FIFO] read '%s.fifopath', value is '%s'", Section, fifopath);
    }
    free(s);
}


static void removeFifo(void)
{
    debug("Removing FIFO \"%s\"\n", fd.path);
    if (unlink(fd.path) < 0) {
	error("Could not remove FIFO \"%s\": %s\n", fd.path, strerror(errno));
	return;
    }
    fd.created = 0;
}


static void closeFifo(void)
{
    struct stat st;
    if (fd.input >= 0) {
	close(fd.input);
	fd.input = -1;
    }
    if (fd.created && (stat(fd.path, &st) == 0))
	removeFifo();
}

static int makeFifo(void)
{
    if (mkfifo(fd.path, 0666) < 0) {
	error("Couldn't create FIFO \"%s\": %s\n", fd.path, strerror(errno));
	return -1;
    }
    fd.created = 1;
    return 0;
}


static int checkFifo(void)
{
    struct stat st;
    if (stat(fd.path, &st) < 0) {
	if (errno == ENOENT) {

	    /* Path doesn't exist */
	    return makeFifo();
	}
	error("Failed to stat FIFO \"%s\": %s\n", fd.path, strerror(errno));
	return -1;
    }
    if (!S_ISFIFO(st.st_mode)) {
	error("\"%s\" already exists, but is not a FIFO\n", fd.path);
	return -1;
    }
    return 0;
}


static int openFifo(void)
{
    if (checkFifo() < 0)
	return -1;
    fd.input = open(fd.path, O_RDONLY | O_NONBLOCK);
    if (fd.input < 0) {
	error("Could not open FIFO \"%s\" for reading: %s\n", fd.path, strerror(errno));
	closeFifo();
	return -1;
    }
    return 0;
}


static void startFifo(void)
{
    static int started = 0;

    if (started)
	return;

    started = 1;

    configure_fifo();
    fd.path = fifopath;
    fd.input = -1;
    fd.created = 0;
    openFifo();

    /* ignore broken pipe */
    signal(SIGPIPE, SIG_IGN);

    memset(msg, 0, FIFO_BUFFER_SIZE);

}


static void fiforead(RESULT * result)
{
    char buf[FIFO_BUFFER_SIZE];
    unsigned int i;
    int bytes = 1;

    startFifo();

    memset(buf, 0, FIFO_BUFFER_SIZE);
    strcat(buf, "ERROR");

    if (checkFifo() == 0) {
	memset(buf, 0, FIFO_BUFFER_SIZE);

	while (bytes > 0 && errno != EINTR) {
	    bytes = read(fd.input, buf, FIFO_BUFFER_SIZE);
	}

	if (bytes < 0 || (errno > 0 && errno != EAGAIN)) {
	    error("[FIFO] Error %i: %s", errno, strerror(errno));
	} else {
	    if (strlen(buf) > 0) {
		strcpy(msg, buf);
	    }
	    for (i = 0; i < strlen(buf); i++) {
		if (msg[i] < 0x20)
		    msg[i] = ' ';
	    }
	}
    }
    /* store result */
    SetResult(&result, R_STRING, msg);
}


/* plugin initialization */
int plugin_init_fifo(void)
{
    AddFunction("fifo::read", 0, fiforead);
    return 0;
}


void plugin_exit_fifo(void)
{
    /* close filedescriptors */
    closeFifo();
}