Imported Upstream version 3.3.3
[debian/amanda] / device-src / directtcp-connection.c
1 /*
2  * Copyright (c) 2009-2012 Zmanda, Inc.  All Rights Reserved.
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful, but
10  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
11  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12  * for more details.
13  *
14  * You should have received a copy of the GNU General Public License along
15  * with this program; if not, write to the Free Software Foundation, Inc.,
16  * 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
17  *
18  * Contact information: Zmanda Inc., 465 N Mathlida Ave, Suite 300
19  * Sunnyvale, CA 94085, USA, or: http://www.zmanda.com
20  */
21
22 #include "amanda.h"
23 #include "directtcp-connection.h"
24 #include <glib-object.h>
25
26 /*
27  * DirectTCPConnection class implementation
28  */
29
30 static GObjectClass *parent_class = NULL;
31
32 static void
33 directtcp_connection_finalize(GObject *goself)
34 {
35     DirectTCPConnection *self = DIRECTTCP_CONNECTION(goself);
36
37     /* close this socket if necessary, failing fatally if that doesn't work */
38     if (!self->closed) {
39         char *errmsg;
40
41         g_warning("connection freed without being closed first; any error will be fatal");
42         errmsg = directtcp_connection_close(self);
43         if (errmsg)
44             error("while closing directtcp connection: %s", errmsg);
45     }
46
47     G_OBJECT_CLASS(parent_class)->finalize(goself);
48 }
49
50 static void
51 directtcp_connection_class_init(
52         DirectTCPConnectionClass * c)
53 {
54     GObjectClass *goc = (GObjectClass *)c;
55
56     goc->finalize =  directtcp_connection_finalize;
57
58     parent_class = g_type_class_peek_parent(c);
59 }
60
61 GType
62 directtcp_connection_get_type(void)
63 {
64     static GType type = 0;
65     if G_UNLIKELY(type == 0) {
66         static const GTypeInfo info = {
67             sizeof (DirectTCPConnectionClass),
68             (GBaseInitFunc) NULL,
69             (GBaseFinalizeFunc) NULL,
70             (GClassInitFunc) directtcp_connection_class_init,
71             (GClassFinalizeFunc) NULL,
72             NULL /* class_data */,
73             sizeof (DirectTCPConnection),
74             0 /* n_preallocs */,
75             (GInstanceInitFunc) NULL,
76             NULL
77         };
78
79         type = g_type_register_static (G_TYPE_OBJECT, "DirectTCPConnection", &info,
80                                        (GTypeFlags)G_TYPE_FLAG_ABSTRACT);
81     }
82     return type;
83 }
84
85 char *
86 directtcp_connection_close(
87     DirectTCPConnection *self)
88 {
89     DirectTCPConnectionClass *klass = DIRECTTCP_CONNECTION_GET_CLASS(self);
90     char *rv;
91
92     /* Note that this also tracks the 'closed' value, which is used by finalize
93      * to ensure that the connection has been closed */
94
95     g_assert(!self->closed);
96
97     g_assert(klass->close);
98     rv = klass->close(self);
99     self->closed = TRUE;
100     return rv;
101 }
102
103 /*
104  * DirectTCPConnSocket class implementation
105  */
106
107 DirectTCPConnectionSocket *
108 directtcp_connection_socket_new(
109     int socket)
110 {
111     DirectTCPConnectionSocket *conn = DIRECTTCP_CONNECTION_SOCKET(g_object_new(TYPE_DIRECTTCP_CONNECTION_SOCKET, NULL));
112     conn->socket = socket;
113     return conn;
114 }
115
116 static char *
117 directtcp_connection_socket_close(DirectTCPConnection *dself)
118 {
119     DirectTCPConnectionSocket *self = DIRECTTCP_CONNECTION_SOCKET(dself);
120     if (self->socket >= 0 && close(self->socket)) {
121         return g_strdup_printf("while closing socket: %s", strerror(errno));
122     }
123     self->socket = -1;
124
125     return NULL;
126 }
127
128 static void
129 directtcp_connection_socket_init(DirectTCPConnectionSocket *self)
130 {
131     self->socket = -1;
132 }
133
134 static void
135 directtcp_connection_socket_class_init(DirectTCPConnectionSocketClass * c)
136 {
137     DirectTCPConnectionClass *connc = (DirectTCPConnectionClass *)c;
138
139     connc->close = directtcp_connection_socket_close;
140 }
141
142 GType
143 directtcp_connection_socket_get_type (void)
144 {
145     static GType type = 0;
146
147     if G_UNLIKELY(type == 0) {
148         static const GTypeInfo info = {
149             sizeof (DirectTCPConnectionSocketClass),
150             (GBaseInitFunc) NULL,
151             (GBaseFinalizeFunc) NULL,
152             (GClassInitFunc) directtcp_connection_socket_class_init,
153             (GClassFinalizeFunc) NULL,
154             NULL /* class_data */,
155             sizeof (DirectTCPConnectionSocket),
156             0 /* n_preallocs */,
157             (GInstanceInitFunc) directtcp_connection_socket_init,
158             NULL
159         };
160
161         type = g_type_register_static(TYPE_DIRECTTCP_CONNECTION,
162                                 "DirectTCPConnectionSocket", &info, (GTypeFlags)0);
163     }
164
165     return type;
166 }