diff options
Diffstat (limited to '')
-rw-r--r-- | plugin_pop3.c | 444 |
1 files changed, 223 insertions, 221 deletions
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); } |