]> git.proxmox.com Git - libgit2.git/blob - src/streams/registry.c
New upstream version 0.28.1+dfsg.1
[libgit2.git] / src / streams / registry.c
1 /*
2 * Copyright (C) the libgit2 contributors. All rights reserved.
3 *
4 * This file is part of libgit2, distributed under the GNU GPL v2 with
5 * a Linking Exception. For full terms see the included COPYING file.
6 */
7
8 #include "git2/errors.h"
9
10 #include "common.h"
11 #include "global.h"
12 #include "streams/tls.h"
13 #include "streams/mbedtls.h"
14 #include "streams/openssl.h"
15 #include "streams/stransport.h"
16
17 struct stream_registry {
18 git_rwlock lock;
19 git_stream_registration callbacks;
20 git_stream_registration tls_callbacks;
21 };
22
23 static struct stream_registry stream_registry;
24
25 static void shutdown_stream_registry(void)
26 {
27 git_rwlock_free(&stream_registry.lock);
28 }
29
30 int git_stream_registry_global_init(void)
31 {
32 if (git_rwlock_init(&stream_registry.lock) < 0)
33 return -1;
34
35 git__on_shutdown(shutdown_stream_registry);
36 return 0;
37 }
38
39 GIT_INLINE(void) stream_registration_cpy(
40 git_stream_registration *target,
41 git_stream_registration *src)
42 {
43 if (src)
44 memcpy(target, src, sizeof(git_stream_registration));
45 else
46 memset(target, 0, sizeof(git_stream_registration));
47 }
48
49 int git_stream_registry_lookup(git_stream_registration *out, git_stream_t type)
50 {
51 git_stream_registration *target;
52 int error = GIT_ENOTFOUND;
53
54 assert(out);
55
56 switch(type) {
57 case GIT_STREAM_STANDARD:
58 target = &stream_registry.callbacks;
59 break;
60 case GIT_STREAM_TLS:
61 target = &stream_registry.tls_callbacks;
62 break;
63 default:
64 assert(0);
65 return -1;
66 }
67
68 if (git_rwlock_rdlock(&stream_registry.lock) < 0) {
69 git_error_set(GIT_ERROR_OS, "failed to lock stream registry");
70 return -1;
71 }
72
73 if (target->init) {
74 stream_registration_cpy(out, target);
75 error = 0;
76 }
77
78 git_rwlock_rdunlock(&stream_registry.lock);
79 return error;
80 }
81
82 int git_stream_register(git_stream_t type, git_stream_registration *registration)
83 {
84 assert(!registration || registration->init);
85
86 GIT_ERROR_CHECK_VERSION(registration, GIT_STREAM_VERSION, "stream_registration");
87
88 if (git_rwlock_wrlock(&stream_registry.lock) < 0) {
89 git_error_set(GIT_ERROR_OS, "failed to lock stream registry");
90 return -1;
91 }
92
93 if ((type & GIT_STREAM_STANDARD) == GIT_STREAM_STANDARD)
94 stream_registration_cpy(&stream_registry.callbacks, registration);
95
96 if ((type & GIT_STREAM_TLS) == GIT_STREAM_TLS)
97 stream_registration_cpy(&stream_registry.tls_callbacks, registration);
98
99 git_rwlock_wrunlock(&stream_registry.lock);
100 return 0;
101 }
102
103
104 int git_stream_register_tls(
105 int GIT_CALLBACK(ctor)(git_stream **out, const char *host, const char *port))
106 {
107 git_stream_registration registration = {0};
108
109 if (ctor) {
110 registration.version = GIT_STREAM_VERSION;
111 registration.init = ctor;
112 registration.wrap = NULL;
113
114 return git_stream_register(GIT_STREAM_TLS, &registration);
115 } else {
116 return git_stream_register(GIT_STREAM_TLS, NULL);
117 }
118 }