aboutsummaryrefslogtreecommitdiffstats
path: root/plugin_cfg.c
blob: e3fa895304a88f9ed3c482d584def61d39de692e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
/* $Id$
 * $URL$
 *
 * plugin for config file access
 *
 * Copyright (C) 2003, 2004 Michael Reinelt <michael@reinelt.co.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.
 *
 */

/* 
 * exported functions:
 *
 * int plugin_init_cfg (void)
 *  adds cfg() function for config access
 *  initializes variables from the config file
 *
 */


#include "config.h"

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

#include "debug.h"
#include "evaluator.h"
#include "plugin.h"
#include "cfg.h"

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


static void load_variables(void)
{
    char *section = "Variables";
    char *list, *l, *p;
    char *expression;
    void *tree;
    RESULT result = { 0, 0, 0, NULL };

    list = cfg_list(section);
    l = list;
    while (l != NULL) {
	while (*l == '|')
	    l++;
	if ((p = strchr(l, '|')) != NULL)
	    *p = '\0';
	if (strchr(l, '.') != NULL || strchr(l, ':') != 0) {
	    error("ignoring variable '%s' from %s: structures not allowed", l, cfg_source());
	} else {
	    expression = cfg_get_raw(section, l, "");
	    if (expression != NULL && *expression != '\0') {
		tree = NULL;
		if (Compile(expression, &tree) == 0 && Eval(tree, &result) == 0) {
		    SetVariable(l, &result);
		    debug("Variable %s = '%s' (%g)", l, R2S(&result), R2N(&result));
		    DelResult(&result);
		} else {
		    error("error evaluating variable '%s' from %s", list, cfg_source());
		}
		DelTree(tree);
	    }
	}
	l = p ? p + 1 : NULL;
    }
    free(list);

}


static void my_cfg(RESULT * result, const int argc, RESULT * argv[])
{
    int i, len;
    char *value;
    char *buffer;

    /* calculate key length */
    len = 0;
    for (i = 0; i < argc; i++) {
	len += strlen(R2S(argv[i])) + 1;
    }

    /* allocate key buffer */
    buffer = malloc(len + 1);

    /* prepare key buffer */
    *buffer = '\0';
    for (i = 0; i < argc; i++) {
	strcat(buffer, ".");
	strcat(buffer, R2S(argv[i]));
    }

    /* buffer starts with '.', so cut off first char */
    value = cfg_get("", buffer + 1, "");

    /* store result */
    SetResult(&result, R_STRING, value);

    /* free buffer again */
    free(buffer);

    free(value);
}


int plugin_init_cfg(void)
{
    /* load "Variables" section from cfg */
    load_variables();

    /* register plugin */
    AddFunction("cfg", -1, my_cfg);

    return 0;
}

