~ubuntu-branches/ubuntu/feisty/clamav/feisty

« back to all changes in this revision

Viewing changes to freshclam/notify.c

  • Committer: Bazaar Package Importer
  • Author(s): Kees Cook
  • Date: 2007-02-20 10:33:44 UTC
  • mto: This revision was merged to the branch mainline in revision 16.
  • Revision ID: james.westby@ubuntu.com-20070220103344-zgcu2psnx9d98fpa
Tags: upstream-0.90
ImportĀ upstreamĀ versionĀ 0.90

Show diffs side-by-side

added added

removed removed

Lines of Context:
2
2
 *  Copyright (C) 2002 - 2005 Tomasz Kojm <tkojm@clamav.net>
3
3
 *
4
4
 *  This program is free software; you can redistribute it and/or modify
5
 
 *  it under the terms of the GNU General Public License version 2 as
6
 
 *  published by the Free Software Foundation.
 
5
 *  it under the terms of the GNU General Public License as published by
 
6
 *  the Free Software Foundation; either version 2 of the License, or
 
7
 *  (at your option) any later version.
7
8
 *
8
9
 *  This program is distributed in the hope that it will be useful,
9
10
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
23
24
#ifdef BUILD_CLAMD
24
25
 
25
26
#include <stdio.h>
26
 
#ifdef  HAVE_UNISTD_H
27
27
#include <unistd.h>
28
 
#endif
29
28
#include <sys/types.h>
30
 
#ifndef _WIN32
31
29
#include <sys/socket.h>
32
30
#include <sys/un.h>
33
31
#include <netinet/in.h>
34
32
#include <arpa/inet.h>
35
33
#include <netdb.h>
36
 
#endif
37
34
#include <string.h>
38
 
#include <errno.h>
39
35
 
40
 
#include "shared/optparser.h"
 
36
#include "shared/cfgparser.h"
41
37
#include "shared/output.h"
42
 
#include "shared/clamdcom.h"
43
 
 
44
38
#include "notify.h"
45
39
 
46
 
int clamd_connect(const char *cfgfile, const char *option)
 
40
int notify(const char *cfgfile)
47
41
{
48
 
#ifndef _WIN32
 
42
        char buff[20];
49
43
        struct sockaddr_un server;
50
 
#endif
51
 
#ifdef HAVE_GETADDRINFO
52
 
        struct addrinfo hints, *res;
53
 
        char port[6];
54
 
        const char *addr;
55
 
        int ret;
56
 
#else
57
44
        struct sockaddr_in server2;
58
45
        struct hostent *he;
59
 
#endif
60
 
        struct optstruct *opts;
61
 
        const struct optstruct *opt;
 
46
        struct cfgstruct *copt, *cpt;
62
47
        int sockd, bread;
63
 
        const char *socktype;
64
 
 
65
 
 
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);
68
 
        return -11;
 
48
        char *socktype;
 
49
 
 
50
 
 
51
    if((copt = getcfg(cfgfile, 1)) == NULL) {
 
52
        logg("^Clamd was NOT notified: Can't find or parse configuration file %s\n", cfgfile);
 
53
        return 1;
69
54
    }
70
55
 
71
 
#ifndef _WIN32
72
 
    if((opt = optget(opts, "LocalSocket"))->enabled) {
 
56
    if((cpt = cfgopt(copt, "LocalSocket"))->enabled) {
73
57
        socktype = "UNIX";
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));
77
60
 
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()");
81
 
            optfree(opts);
82
 
            return -1;
 
64
            return 1;
83
65
        }
84
66
 
85
67
        if(connect(sockd, (struct sockaddr *) &server, sizeof(struct sockaddr_un)) < 0) {
86
 
            closesocket(sockd);
87
 
            logg("^Clamd was NOT notified: Can't connect to clamd through %s\n", opt->strarg);
 
68
            close(sockd);
 
69
            logg("^Clamd was NOT notified: Can't connect to clamd through %s\n", cpt->strarg);
88
70
            perror("connect()");
89
 
            optfree(opts);
90
 
            return -11;
 
71
            return 1;
91
72
        }
92
73
 
93
 
    } else
94
 
