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