Line data Source code
1 : /*
2 : * SPDX-License-Identifier: MPL-2.0
3 : *
4 : * This Source Code Form is subject to the terms of the Mozilla Public
5 : * License, v. 2.0. If a copy of the MPL was not distributed with this
6 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
7 : *
8 : * Copyright 2024 MonetDB Foundation;
9 : * Copyright August 2008 - 2023 MonetDB B.V.;
10 : * Copyright 1997 - July 2008 CWI.
11 : */
12 :
13 : #include "monetdb_config.h"
14 : #include "rel_remote.h"
15 :
16 : #define mapi_prefix "mapi:monetdb://"
17 :
18 : int
19 94 : mapiuri_valid( const char *uri)
20 : {
21 94 : int i = 0, l = 0;
22 94 : const char *p = uri;
23 :
24 94 : if (strncmp(p, mapi_prefix, strlen(mapi_prefix)))
25 : return 0;
26 : /* optional host (todo limit to valid hostnames ??) */
27 94 : p += strlen(mapi_prefix);
28 94 : if (*p == '[') { //check for IPv6 addresses
29 0 : for (; *p; p++) {
30 0 : if (*p == ']')
31 : break;
32 : }
33 : }
34 : if (!p)
35 : return 0;
36 964 : for (; *p; p++) {
37 964 : if (*p == ':' || *p == '/')
38 : break;
39 : }
40 94 : if (!p)
41 : return 0;
42 94 : if (*p == ':') {
43 94 : char *x;
44 94 : int i = strtol(p+1, &x, 10);
45 :
46 94 : if (!x || i < 0 || i >= 64*1024)
47 0 : return 0;
48 94 : p = x;
49 : }
50 94 : if (*p != '/')
51 : return 0;
52 94 : p++;
53 : /* now find at most 2 '/'s, with some string inbetween */
54 1327 : for(; *p; p++, l++) {
55 1233 : if (*p == '/') {
56 61 : if (l == 0) /* no string inbetween */
57 : return 0;
58 61 : if (i == 2) /* 3 parts (ie database/schema/table) */
59 : return 0;
60 61 : i++;
61 61 : l=0;
62 : }
63 : }
64 94 : if (i == 0 && l == 0) /* missing database name */
65 : return 0;
66 : return 1;
67 : }
68 :
69 : /* assume valid uri's next functions */
70 :
71 : /* mapiuri_uri prefix including database name */
72 : const char *
73 547 : mapiuri_uri( const char *uri, sql_allocator *sa)
74 : {
75 547 : const char *p = uri, *b = uri, *e;
76 :
77 547 : p = strchr(p, '/')+1;
78 547 : p++;
79 547 : e = p = strchr(p, '/');
80 547 : e = strchr(p+1, '/');
81 547 : if (e)
82 325 : return sa_strndup(sa, b, e - b);
83 : else
84 222 : return sa_strdup(sa, b);
85 : }
86 :
87 : const char *
88 0 : mapiuri_database( const char *uri, sql_allocator *sa)
89 : {
90 0 : const char *p = uri, *b, *e;
91 :
92 0 : p = strchr(p, '/')+1;
93 0 : p++;
94 0 : b = p = strchr(p, '/')+1;
95 0 : e = strchr(p, '/');
96 :
97 0 : if (e) {
98 0 : return sa_strndup(sa, b, e - b);
99 : } else {
100 0 : return sa_strdup(sa, b);
101 : }
102 : }
103 :
104 : const char *
105 215 : mapiuri_schema( const char *uri, sql_allocator *sa, const char *fallback)
106 : {
107 215 : const char *p = uri, *b, *e;
108 :
109 215 : p = strchr(p, '/')+1;
110 215 : p = strchr(p+1, '/');
111 215 : p = strchr(p+1, '/');
112 215 : if (!p)
113 : return fallback;
114 145 : b = ++p;
115 145 : e = strchr(p, '/');
116 :
117 145 : if (e) {
118 145 : return sa_strndup(sa, b, e - b);
119 : } else {
120 0 : return sa_strdup(sa, b);
121 : }
122 : }
123 :
124 : const char *
125 530 : mapiuri_table( const char *uri, sql_allocator *sa, const char *fallback)
126 : {
127 530 : const char *p = uri, *b;
128 :
129 530 : p = strchr(p, '/')+1;
130 530 : p = strchr(p+1, '/');
131 530 : p = strchr(p+1, '/');
132 530 : if (!p)
133 : return fallback;
134 319 : p = strchr(p+1, '/');
135 319 : if (!p)
136 : return fallback;
137 318 : b = ++p;
138 318 : return sa_strdup(sa, b);
139 : }
|