Line Flow Count Block(s) Source
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 "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 9 2 static void shutdown_stream_registry(void)
27 - {
28 9 2 git_rwlock_free(&stream_registry.lock);
29 9 3 }
30 -
31 9 2 int git_stream_registry_global_init(void)
32 - {
33 9 2,3 if (git_rwlock_init(&stream_registry.lock) < 0)
34 ##### 4 return -1;
35 -
36 9 5 git__on_shutdown(shutdown_stream_registry);
37 9 6 return 0;
38 - }
39 -
40 18 2 GIT_INLINE(void) stream_registration_cpy(
41 - git_stream_registration *target,
42 - git_stream_registration *src)
43 - {
44 18 2 if (src)
45 8 3 memcpy(target, src, sizeof(git_stream_registration));
46 - else
47 10 4 memset(target, 0, sizeof(git_stream_registration));
48 18 5 }
49 -
50 147 2 int git_stream_registry_lookup(git_stream_registration *out, git_stream_t type)
51 - {
52 - git_stream_registration *target;
53 147 2 int error = GIT_ENOTFOUND;
54 -
55 147 2,3 assert(out);
56 -
57 147 4 switch(type) {
58 - case GIT_STREAM_STANDARD:
59 96 5 target = &stream_registry.callbacks;
60 96 5 break;
61 - case GIT_STREAM_TLS:
62 51 6 target = &stream_registry.tls_callbacks;
63 51 6 break;
64 - default:
65 - 7 assert(0);
66 - return -1;
67 - }
68 -
69 147 8,9 if (git_rwlock_rdlock(&stream_registry.lock) < 0) {
70 ##### 10 git_error_set(GIT_ERROR_OS, "failed to lock stream registry");
71 ##### 11 return -1;
72 - }
73 -
74 147 12 if (target->init) {
75 4 13 stream_registration_cpy(out, target);
76 4 14 error = 0;
77 - }
78 -
79 147 15 git_rwlock_rdunlock(&stream_registry.lock);
80 147 16 return error;
81 - }
82 -
83 9 2 int git_stream_register(git_stream_t type, git_stream_registration *registration)
84 - {
85 9 2-4 assert(!registration || registration->init);
86 -
87 9 5-7 GIT_ERROR_CHECK_VERSION(registration, GIT_STREAM_VERSION, "stream_registration");
88 -
89 9 8,9 if (git_rwlock_wrlock(&stream_registry.lock) < 0) {
90 ##### 10 git_error_set(GIT_ERROR_OS, "failed to lock stream registry");
91 ##### 11 return -1;
92 - }
93 -
94 9 12 if ((type & GIT_STREAM_STANDARD) == GIT_STREAM_STANDARD)
95 7 13 stream_registration_cpy(&stream_registry.callbacks, registration);
96 -
97 9 14 if ((type & GIT_STREAM_TLS) == GIT_STREAM_TLS)
98 7 15 stream_registration_cpy(&stream_registry.tls_callbacks, registration);
99 -
100 9 16 git_rwlock_wrunlock(&stream_registry.lock);
101 9 17 return 0;
102 - }
103 -
104 - #ifndef GIT_DEPRECATE_HARD
105 ##### 2 int git_stream_register_tls(
106 - int GIT_CALLBACK(ctor)(git_stream **out, const char *host, const char *port))
107 - {
108 ##### 2 git_stream_registration registration = {0};
109 -
110 ##### 2 if (ctor) {
111 ##### 3 registration.version = GIT_STREAM_VERSION;
112 ##### 3 registration.init = ctor;
113 ##### 3 registration.wrap = NULL;
114 -
115 ##### 3 return git_stream_register(GIT_STREAM_TLS, &registration);
116 - } else {
117 ##### 4 return git_stream_register(GIT_STREAM_TLS, NULL);
118 - }
119 - }
120 - #endif