]> git.proxmox.com Git - libgit2.git/blob - src/streams/registry.c
New upstream version 1.4.3+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 "common.h"
9
10 #include "streams/registry.h"
11
12 #include "runtime.h"
13 #include "streams/tls.h"
14 #include "streams/mbedtls.h"
15 #include "streams/openssl.h"
16 #include "streams/stransport.h"
17
18 struct stream_registry {
19 git_rwlock lock;
20 git_stream_registration callbacks;
21 git_stream_registration tls_callbacks;
22 };
23
24 static struct stream_registry stream_registry;
25
26 static void shutdown_stream_registry(void)
27 {
28 git_rwlock_free(&stream_registry.lock);
29 }
30
31 int git_stream_registry_global_init(void)
32 {
33 if (git_rwlock_init(&stream_registry.lock) < 0)
34 return -1;
35
36 return git_runtime_shutdown_register(shutdown_stream_registry);
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 GIT_ASSERT_ARG(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 git_error_set(GIT_ERROR_INVALID, "invalid stream type");
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 GIT_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 #ifndef GIT_DEPRECATE_HARD
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 }
119 #endif