27
27
#include <unistd.h>
29
28
#include <sys/types.h>
31
29
#include <sys/socket.h>
32
30
#include <sys/un.h>
33
31
#include <netinet/in.h>
34
32
#include <arpa/inet.h>
37
34
#include <string.h>
40
#include "shared/optparser.h"
36
#include "shared/cfgparser.h"
41
37
#include "shared/output.h"
42
#include "shared/clamdcom.h"
44
38
#include "notify.h"
46
int clamd_connect(const char *cfgfile, const char *option)
40
int notify(const char *cfgfile)
49
43
struct sockaddr_un server;
51
#ifdef HAVE_GETADDRINFO
52
struct addrinfo hints, *res;
57
44
struct sockaddr_in server2;
58
45
struct hostent *he;
60
struct optstruct *opts;
61
const struct optstruct *opt;
46
struct cfgstruct *copt, *cpt;
66
if((opts = optparse(cfgfile, 0, NULL, 1, OPT_CLAMD, 0, NULL)) == NULL) {
67
logg("!%s: Can't find or parse configuration file %s\n", option, cfgfile);
51
if((copt = getcfg(cfgfile, 1)) == NULL) {
52
logg("^Clamd was NOT notified: Can't find or parse configuration file %s\n", cfgfile);
72
if((opt = optget(opts, "LocalSocket"))->enabled) {
56
if((cpt = cfgopt(copt, "LocalSocket"))->enabled) {
74
58
server.sun_family = AF_UNIX;
75
strncpy(server.sun_path, opt->strarg, sizeof(server.sun_path));
76
server.sun_path[sizeof(server.sun_path)-1]='\0';
59
strncpy(server.sun_path, cpt->strarg, sizeof(server.sun_path));
78
61
if((sockd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
79
logg("^Clamd was NOT notified: Can't create socket endpoint for %s\n", opt->strarg);
62
logg("^Clamd was NOT notified: Can't create socket endpoint for %s\n", cpt->strarg);
80
63
perror("socket()");
85
67
if(connect(sockd, (struct sockaddr *) &server, sizeof(struct sockaddr_un)) < 0) {
87
logg("^Clamd was NOT notified: Can't connect to clamd through %s\n", opt->strarg);
69
logg("^Clamd was NOT notified: Can't connect to clamd through %s\n", cpt->strarg);
88
70
perror("connect()");
95
if((opt = optget(opts, "TCPSocket"))->enabled) {
74
} else if((cpt = cfgopt(copt, "TCPSocket"))->enabled) {
98
#ifdef HAVE_GETADDRINFO
99
memset(&hints, 0, sizeof(hints));
102
hints.ai_family = AF_UNSPEC;
78
if((sockd = socket(PF_INET, SOCK_STREAM, 0)) < 0) {
105
hints.ai_family = AF_INET;
106
hints.ai_socktype = SOCK_STREAM;
107
snprintf(port, sizeof(port), "%u", (unsigned int) opt->numarg);
110
if((opt = optget(opts, "TCPAddr"))->enabled)
115
ret = getaddrinfo(addr, port, &hints, &res);
118
logg("!%s: Can't resolve hostname %s (%s)\n", option, addr ? addr : "", (ret == EAI_SYSTEM) ? strerror(errno) : gai_strerror(ret));
123
if((sockd = socket(res->ai_family, SOCK_STREAM, 0)) < 0) {
125
logg("!%s: Can't create TCP socket\n", option);
131
if(connect(sockd, res->ai_addr, res->ai_addrlen) == -1) {
134
logg("!%s: Can't connect to clamd on %s:%s\n", option, addr ? addr : "localhost", port);
143
80
if((sockd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
144
logg("!%s: Can't create TCP socket\n", option);
82
logg("^Clamd was NOT notified: Can't create TCP socket\n");
145
83
perror("socket()");
150
87
server2.sin_family = AF_INET;
151
server2.sin_port = htons(opt->numarg);
88
server2.sin_port = htons(cpt->numarg);
153
if((opt = optget(opts, "TCPAddr"))->enabled) {
154
if((he = gethostbyname(opt->strarg)) == 0) {
90
if((cpt = cfgopt(copt, "TCPAddr"))->enabled) {
91
if ((he = gethostbyname(cpt->strarg)) == 0) {
155
92
perror("gethostbyname()");
156
logg("^Clamd was NOT notified: Can't resolve hostname '%s'\n", opt->strarg);
93
logg("^Clamd was NOT notified: Can't resolve hostname '%s'\n", cpt->strarg);
161
96
server2.sin_addr = *(struct in_addr *) he->h_addr_list[0];
166
101
if(connect(sockd, (struct sockaddr *) &server2, sizeof(struct sockaddr_in)) < 0) {
168
103
logg("^Clamd was NOT notified: Can't connect to clamd on %s:%d\n",
169
104
inet_ntoa(server2.sin_addr), ntohs(server2.sin_port));
170
105
perror("connect()");
178
logg("!%s: No communication socket specified in %s\n", option, cfgfile);
187
int notify(const char *cfgfile)
191
const char *socktype;
193
if((sockd = clamd_connect(cfgfile, "NotifyClamd")) < 0)
196
if(sendln(sockd, "RELOAD", 7) < 0) {
197
logg("!NotifyClamd: Could not write to clamd socket\n");
110
logg("^Clamd was NOT notified: No socket specified in %s\n", cfgfile);
114
if(write(sockd, "RELOAD", 6) < 0) {
115
logg("^Clamd was NOT notified: Could not write to %s socket\n", socktype);
121
/* TODO: Handle timeout */
203
122
memset(buff, 0, sizeof(buff));
204
if((bread = recv(sockd, buff, sizeof(buff), 0)) > 0) {
123
if((bread = read(sockd, buff, sizeof(buff))) > 0)
205
124
if(!strstr(buff, "RELOADING")) {
206
logg("!NotifyClamd: Unknown answer from clamd: '%s'\n", buff);
125
logg("^Clamd was NOT notified: Unknown answer from clamd: '%s'\n", buff);
213
131
logg("Clamd successfully notified about the update.\n");