#endif
95
 
    if((opt = optget(opts, "TCPSocket"))->enabled) {
 
74
    } else if((cpt = cfgopt(copt, "TCPSocket"))->enabled) {
 
75
 
96
76
        socktype = "TCP";
97
 
 
98
 
#ifdef HAVE_GETADDRINFO
99
 
        memset(&hints, 0, sizeof(hints));
100
 
/*
101
 
#ifdef SUPPORT_IPv6
102
 
        hints.ai_family = AF_UNSPEC;
 
77
#ifdef PF_INET
 
78
        if((sockd = socket(PF_INET, SOCK_STREAM, 0)) < 0) {
103
79
#else
104
 
*/
105
 
        hints.ai_family = AF_INET;
106
 
        hints.ai_socktype = SOCK_STREAM;
107
 
        snprintf(port, sizeof(port), "%u", (unsigned int) opt->numarg);
108
 
        port[5] = 0;
109
 
 
110
 
        if((opt = optget(opts, "TCPAddr"))->enabled)
111
 
            addr = opt->strarg;
112
 
        else
113
 
            addr = NULL;
114
 
 
115
 
        ret = getaddrinfo(addr, port, &hints, &res);
116
 
 
117
 
        if(ret) {
118
 
            logg("!%s: Can't resolve hostname %s (%s)\n", option, addr ? addr : "", (ret == EAI_SYSTEM) ? strerror(errno) : gai_strerror(ret));
119
 
            optfree(opts);
120
 
            return -1;
121
 
        }
122
 
 
123
 
        if((sockd = socket(res->ai_family, SOCK_STREAM, 0)) < 0) {
124
 
            perror("socket()");
125
 
            logg("!%s: Can't create TCP socket\n", option);
126
 
            optfree(opts);
127
 
            freeaddrinfo(res);
128
 
            return -1;
129
 
        }
130
 
 
131
 
        if(connect(sockd, res->ai_addr, res->ai_addrlen) == -1) {
132
 
            perror("connect()");
133
 
            closesocket(sockd);
134
 
            logg("!%s: Can't connect to clamd on %s:%s\n", option, addr ? addr : "localhost", port);
135
 
            optfree(opts);
136
 
            freeaddrinfo(res);
137
 
            return -1;
138
 
        }
139
 
        freeaddrinfo(res);
140
 
 
141
 
#else /* IPv4 */
142
 
 
143
80
        if((sockd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
144
 
            logg("!%s: Can't create TCP socket\n", option);
 
81
#endif
 
82
            logg("^Clamd was NOT notified: Can't create TCP socket\n");
145
83
            perror("socket()");
146
 
            optfree(opts);
147
 
            return -1;
 
84
            return 1;
148
85
        }
149
86
 
150
87
        server2.sin_family = AF_INET;
151
 
        server2.sin_port = htons(opt->numarg);
 
88
        server2.sin_port = htons(cpt->numarg);
152
89
 
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);
157
 
                optfree(opts);
158
 
                closesocket(sockd);
159
 
                return -1;
 
93
                logg("^Clamd was NOT notified: Can't resolve hostname '%s'\n", cpt->strarg);
 
94
                return 1;
160
95
            }
161
96
            server2.sin_addr = *(struct in_addr *) he->h_addr_list[0];
162
97
        } else
164
99
 
165
100
 
166
101
        if(connect(sockd, (struct sockaddr *) &server2, sizeof(struct sockaddr_in)) < 0) {
167
 
            closesocket(sockd);
 
102
            close(sockd);
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()");
171
 
            optfree(opts);
172
 
            return -1;
 
106
            return 1;
173
107
        }
174
108
 
175
 
#endif
176
 
 
177
109
    } else {
178
 
        logg("!%s: No communication socket specified in %s\n", option, cfgfile);
179
 
        optfree(opts);
180
 
        return 1;
181
 
    }
182
 
 
183
 
    optfree(opts);
184
 
    return sockd;
185
 
}
186
 
 
187
 
int notify(const char *cfgfile)
188
 
{
189
 
        char buff[20];
190
 
        int sockd, bread;
191
 
        const char *socktype;
192
 
 
193
 
    if((sockd = clamd_connect(cfgfile, "NotifyClamd")) < 0)
194
 
        return 1;
195
 
 
196
 
    if(sendln(sockd, "RELOAD", 7) < 0) {
197
 
        logg("!NotifyClamd: Could not write to clamd socket\n");
198
 
        perror("send()");
199
 
        closesocket(sockd);
200
 
        return 1;
201
 
    }
202
 
 
 
110
        logg("^Clamd was NOT notified: No socket specified in %s\n", cfgfile);
 
111
        return 1;
 
112
    }
 
113
 
 
114
    if(write(sockd, "RELOAD", 6) < 0) {
 
115
        logg("^Clamd was NOT notified: Could not write to %s socket\n", socktype);
 
116
        perror("write()");
 
117
        close(sockd);
 
118
        return 1;
 
119
    }
 
120
 
 
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);
207
 
            closesocket(sockd);
 
125
            logg("^Clamd was NOT notified: Unknown answer from clamd: '%s'\n", buff);
 
126
            close(sockd);
208
127
            return 1;
209
128
        }
210
 
    }
211
129
 
212
 
    closesocket(sockd);
 
130
    close(sockd);
213
131
    logg("Clamd successfully notified about the update.\n");
214
132
    return 0;
215
133
}
 
134
 
216
135
#endif