File: control-client-unix.c

package info (click to toggle)
syslog-ng 4.8.1-6
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 20,456 kB
  • sloc: ansic: 177,631; python: 13,035; cpp: 11,611; makefile: 7,012; sh: 5,147; java: 3,651; xml: 3,344; yacc: 1,377; lex: 599; perl: 193; awk: 190; objc: 162
file content (129 lines) | stat: -rw-r--r-- 3,240 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
/*
 * Copyright (c) 2002-2013 Balabit
 * Copyright (c) 1998-2013 Balázs Scheidler
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 * As an additional exemption you are allowed to compile & link against the
 * OpenSSL libraries as published by the OpenSSL project. See the file
 * COPYING for details.
 *
 */

#include "control-client.h"
#include "gsocket.h"

#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>

struct _ControlClient
{
  gchar *path;
  FILE *control_socket;
  gint control_fd;
};

ControlClient *
control_client_new(const gchar *name)
{
  ControlClient *self = g_new0(ControlClient, 1);

  self->path = g_strdup(name);

  return self;
}

gboolean
control_client_connect(ControlClient *self)
{
  GSockAddr *saddr = NULL;

  if (self->control_socket != NULL)
    {
      return TRUE;
    }

  saddr = g_sockaddr_unix_new(self->path);
  self->control_fd = socket(PF_UNIX, SOCK_STREAM, 0);

  if (self->control_fd == -1)
    {
      fprintf(stderr, "Error opening control socket, socket='%s', error='%s'\n", self->path, strerror(errno));
      goto error;
    }

  if (g_connect(self->control_fd, saddr) != G_IO_STATUS_NORMAL)
    {
      fprintf(stderr, "Error connecting control socket, socket='%s', error='%s'\n", self->path, strerror(errno));
      close(self->control_fd);
      goto error;
    }
  self->control_socket = fdopen(self->control_fd, "r+");
error:
  g_sockaddr_unref(saddr);
  return !!self->control_socket;
}

gint
control_client_send_command(ControlClient *self, const gchar *cmd)
{
  return fwrite(cmd, strlen(cmd), 1, self->control_socket);
}

#define BUFF_LEN 8192

gint
control_client_read_reply(ControlClient *self, CommandResponseHandlerFunc response_handler, gpointer user_data)
{
  gint retval = 0;
  gchar buf[BUFF_LEN], *line;
  GString *chunk = g_string_sized_new(256);

  while (1)
    {
      line = fgets(buf, sizeof(buf), self->control_socket);

      if (!line)
        {
          fprintf(stderr, "Error reading or EOF occured on socket, error='%s'\n", strerror(errno));
          return 1;
        }

      if (strcmp(line, ".\n") == 0)
        break;

      g_string_assign(chunk, line);
      if (retval == 0)
        retval = response_handler(chunk, user_data);
    }

  g_string_free(chunk, TRUE);
  return retval;
}

void
control_client_free(ControlClient *self)
{
  if (self->control_socket)
    {
      fflush(self->control_socket);
      shutdown(self->control_fd, SHUT_RDWR);
      fclose(self->control_socket);
    }
  g_free(self->path);
  g_free(self);
}