~ubuntu-branches/ubuntu/trusty/syslog-ng/trusty-proposed

« back to all changes in this revision

Viewing changes to src/gsocket.c

  • Committer: Bazaar Package Importer
  • Author(s): Laszlo Boszormenyi (GCS)
  • Date: 2010-03-14 12:57:49 UTC
  • mfrom: (1.3.1 upstream) (12.1.1 experimental)
  • Revision ID: james.westby@ubuntu.com-20100314125749-m3ats648sp2urg0f
Tags: 3.0.5-1
New upstream release, new maintainer.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (c) 2002-2009 BalaBit IT Ltd, Budapest, Hungary
 
3
 *
 
4
 * This program is free software; you can redistribute it and/or modify it
 
5
 * under the terms of the GNU General Public License version 2 as published
 
6
 * by the Free Software Foundation.
 
7
 *
 
8
 * Note that this permission is granted for only version 2 of the GPL.
 
9
 *
 
10
 * As an additional exemption you are allowed to compile & link against the
 
11
 * OpenSSL libraries as published by the OpenSSL project. See the file
 
12
 * COPYING for details.
 
13
 *
 
14
 * This program is distributed in the hope that it will be useful,
 
15
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
16
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
17
 * GNU General Public License for more details.
 
18
 *
 
19
 * You should have received a copy of the GNU General Public License
 
20
 * along with this program; if not, write to the Free Software
 
21
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
22
 */
 
23
 
 
24
#include "gsocket.h"
 
25
#include <arpa/inet.h>
 
26
 
 
27
 
 
28
typedef struct _GListenSource
 
29
{
 
30
  GSource super;
 
31
  GPollFD pollfd;
 
32
} GListenSource;
 
33
 
 
34
static gboolean
 
35
g_listen_prepare(GSource *source,
 
36
                 gint *timeout)
 
37
{
 
38
  GListenSource *self = (GListenSource *) source;
 
39
 
 
40
  self->pollfd.events = G_IO_IN;
 
41
  self->pollfd.revents = 0;
 
42
  *timeout = -1;
 
43
  return FALSE;
 
44
}
 
45
 
 
46
static gboolean
 
47
g_listen_check(GSource *source)
 
48
{
 
49
  GListenSource *self = (GListenSource *) source;
 
50
 
 
51
  return !!(self->pollfd.revents & (G_IO_IN | G_IO_ERR | G_IO_HUP));
 
52
}
 
53
 
 
54
static gboolean
 
55
g_listen_dispatch(GSource *source,
 
56
                  GSourceFunc callback,
 
57
                  gpointer user_data)
 
58
{
 
59
  return callback(user_data);
 
60
}
 
61
 
 
62
GSourceFuncs g_listen_source_funcs =
 
63
{
 
64
  g_listen_prepare,
 
65
  g_listen_check,
 
66
  g_listen_dispatch,
 
67
  NULL
 
68
};
 
69
 
 
70
GSource *
 
71
g_listen_source_new(gint fd)
 
72
{
 
73
  GListenSource *self = (GListenSource *) g_source_new(&g_listen_source_funcs, sizeof(GListenSource));
 
74
 
 
75
  self->pollfd.fd = fd;  
 
76
  g_source_set_priority(&self->super, LOG_PRIORITY_LISTEN);
 
77
  g_source_add_poll(&self->super, &self->pollfd);
 
78
  return &self->super;
 
79
}
 
80
 
 
81
typedef struct _GConnectSource
 
82
{
 
83
  GSource super;
 
84
  GPollFD pollfd;
 
85
} GConnectSource;
 
86
 
 
87
static gboolean
 
88
g_connect_prepare(GSource *source,
 
89
                  gint *timeout)
 
90
{
 
91
  GConnectSource *self = (GConnectSource *) source;
 
92
 
 
93
  self->pollfd.events = G_IO_OUT;
 
94
  self->pollfd.revents = 0;
 
95
  *timeout = -1;
 
96
  return FALSE;
 
97
}
 
98
 
 
99
static gboolean
 
100
g_connect_check(GSource *source)
 
101
{
 
102
  GConnectSource *self = (GConnectSource *) source;
 
103
 
 
104
  return !!(self->pollfd.revents & (G_IO_OUT | G_IO_ERR | G_IO_HUP));
 
105
}
 
106
 
 
107
static gboolean
 
108
g_connect_dispatch(GSource *source,
 
109
                   GSourceFunc callback,
 
110
                   gpointer user_data)
 
111
{
 
112
  callback(user_data);
 
113
  return FALSE;
 
114
}
 
115
 
 
116
GSourceFuncs g_connect_source_funcs =
 
117
{
 
118
  g_connect_prepare,
 
119
  g_connect_check,
 
120
  g_connect_dispatch,
 
121
  NULL
 
122
};
 
123
 
 
124
GSource *
 
125
g_connect_source_new(gint fd)
 
