v2003-06-09 Moritz Schulte <moritz@g10code.com>
[libgcrypt.git] / src / module.c
1 /* module.c - Module management for libgcrypt.
2  * Copyright (C) 2003 Free Software Foundation, Inc.
3  *
4  * This file is part of Libgcrypt.
5  *
6  * Libgcrypt is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU Lesser general Public License as
8  * published by the Free Software Foundation; either version 2.1 of
9  * the License, or (at your option) any later version.
10  *
11  * Libgcrypt is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
19  */
20
21 #include <assert.h>
22 #include <config.h>
23 #include <errno.h>
24 #include "g10lib.h"
25
26 /* Public function.  Add a module specification to the list ENTRIES.
27    The new module has it's use-counter set to one.  */
28 gpg_err_code_t
29 _gcry_module_add (GcryModule **entries, void *spec,
30                   GcryModule **module)
31 {
32   gpg_err_code_t err = 0;
33   GcryModule *entry;
34
35   entry = gcry_malloc (sizeof (GcryModule));
36   if (! entry)
37     err = gpg_err_code_from_errno (errno);
38   else
39     {
40       /* Fill new module entry.  */
41       entry->flags = 0;
42       entry->counter = 1;
43       entry->spec = spec;
44
45       /* Link it into the list.  */
46       entry->next = *entries;
47       entry->prevp = entries;
48       if (*entries)
49         (*entries)->prevp = &entry->next;
50       *entries = entry;
51
52       /* And give it to the caller.  */
53       if (module)
54         *module = entry;
55     }
56   return err;
57 }
58
59 /* Internal function.  Unlink CIPHER_ENTRY from the list of registered
60    ciphers and destroy it.  */
61 static void
62 _gcry_module_drop (GcryModule *entry)
63 {
64   *entry->prevp = entry->next;
65   if (entry->next)
66     entry->next->prevp = entry->prevp;
67
68   gcry_free (entry);
69 }
70
71 /* Public function.  Lookup a module specification.  After a
72    successfull lookup, the module has it's resource counter
73    incremented.  FUNC is a function provided by the caller, which is
74    responsible for identifying the wanted module.  */
75 GcryModule *
76 _gcry_module_lookup (GcryModule *entries, void *data,
77                      GcryModuleLookup func)
78 {
79   GcryModule *entry;
80
81   for (entry = entries; entry; entry = entry->next)
82     if ((*func) (entry->spec, data))
83       {
84         entry->counter++;
85         break;
86       }
87
88   return entry;
89 }
90
91 /* Public function.  Release a module.  In case the use-counter
92    reaches zero, destroy the module.  */
93 void
94 _gcry_module_release (GcryModule *module)
95 {
96   if (! --module->counter)
97     _gcry_module_drop (module);
98 }
99
100 /* Public function.  Add a reference to a module.  */
101 void
102 _gcry_module_use (GcryModule *module)
103 {
104   ++module->counter;
105 }