[Commits] Makefile.am NONE 1.1.2.1 clamd-plugin.c NONE 1.1.2.1 clamd-plugin.h NONE 1.1.2.1
colin at claws-mail.org
colin at claws-mail.org
Sun Feb 17 22:21:59 CET 2013
Update of /home/claws-mail/claws/src/plugins/clamd/libclamd
In directory srv:/tmp/cvs-serv7104/src/plugins/clamd/libclamd
Added Files:
Tag: gtk2
Makefile.am clamd-plugin.c clamd-plugin.h
Log Message:
2013-02-17 [colin] 3.9.0cvs75
* src/plugins/Makefile.am
* src/plugins/archive/Makefile.am
* src/plugins/clamd/Makefile.am
* src/plugins/clamd/clamav_plugin.c
* src/plugins/clamd/clamav_plugin.h
* src/plugins/clamd/clamav_plugin_gtk.c
* src/plugins/clamd/placeholder.txt
* src/plugins/clamd/libclamd/Makefile.am
* src/plugins/clamd/libclamd/clamd-plugin.c
* src/plugins/clamd/libclamd/clamd-plugin.h
* src/plugins/fetchinfo/Makefile.am
* src/plugins/fetchinfo/fetchinfo_plugin.c
* src/plugins/fetchinfo/fetchinfo_plugin.h
* src/plugins/fetchinfo/fetchinfo_plugin_gtk.c
* src/plugins/fetchinfo/placeholder.txt
* src/plugins/gdata/Makefile.am
* src/plugins/gdata/cm_gdata_contacts.c
* src/plugins/gdata/cm_gdata_contacts.h
* src/plugins/gdata/cm_gdata_prefs.c
* src/plugins/gdata/cm_gdata_prefs.h
* src/plugins/gdata/gdata_plugin.c
* src/plugins/gdata/gdata_plugin.h
* src/plugins/gdata/placeholder.txt
* src/plugins/geolocation/placeholder.txt
* src/plugins/gtkhtml2_viewer/placeholder.txt
* src/plugins/mailmbox/Makefile.am
* src/plugins/mailmbox/carray.c
* src/plugins/mailmbox/carray.h
* src/plugins/mailmbox/chash.c
* src/plugins/mailmbox/chash.h
* src/plugins/mailmbox/clist.c
* src/plugins/mailmbox/clist.h
* src/plugins/mailmbox/mailimf.c
* src/plugins/mailmbox/mailimf.h
* src/plugins/mailmbox/mailimf_types.c
* src/plugins/mailmbox/mailimf_types.h
* src/plugins/mailmbox/mailimf_types_helper.c
* src/plugins/mailmbox/mailimf_types_helper.h
* src/plugins/mailmbox/mailimf_write.c
* src/plugins/mailmbox/mailimf_write.h
* src/plugins/mailmbox/maillock.c
* src/plugins/mailmbox/maillock.h
* src/plugins/mailmbox/mailmbox.c
* src/plugins/mailmbox/mailmbox.h
* src/plugins/mailmbox/mailmbox_folder.c
* src/plugins/mailmbox/mailmbox_folder.h
* src/plugins/mailmbox/mailmbox_gtk.deps
* src/plugins/mailmbox/mailmbox_parse.c
* src/plugins/mailmbox/mailmbox_parse.h
* src/plugins/mailmbox/mailmbox_types.c
* src/plugins/mailmbox/mailmbox_types.h
* src/plugins/mailmbox/mmapstring.c
* src/plugins/mailmbox/mmapstring.h
* src/plugins/mailmbox/placeholder.txt
* src/plugins/mailmbox/plugin.c
* src/plugins/mailmbox/plugin_gtk.c
* src/plugins/mailmbox/plugin_gtk.h
* src/plugins/newmail/Makefile.am
* src/plugins/newmail/newmail.c
* src/plugins/newmail/placeholder.txt
* src/plugins/notification/Makefile.am
* src/plugins/notification/claws.def
* src/plugins/notification/notification_banner.c
* src/plugins/notification/notification_banner.h
* src/plugins/notification/notification_command.c
* src/plugins/notification/notification_command.h
* src/plugins/notification/notification_core.c
* src/plugins/notification/notification_core.h
* src/plugins/notification/notification_foldercheck.c
* src/plugins/notification/notification_foldercheck.h
* src/plugins/notification/notification_hotkeys.c
* src/plugins/notification/notification_hotkeys.h
* src/plugins/notification/notification_indicator.c
* src/plugins/notification/notification_indicator.h
* src/plugins/notification/notification_lcdproc.c
* src/plugins/notification/notification_lcdproc.h
* src/plugins/notification/notification_pixbuf.c
* src/plugins/notification/notification_pixbuf.h
* src/plugins/notification/notification_plugin.c
* src/plugins/notification/notification_plugin.h
* src/plugins/notification/notification_popup.c
* src/plugins/notification/notification_popup.h
* src/plugins/notification/notification_prefs.c
* src/plugins/notification/notification_prefs.h
* src/plugins/notification/notification_trayicon.c
* src/plugins/notification/notification_trayicon.h
* src/plugins/notification/placeholder.txt
* src/plugins/notification/plugin.def
* src/plugins/notification/raw_claws_mail_logo_64x64.h
* src/plugins/notification/version.rc
* src/plugins/pdf_viewer/Makefile.am
* src/plugins/pdf_viewer/doc_index.xpm
* src/plugins/pdf_viewer/doc_index_close.xpm
* src/plugins/pdf_viewer/doc_info.xpm
* src/plugins/pdf_viewer/first_arrow.xpm
* src/plugins/pdf_viewer/last_arrow.xpm
* src/plugins/pdf_viewer/left_arrow.xpm
* src/plugins/pdf_viewer/placeholder.txt
* src/plugins/pdf_viewer/poppler_viewer.c
* src/plugins/pdf_viewer/poppler_viewer.h
* src/plugins/pdf_viewer/right_arrow.xpm
* src/plugins/pdf_viewer/rotate_left.xpm
* src/plugins/pdf_viewer/rotate_right.xpm
* src/plugins/pdf_viewer/zoom_fit.xpm
* src/plugins/pdf_viewer/zoom_in.xpm
* src/plugins/pdf_viewer/zoom_out.xpm
* src/plugins/pdf_viewer/zoom_width.xpm
* src/plugins/perl/Makefile.am
* src/plugins/perl/perl_gtk.c
* src/plugins/perl/perl_gtk.h
* src/plugins/perl/perl_plugin.c
* src/plugins/perl/perl_plugin.h
* src/plugins/perl/placeholder.txt
* src/plugins/python/Makefile.am
* src/plugins/python/clawsmailmodule.c
* src/plugins/python/clawsmailmodule.h
* src/plugins/python/composewindowtype.c
* src/plugins/python/composewindowtype.h
* src/plugins/python/foldertype.c
* src/plugins/python/foldertype.h
* src/plugins/python/messageinfotype.c
* src/plugins/python/messageinfotype.h
* src/plugins/python/nodetype.c
* src/plugins/python/nodetype.h
* src/plugins/python/placeholder.txt
* src/plugins/python/python-hooks.c
* src/plugins/python/python-hooks.h
* src/plugins/python/python-shell.c
* src/plugins/python/python-shell.h
* src/plugins/python/python_plugin.c
* src/plugins/vcalendar/Makefile.in
Add some plugins (clamd, fetchinfo, gdata, mailmbox, newmail,
notification, pdf_viewer, perl, python). Notification not yet
enabled because it has too much autoconf switches for my taste.
--- NEW FILE: Makefile.am ---
INCLUDES = @GLIB_CFLAGS@ \
@GTK_CFLAGS@ \
-I$(top_srcdir) \
-I$(top_builddir) \
$(CLAWS_MAIL_CFLAGS) \
-I$(top_srcdir)/src \
-I$(top_srcdir)/src/common \
-I$(top_srcdir)/src/gtk
noinst_LTLIBRARIES = libclamd-plugin.la
libclamd_plugin_la_SOURCES = \
clamd-plugin.h \
clamd-plugin.c
noinst_HEADERS = clamd-plugin.h
libclamd_plugin_la_LIBADD = \
@GLIB_LIBS@ \
@GTK_LIBS@
--- NEW FILE: clamd-plugin.c ---
/* vim: set textwidth=80 tabstop=4: */
/*
* Claws Mail -- a GTK+ based, lightweight, and fast e-mail client
* Copyright (C) 1999-2008 Michael Rasmussen and the Claws Mail Team
*
* This program 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 3 of the License, or
* (at your option) any later version.
*
* This program 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, see <http://www.gnu.org/licenses/>.
*
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include "defs.h"
#include <glib.h>
#include <glib/gi18n.h>
#include <gtk/gtk.h>
#include <gtk/gtkutils.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <netinet/in.h>
#include <sys/un.h>
#include <arpa/inet.h>
#include <netdb.h>
#include "common/claws.h"
#include "common/version.h"
#include "plugin.h"
#include "utils.h"
#include "prefs.h"
#include "folder.h"
#include "prefs_gtk.h"
#include "foldersel.h"
#include "statusbar.h"
#include "alertpanel.h"
#include "clamd-plugin.h"
/* needs to be generic */
static const gchar* config_dirs[] = {
"/etc",
"/usr/local/etc",
"/etc/clamav",
"/usr/local/etc/clamav",
NULL };
static const gchar* clamd_tokens[] = {
"LocalSocket",
"TCPSocket",
"TCPAddr",
NULL };
static Clamd_Socket* Socket = NULL;
static int sock;
static Config* config = NULL;
/**
* clamd commands used
* prefixing with either z or n is recommended
* z <=> null terminated command
* n <=> newline terminated command
*/
static const gchar ping[] = "nPING\n";
static const gchar version[] = "nVERSION\n";
static const gchar scan[] = "nSCAN";
static const gchar contscan[] = "nCONTSCAN";
static const gchar instream[10] = "zINSTREAM\0";
void clamd_create_config_automatic(const gchar* path) {
FILE* conf;
char buf[1024];
gchar* key = NULL;
gchar* value = NULL;
/*debug_set_mode(TRUE);*/
/*debug_print("%s : %s\n", folder, path);*/
if (! path) {
g_warning("Missing path");
return;
}
if (config && config->ConfigType == AUTOMATIC &&
config->automatic.folder &&
strcmp(config->automatic.folder, path) == 0) {
debug_print("%s : %s - Identical. No need to read again\n",
config->automatic.folder, path);
return;
}
if (config)
clamd_config_free(config);
config = clamd_config_new();
config->ConfigType = AUTOMATIC;
config->automatic.folder = g_strdup(path);
debug_print("Opening %s to parse config file\n", path);
conf = fopen(path, "r");
if (!conf) {
/*g_error("%s: Unable to open", path);*/
alertpanel_error(_("%s: Unable to open\nclamd will be disabled"), path);
return;
}
while (fgets(buf, sizeof(buf), conf)) {
g_strstrip(buf);
if (buf[0] == '#')
continue;
const gchar** tokens = clamd_tokens;
while (*tokens) {
const gchar* token = *tokens++;
if ((key = g_strstr_len(buf, strlen(buf), token)) != NULL) {
gchar* tmp = &(*(key + strlen(token)));
tmp = g_strchug(tmp);
gchar* end = index(tmp, '#');
if (end)
value = g_strndup(tmp, end - tmp);
else
value = g_strdup(g_strchomp(tmp));
if (strcmp(clamd_tokens[0], token) == 0) {
/* UNIX socket */
Socket = (Clamd_Socket *) malloc(sizeof(Clamd_Socket *));
if (Socket) {
Socket->socket.path = NULL;
Socket->socket.host = NULL;
Socket->socket.port = -1;
Socket->type = UNIX_SOCKET;
Socket->socket.path = g_strdup(value);
g_free(value);
value = NULL;
fclose(conf);
debug_print("clamctl: %s\n", Socket->socket.path);
return;
}
}
else if (strcmp(clamd_tokens[1], token) == 0) {
/* INET socket */
if (! Socket) {
Socket = (Clamd_Socket *) malloc(sizeof(Clamd_Socket *));
if (Socket) {
Socket->socket.path = NULL;
Socket->socket.host = NULL;
Socket->socket.port = -1;
Socket->type = INET_SOCKET;
Socket->socket.port = atoi(value);
Socket->socket.host = g_strdup("localhost");
g_free(value);
value = NULL;
debug_print("clamctl: %s:%d\n",
Socket->socket.host, Socket->socket.port);
}
}
else {
Socket->type = INET_SOCKET;
Socket->socket.port = atoi(value);
g_free(value);
value = NULL;
if (! Socket->socket.host)
Socket->socket.host = g_strdup("localhost");
debug_print("clamctl: %s:%d\n",
Socket->socket.host, Socket->socket.port);
}
/* We must continue since TCPAddr could also be configured */
}
else if (strcmp(clamd_tokens[2], token) == 0) {
if (! Socket) {
Socket = (Clamd_Socket *) malloc(sizeof(Clamd_Socket *));
if (Socket) {
Socket->socket.path = NULL;
Socket->socket.host = NULL;
Socket->socket.port = 3310; /* default port */
Socket->type = INET_SOCKET;
Socket->socket.host = g_strdup(value);
g_free(value);
value = NULL;
debug_print("clamctl: %s:%d\n",
Socket->socket.host, Socket->socket.port);
}
}
else {
Socket->type = INET_SOCKET;
if (Socket->socket.host)
g_free(Socket->socket.host);
Socket->socket.host = g_strdup(value);
g_free(value);
value = NULL;
if (Socket->socket.port == -1)
Socket->socket.port = 3310;
debug_print("clamctl: %s:%d\n",
Socket->socket.host, Socket->socket.port);
}
/* We must continue since TCPSocket could also be configured */
}
}
}
}
fclose(conf);
if (! (Socket && (Socket->socket.port || Socket->socket.path))) {
/*g_error("%s: Not able to find required information", path);*/
alertpanel_error(_("%s: Not able to find required information\nclamd will be disabled"), path);
}
/*debug_set_mode(FALSE);*/
}
void clamd_create_config_manual(const gchar* host, int port) {
if (! host || port < 1) {
g_warning("Missing host or port < 1");
return;
}
if (config && config->ConfigType == MANUAL &&
config->manual.host && config->manual.port == port &&
strcmp(config->manual.host, host) == 0) {
debug_print("%s : %s and %d : %d - Identical. No need to read again\n",
config->manual.host, host, config->manual.port, port);
return;
}
if (config)
clamd_config_free(config);
config = clamd_config_new();
config->ConfigType = MANUAL;
config->manual.host = g_strdup(host);
config->manual.port = port;
/* INET socket */
Socket = (Clamd_Socket *) malloc(sizeof(Clamd_Socket *));
if (Socket) {
Socket->type = INET_SOCKET;
Socket->socket.port = port;
Socket->socket.host = g_strdup(host);
}
else {
/*g_error("%s: Not able to find required information", path);*/
alertpanel_error(_("Could not create socket"));
}
}
gboolean clamd_find_socket() {
const gchar** config_dir = config_dirs;
gchar *clamd_conf = NULL;
while (*config_dir) {
clamd_conf = g_strdup_printf("%s/clamd.conf", *config_dir++);
debug_print("Looking for %s\n", clamd_conf);
if (g_file_test(clamd_conf, G_FILE_TEST_EXISTS))
break;
g_free(clamd_conf);
clamd_conf = NULL;
}
if (! clamd_conf)
return FALSE;
debug_print("Using %s to find configuration\n", clamd_conf);
clamd_create_config_automatic(clamd_conf);
g_free(clamd_conf);
return TRUE;
}
Config* clamd_get_config() {
return config;
}
Clamd_Socket* clamd_get_socket() {
return Socket;
}
static void close_socket() {
debug_print("Closing socket: %d\n", sock);
close(sock);
}
static void create_socket() {
struct sockaddr_un addr_u;
struct sockaddr_in addr_i;
struct hostent *hp;
/*debug_set_mode(TRUE);*/
if (! Socket) {
sock = -1;
return;
}
memset(&addr_u, 0, sizeof(addr_u));
memset(&addr_i, 0, sizeof(addr_i));
debug_print("socket->type: %d\n", Socket->type);
switch (Socket->type) {
case UNIX_SOCKET:
debug_print("socket path: %s\n", Socket->socket.path);
sock = socket(PF_UNIX, SOCK_STREAM, 0);
debug_print("socket file (create): %d\n", sock);
if (sock < 0)
return;
addr_u.sun_family = AF_UNIX;
memcpy(addr_u.sun_path, Socket->socket.path,
strlen(Socket->socket.path));
if (connect(sock, (struct sockaddr *) &addr_u, sizeof(addr_u)) < 0) {
perror("connect socket");
close_socket();
sock = -2;
}
debug_print("socket file (connect): %d\n", sock);
break;
case INET_SOCKET:
addr_i.sin_family = AF_INET;
addr_i.sin_port = htons(Socket->socket.port);
hp = gethostbyname(Socket->socket.host);
bcopy((void *)hp->h_addr, (void *)&addr_i.sin_addr, hp->h_length);
sock = socket(PF_INET, SOCK_STREAM, 0);
if (sock < 0)
return;
if (connect(sock, (struct sockaddr *)&addr_i, sizeof(addr_i)) < 0) {
perror("connect socket");
close_socket();
sock = -2;
}
break;
}
/*debug_set_mode(FALSE);*/
}
static void copy_socket(Clamd_Socket* sock) {
Socket = (Clamd_Socket *) malloc(sizeof(Clamd_Socket *));
Socket->socket.path = NULL;
Socket->socket.host = NULL;
Socket->type = sock->type;
if (Socket->type == UNIX_SOCKET) {
Socket->socket.path = g_strdup(sock->socket.path);
}
else {
Socket->socket.host = g_strdup(sock->socket.host);
Socket->socket.port = sock->socket.port;
}
}
Clamd_Stat clamd_init(Clamd_Socket* config) {
gchar buf[BUFSIZ];
int n_read;
gboolean connect = FALSE;
/*debug_set_mode(TRUE);*/
if (config != NULL && Socket != NULL)
return NO_SOCKET;
if (config) {
debug_print("socket: %s\n", config->socket.path);
copy_socket(config);
}
create_socket();
if (sock < 0) {
debug_print("no connection\n");
return NO_CONNECTION;
}
if (write(sock, ping, strlen(ping)) == -1) {
debug_print("no connection\n");
return NO_CONNECTION;
}
memset(buf, '\0', sizeof(buf));
while ((n_read = read(sock, buf, BUFSIZ)) > 0) {
if (buf[strlen(buf) - 1] == '\n')
buf[strlen(buf) - 1] = '\0';
debug_print("Ping result: %s\n", buf);
if (strcmp("PONG", buf) == 0)
connect = TRUE;
}
close_socket();
create_socket();
if (sock < 0) {
debug_print("no connection\n");
return NO_CONNECTION;
}
if (write(sock, version, strlen(version)) == -1) {
debug_print("no connection\n");
return NO_CONNECTION;
}
memset(buf, '\0', sizeof(buf));
while ((n_read = read(sock, buf, BUFSIZ)) > 0) {
if (buf[strlen(buf) - 1] == '\n')
buf[strlen(buf) - 1] = '\0';
debug_print("Version: %s\n", buf);
}
close_socket();
/*debug_set_mode(FALSE);*/
return (connect) ? OK : NO_CONNECTION;
}
static Clamd_Stat clamd_stream_scan(
const gchar* path, gchar** res, ssize_t size) {
int fd;
ssize_t count;
gchar buf[BUFSIZ];
int n_read;
int32_t chunk;
debug_print("Scanning: %s\n", path);
memset(buf, '\0', sizeof(buf));
if (! res || size < 1) {
return SCAN_ERROR;
}
if (! *res)
*res = g_new(gchar, size);
memset(*res, '\0', size);
if (! g_file_test(path, G_FILE_TEST_EXISTS)) {
*res = g_strconcat("ERROR -> ", path, _(": File does not exist"), NULL);
debug_print("res: %s\n", *res);
return SCAN_ERROR;
}
#ifdef _LARGE_FILES
fd = open(path, O_RDONLY, O_LARGEFILE);
#else
fd = open(path, O_RDONLY);
#endif
if (fd < 0) {
/*g_error("%s: Unable to open", path);*/
*res = g_strconcat("ERROR -> ", path, _(": Unable to open"), NULL);
return SCAN_ERROR;
}
debug_print("command: %s\n", instream);
if (write(sock, instream, strlen(instream) + 1) == -1) {
close(fd);
return NO_CONNECTION;
}
while ((count = read(fd, (void *) buf, sizeof(buf))) > 0) {
if (count == -1) {
close(fd);
*res = g_strconcat("ERROR -> ", path, _("%s: Error reading"), NULL);
return SCAN_ERROR;
}
if (buf[strlen(buf) - 1] == '\n')
buf[strlen(buf) - 1] = '\0';
debug_print("read: %ld bytes\n", count);
debug_print("chunk size: %ld\n", count);
chunk = htonl(count);
if (write(sock, &chunk, 4) == -1) {
close(fd);
*res = g_strconcat("ERROR -> ", _("Socket write error"), NULL);
return SCAN_ERROR;
}
if (write(sock, buf, count) == -1) {
close(fd);
*res = g_strconcat("ERROR -> ", _("Socket write error"), NULL);
return SCAN_ERROR;
}
memset(buf, '\0', sizeof(buf));
}
close(fd);
chunk = htonl(0);
if (write(sock, &chunk, 4) == -1) {
*res = g_strconcat("ERROR -> ", _("Socket write error"), NULL);
return SCAN_ERROR;
}
debug_print("reading from socket\n");
n_read = read(sock, *res, size);
if (n_read < 0) {
*res = g_strconcat("ERROR -> ", _("Socket read error"), NULL);
return SCAN_ERROR;
}
debug_print("received: %s\n", *res);
return OK;
}
Clamd_Stat clamd_verify_email(const gchar* path, response* result) {
gchar buf[BUFSIZ];
int n_read;
gchar* command;
Clamd_Stat stat;
/*debug_set_mode(TRUE);*/
if (!result) {
result = malloc(sizeof(response *));
memset(result, '\0', sizeof(response *));
}
create_socket();
if (sock < 0) {
debug_print("no connection\n");
return NO_CONNECTION;
}
memset(buf, '\0', sizeof(buf));
if (Socket->type == INET_SOCKET) {
gchar* tmp = g_new0(gchar, BUFSIZ);
stat = clamd_stream_scan(path, &tmp, BUFSIZ);
if (stat != OK) {
close_socket();
result->msg = g_strdup(tmp);
g_free(tmp);
debug_print("result: %s\n", result->msg);
/*debug_set_mode(FALSE);*/
return stat;
}
debug_print("copy to buf: %s\n", tmp);
memcpy(&buf, tmp, BUFSIZ);
g_free(tmp);
}
else {
command = g_strconcat(scan, " ", path, "\n", NULL);
debug_print("command: %s\n", command);
if (write(sock, command, strlen(command)) == -1) {
debug_print("no connection\n");
stat = NO_CONNECTION;
}
g_free(command);
memset(buf, '\0', sizeof(buf));
while ((n_read = read(sock, buf, BUFSIZ)) > 0) {
if (buf[strlen(buf) - 1] == '\n')
buf[strlen(buf) - 1] = '\0';
}
}
debug_print("response: %s\n", buf);
if (strstr(buf, "ERROR")) {
stat = SCAN_ERROR;
result->msg = g_strdup(buf);
}
else if (strstr(buf, "FOUND")) {
stat = VIRUS;
result->msg = g_strdup(buf);
}
else {
stat = OK;
result->msg = NULL;
}
close_socket();
/*debug_set_mode(FALSE);*/
return stat;
}
GSList* clamd_verify_dir(const gchar* path) {
gchar buf[BUFSIZ];
int n_read;
gchar* command;
GSList *list = NULL;
if (Socket->type == INET_SOCKET)
return list;
create_socket();
if (sock < 0) {
debug_print("No socket\n");
return list;
}
command = g_strconcat(contscan, path, "\n", NULL);
debug_print("command: %s\n", command);
if (write(sock, command, strlen(command)) == -1) {
debug_print("No socket\n");
return list;
}
g_free(command);
memset(buf, '\0', sizeof(buf));
while ((n_read = read(sock, buf, BUFSIZ)) > 0) {
gchar** tmp = g_strsplit(buf, "\n", 0);
gchar** head = tmp;
while (*tmp) {
gchar* file = *tmp++;
debug_print("%s\n", file);
if (strstr(file, "ERROR")) {
g_warning("%s", file);
/* dont report files with errors */
}
else if (strstr(file, "FOUND")) {
list = g_slist_append(list, g_strdup(file));
}
}
g_strfreev(head);
}
close_socket();
return list;
}
void clamd_free_gslist(GSList* list) {
GSList* tmp = list;
while(tmp) {
g_free(tmp->data);
tmp = g_slist_next(tmp);
}
g_slist_free(list);
}
gchar* clamd_get_virus_name(gchar* msg) {
gchar *head, *tail, *name;
tail = g_strrstr_len(msg, strlen(msg), "FOUND");
if (! tail)
return NULL;
head = g_strstr_len(msg, strlen(msg), ":");
++head;
name = g_strndup(head, tail - head);
g_strstrip(name);
return name;
}
void clamd_free() {
/*
* struct _Clamd_Socket {
* Type type;
* union {
* struct {
* gchar* path;
* };
* struct {
* gchar* host;
* int port;
* };
* } socket;
* };
*/
if (sock > 0) {
close_socket();
sock = 0;
}
if (Socket) {
switch (Socket->type) {
case UNIX_SOCKET:
if (Socket->socket.path) {
g_free(Socket->socket.path);
Socket->socket.path = NULL;
}
break;
case INET_SOCKET:
if (Socket->socket.host) {
g_free(Socket->socket.host);
Socket->socket.host = NULL;
}
break;
}
g_free(Socket);
Socket = NULL;
}
if (config) {
clamd_config_free(config);
config = NULL;
}
}
Config* clamd_config_new() {
return g_new0(Config, 1);
}
void clamd_config_free(Config* c) {
if (c->ConfigType == AUTOMATIC) {
g_free(c->automatic.folder);
c->automatic.folder = NULL;
}
else {
g_free(c->manual.host);
c->manual.host = NULL;
}
g_free(c);
}
gchar* int2char(int i) {
gchar* s = g_new0(gchar, 5);
sprintf(s, "%d", i);
return s;
}
gchar* long2char(long l) {
gchar* s = g_new0(gchar, 5);
debug_print("l: %ld\n", l);
sprintf(s, "%ld", l);
debug_print("s: %s\n", s);
return s;
}
--- NEW FILE: clamd-plugin.h ---
/* vim: set textwidth=80 tabstop=4: */
/*
* Claws Mail -- a GTK+ based, lightweight, and fast e-mail client
* Copyright (C) 1999-2008 Michael Rasmussen and the Claws Mail Team
*
* This program 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 3 of the License, or
* (at your option) any later version.
*
* This program 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, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef __CLAMD_PLUGIN_H__
#define __CLAMD_PLUGIN_H__
#include <glib.h>
typedef enum _Type Type;
enum _Type { UNIX_SOCKET, INET_SOCKET };
typedef enum _Clamd_Stat Clamd_Stat;
enum _Clamd_Stat { OK, VIRUS, NO_SOCKET, NO_CONNECTION, SCAN_ERROR };
typedef struct _Clamd_Socket Clamd_Socket;
struct _Clamd_Socket {
Type type;
union {
struct {
gchar* path;
};
struct {
gchar* host;
int port;
};
} socket;
};
typedef struct {
enum { AUTOMATIC, MANUAL } ConfigType;
union {
struct {
gchar* folder;
} automatic;
struct {
gchar* host;
int port;
} manual;
};
} Config;
typedef struct _response response;
struct _response {
gchar* msg;
};
void clamd_create_config_automatic(const gchar* path);
void clamd_create_config_manual(const gchar* host, int port);
gchar* int2char(int i);
gchar* long2char(long l);
/**
* Function which looks for clamd.conf the default places
* and configures the plugin according to the information
* found.
* @return <b>TRUE</b> if clamd.conf found which means all
* information need to make a connection has been found.
* <b>FALSE</b> otherwise.
*/
gboolean clamd_find_socket();
/**
* Function to get current configuration
* @return the current configuration for clamd or <b>NULL</b>
*/
Config* clamd_get_config();
/**
* Function to retrieve virus name from msg
* @param msg Message returned from clamd
* @return virus name or <b>NULL</b> if no virus name found
*/
gchar* clamd_get_virus_name(gchar* msg);
/**
* Function to initialize the connection to clamd.
* @param config A pointer to a struct _Clamd_Socket having
* the required information. If clamd_find_socket returned
* TRUE config should be <b>NULL</b> because all the needed
* information is already present @see clamd_find_socket.
* @return Clamd_Stat. @see _Clamd_Stat.
*/
Clamd_Stat clamd_init(Clamd_Socket* config);
/**
* Function returning the current socket information.
* @return reference to the current Clamd_Socket. @see _Clamd_Socket.
*/
Clamd_Socket* clamd_get_socket();
/**
* Function which is checks a specific email for known viruses
* @param path Absolut path to email to check.
* @param msg String to which result of scan will be copied. Will be
* <b>NULL</b> if no virus was found.
* @return Clamd_Stat. @see _Clamd_Stat.
*/
Clamd_Stat clamd_verify_email(const gchar* path, response* result);
/**
* Function which is checks files in a specific directory for
* known viruses. Dont stop when a virus is found but keeps going
* @param path Absolut path to directory to check.
* @return list of list with virus or <b>NULL</b>.
*/
GSList* clamd_verify_dir(const gchar* path);
/**
* Function to free all memory assigned to a GSList
* @param list The GSList to free
*/
void clamd_free_gslist(GSList* list);
/**
* Function which frees all memory assigned to clamd_plugin
*/
void clamd_free();
Config* clamd_config_new();
void clamd_config_free(Config* c);
#endif
More information about the Commits
mailing list