126
{
 
127
  GConnectSource *self = (GConnectSource *) g_source_new(&g_connect_source_funcs, sizeof(GConnectSource));
 
128
 
 
129
  self->pollfd.fd = fd;  
 
130
  g_source_set_priority(&self->super, LOG_PRIORITY_CONNECT);
 
131
  g_source_add_poll(&self->super, &self->pollfd);
 
132
  return &self->super;
 
133
}
 
134
 
 
135
/**
 
136
 * g_inet_ntoa:
 
137
 * @buf:        store result in this buffer
 
138
 * @bufsize:    the available space in buf
 
139
 * @a:          address to convert.
 
140
 * 
 
141
 * Thread friendly version of inet_ntoa(), converts an IP address to
 
142
 * human readable form. Returns: the address of buf
 
143
 **/
 
144
gchar *
 
145
g_inet_ntoa(char *buf, size_t bufsize, struct in_addr a)
 
146
{
 
147
  unsigned int ip = ntohl(a.s_addr);
 
148
 
 
149
  g_snprintf(buf, bufsize, "%d.%d.%d.%d", 
 
150
             (ip & 0xff000000) >> 24,
 
151
             (ip & 0x00ff0000) >> 16,
 
152
             (ip & 0x0000ff00) >> 8,
 
153
             (ip & 0x000000ff));
 
154
  return buf;
 
155
}
 
156
 
 
157
gint
 
158
g_inet_aton(char *buf, struct in_addr *a)
 
159
{
 
160
  return inet_aton(buf, a);
 
161
}
 
162
 
 
163
/**
 
164
 * g_bind:
 
165
 * @fd:         fd to bind
 
166
 * @addr:       address to bind to
 
167
 * 
 
168
 * A thin interface around bind() using a GSockAddr structure for
 
169
 * socket address. It enables the NET_BIND_SERVICE capability (should be
 
170
 * in the permitted set.
 
171
 **/
 
172
GIOStatus 
 
173
g_bind(int fd, GSockAddr *addr)
 
174
{
 
175
  GIOStatus rc;
 
176
  
 
177
  if (addr->sa_funcs && addr->sa_funcs->sa_bind_prepare)
 
178
    addr->sa_funcs->sa_bind_prepare(fd, addr);
 
179
 
 
180
  if (addr->sa_funcs && addr->sa_funcs->sa_bind)
 
181
    rc = addr->sa_funcs->sa_bind(fd, addr);
 
182
  else
 
183
    {
 
184
      if (addr && bind(fd, &addr->sa, addr->salen) < 0)
 
185
        {
 
186
          return G_IO_STATUS_ERROR;
 
187
        }
 
188
      rc = G_IO_STATUS_NORMAL;
 
189
    }
 
190
  return rc;
 
191
}
 
192
 
 
193
/**
 
194
 * g_accept:
 
195
 * @fd:         accept connection on this socket
 
196
 * @newfd:      fd of the accepted connection
 
197
 * @addr:       store the address of the client here
 
198
 * 
 
199
 * Accept a connection on the given fd, returning the newfd and the
 
200
 * address of the client in a Zorp SockAddr structure.
 
201
 *
 
202
 *  Returns: glib style I/O error
 
203
 **/
 
204
GIOStatus 
 
205
g_accept(int fd, int *newfd, GSockAddr **addr)
 
206
{
 
207
  char sabuf[1024];
 
208
  socklen_t salen = sizeof(sabuf);
 
209
  
 
210
  do
 
211
    {
 
212
      *newfd = accept(fd, (struct sockaddr *) sabuf, &salen);
 
213
    }
 
214
  while (*newfd == -1 && errno == EINTR);
 
215
  if (*newfd != -1)
 
216
    {
 
217
      *addr = g_sockaddr_new((struct sockaddr *) sabuf, salen);
 
218
    }
 
219
  else if (errno == EAGAIN)
 
220
    {
 
221
      return G_IO_STATUS_AGAIN;
 
222
    }
 
223
  else
 
224
    {
 
225
      return G_IO_STATUS_ERROR;
 
226
    }
 
227
  return G_IO_STATUS_NORMAL;
 
228
}
 
229
 
 
230
/**
 
231
 * g_connect:
 
232
 * @fd: socket to connect 
 
233
 * @remote:  remote address
 
234
 * 
 
235
 * Connect a socket using Zorp style GSockAddr structure.
 
236
 *
 
237
 * Returns: glib style I/O error
 
238
 **/
 
239
GIOStatus 
 
240
g_connect(int fd, GSockAddr *remote)
 
241
{
 
242
  int rc;
 
243
 
 
244
  do
 
245
    {
 
246
      rc = connect(fd, &remote->sa, remote->salen);
 
247
    }
 
248
  while (rc == -1 && errno == EINTR);
 
249
  if (rc == -1)
 
250
    {
 
251
      if (errno == EAGAIN)
 
252
        return G_IO_STATUS_AGAIN;
 
253
      else
 
254
        return G_IO_STATUS_ERROR;
 
255
    }
 
256
  else
 
257
    {
 
258
      return G_IO_STATUS_NORMAL;
 
259
    }
 
260
}