1 /*
2  * Copyright (c) 2002-2018 Balabit
3  * Copyright (c) 2018 Laszlo Budai <laszlo.budai@balabit.com>
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 "transport/transport-factory-id.h"
26 #include "mainloop.h"
27 
28 struct _TransportFactoryId
29 {
30   gchar *transport_name;
31   gint uniq_id;
32 };
33 
34 typedef struct _Sequence Sequence;
35 
36 struct _Sequence
37 {
38   gint ctr;
39 } sequence;
40 
41 static void
sequence_inc(Sequence * seq)42 sequence_inc(Sequence *seq)
43 {
44   seq->ctr++;
45 }
46 
47 static gint
sequence_get(Sequence * seq)48 sequence_get(Sequence *seq)
49 {
50   return seq->ctr;
51 }
52 
53 static void
sequence_reset(Sequence * seq,gint init_value)54 sequence_reset(Sequence *seq, gint init_value)
55 {
56   seq->ctr = init_value;
57 }
58 
59 static GList *transport_factory_ids;
60 GMutex transport_factory_ids_mutex;
61 
62 void
transport_factory_id_global_init(void)63 transport_factory_id_global_init(void)
64 {
65   sequence_reset(&sequence, 1);
66   g_mutex_init(&transport_factory_ids_mutex);
67 }
68 
69 static inline void
_free(gpointer s)70 _free(gpointer s)
71 {
72   transport_factory_id_free((TransportFactoryId *)s);
73 }
74 
75 void
transport_factory_id_global_deinit(void)76 transport_factory_id_global_deinit(void)
77 {
78   g_list_free_full(transport_factory_ids, _free);
79   transport_factory_ids = NULL;
80   g_mutex_clear(&transport_factory_ids_mutex);
81 }
82 
83 void
_transport_factory_id_register(TransportFactoryId * id)84 _transport_factory_id_register(TransportFactoryId *id)
85 {
86   transport_factory_ids = g_list_append(transport_factory_ids, id);
87 }
88 
89 static gpointer
_clone(gconstpointer s)90 _clone(gconstpointer s)
91 {
92   TransportFactoryId *id = (TransportFactoryId *)s;
93   TransportFactoryId *cloned = g_new0(TransportFactoryId, 1);
94 
95   cloned->transport_name = g_strdup(id->transport_name);
96   cloned->uniq_id = id->uniq_id;
97 
98   return cloned;
99 }
100 
101 TransportFactoryId *
_transport_factory_id_clone(const TransportFactoryId * id)102 _transport_factory_id_clone(const TransportFactoryId *id)
103 {
104   return (TransportFactoryId *)_clone((gconstpointer) id);
105 }
106 
107 static gpointer
_copy_func(gconstpointer src,gpointer data)108 _copy_func(gconstpointer src, gpointer data)
109 {
110   return _clone(src);
111 }
112 
113 GList *
_transport_factory_id_clone_registered_ids(void)114 _transport_factory_id_clone_registered_ids(void)
115 {
116   return g_list_copy_deep(transport_factory_ids, _copy_func, NULL);
117 }
118 
119 void
transport_factory_id_free(TransportFactoryId * id)120 transport_factory_id_free(TransportFactoryId *id)
121 {
122   g_free(id->transport_name);
123   g_free(id);
124 }
125 
126 guint
transport_factory_id_hash(gconstpointer key)127 transport_factory_id_hash(gconstpointer key)
128 {
129   TransportFactoryId *id = (TransportFactoryId *)key;
130   return g_direct_hash(GINT_TO_POINTER(id->uniq_id));
131 }
132 
133 gboolean
transport_factory_id_equal(const TransportFactoryId * id1,const TransportFactoryId * id2)134 transport_factory_id_equal(const TransportFactoryId *id1, const TransportFactoryId *id2)
135 {
136   return (id1->uniq_id == id2->uniq_id) ? TRUE : FALSE;
137 }
138 
139 const gchar *
transport_factory_id_get_transport_name(const TransportFactoryId * id)140 transport_factory_id_get_transport_name(const TransportFactoryId *id)
141 {
142   return id->transport_name;
143 }
144 
145 void
_transport_factory_id_lock(void)146 _transport_factory_id_lock(void)
147 {
148   g_mutex_lock(&transport_factory_ids_mutex);
149 }
150 
151 void
_transport_factory_id_unlock(void)152 _transport_factory_id_unlock(void)
153 {
154   g_mutex_unlock(&transport_factory_ids_mutex);
155 }
156 
157 TransportFactoryId *
_transport_factory_id_new(const gchar * transport_name)158 _transport_factory_id_new(const gchar *transport_name)
159 {
160   TransportFactoryId *id = g_new0(TransportFactoryId, 1);
161 
162   sequence_inc(&sequence);
163   id->transport_name = g_strdup(transport_name);
164   id->uniq_id = sequence_get(&sequence);
165 
166   return id;
167 }
168