]>
Commit | Line | Data |
---|---|---|
ac3d33df JK |
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 | ||
ac3d33df | 8 | #include "common.h" |
22a2d3d5 UG |
9 | |
10 | #include "streams/registry.h" | |
11 | ||
ac3d33df JK |
12 | #include "global.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 | git__on_shutdown(shutdown_stream_registry); | |
37 | return 0; | |
38 | } | |
39 | ||
40 | GIT_INLINE(void) stream_registration_cpy( | |
41 | git_stream_registration *target, | |
42 | git_stream_registration *src) | |
43 | { | |
44 | if (src) | |
45 | memcpy(target, src, sizeof(git_stream_registration)); | |
46 | else | |
47 | memset(target, 0, sizeof(git_stream_registration)); | |
48 | } | |
49 | ||
50 | int git_stream_registry_lookup(git_stream_registration *out, git_stream_t type) | |
51 | { | |
52 | git_stream_registration *target; | |
53 | int error = GIT_ENOTFOUND; | |
54 | ||
55 | assert(out); | |
56 | ||
57 | switch(type) { | |
58 | case GIT_STREAM_STANDARD: | |
59 | target = &stream_registry.callbacks; | |
60 | break; | |
61 | case GIT_STREAM_TLS: | |
62 | target = &stream_registry.tls_callbacks; | |
63 | break; | |
64 | default: | |
65 | assert(0); | |
66 | return -1; | |
67 | } | |
68 | ||
69 | if (git_rwlock_rdlock(&stream_registry.lock) < 0) { | |
70 | git_error_set(GIT_ERROR_OS, "failed to lock stream registry"); | |
71 | return -1; | |
72 | } | |
73 | ||
74 | if (target->init) { | |
75 | stream_registration_cpy(out, target); | |
76 | error = 0; | |
77 | } | |
78 | ||
79 | git_rwlock_rdunlock(&stream_registry.lock); | |
80 | return error; | |
81 | } | |
82 | ||
83 | int git_stream_register(git_stream_t type, git_stream_registration *registration) | |
84 | { | |
85 | assert(!registration || registration->init); | |
86 | ||
87 | GIT_ERROR_CHECK_VERSION(registration, GIT_STREAM_VERSION, "stream_registration"); | |
88 | ||
89 | if (git_rwlock_wrlock(&stream_registry.lock) < 0) { | |
90 | git_error_set(GIT_ERROR_OS, "failed to lock stream registry"); | |
91 | return -1; | |
92 | } | |
93 | ||
94 | if ((type & GIT_STREAM_STANDARD) == GIT_STREAM_STANDARD) | |
95 | stream_registration_cpy(&stream_registry.callbacks, registration); | |
96 | ||
97 | if ((type & GIT_STREAM_TLS) == GIT_STREAM_TLS) | |
98 | stream_registration_cpy(&stream_registry.tls_callbacks, registration); | |
99 | ||
100 | git_rwlock_wrunlock(&stream_registry.lock); | |
101 | return 0; | |
102 | } | |
103 | ||
22a2d3d5 | 104 | #ifndef GIT_DEPRECATE_HARD |
ac3d33df JK |
105 | int git_stream_register_tls( |
106 | int GIT_CALLBACK(ctor)(git_stream **out, const char *host, const char *port)) | |
107 | { | |
108 | git_stream_registration registration = {0}; | |
109 | ||
110 | if (ctor) { | |
111 | registration.version = GIT_STREAM_VERSION; | |
112 | registration.init = ctor; | |
113 | registration.wrap = NULL; | |
114 | ||
115 | return git_stream_register(GIT_STREAM_TLS, ®istration); | |
116 | } else { | |
117 | return git_stream_register(GIT_STREAM_TLS, NULL); | |
118 | } | |
119 | } | |
22a2d3d5 | 120 | #endif |