1
/* Editor Settings: expandtabs and use 4 spaces for indentation
2
* ex: set softtabstop=4 tabstop=8 expandtab shiftwidth=4: *
6
* Copyright Likewise Software
9
* This library is free software; you can redistribute it and/or modify it
10
* under the terms of the GNU Lesser General Public License as published by
11
* the Free Software Foundation; either version 2.1 of the license, or (at
12
* your option) any later version.
14
* This library is distributed in the hope that it will be useful,
15
* but WITHOUT ANY WARRANTY; without even the implied warranty of
16
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
17
* General Public License for more details. You should have received a copy
18
* of the GNU Lesser General Public License along with this program. If
19
* not, see <http://www.gnu.org/licenses/>.
21
* LIKEWISE SOFTWARE MAKES THIS SOFTWARE AVAILABLE UNDER OTHER LICENSING
22
* TERMS AS WELL. IF YOU HAVE ENTERED INTO A SEPARATE LICENSE AGREEMENT
23
* WITH LIKEWISE SOFTWARE, THEN YOU MAY ELECT TO USE THE SOFTWARE UNDER THE
24
* TERMS OF THAT SOFTWARE LICENSE AGREEMENT INSTEAD OF THE TERMS OF THE GNU
25
* LESSER GENERAL PUBLIC LICENSE, NOTWITHSTANDING THE ABOVE NOTICE. IF YOU
26
* HAVE QUESTIONS, OR WISH TO REQUEST A COPY OF THE ALTERNATE LICENSING
27
* TERMS OFFERED BY LIKEWISE SOFTWARE, PLEASE CONTACT LIKEWISE SOFTWARE AT
28
* license@likewisesoftware.com
34
#if !defined(HAVE_STRNDUP)
35
char* strndup(const char *s, size_t maxlen)
41
len = (len > maxlen) ? maxlen : len;
42
size = (len + 1) * sizeof(char);
43
ret = (char*) malloc(size);
46
/* ensure null termination */
55
* Handles "escaped" separator character. It allows separator character
56
* to be treated as part of value string.
58
static char* cleanup_sep(char *s, char sep)
63
if (s == NULL) return s;
68
seppos = strstr(s, sepstr);
70
while (*seppos) seppos[0] = (seppos)[1];
73
seppos = strstr(s, sepstr);
81
* Splits a string into array of strings given separator character
83
char** get_string_list(char *list, const char sep)
86
char *start, *end = NULL;
89
/* count the elements */
91
end = strchr(list, sep);
93
end = strchr(end, sep);
95
/* skip any "escaped" separator */
96
if (end > start && *(end-1) == '\\') continue;
100
ret = (char**) malloc(sizeof(char*) * (count + 1));
101
if (!ret) return NULL;
103
memset((void*)ret, 0, sizeof(char*) * (count + 1));
105
/* copy elements to the array */
107
for (i = 0; i < count; i++) {
108
end = strchr(start, sep);
110
/* skip any "escaped" separator */
111
while (start && end > start && *(end-1) == '\\') {
112
char *pos = (char*)(end+1);
113
end = strchr(pos,sep);
117
ret[i] = strndup(start, (size_t)(end - start));
120
} else if (strlen(start)) {
121
ret[i] = strdup(start);
124
ret[i] = cleanup_sep(ret[i], sep);
132
* Returns array of strings for multi-value parameters
134
char** get_value_list(const char *list)
136
const char start_list = '[';
137
const char end_list = ']';
138
const char element_sep = ':';
140
size_t input_str_len = 0;
141
char *str_list = NULL;
142
const char *start = NULL;
145
/* List has to start with '[' char ... */
146
if (list[0] != start_list) return NULL;
148
/* ... and has to end with ']' char */
149
input_str_len = strlen(list);
150
if (list[input_str_len - 1] != end_list) return NULL;
153
str_list = strndup(start, strlen(start) - 1);
154
if (str_list == NULL) return NULL;
156
/* Split the list to array of values */
157
ret = get_string_list(str_list, element_sep);
165
* Parses string of optional parameters (key=value pairs) into array
168
struct parameter* get_optional_params(char *opt, int *count)
170
const char separator = ',';
171
const char equal = '=';
172
struct parameter *params;
177
if (count) *count = 0;
181
if (!count) return NULL;
186
opts = get_string_list(opt, separator);
187
if (opts == NULL) return NULL;
189
while (opts[(*count)]) (*count)++;
191
params = (struct parameter*) malloc(sizeof(struct parameter) * (*count));
192
if (params == NULL) return NULL;
195
size_t key_size, val_size;
196
char *param = opts[i];
197
char *value = strchr(param, equal);
200
key_size = (size_t)(value - param);
201
params[i].key = strndup(param, key_size);
204
val_size = strlen(param) - key_size - 1; /* equal char doesn't count */
205
params[i].val = strndup((char*)(value + sizeof(char)), val_size);
208
/* if param is specified but does not equal to anything we can
209
assume it's a boolean flag set */
210
params[i].val = strdup("1");
217
for (i = 0; i < (*count); i++) {
226
const char* find_value(struct parameter *params, int count, const char *key)
229
size_t sParamLen = 0;
230
size_t sKeyLen = strlen(key);
232
for (i = 0; i < count; i++)
234
sParamLen = strlen(params[i].key);
236
if (sParamLen != sKeyLen)
241
if (memcmp(params[i].key, key, sKeyLen) == 0)
243
return params[i].val;
252
* Converts array of strings to array of 2-byte unicode strings
254
wchar16_t **create_wc16str_list(char **strlist)
257
wchar16_t **wc16str_list = NULL;
260
if (strlist == NULL) return NULL;
262
/* count the elements (including terminating zero) */
263
while (strlist[list_len++]);
265
/* allocate the wchar16_t strings array */
266
wc16str_list = (wchar16_t**) malloc(sizeof(wchar16_t*) * list_len);
267
if (wc16str_list == NULL) return NULL;
269
memset((void*)wc16str_list, 0, sizeof(wchar16_t*) * list_len);
271
/* copy mbs strings to wchar16_t strings */
272
for (i = 0; strlist[i] && i < list_len; i++) {
273
wc16str_list[i] = ambstowc16s(strlist[i]);
274
if (wc16str_list[i] == NULL) {
277
free(wc16str_list[i--]);
291
* Converts array of sid strings to array of sids
293
PSID* create_sid_list(char **strlist)
296
PSID* sid_list = NULL;
299
if (strlist == NULL) return NULL;
301
/* count the elements (including terminating zero) */
302
while (strlist[list_len++]);
304
/* allocate the wchar16_t strings array */
305
sid_list = (PSID*) malloc(sizeof(PSID) * list_len);
306
if (sid_list == NULL) return NULL;
308
memset((void*)sid_list, 0, sizeof(PSID) * list_len);
310
/* copy mbs strings to wchar16_t strings */
311
for (i = 0; strlist[i] && i < list_len; i++) {
312
RtlAllocateSidFromCString(&sid_list[i], strlist[i]);
313
if (sid_list[i] == NULL) {
316
RTL_FREE(&sid_list[i--]);
328
enum param_err fetch_value(struct parameter *params, int count,
329
const char *key, enum param_type type,
330
void *val, const void *def)
334
char **valstr, **defstr;
335
char *valchar, *defchar;
336
wchar16_t **valw16str;
337
wchar16_t ***valw16str_list;
338
int *valint, *defint;
339
unsigned int *valuint, *defuint;
341
PSID** valsid_list = NULL;
342
char **strlist = NULL;
343
enum param_err ret = perr_success;
346
if (params && !key) return perr_nullptr_passed;
347
if (!val) return perr_invalid_out_param;
349
value = find_value(params, count, key);
350
if (!value && !def) return perr_not_found;
354
valstr = (char**)val;
355
defstr = (char**)def;
356
*valstr = (value) ? strdup(value) : strdup(*defstr);
360
valw16str = (wchar16_t**)val;
361
defstr = (char**)def;
362
*valw16str = (value) ? ambstowc16s(value) : ambstowc16s(*defstr);
365
case pt_w16string_list:
366
valw16str_list = (wchar16_t***)val;
367
defstr = (char**)def;
368
strlist = (value) ? get_value_list(value) : get_value_list(*defstr);
369
*valw16str_list = create_wc16str_list(strlist);
370
if (*valw16str_list == NULL) ret = perr_invalid_out_param;
374
valchar = (char*)val;
375
defchar = (char*)def;
376
*valchar = (value) ? value[0] : *defchar;
382
*valint = (value) ? atoi(value) : *defint;
386
valuint = (unsigned int*)val;
387
defuint = (unsigned int*)def;
388
*valuint = (unsigned int)((value) ? atol(value) : *defuint);
393
defstr = (char**)def;
394
status = RtlAllocateSidFromCString(valsid,
395
((value) ? (const char*)value : *defstr));
396
if (status != STATUS_SUCCESS) ret = perr_invalid_out_param;
400
valsid_list = (PSID**)val;
401
defstr = (char**)def;
402
strlist = get_value_list((value) ? (const char*)value : *defstr);
403
*valsid_list = create_sid_list(strlist);
404
if (*valsid_list == NULL) ret = perr_invalid_out_param;
408
ret = perr_unknown_type;
425
const char *param_errstr(enum param_err perr)
427
const int errcount = sizeof(param_errstr_maps)/sizeof(struct param_errstr_map);
430
while (i < errcount && perr != param_errstr_maps[i].perr) i++;
431
return param_errstr_maps[i].desc;
435
#define CHECK_PARAM_INFO_PTR(v) \
437
printf("warning: Parameter value ptr is NULL!\n"); \
442
static void ParamInfoStr(void *value)
446
CHECK_PARAM_INFO_PTR(value);
448
v = strdup((char*)value);
451
printf("(char*)\"%s\"\n", v);
458
static void ParamInfoWc16Str(void *value)
462
CHECK_PARAM_INFO_PTR(value);
464
v = awc16stombs((wchar16_t*)value);
467
printf("(wchar16_t*)\"%s\"\n", v);
474
static void ParamInfoChar(void *value)
478
CHECK_PARAM_INFO_PTR(value);
481
printf("(char)\'%c\'\n", (*v));
485
static void ParamInfoInt32(void *value)
489
CHECK_PARAM_INFO_PTR(value);
492
printf("(int32) %d (0x%08x)\n", (*v), (unsigned int)(*v));
496
static void ParamInfoUInt32(void *value)
500
CHECK_PARAM_INFO_PTR(value);
503
printf("(UINT32) %u (0x%08x)\n", (*v), (*v));
507
void ParamInfo(const char* name, enum param_type type, void *value)
509
printf("# %s = ", name);
517
ParamInfoWc16Str(value);
521
ParamInfoChar(value);
525
ParamInfoInt32(value);
528
ParamInfoUInt32(value);
532
printf("(unknown type)\n");
541
indent-tabs-mode: nil