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