void plugin_exit_cfg(void)
{
    /* empty */
}
class="p">[] = "EFN"; char *Host; int Port; int DataSocket; static void drv_EFN_clear(void); /****************************************/ /*** hardware dependant functions ***/ /****************************************/ static int drv_EFN_open(const char __attribute__ ((unused)) * section) { int sockfd_conf, portno_conf, n; struct sockaddr_in serv_addr; struct sockaddr_in conf_addr; struct hostent *server; char buffer[5]; /* open tcp sockets to config port to EUG 100 t0 set serial parameter */ /* 9600 BAUD; no parity; 1 stop bit */ // socket to config EUG portno_conf = Port + 1; sockfd_conf = socket(AF_INET, SOCK_STREAM, 0); if (sockfd_conf < 0) { error("ERROR opening config socket"); return -1; } // resolve DNS name of EFN server (= EUG 100) server = gethostbyname(Host); if (server == NULL) { error("ERROR, no such host\n"); return -1; } // socket addr for config socket bzero((char *) &conf_addr, sizeof(struct sockaddr_in)); conf_addr.sin_family = AF_INET; bcopy((char *) server->h_addr, (char *) &conf_addr.sin_addr.s_addr, server->h_length); conf_addr.sin_port = htons(portno_conf); // open config socket if (connect(sockfd_conf, (struct sockaddr *) &conf_addr, sizeof(struct sockaddr_in)) < 0) { error("ERROR connecting to config port"); return -1; } // sent config message bzero(buffer, 5); buffer[0] = '4'; buffer[1] = '0'; buffer[2] = '1'; n = write(sockfd_conf, buffer, 3); if (n < 0) { error("ERROR writing to config socket"); close(sockfd_conf); return -1; } close(sockfd_conf); // open data socket DataSocket = socket(AF_INET, SOCK_STREAM, 0); if (DataSocket < 0) { error("ERROR opening data socket"); return -1; } // socket addr for data socket bzero((char *) &serv_addr, sizeof(struct sockaddr_in)); serv_addr.sin_family = AF_INET; bcopy((char *) server->h_addr, (char *) &serv_addr.sin_addr.s_addr, server->h_length); serv_addr.sin_port = htons(Port); if (connect(DataSocket, (struct sockaddr *) &serv_addr, sizeof(struct sockaddr_in)) < 0) { error("ERROR connecting to data socket"); return -1; } return 0; } static int drv_EFN_close(void) { /* close whatever port you've opened */ drv_EFN_clear(); close(DataSocket); return 0; } /* dummy function that sends something to the display */ static void drv_EFN_send(const char *data, const unsigned int len) { int n; // transport command string to EUG 100 n = write(DataSocket, data, len); if (n < 0) { error("%s:drv_EFN_send: Failed to write to data socket\n", Name); } } /* text mode displays only */ static void drv_EFN_clear(void) { char *cmd; int max_char, max_cmd, k; max_char = DROWS * DCOLS; max_cmd = 3 * max_char; // each EFN module expects 3 bytes if ((cmd = malloc(max_cmd)) == NULL) { error("%s : Failed to allocate memory in drv_Sample_write\n", Name); // return -1; } else { /* do whatever is necessary to clear the display */ for (k = 0; k < max_char; k++) { cmd[(3 * k) + 0] = 0xff; cmd[(3 * k) + 1] = k + 1; cmd[(3 * k) + 2] = ' '; } drv_EFN_send(cmd, max_cmd); drv_EFN_send(cmd, max_cmd); free(cmd); //return 0; } } /* text mode displays only */ static void drv_EFN_write(const int row, const int col, const char *data, int len) { char *cmd; int offset, i, k, max_char, max_cmd; max_char = DROWS * DCOLS; max_cmd = 3 * max_char; // each LED blocks expects a 3 byte sequence if ((cmd = (char *) malloc(max_cmd)) == NULL) { error("%s : Failed to allocate memory in drv_Sample_write\n", Name); //return -1; } else { /* do the cursor positioning here */ offset = ((row) * DCOLS) + col; for (i = max_char - offset, k = 0; ((i > 0) && (k < len)); i--, k++) { cmd[(3 * k) + 0] = 0xff; cmd[(3 * k) + 1] = i; cmd[(3 * k) + 2] = data[k]; } /* send string to the display twice (to make transmission * reliable) */ drv_EFN_send(cmd, 3 * (k)); drv_EFN_send(cmd, 3 * (k)); free(cmd); // return 0; } } static void drv_EFN_defchar(const int __attribute__ ((unused)) ascii, const unsigned char __attribute__ ((unused)) * matrix) { error("%s:drv_EFN_defchar: Function not supported by EFN modules\n", Name); } /* start text mode display */ static int drv_EFN_start(const char *section) { int rows = -1, cols = -1; char *s; Host = cfg_get(section, "Host", NULL); if (Host == NULL || *Host == '\0') { error("%s: no '%s.Host' entry from %s", Name, section, cfg_source()); return -1; } if (cfg_number(section, "Port", 1000, 0, 65535, &Port) < 0) return -1; s = cfg_get(section, "Size", NULL); if (s == NULL || *s == '\0') { error("%s: no '%s.Size' entry from %s", Name, section, cfg_source()); return -1; } if (sscanf(s, "%dx%d", &cols, &rows) != 2 || rows < 1 || cols < 1) { error("%s: bad %s.Size '%s' from %s", Name, section, s, cfg_source()); free(s); return -1; } DROWS = rows; DCOLS = cols; /* open communication with the display */ if (drv_EFN_open(section) < 0) { return -1; } /* initialize display */ drv_EFN_clear(); /* clear display */ return 0; } /****************************************/ /*** plugins ***/ /****************************************/ /****************************************/ /*** widget callbacks ***/ /****************************************/ /****************************************/ /*** exported functions ***/ /****************************************/ /* list models */ int drv_EFN_list(void) { printf("EFN LED modules + EUG100 Ethernet to serial converter"); return 0; } /* initialize driver & display */ /* use this function for a text display */ int drv_EFN_init(const char *section, const int quiet) { WIDGET_CLASS wc; int ret; info("%s: %s", Name, "$Rev: 773 $"); /* display preferences */ /* real worker functions */ drv_generic_text_real_write = drv_EFN_write; drv_generic_text_real_defchar = drv_EFN_defchar; /* start display */ if ((ret = drv_EFN_start(section)) != 0) return ret; if (!quiet) { char buffer[40]; qprintf(buffer, sizeof(buffer), "%s %dx%d", Name, DCOLS, DROWS); sleep(3); drv_EFN_clear(); } /* initialize generic text driver */ if ((ret = drv_generic_text_init(section, Name)) != 0) return ret; /* register text widget */ wc = Widget_Text; wc.draw = drv_generic_text_draw; widget_register(&wc); return 0; } /* close driver & display */ /* use this function for a text display */ int drv_EFN_quit(const int quiet) { info("%s: shutting down.", Name); drv_generic_text_quit(); /* clear display */ drv_EFN_clear(); /* say goodbye... */ if (!quiet) { drv_generic_text_greet("goodbye!", NULL); } debug("closing connection"); drv_EFN_close(); return (0); } /* close driver & display */ /* use this one for a text display */ DRIVER drv_EFN = { .name = Name, .list = drv_EFN_list, .init = drv_EFN_init, .quit = drv_EFN_quit, };