| 1 |
/* |
|---|
| 2 |
* Copyright (c) 2007, OmniTI Computer Consulting, Inc. |
|---|
| 3 |
* All rights reserved. |
|---|
| 4 |
* |
|---|
| 5 |
* Redistribution and use in source and binary forms, with or without |
|---|
| 6 |
* modification, are permitted provided that the following conditions are |
|---|
| 7 |
* met: |
|---|
| 8 |
* |
|---|
| 9 |
* * Redistributions of source code must retain the above copyright |
|---|
| 10 |
* notice, this list of conditions and the following disclaimer. |
|---|
| 11 |
* * Redistributions in binary form must reproduce the above |
|---|
| 12 |
* copyright notice, this list of conditions and the following |
|---|
| 13 |
* disclaimer in the documentation and/or other materials provided |
|---|
| 14 |
* with the distribution. |
|---|
| 15 |
* * Neither the name OmniTI Computer Consulting, Inc. nor the names |
|---|
| 16 |
* of its contributors may be used to endorse or promote products |
|---|
| 17 |
* derived from this software without specific prior written |
|---|
| 18 |
* permission. |
|---|
| 19 |
* |
|---|
| 20 |
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
|---|
| 21 |
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
|---|
| 22 |
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
|---|
| 23 |
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
|---|
| 24 |
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
|---|
| 25 |
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
|---|
| 26 |
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
|---|
| 27 |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
|---|
| 28 |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
|---|
| 29 |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
|---|
| 30 |
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
|---|
| 31 |
*/ |
|---|
| 32 |
|
|---|
| 33 |
#include "noit_defines.h" |
|---|
| 34 |
#include "noit_check_tools.h" |
|---|
| 35 |
#include "utils/noit_str.h" |
|---|
| 36 |
|
|---|
| 37 |
#include <assert.h> |
|---|
| 38 |
|
|---|
| 39 |
static noit_hash_table interpolation_operators = NOIT_HASH_EMPTY; |
|---|
| 40 |
|
|---|
| 41 |
static int |
|---|
| 42 |
interpolate_oper_copy(char *buff, int len, const char *replacement) { |
|---|
| 43 |
strlcpy(buff, replacement, len); |
|---|
| 44 |
return strlen(buff); |
|---|
| 45 |
} |
|---|
| 46 |
static int |
|---|
| 47 |
interpolate_oper_ccns(char *buff, int len, const char *replacement) { |
|---|
| 48 |
char *start; |
|---|
| 49 |
start = strstr(replacement, "::"); |
|---|
| 50 |
return interpolate_oper_copy(buff, len, start ? (start + 2) : replacement); |
|---|
| 51 |
} |
|---|
| 52 |
|
|---|
| 53 |
int |
|---|
| 54 |
noit_check_interpolate_register_oper_fn(const char *name, |
|---|
| 55 |
intperpolate_oper_fn f) { |
|---|
| 56 |
noit_hash_replace(&interpolation_operators, |
|---|
| 57 |
strdup(name), strlen(name), |
|---|
| 58 |
(void *)f, |
|---|
| 59 |
free, NULL); |
|---|
| 60 |
return 0; |
|---|
| 61 |
} |
|---|
| 62 |
|
|---|
| 63 |
int |
|---|
| 64 |
noit_check_interpolate(char *buff, int len, const char *fmt, |
|---|
| 65 |
noit_hash_table *attrs, |
|---|
| 66 |
noit_hash_table *config) { |
|---|
| 67 |
char *copy = NULL; |
|---|
| 68 |
char closer; |
|---|
| 69 |
const char *fmte, *key; |
|---|
| 70 |
int replaced_something = 1; |
|---|
| 71 |
int iterations = 3; |
|---|
| 72 |
|
|---|
| 73 |
while(replaced_something && iterations > 0) { |
|---|
| 74 |
char *cp = buff, * const end = buff + len; |
|---|
| 75 |
iterations--; |
|---|
| 76 |
replaced_something = 0; |
|---|
| 77 |
while(*fmt && cp < end) { |
|---|
| 78 |
switch(*fmt) { |
|---|
| 79 |
case '%': |
|---|
| 80 |
if(fmt[1] == '{' || fmt[1] == '[') { |
|---|
| 81 |
closer = (fmt[1] == '{') ? '}' : ']'; |
|---|
| 82 |
fmte = fmt + 2; |
|---|
| 83 |
key = fmte; |
|---|
| 84 |
while(*fmte && *fmte != closer) fmte++; |
|---|
| 85 |
if(*fmte == closer) { |
|---|
| 86 |
/* We have a full key here */ |
|---|
| 87 |
const char *replacement, *oper, *nkey; |
|---|
| 88 |
intperpolate_oper_fn oper_sprint; |
|---|
| 89 |
|
|---|
| 90 |
/* keys can be of the form: :operator:key */ |
|---|
| 91 |
oper = key; |
|---|
| 92 |
if(*oper == ':' && |
|---|
| 93 |
(nkey = strnstrn(":", 1, oper + 1, fmte - key - 1)) != NULL) { |
|---|
| 94 |
void *voper; |
|---|
| 95 |
oper++; |
|---|
| 96 |
/* find oper, nkey-oper */ |
|---|
| 97 |
if(!noit_hash_retrieve(&interpolation_operators, |
|---|
| 98 |
oper, nkey - oper, |
|---|
| 99 |
&voper)) { |
|---|
| 100 |
/* else oper <- copy */ |
|---|
| 101 |
oper_sprint = interpolate_oper_copy; |
|---|
| 102 |
} |
|---|
| 103 |
else |
|---|
| 104 |
oper_sprint = (intperpolate_oper_fn)voper; |
|---|
| 105 |
nkey++; |
|---|
| 106 |
} |
|---|
| 107 |
else { |
|---|
| 108 |
oper_sprint = interpolate_oper_copy; |
|---|
| 109 |
nkey = key; |
|---|
| 110 |
} |
|---|
| 111 |
if(!noit_hash_retr_str((closer == '}') ? config : attrs, |
|---|
| 112 |
nkey, fmte - nkey, &replacement)) |
|---|
| 113 |
replacement = ""; |
|---|
| 114 |
fmt = fmte + 1; /* Format points just after the end of the key */ |
|---|
| 115 |
cp += oper_sprint(cp, end-cp, replacement); |
|---|
| 116 |
*(end-1) = '\0'; /* In case the oper_sprint didn't teminate */ |
|---|
| 117 |
replaced_something = 1; |
|---|
| 118 |
break; |
|---|
| 119 |
} |
|---|
| 120 |
} |
|---|
| 121 |
default: |
|---|
| 122 |
*cp++ = *fmt++; |
|---|
| 123 |
} |
|---|
| 124 |
} |
|---|
| 125 |
*cp = '\0'; |
|---|
| 126 |
if(copy) free(copy); |
|---|
| 127 |
if(replaced_something) |
|---|
| 128 |
copy = strdup(buff); |
|---|
| 129 |
fmt = copy; |
|---|
| 130 |
} |
|---|
| 131 |
return strlen(buff); |
|---|
| 132 |
} |
|---|
| 133 |
|
|---|
| 134 |
void |
|---|
| 135 |
noit_check_extended_id_split(const char *in, int len, |
|---|
| 136 |
char *target, int target_len, |
|---|
| 137 |
char *module, int module_len, |
|---|
| 138 |
char *name, int name_len, |
|---|
| 139 |
char *uuid, int uuid_len) { |
|---|
| 140 |
if(!in || len == 0) return; |
|---|
| 141 |
if(target) *target = '\0'; |
|---|
| 142 |
if(module) *module = '\0'; |
|---|
| 143 |
if(name) *name = '\0'; |
|---|
| 144 |
if(uuid) *uuid = '\0'; |
|---|
| 145 |
if(uuid && len >= UUID_STR_LEN) { |
|---|
| 146 |
memcpy(uuid, in + len - UUID_STR_LEN, UUID_STR_LEN); |
|---|
| 147 |
uuid[UUID_STR_LEN] = '\0'; |
|---|
| 148 |
} |
|---|
| 149 |
if(len > UUID_STR_LEN) { |
|---|
| 150 |
const char *tcp = in; |
|---|
| 151 |
const char *mcp, *ncp, *ucp; |
|---|
| 152 |
/* find the end of the target */ |
|---|
| 153 |
mcp = strchr(tcp,'`'); |
|---|
| 154 |
if(!mcp) return; |
|---|
| 155 |
/* copy in the target */ |
|---|
| 156 |
if(target && target_len > mcp-tcp) { |
|---|
| 157 |
memcpy(target,tcp,mcp-tcp); |
|---|
| 158 |
target[mcp-tcp] = '\0'; |
|---|
| 159 |
} |
|---|
| 160 |
mcp++; |
|---|
| 161 |
ncp = strchr(mcp,'`'); |
|---|
| 162 |
if(!ncp) return; |
|---|
| 163 |
/* copy in the module */ |
|---|
| 164 |
if(module && module_len > ncp-mcp) { |
|---|
| 165 |
memcpy(module,mcp,ncp-mcp); |
|---|
| 166 |
module[ncp-mcp] = '\0'; |
|---|
| 167 |
} |
|---|
| 168 |
ncp++; |
|---|
| 169 |
/* copy in the name */ |
|---|
| 170 |
ucp = in + len - UUID_STR_LEN - 1; |
|---|
| 171 |
if(ncp < ucp) { |
|---|
| 172 |
if(name && name_len > ucp-ncp) { |
|---|
| 173 |
memcpy(name, ncp, ucp-ncp); |
|---|
| 174 |
name[ucp-ncp] = '\0'; |
|---|
| 175 |
} |
|---|
| 176 |
} |
|---|
| 177 |
} |
|---|
| 178 |
} |
|---|
| 179 |
|
|---|
| 180 |
void |
|---|
| 181 |
noit_check_make_attrs(noit_check_t *check, noit_hash_table *attrs) { |
|---|
| 182 |
#define CA_STORE(a,b) noit_hash_store(attrs, a, strlen(a), b) |
|---|
| 183 |
CA_STORE("target", check->target); |
|---|
| 184 |
CA_STORE("target_ip", check->target_ip); |
|---|
| 185 |
CA_STORE("name", check->name); |
|---|
| 186 |
CA_STORE("module", check->module); |
|---|
| 187 |
} |
|---|
| 188 |
void |
|---|
| 189 |
noit_check_release_attrs(noit_hash_table *attrs) { |
|---|
| 190 |
noit_hash_destroy(attrs, NULL, NULL); |
|---|
| 191 |
} |
|---|
| 192 |
|
|---|
| 193 |
void |
|---|
| 194 |
noit_check_tools_shared_init() { |
|---|
| 195 |
noit_check_interpolate_register_oper_fn("copy", interpolate_oper_copy); |
|---|
| 196 |
noit_check_interpolate_register_oper_fn("ccns", interpolate_oper_ccns); |
|---|
| 197 |
} |
|---|
| 198 |
|
|---|