~ubuntu-branches/ubuntu/oneiric/syslog-ng/oneiric

« back to all changes in this revision

Viewing changes to lib/logtransport.c

  • Committer: Bazaar Package Importer
  • Author(s): Laszlo Boszormenyi (GCS)
  • Date: 2011-05-16 22:02:46 UTC
  • mfrom: (26.1.1 sid)
  • Revision ID: james.westby@ubuntu.com-20110516220246-nknmeu831n49bx1z
Tags: 3.2.4-1
* New upstream release, fixing infinite loop via PCRE and global. No CVE
  number yet, Vigil@nce id is 10648.
* Remove all patches, they were applied upstream.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (c) 2002-2010 BalaBit IT Ltd, Budapest, Hungary
 
3
 * Copyright (c) 1998-2010 Balázs Scheidler
 
4
 *
 
5
 * This library is free software; you can redistribute it and/or
 
6
 * modify it under the terms of the GNU Lesser General Public
 
7
 * License as published by the Free Software Foundation; either
 
8
 * version 2.1 of the License, or (at your option) any later version.
 
9
 *
 
10
 * This library is distributed in the hope that it will be useful,
 
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
13
 * Lesser General Public License for more details.
 
14
 *
 
15
 * You should have received a copy of the GNU Lesser General Public
 
16
 * License along with this library; if not, write to the Free Software
 
17
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 
18
 *
 
19
 * As an additional exemption you are allowed to compile & link against the
 
20
 * OpenSSL libraries as published by the OpenSSL project. See the file
 
21
 * COPYING for details.
 
22
 *
 
23
 */
 
24
 
 
25
#include "logtransport.h"
 
26
#include "messages.h"
 
27
#include "alarms.h"
 
28
 
 
29
#include <errno.h>
 
30
#include <ctype.h>
 
31
 
 
32
void
 
33
log_transport_free_method(LogTransport *s)
 
34
{
 
35
  if (((s->flags & LTF_DONTCLOSE) == 0) && s->fd != -1)
 
36
    {
 
37
      msg_verbose("Closing log transport fd",
 
38
                  evt_tag_int("fd", s->fd),
 
39
                  NULL);
 
40
      if (s->flags & LTF_SHUTDOWN)
 
41
        shutdown(s->fd, SHUT_RDWR);
 
42
      close(s->fd);
 
43
    }
 
44
}
 
45
 
 
46
void
 
47
log_transport_free(LogTransport *self)
 
48
{
 
49
  self->free_fn(self);
 
50
  g_free(self);
 
51
}
 
52
 
 
53
/* log transport that simply sends messages to an fd */
 
54
typedef struct _LogTransportPlain LogTransportPlain;
 
55
 
 
56
struct _LogTransportPlain
 
57
{
 
58
  LogTransport super;
 
59
};
 
60
 
 
61
static gssize
 
62
log_transport_plain_read_method(LogTransport *s, gpointer buf, gsize buflen, GSockAddr **sa)
 
63
{
 
64
  LogTransportPlain *self = (LogTransportPlain *) s;
 
65
  gint rc;
 
66
  
 
67
  if ((self->super.flags & LTF_RECV) == 0)
 
68
    {
 
69
      if (sa)
 
70
        *sa = NULL;
 
71
 
 
72
      do
 
73
        {
 
74
          if (self->super.timeout)
 
75
            alarm_set(self->super.timeout);
 
76
          rc = read(self->super.fd, buf, buflen);
 
77
          
 
78
          if (self->super.timeout > 0 && rc == -1 && errno == EINTR && alarm_has_fired())
 
79
            {
 
80
              msg_notice("Nonblocking read has blocked, returning with an error",
 
81
                         evt_tag_int("fd", self->super.fd),
 
82
                         evt_tag_int("timeout", self->super.timeout),
 
83
                         NULL);
 
84
              alarm_cancel();
 
85
              break;
 
86
            }
 
87
          if (self->super.timeout)
 
88
            alarm_cancel();
 
89
        }
 
90
      while (rc == -1 && errno == EINTR);
 
91
    }
 
92
  else 
 
93
    {
 
94
      union
 
95
      {
 
96
#if HAVE_STRUCT_SOCKADDR_STORAGE
 
97
        struct sockaddr_storage __sas;
 
98
#endif
 
99
        struct sockaddr __sa;
 
100
      } sas;
 
101
      
 
102
      socklen_t salen = sizeof(sas);
 
103
 
 
104
      do
 
105
        {
 
106
          rc = recvfrom(self->super.fd, buf, buflen, 0, 
 
107
                        (struct sockaddr *) &sas, &salen);
 
108
        }
 
109
      while (rc == -1 && errno == EINTR);
 
110
      if (rc != -1 && salen && sa)
 
111
        (*sa) = g_sockaddr_new((struct sockaddr *) &sas, salen);
 
112
    }
 
113
  return rc;
 
114
}
 
115
 
 
116
static gssize
 
117
log_transport_plain_write_method(LogTransport *s, const gpointer buf, gsize buflen)
 
118
{
 
119
  LogTransportPlain *self = (LogTransportPlain *) s;
 
120
  gint rc;
 
121
  
 
122
  do
 
123
    {
 
124
      if (self->super.timeout)
 
125
        alarm_set(self->super.timeout);
 
126
      if (self->super.flags & LTF_APPEND)
 
127
        lseek(self->super.fd, 0, SEEK_END);
 
128
      rc = write(self->super.fd, buf, buflen);
 
129
      if (self->super.timeout > 0 && rc == -1 && errno == EINTR && alarm_has_fired())
 
130
        {
 
131
          msg_notice("Nonblocking write has blocked, returning with an error",
 
132
                     evt_tag_int("fd", self->super.fd),
 
133
                     evt_tag_int("timeout", self->super.timeout),
 
134
                     NULL);
 
135
          alarm_cancel();
 
136
          break;
 
137
        }
 
138
      if (self->super.timeout)
 
139
        alarm_cancel();
 
140
      if (self->super.flags & LTF_FSYNC)
 
141
        fsync(self->super.fd);
 
142
    }
 
143
  while (rc == -1 && errno == EINTR);
 
144
  return rc;
 
145
}
 
146
 
 
147
 
 
148
LogTransport *
 
149
log_transport_plain_new(gint fd, guint flags)
 
150
{
 
151
  LogTransportPlain *self = g_new0(LogTransportPlain, 1);
 
152
  
 
153
  self->super.fd = fd;
 
154
  self->super.cond = 0;
 
155
  self->super.flags = flags;
 
156
  self->super.read = log_transport_plain_read_method;
 
157
  self->super.write = log_transport_plain_write_method;
 
158
  self->super.free_fn = log_transport_free_method;
 
159
  return &self->super;
 
160
}
 
161
 
 
162