diff options
-rw-r--r-- | lcd4linux.conf.sample | 4 | ||||
-rw-r--r-- | plugin_i2c_sensors.c | 93 | ||||
-rwxr-xr-x | plugin_imon.c | 581 | ||||
-rw-r--r-- | plugin_mysql.c | 156 | ||||
-rw-r--r-- | plugin_pop3.c | 444 |
5 files changed, 694 insertions, 584 deletions
diff --git a/lcd4linux.conf.sample b/lcd4linux.conf.sample index 2a29036..9aa6c59 100644 --- a/lcd4linux.conf.sample +++ b/lcd4linux.conf.sample @@ -729,7 +729,7 @@ Layout testMySQL { } -Display 'LCD-Linux' +#Display 'LCD-Linux' #Display 'LK204' #Display 'MI240' #Display 'CW12232' @@ -744,7 +744,7 @@ Display 'LCD-Linux' #Display 'LCDTerm' #Display 'CT20x4' #Display 'T6963-240x64' -#Display 'XWindow' +Display 'XWindow' #Display 'USBLCD' #Display 'BWCT' #Display 'Image' diff --git a/plugin_i2c_sensors.c b/plugin_i2c_sensors.c index b6f9168..df5e6ab 100644 --- a/plugin_i2c_sensors.c +++ b/plugin_i2c_sensors.c @@ -1,4 +1,4 @@ -/* $Id: plugin_i2c_sensors.c,v 1.22 2005/01/18 06:30:23 reinelt Exp $ +/* $Id: plugin_i2c_sensors.c,v 1.23 2005/04/01 05:16:04 reinelt Exp $ * * I2C sensors plugin * @@ -23,6 +23,9 @@ * * * $Log: plugin_i2c_sensors.c,v $ + * Revision 1.23 2005/04/01 05:16:04 reinelt + * moved plugin init stuff to a seperate function called on first use + * * Revision 1.22 2005/01/18 06:30:23 reinelt * added (C) to all copyright statements * @@ -308,26 +311,8 @@ static int parse_i2c_sensors_procfs(const char *key) * Common functions (path search and init) * \*****************************************/ -void my_i2c_sensors(RESULT *result, RESULT *arg) -{ - int age; - char *val; - char *key=R2S(arg); - - age=hash_age(&I2Csensors, key); - if (age<0 || age>250) { - parse_i2c_sensors(key); - } - val=hash_get(&I2Csensors, key, NULL); - if (val) { - SetResult(&result, R_STRING, val); - } else { - SetResult(&result, R_STRING, "??"); - } -} - -void my_i2c_sensors_path(const char *method) +static void my_i2c_sensors_path(const char *method) { struct dirent *dir; struct dirent *file; @@ -382,11 +367,12 @@ void my_i2c_sensors_path(const char *method) } -int plugin_init_i2c_sensors (void) +static int configure_i2c_sensors (void) { + static int configured = 0; char *path_cfg; - hash_create(&I2Csensors); + if (configured != 0) return configured; path_cfg = cfg_get(NULL, "i2c_sensors-path", ""); if (path_cfg == NULL || *path_cfg == '\0') { @@ -397,9 +383,12 @@ int plugin_init_i2c_sensors (void) if (!path) { error("i2c_sensors: unable to autodetect i2c sensors!"); - } else { - debug("using i2c sensors at %s (autodetected)", path); - } + configured = -1; + return configured; + } + + debug("using i2c sensors at %s (autodetected)", path); + } else { if (path_cfg[strlen(path_cfg)-1] != '/') { /* the headless user forgot the trailing slash :/ */ @@ -414,23 +403,55 @@ int plugin_init_i2c_sensors (void) if (path_cfg) free(path_cfg); /* we activate the function only if there's a possibly path found */ - if (path!=NULL) { - if (strncmp(path, "/sys", 4)==0) { - parse_i2c_sensors = parse_i2c_sensors_sysfs; - AddFunction ("i2c_sensors", 1, my_i2c_sensors); - } else if (strncmp(path, "/proc", 5)==0) { - parse_i2c_sensors = parse_i2c_sensors_procfs; - AddFunction ("i2c_sensors", 1, my_i2c_sensors); - } else { - error("i2c_sensors: unknown path %s, should start with /sys or /proc"); - } + if (strncmp(path, "/sys", 4)==0) { + parse_i2c_sensors = parse_i2c_sensors_sysfs; + } else if (strncmp(path, "/proc", 5)==0) { + parse_i2c_sensors = parse_i2c_sensors_procfs; + } else { + error("i2c_sensors: unknown path %s, should start with /sys or /proc"); + configured = -1; + return configured; } - + hash_create(&I2Csensors); + configured = 1; + return configured; +} + + +void my_i2c_sensors(RESULT *result, RESULT *arg) +{ + int age; + char *key; + char *val; + + if (configure_i2c_sensors() < 0) { + SetResult(&result, R_STRING, "??"); + return; + } + + key=R2S(arg); + age=hash_age(&I2Csensors, key); + if (age<0 || age>250) { + parse_i2c_sensors(key); + } + val=hash_get(&I2Csensors, key, NULL); + if (val) { + SetResult(&result, R_STRING, val); + } else { + SetResult(&result, R_STRING, "??"); + } +} + + +int plugin_init_i2c_sensors (void) +{ + AddFunction ("i2c_sensors", 1, my_i2c_sensors); return 0; } + void plugin_exit_i2c_sensors(void) { hash_destroy(&I2Csensors); diff --git a/plugin_imon.c b/plugin_imon.c index 6a3aa35..3e27006 100755 --- a/plugin_imon.c +++ b/plugin_imon.c @@ -1,4 +1,4 @@ -/* $Id: plugin_imon.c,v 1.14 2005/01/18 06:30:23 reinelt Exp $ +/* $Id: plugin_imon.c,v 1.15 2005/04/01 05:16:04 reinelt Exp $ * * imond/telmond data processing * @@ -22,6 +22,9 @@ * * * $Log: plugin_imon.c,v $ + * Revision 1.15 2005/04/01 05:16:04 reinelt + * moved plugin init stuff to a seperate function called on first use + * * Revision 1.14 2005/01/18 06:30:23 reinelt * added (C) to all copyright statements * @@ -121,64 +124,58 @@ static int err=0; * service_connect (host_name, port) - connect to tcp-service *---------------------------------------------------------------------------- */ -static int service_connect (const char * host_name, const int port){ - struct sockaddr_in addr; - struct hostent * host_p; - int fd; - int opt = 1; - - (void) memset ((char *) &addr, 0, sizeof (addr)); - - if ((addr.sin_addr.s_addr = inet_addr ((char *) host_name)) == INADDR_NONE) - { - host_p = gethostbyname (host_name); - - if (! host_p) - { - error ("%s: host not found\n", host_name); - return (-1); - } - - (void) memcpy ((char *) (&addr.sin_addr), host_p->h_addr, - host_p->h_length); - } - - addr.sin_family = AF_INET; - addr.sin_port = htons ((unsigned short) port); - - if ((fd = socket (AF_INET, SOCK_STREAM, 0)) < 0) - { /* open socket */ - perror ("socket"); - return (-1); +static int service_connect (const char * host_name, const int port) +{ + struct sockaddr_in addr; + struct hostent * host_p; + int fd; + int opt = 1; + + (void) memset ((char *) &addr, 0, sizeof (addr)); + + if ((addr.sin_addr.s_addr = inet_addr ((char *) host_name)) == INADDR_NONE) { + host_p = gethostbyname (host_name); + if (!host_p) { + error ("%s: host not found\n", host_name); + return (-1); } + (void) memcpy ((char *) (&addr.sin_addr), host_p->h_addr, host_p->h_length); + } + + addr.sin_family = AF_INET; + addr.sin_port = htons ((unsigned short) port); + + /* open socket */ + if ((fd = socket (AF_INET, SOCK_STREAM, 0)) < 0) { + perror ("socket"); + return (-1); + } - (void) setsockopt (fd, IPPROTO_TCP, TCP_NODELAY, - (char *) &opt, sizeof (opt)); - - if (connect (fd, (struct sockaddr *) &addr, sizeof (addr)) != 0) - { - (void) close (fd); - perror (host_name); - return (-1); - } - - return (fd); + (void) setsockopt (fd, IPPROTO_TCP, TCP_NODELAY, (char *) &opt, sizeof (opt)); + + if (connect (fd, (struct sockaddr *) &addr, sizeof (addr)) != 0) { + (void) close (fd); + perror (host_name); + return (-1); + } + + return (fd); } /* service_connect (char * host_name, int port) */ + /*---------------------------------------------------------------------------- * send_command (int fd, char * str) - send command to imond *---------------------------------------------------------------------------- */ -static void -send_command (const int fd, const char * str) +static void send_command (const int fd, const char * str) { - char buf[256]; - int len = strlen (str); + char buf[256]; + int len = strlen (str); - sprintf (buf, "%s\r\n", str); - write (fd, buf, len + 2); + sprintf (buf, "%s\r\n", str); + write (fd, buf, len + 2); - return; + return; } /* send_command (int fd, char * str) */ @@ -186,64 +183,58 @@ send_command (const int fd, const char * str) * get_answer (int fd) - get answer from imond *---------------------------------------------------------------------------- */ -static char * -get_answer (const int fd) +static char* get_answer (const int fd) { - static char buf[8192]; - int len; + static char buf[8192]; + int len; - len = read (fd, buf, 8192); + len = read (fd, buf, 8192); - if (len <= 0) - { - return ((char *) NULL); - } + if (len <= 0) { + return ((char *) NULL); + } - while (len > 1 && (buf[len - 1] == '\n' || buf[len - 1] == '\r')) - { - buf[len - 1] = '\0'; - len--; - } + while (len > 1 && (buf[len - 1] == '\n' || buf[len - 1] == '\r')) { + buf[len - 1] = '\0'; + len--; + } - if (! strncmp (buf, "OK ", 3)) /* OK xxxx */ - { - return (buf + 3); - } - else if (len > 2 && ! strcmp (buf + len - 2, "OK")) - { - *(buf + len - 2) = '\0'; - return (buf); - } - else if (len == 2 && ! strcmp (buf + len - 2, "OK")) - { - return (buf); - } + if (! strncmp (buf, "OK ", 3)) { /* OK xxxx */ + return (buf + 3); + } + else if (len > 2 && ! strcmp (buf + len - 2, "OK")) { + *(buf + len - 2) = '\0'; + return (buf); + } + else if (len == 2 && ! strcmp (buf + len - 2, "OK")) { + return (buf); + } - return ((char *) NULL); /* ERR xxxx */ + return ((char *) NULL); /* ERR xxxx */ } /* get_answer (int fd) */ /*---------------------------------------------------------------------------- * get_value (char * cmd) - send command, get value *---------------------------------------------------------------------------- */ -static char * -get_value (const char * cmd) +static char* get_value (const char * cmd) { - char * answer; - - send_command (fd, cmd); - - answer = get_answer (fd); - - if (answer) - { - return (answer); - } - - return (""); + char *answer; + + send_command (fd, cmd); + + answer = get_answer (fd); + + if (answer) { + return (answer); + } + + return (""); } /* get_value (char * cmd, int arg) */ -static void phonebook(char *number){ + +static void phonebook(char *number) +{ FILE * fp; char line[256]; @@ -251,40 +242,41 @@ static void phonebook(char *number){ if (! fp) return; - while (fgets (line, 128, fp)){ - if (*line == '#') continue; - if (!strncmp(line,number,strlen(number))){ - char *komma=strchr(line,','); - char *beginn=strchr(line,'='); - if (!beginn) return; - while (strrchr(line,'\r')) strrchr(line,'\r')[0]='\0'; - while (strrchr(line,'\n')) strrchr(line,'\n')[0]='\0'; - if (komma) komma[0]='\0'; - strcpy(number,beginn+1); - break; - } + while (fgets (line, 128, fp)) { + if (*line == '#') continue; + if (!strncmp(line,number,strlen(number))) { + char *komma=strchr(line,','); + char *beginn=strchr(line,'='); + if (!beginn) return; + while (strrchr(line,'\r')) strrchr(line,'\r')[0]='\0'; + while (strrchr(line,'\n')) strrchr(line,'\n')[0]='\0'; + if (komma) komma[0]='\0'; + strcpy(number,beginn+1); + break; + } } fclose(fp); } -static int parse_telmon(){ - static int telmond_fd=-2; - static char oldanswer[128]; - int age; +static int parse_telmon() +{ + static int telmond_fd=-2; + static char oldanswer[128]; + int age; - /* reread every 1 sec only */ - age=hash_age(&TELMON, NULL); - if (age>0 && age<=1000) return 0; + /* reread every 1 sec only */ + age=hash_age(&TELMON, NULL); + if (age>0 && age<=1000) return 0; - if (telmond_fd != -1){ - char telbuf[128]; + if (telmond_fd != -1) { + char telbuf[128]; - telmond_fd = service_connect (thost, tport); - if (telmond_fd >= 0){ - int l = read (telmond_fd, telbuf, 127); - if ((l > 0) && (strcmp(telbuf,oldanswer))){ + telmond_fd = service_connect (thost, tport); + if (telmond_fd >= 0) { + int l = read (telmond_fd, telbuf, 127); + if ((l > 0) && (strcmp(telbuf,oldanswer))){ char date[11]; char time[11]; char number[256]; @@ -301,195 +293,262 @@ static int parse_telmon(){ phonebook(msn); hash_put (&TELMON, "name", number); hash_put (&TELMON, "msnname", msn); - } - close (telmond_fd); - strcpy(oldanswer,telbuf); + } + close (telmond_fd); + strcpy(oldanswer,telbuf); + } } - } - return 0; + return 0; } -static void my_telmon (RESULT *result, RESULT *arg1){ - char *val=NULL; - if (parse_telmon()<0) { - SetResult(&result, R_STRING, ""); - return; - } + +static int configure_telmon (void) +{ + static int configured = 0; + + char *s; + + if (configured != 0) return configured; - val=hash_get(&TELMON, R2S(arg1), NULL); - if (val==NULL) val=""; - SetResult(&result, R_STRING, val); + hash_create(&TELMON); + + s=cfg_get ("Plugin:Telmon", "Host","127.0.0.1"); + if (*s=='\0') { + error ("[Telmon] empty 'Host' entry in %s", cfg_source()); + configured = -1; + return configured; + } + strcpy(thost,s); + free(s); + + if (cfg_number("Plugin:Telmon", "Port", 5001, 1, 65536, &tport) < 0) { + error ("[Telmon] no valid port definition"); + configured = -1; + return configured; + } + + s = cfg_get ("Plugin:Telmon", "Phonebook", "/etc/phonebook"); + strcpy(phoneb, s); + free(s); + + configured = 1; + return configured; } -void init(){ - if (fd!=0) return; - - fd=service_connect(ihost,iport); - - if (fd<0){ - err++; - } else if ((ipass!=NULL) && (*ipass!='\0')) { /* Passwort senden */ - char buf[40]; - qprintf(buf,sizeof(buf),"pass %s",ipass); - send_command(fd,buf); - get_answer(fd); - } + +static void my_telmon (RESULT *result, RESULT *arg1) +{ + char *val = NULL; + + if (configure_telmon() < 0) { + SetResult(&result, R_STRING, ""); + return; + } + + if (parse_telmon() < 0) { + SetResult(&result, R_STRING, ""); + return; + } + + val = hash_get(&TELMON, R2S(arg1), NULL); + if (val == NULL) val=""; + SetResult(&result, R_STRING, val); } -static int parse_imon(const char *cmd){ + +void init() +{ + if (fd != 0) return; + + fd = service_connect(ihost, iport); + + if (fd < 0){ + err++; + } else if ((ipass != NULL) && (*ipass != '\0')) { /* Passwort senden */ + char buf[40]; + qprintf(buf,sizeof(buf), "pass %s", ipass); + send_command(fd, buf); + get_answer(fd); + } +} + + +static int parse_imon(const char *cmd) +{ /* reread every half sec only */ - int age=hash_age(&IMON, cmd); - if (age>0 && age<=500) return 0; + int age = hash_age(&IMON, cmd); + if (age > 0 && age <= 500) return 0; - init(); /* establish connection */ + init(); /* establish connection */ - if (err) return -1; + if (err) return -1; - hash_put (&IMON, cmd , get_value(cmd)); + hash_put (&IMON, cmd , get_value(cmd)); - return 0; + return 0; } -static void my_imon_version (RESULT *result){ - char *val; - /* read only ones */ - int age=hash_age(&IMON, "version"); - if (age<0){ + +static int configure_imon (void) +{ + static int configured = 0; + char *s; - init(); - if (err){ - SetResult(&result, R_STRING, ""); - return; + + if (configured != 0) return configured; + + hash_create(&IMON); + + s=cfg_get ("Plugin:Imon", "Host", "127.0.0.1"); + if (*s=='\0') { + error ("[Imon] empty 'Host' entry in %s", cfg_source()); + configured = -1; + return configured; } - s=get_value("version"); - for (;;){ /* interne Versionsnummer killen */ - if (s[0]==' '){ - s=s+1; - break; - } - s=s+1; + strcpy(ihost,s); + free(s); + + if (cfg_number("Plugin:Imon", "Port", 5000, 1, 65536, &iport) < 0) { + error ("[Imon] no valid port definition"); + configured = -1; + return configured; } - hash_put (&IMON, "version", s); - } - - val=hash_get(&IMON, "version", NULL); - if (val==NULL) val=""; - SetResult(&result, R_STRING, val); + + s = cfg_get ("Plugin:Imon", "Pass", ""); + strcpy(ipass, s); + free(s); + + configured = 1; + return configured; } -static int parse_imon_rates(const char *channel){ - char buf[128],in[25],out[25]; - char *s; - int age; + +static void my_imon_version (RESULT *result) +{ + char *val; + + if (configure_imon() < 0) { + SetResult(&result, R_STRING, ""); + return; + } + + /* read only once */ + int age=hash_age(&IMON, "version"); + if (age<0){ + char *s; + init(); + if (err){ + SetResult(&result, R_STRING, ""); + return; + } + s=get_value("version"); + for (;;){ /* interne Versionsnummer killen */ + if (s[0]==' '){ + s=s+1; + break; + } + s=s+1; + } + hash_put (&IMON, "version", s); + } + + val=hash_get(&IMON, "version", NULL); + if (val==NULL) val=""; + SetResult(&result, R_STRING, val); +} + + +static int parse_imon_rates(const char *channel) +{ + char buf[128],in[25],out[25]; + char *s; + int age; - qprintf(buf,sizeof(buf),"rate %s in",channel); + qprintf(buf,sizeof(buf),"rate %s in",channel); - /* reread every half sec only */ - age=hash_age(&IMON, buf); - if (age>0 && age<=500) return 0; + /* reread every half sec only */ + age=hash_age(&IMON, buf); + if (age>0 && age<=500) return 0; - init(); /* establish connection */ + init(); /* establish connection */ - if (err) return -1; + if (err) return -1; - qprintf(buf, sizeof(buf), "rate %s", channel); - s=get_value(buf); + qprintf(buf, sizeof(buf), "rate %s", channel); + s=get_value(buf); - if (sscanf(s,"%s %s",in, out)!=2) return -1; + if (sscanf(s,"%s %s",in, out)!=2) return -1; - qprintf(buf, sizeof(buf), "rate %s in", channel); - hash_put (&IMON, buf , in); - qprintf(buf, sizeof(buf), "rate %s out", channel); - hash_put (&IMON, buf , out); + qprintf(buf, sizeof(buf), "rate %s in", channel); + hash_put (&IMON, buf , in); + qprintf(buf, sizeof(buf), "rate %s out", channel); + hash_put (&IMON, buf , out); - return 0; + return 0; } -static void my_imon_rates (RESULT *result, RESULT *arg1, RESULT *arg2){ - char *val; - char buf[128]; +static void my_imon_rates (RESULT *result, RESULT *arg1, RESULT *arg2) +{ + char *val; + char buf[128]; - if (parse_imon_rates(R2S(arg1))<0) { - SetResult(&result, R_STRING, ""); - return; - } + if (configure_imon() < 0) { + SetResult(&result, R_STRING, ""); + return; + } + + if (parse_imon_rates(R2S(arg1)) < 0) { + SetResult(&result, R_STRING, ""); + return; + } - qprintf(buf,sizeof(buf),"rate %s %s",R2S(arg1),R2S(arg2)); + qprintf(buf,sizeof(buf),"rate %s %s",R2S(arg1),R2S(arg2)); - val=hash_get(&IMON, buf, NULL); - if (val==NULL) val=""; - SetResult(&result, R_STRING, val); + val = hash_get(&IMON, buf, NULL); + if (val == NULL) val = ""; + SetResult(&result, R_STRING, val); } -static void my_imon (RESULT *result, RESULT *arg1){ - char *val=NULL,*cmd=R2S(arg1); + +static void my_imon (RESULT *result, RESULT *arg1) +{ + char *val; + char *cmd; - if (parse_imon(cmd)<0) { - SetResult(&result, R_STRING, ""); - return; - } + if (configure_imon() < 0) { + SetResult(&result, R_STRING, ""); + return; + } + + cmd = R2S(arg1); + if (parse_imon(cmd)<0) { + SetResult(&result, R_STRING, ""); + return; + } - val=hash_get(&IMON, cmd, NULL); - if (val==NULL) val=""; - SetResult(&result, R_STRING, val); + val = hash_get(&IMON, cmd, NULL); + if (val == NULL) val = ""; + SetResult(&result, R_STRING, val); } -int plugin_init_imon (void){ - char telmon='\1',imon='\1'; - char *s=cfg_get ("Plugin:Telmon", "Host","127.0.0.1"); - - hash_create(&TELMON); - hash_create(&IMON); - if (*s=='\0') { - error ("[Telmon] no 'Host' entry in %s", cfg_source()); - telmon='\0'; - } - strcpy(thost,s); - free(s); +int plugin_init_imon (void) +{ + AddFunction ("imon", 1, my_imon); + AddFunction ("imon::version", 0, my_imon_version); + AddFunction ("imon::rates", 2, my_imon_rates); + AddFunction ("imon::telmon", 1, my_telmon); - if ((telmon=='\01') && (cfg_number("Plugin:Telmon", "Port",5001,1,65536,&tport)<0)){ - error ("[Telmon] no valid port definition"); - telmon='\0'; - } - - s=cfg_get ("Plugin:Telmon", "Phonebook","/etc/phonebook"); - strcpy(phoneb,s); - free(s); - - s=cfg_get ("Plugin:Imon", "Host", "127.0.0.1"); - if (*s=='\0') { - error ("[Imon] no 'Host' entry in %s", cfg_source()); - imon='\0'; - } - strcpy(ihost,s); - free(s); - - if ((imon=='\01') && (cfg_number("Plugin:Imon", "Port",5000,1,65536,&iport)<0)){ - error ("[Imon] no valid port definition"); - imon='\0'; - } - - s=cfg_get ("Plugin:Imon", "Pass", ""); - strcpy(ipass,s); - free(s); - - if (imon=='\1'){ - AddFunction ("imon", 1, my_imon); - AddFunction ("imon::version", 0, my_imon_version); - AddFunction ("imon::rates", 2, my_imon_rates); - } - - if (telmon=='\1') AddFunction ("imon::telmon", 1, my_telmon); - - return 0; + return 0; } -void plugin_exit_imon(void){ - if (fd>0){ - send_command(fd,"quit"); - close(fd); + +void plugin_exit_imon(void) +{ + if (fd > 0){ + send_command(fd, "quit"); + close(fd); } hash_destroy(&TELMON); hash_destroy(&IMON); diff --git a/plugin_mysql.c b/plugin_mysql.c index 171b6a5..ad3a3c5 100644 --- a/plugin_mysql.c +++ b/plugin_mysql.c @@ -1,4 +1,4 @@ -/* $Id: plugin_mysql.c,v 1.4 2005/01/18 06:30:23 reinelt Exp $ +/* $Id: plugin_mysql.c,v 1.5 2005/04/01 05:16:04 reinelt Exp $ * * plugin for execute SQL queries into a MySQL DBSM. * @@ -23,6 +23,9 @@ * * * $Log: plugin_mysql.c,v $ + * Revision 1.5 2005/04/01 05:16:04 reinelt + * moved plugin init stuff to a seperate function called on first use + * * Revision 1.4 2005/01/18 06:30:23 reinelt * added (C) to all copyright statements * @@ -80,62 +83,21 @@ static MYSQL conex; static char Section[] = "Plugin:MySQL"; -static void my_MySQLquery (RESULT *result, RESULT *query) -{ - double value; - MYSQL_RES *res; - char *q=R2S(query); - - /* mysql_ping(MYSQL *mysql) checks whether the connection to the server is working. - If it has gone down, an automatic reconnection is attempted. */ - mysql_ping(&conex); - if (mysql_real_query(&conex,q,(unsigned int) strlen(q))) - { - error( "[MySQL] query error: %s",mysql_error(&conex)); - value=-1; - } - else - { - /* We don't use res=mysql_use_result(); because mysql_num_rows() will not - return the correct value until all the rows in the result set have been retrieved - with mysql_fetch_row(), so we use res=mysql_store_result(); instead */ - res=mysql_store_result(&conex); - value = (double) mysql_num_rows(res); - mysql_free_result(res); - } - SetResult(&result, R_NUMBER, &value); -} - -static void my_MySQLstatus (RESULT *result) +static int configure_mysql (void) { - char *value; - char *status; - - mysql_ping(&conex); - status=strdup(mysql_stat(&conex)); - if (!status) - { - error( "[MySQL] status error: %s",mysql_error(&conex)); - value="error"; - } - else value = status; - - SetResult(&result, R_STRING, value); -} + static int configured = 0; -#endif - -int plugin_init_mysql (void) -{ -#ifdef HAVE_MYSQL_MYSQL_H char server[256]; unsigned int port; char user[128]; char password[256]; char database[256]; + char *s; + + if (configured != 0) return configured; - char *s = cfg_get (Section, "server", "localhost"); + s = cfg_get (Section, "server", "localhost"); if (*s=='\0') { info ("[MySQL] empty '%s.server' entry from %s, assuming 'localhost'", Section, cfg_source()); strcpy(server,"localhost"); @@ -147,7 +109,7 @@ int plugin_init_mysql (void) /* using 0 as default port because mysql_real_connect() will convert it to real default one */ info ("[MySQL] no '%s.port' entry from %s using MySQL's default", Section, cfg_source()); } - + s = cfg_get (Section, "user", ""); if (*s=='\0') { /* If user is NULL or the empty string "", the lcd4linux Unix user is assumed. */ @@ -156,10 +118,9 @@ int plugin_init_mysql (void) } else strcpy(user,s); free(s); - + s = cfg_get (Section, "password",""); - /*Do not encrypt the password because encryption is handled automatically - by the MySQL client API.*/ + /* Do not encrypt the password because encryption is handled automatically by the MySQL client API. */ if (*s=='\0') { info ("[MySQL] empty '%s.password' entry in %s, assuming none", Section, cfg_source()); strcpy(password,""); @@ -167,23 +128,90 @@ int plugin_init_mysql (void) else strcpy(password,s); free(s); - s = cfg_get (Section, "database","\0"); + s = cfg_get (Section, "database", ""); if (*s=='\0') { error ("[MySQL] no '%s:database' entry from %s, specify one", Section, cfg_source()); + free (s); + configured = -1; + return configured; } - else { - strcpy(database,s); - free(s); - - mysql_init(&conex); - if (!mysql_real_connect(&conex,server,user,password,database,port,NULL,0)) - error( "[MySQL] conection error: %s",mysql_error(&conex)); - else - { - AddFunction ("MySQL::query", 1, my_MySQLquery); - AddFunction ("MySQL::status", 0, my_MySQLstatus); + strcpy(database,s); + free(s); + + mysql_init(&conex); + if (!mysql_real_connect(&conex,server,user,password,database,port,NULL,0)) { + error( "[MySQL] conection error: %s",mysql_error(&conex)); + configured = -1; + return configured; + } + + configured = 1; + return configured; +} + + +static void my_MySQLquery (RESULT *result, RESULT *query) +{ + char *q; + double value; + MYSQL_RES *res; + + if (configure_mysql() < 0) { + value = -1; + SetResult(&result, R_NUMBER, &value); + return; + } + + q = R2S(query); + + /* mysql_ping(MYSQL *mysql) checks whether the connection to the server is working. */ + /* If it has gone down, an automatic reconnection is attempted. */ + mysql_ping(&conex); + if (mysql_real_query(&conex,q,(unsigned int) strlen(q))) { + error( "[MySQL] query error: %s",mysql_error(&conex)); + value = -1; + } else { + /* We don't use res=mysql_use_result(); because mysql_num_rows() will not */ + /* return the correct value until all the rows in the result set have been retrieved */ + /* with mysql_fetch_row(), so we use res=mysql_store_result(); instead */ + res=mysql_store_result(&conex); + value = (double) mysql_num_rows(res); + mysql_free_result(res); + } + + SetResult(&result, R_NUMBER, &value); +} + + +static void my_MySQLstatus (RESULT *result) +{ + char *value = ""; + char *status; + + if (configure_mysql > 0) { + + mysql_ping(&conex); + status=mysql_stat(&conex); + if (!status) { + error( "[MySQL] status error: %s",mysql_error(&conex)); + value="error"; + } else { + value = status; } } + + SetResult(&result, R_STRING, value); +} + + +#endif + + +int plugin_init_mysql (void) +{ +#ifdef HAVE_MYSQL_MYSQL_H + AddFunction ("MySQL::query", 1, my_MySQLquery); + AddFunction ("MySQL::status", 0, my_MySQLstatus); #endif return 0; } diff --git a/plugin_pop3.c b/plugin_pop3.c index f4cf2f7..d8501b9 100644 --- a/plugin_pop3.c +++ b/plugin_pop3.c @@ -1,4 +1,4 @@ -/* $Id: plugin_pop3.c,v 1.7 2005/01/18 06:30:23 reinelt Exp $ +/* $Id: plugin_pop3.c,v 1.8 2005/04/01 05:16:04 reinelt Exp $ * * Plugin to check POP3 mail accounts * @@ -27,6 +27,9 @@ * * * $Log: plugin_pop3.c,v $ + * Revision 1.8 2005/04/01 05:16:04 reinelt + * moved plugin init stuff to a seperate function called on first use + * * Revision 1.7 2005/01/18 06:30:23 reinelt * added (C) to all copyright statements * @@ -80,285 +83,284 @@ #include <dmalloc.h> #endif - /*POP 3 */ -#define POPERR "-ERR" -#define LOCKEDERR "-ERR account is locked by another session or for maintenance, try again." -#define BUFSIZE 8192 -#define POP3PORT 110 -#define MAX_NUM_ACCOUNTS 3 +/*POP 3 */ +#define POPERR "-ERR" +#define LOCKEDERR "-ERR account is locked by another session or for maintenance, try again." +#define BUFSIZE 8192 +#define POP3PORT 110 +#define MAX_NUM_ACCOUNTS 3 struct check { - int id; - char *username; - char *password; - char *server; - int port; - int messages; - struct check *next; + int id; + char *username; + char *password; + char *server; + int port; + int messages; + struct check *next; }; + /************************ PROTOTYPES ********************************/ /* list */ static struct check *check_node_alloc(void); static void check_node_add(struct check **head, struct check *new_check); static void check_destroy(struct check **head); + /* pop3 */ static void pop3_check_messages(struct check *hi,int verbose); static void pop3_recv_crlf_terminated(int sockfd, char *buf, int size); + /* socket */ static int tcp_connect(struct check *hi); + + /************************ GLOBAL ***********************************/ static char Section[] = "Plugin:POP3"; -static struct check *head = NULL; +static struct check *head = NULL; /********************************************************************/ -static void my_POP3check (RESULT *result, RESULT *check) -{ - double value; - double param=R2N(check); - - struct check *node = NULL; - - for (node = head; node; node = node->next) - { - if (node->id == param) - break; - } - if (node == NULL) /*Inexistent account */ - value=-1.0; - else - pop3_check_messages(node,0); - value = (double)node->messages; - SetResult(&result, R_NUMBER, &value); -} -static int getConfig (void) -{ - struct check *node = NULL; - int i,n=0; - char *user= (char *)calloc(1, sizeof("user")+sizeof(int)); - char *password= (char *)calloc(1, sizeof("password")+sizeof(int)); - char *server=(char *)calloc(1, sizeof("server")+sizeof(int)); - char *port= (char *)calloc(1, sizeof("port")+sizeof(int)); - - for (i =1;i <= MAX_NUM_ACCOUNTS; i++) - { - char *x; - sprintf(user,"user%d",i); - sprintf(password,"password%d",i); - sprintf(server,"server%d",i); - sprintf(port,"port%d",i); - - x = cfg_get (Section, server, ""); - if (*x=='\0') - { - info ("[POP3] No '%s.%s' entry from %s, disabling POP3 account #%d", Section, server, cfg_source(),i); - free(x); - } - else - { - node = check_node_alloc(); - node->id = i; - node->server = x; - node->messages = 0; - node->next = NULL; - - x = cfg_get (Section, user, ""); - if (*x=='\0') - { - info ("[POP3] No '%s.%s' entry from %s, disabling POP3 account #%d", Section, user, cfg_source(),i); - free(x); - } - else - { - node->username = x; - x = cfg_get (Section, password, ""); - if (*x=='\0') - { - info ("[POP3] No '%s.%s' entry from %s, disabling POP3 account #%d", Section, password, cfg_source(),i); - free(x); - } - else - { - node->password = x; - if (cfg_number(Section, port, POP3PORT, 1, 65536, &node->port)<1) - info("[POP3] No '%s.%s' entry from %s, %d will be used for account #%d", Section, port, cfg_source(),POP3PORT,i); - check_node_add(&head, node); - n++; - } - } - } - } - return(n); -} /************************ LIST ***********************************/ + static struct check *check_node_alloc(void) { - struct check *new_check; - new_check = (struct check *)calloc(1, sizeof(struct check)); - if (new_check == NULL) - { - error( "[POP3] out of memory\n"); - } - return new_check; + struct check *new_check; + new_check = (struct check *)calloc(1, sizeof(struct check)); + if (new_check == NULL) { + error( "[POP3] out of memory\n"); + } + return new_check; } static void check_node_add(struct check **head, struct check *new_check) { - new_check->next = *head ; - *head = new_check; + new_check->next = *head ; + *head = new_check; } static void check_destroy(struct check **head) -{ - struct check *iter; - while (*head) - { - iter = (*head)->next; - free((*head)->username); - free((*head)->password); - free((*head)->server); - free(*head); - *head = iter; - } - *head = NULL; +{ + struct check *iter; + while (*head) { + iter = (*head)->next; + free((*head)->username); + free((*head)->password); + free((*head)->server); + free(*head); + *head = iter; + } + *head = NULL; } /************************ POP3 ********************************/ static void pop3_check_messages(struct check *hi,int verbose) { - char buf[BUFSIZE]; - int sockfd; + char buf[BUFSIZE]; + int sockfd; - if ((sockfd = tcp_connect(hi)) < 0) - { - hi->messages = -1; - return; - } - - pop3_recv_crlf_terminated(sockfd, buf, sizeof(buf)); /* server greeting */ - if (verbose) - info("[POP3] %s -> %s\n", hi->server, buf); - - snprintf(buf, sizeof(buf), "USER %s\r\n", hi->username); - write(sockfd, buf, strlen(buf)); - buf[strlen(buf)-1] = '\0'; - if (verbose) - info("[POP3] %s <- %s\n", hi->server, buf); - pop3_recv_crlf_terminated(sockfd, buf, sizeof(buf)); /* response from USER command */ - if (verbose) - info("[POP3] %s -> %s\n", hi->server, buf); - - snprintf(buf, sizeof(buf), "PASS %s\r\n", hi->password); - write(sockfd, buf, strlen(buf)); - if (verbose) - info("[POP3] %s <- PASS ???\n", hi->server); - pop3_recv_crlf_terminated(sockfd, buf, sizeof(buf)); /* response from PASS command */ - if (verbose) - info("[POP3] %s -> %s\n", hi->server, buf); - - if (strncmp(buf, LOCKEDERR, strlen(LOCKEDERR)) == 0) - { - hi->messages = -2; - close(sockfd); - return; - } - if (strncmp(buf, POPERR, strlen(POPERR)) == 0) - { - error("[POP3] error logging into %s\n", hi->server); - error("[POP3] server responded: %s\n", buf); - hi->messages = -1; - close(sockfd); - return; - } - - snprintf(buf, sizeof(buf), "STAT\r\n"); - write(sockfd, buf, strlen(buf)); - if (verbose) - info("[POP3] %s <- STAT\n", hi->server); - pop3_recv_crlf_terminated(sockfd, buf, sizeof(buf)); /* response from PASS command */ - if (verbose) - info("[POP3] %s -> %s\n", hi->server, buf); - - strtok(buf, " "); - hi->messages = atoi(strtok(NULL, " ")); - - snprintf(buf, sizeof(buf), "QUIT\r\n"); - write(sockfd, buf, strlen(buf)); - if (verbose) - info("[POP3] %s <- QUIT\n", hi->server); - pop3_recv_crlf_terminated(sockfd, buf, sizeof(buf)); /* response from QUIT command */ - if (verbose) - info("[POP3] %s -> %s\n", hi->server, buf); - - close(sockfd); + if ((sockfd = tcp_connect(hi)) < 0) { + hi->messages = -1; + return; + } + + pop3_recv_crlf_terminated(sockfd, buf, sizeof(buf)); /* server greeting */ + if (verbose) info("[POP3] %s -> %s\n", hi->server, buf); + + snprintf(buf, sizeof(buf), "USER %s\r\n", hi->username); + write(sockfd, buf, strlen(buf)); + buf[strlen(buf)-1] = '\0'; + if (verbose) info("[POP3] %s <- %s\n", hi->server, buf); + pop3_recv_crlf_terminated(sockfd, buf, sizeof(buf)); /* response from USER command */ + if (verbose) info("[POP3] %s -> %s\n", hi->server, buf); + + snprintf(buf, sizeof(buf), "PASS %s\r\n", hi->password); + write(sockfd, buf, strlen(buf)); + if (verbose) info("[POP3] %s <- PASS ???\n", hi->server); + pop3_recv_crlf_terminated(sockfd, buf, sizeof(buf)); /* response from PASS command */ + if (verbose) info("[POP3] %s -> %s\n", hi->server, buf); + + if (strncmp(buf, LOCKEDERR, strlen(LOCKEDERR)) == 0) { + hi->messages = -2; + close(sockfd); + return; + } + if (strncmp(buf, POPERR, strlen(POPERR)) == 0) { + error("[POP3] error logging into %s\n", hi->server); + error("[POP3] server responded: %s\n", buf); + hi->messages = -1; + close(sockfd); + return; + } + + snprintf(buf, sizeof(buf), "STAT\r\n"); + write(sockfd, buf, strlen(buf)); + if (verbose) info("[POP3] %s <- STAT\n", hi->server); + pop3_recv_crlf_terminated(sockfd, buf, sizeof(buf)); /* response from PASS command */ + if (verbose) info("[POP3] %s -> %s\n", hi->server, buf); + + strtok(buf, " "); + hi->messages = atoi(strtok(NULL, " ")); + + snprintf(buf, sizeof(buf), "QUIT\r\n"); + write(sockfd, buf, strlen(buf)); + if (verbose) info("[POP3] %s <- QUIT\n", hi->server); + pop3_recv_crlf_terminated(sockfd, buf, sizeof(buf)); /* response from QUIT command */ + if (verbose) info("[POP3] %s -> %s\n", hi->server, buf); + + close(sockfd); } static void pop3_recv_crlf_terminated(int sockfd, char *buf, int size) { -/* receive one line server responses terminated with CRLF */ - char *pos; - int bytes = 0; - memset(buf, 0, size); - while ((pos = strstr(buf, "\r\n")) == NULL) - bytes += read(sockfd, buf+bytes, size-bytes); - *pos = '\0'; + /* receive one line server responses terminated with CRLF */ + char *pos; + int bytes = 0; + memset(buf, 0, size); + while ((pos = strstr(buf, "\r\n")) == NULL) + bytes += read(sockfd, buf+bytes, size-bytes); + *pos = '\0'; } /************************ SOCKET ********************************/ static int tcp_connect(struct check *hi) { - struct sockaddr_in addr; - struct hostent *he = gethostbyname(hi->server); - int sockfd; + struct sockaddr_in addr; + struct hostent *he = gethostbyname(hi->server); + int sockfd; - if (hi == NULL) - return -1; + if (hi == NULL) return -1; - if (!he) - { - error("[POP3] Failed to lookup %s\n",hi->server); - return(-1); - } + if (!he) { + error("[POP3] Failed to lookup %s\n",hi->server); + return(-1); + } - memset((char *)&addr, 0, sizeof(struct sockaddr_in)); - addr.sin_family = AF_INET; - memcpy(&(addr.sin_addr.s_addr), he->h_addr, he->h_length); - addr.sin_port = htons(hi->port); + memset((char *)&addr, 0, sizeof(struct sockaddr_in)); + addr.sin_family = AF_INET; + memcpy(&(addr.sin_addr.s_addr), he->h_addr, he->h_length); + addr.sin_port = htons(hi->port); - if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) - { - perror("socket()"); - return(-1); - } - - if (connect(sockfd, (struct sockaddr *)&addr, sizeof(struct sockaddr)) < 0) - { - perror("connect()"); - close(sockfd); - return(-1); + if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) { + perror("socket()"); + return(-1); + } + + if (connect(sockfd, (struct sockaddr *)&addr, sizeof(struct sockaddr)) < 0) { + perror("connect()"); + close(sockfd); + return(-1); + } + + return(sockfd); +} + + +static int getConfig (void) +{ + struct check *node = NULL; + int i,n=0; + char *user= (char *)calloc(1, sizeof("user")+sizeof(int)); + char *password= (char *)calloc(1, sizeof("password")+sizeof(int)); + char *server=(char *)calloc(1, sizeof("server")+sizeof(int)); + char *port= (char *)calloc(1, sizeof("port")+sizeof(int)); + + for (i =1;i <= MAX_NUM_ACCOUNTS; i++) { + char *x; + sprintf(user,"user%d",i); + sprintf(password,"password%d",i); + sprintf(server,"server%d",i); + sprintf(port,"port%d",i); + + x = cfg_get (Section, server, ""); + if (*x=='\0') { + info ("[POP3] No '%s.%s' entry from %s, disabling POP3 account #%d", Section, server, cfg_source(),i); + free(x); + } else { + node = check_node_alloc(); + node->id = i; + node->server = x; + node->messages = 0; + node->next = NULL; + + x = cfg_get (Section, user, ""); + if (*x=='\0') { + info ("[POP3] No '%s.%s' entry from %s, disabling POP3 account #%d", Section, user, cfg_source(),i); + free(x); + } else { + node->username = x; + x = cfg_get (Section, password, ""); + if (*x=='\0') { + info ("[POP3] No '%s.%s' entry from %s, disabling POP3 account #%d", Section, password, cfg_source(),i); + free(x); + } else { + node->password = x; + if (cfg_number(Section, port, POP3PORT, 1, 65536, &node->port)<1) { + info("[POP3] No '%s.%s' entry from %s, %d will be used for account #%d", Section, port, cfg_source(),POP3PORT,i); + } + check_node_add(&head, node); + n++; } + } + } + } + return(n); +} + + +static int configure_pop3 (void) +{ + static int configured = 0; + int n; + + if (configured != 0) return configured; + + n = getConfig(); + /* by now, head should point to a list of all our accounts */ + if (head) { + info("[POP3] %d POP3 accounts have been succesfully defined",n); + configured = 1; + } else { + configured = -1; + } + return configured; +} + - return(sockfd); +static void my_POP3check (RESULT *result, RESULT *check) +{ + double param = R2N(check); + struct check *node = NULL; + double value; + + if (configure_pop3() < 0) { + value = -1; + SetResult(&result, R_NUMBER, &value); + return; + } + + for (node = head; node; node = node->next) { + if (node->id == param) break; + } + if (node == NULL) { /*Inexistent account */ + value = -1; + } else { + pop3_check_messages(node,0); + value = (double)node->messages; + } + SetResult(&result, R_NUMBER, &value); } int plugin_init_pop3(void) { - - int n = getConfig(); - /* by now, head should point to a list of all our accounts */ - if (head) - { - info("[POP3] %d POP3 accounts have been succesfully defined",n); - AddFunction ("POP3check", 1, my_POP3check); - } - return 0; + AddFunction ("POP3check", 1, my_POP3check); + return 0; } void plugin_exit_pop3(void) { - check_destroy(&head); + check_destroy(&head); } |