~ubuntu-branches/ubuntu/oneiric/likewise-open/oneiric

« back to all changes in this revision

Viewing changes to lwnetapi/test/params.c

  • Committer: Bazaar Package Importer
  • Author(s): Scott Salley
  • Date: 2010-11-22 12:06:00 UTC
  • mfrom: (1.1.6 upstream)
  • Revision ID: james.westby@ubuntu.com-20101122120600-8lba1fpceot71wlb
Tags: 6.0.0.53010-1
Likewise Open 6.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Editor Settings: expandtabs and use 4 spaces for indentation
 
2
 * ex: set softtabstop=4 tabstop=8 expandtab shiftwidth=4: *
 
3
 */
 
4
 
 
5
/*
 
6
 * Copyright Likewise Software
 
7
 * All rights reserved.
 
8
 *
 
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.
 
13
 *
 
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/>.
 
20
 *
 
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
 
29
 */
 
30
 
 
31
#include "includes.h"
 
32
 
 
33
 
 
34
#if !defined(HAVE_STRNDUP)
 
35
char* strndup(const char *s, size_t maxlen)
 
36
{
 
37
    char *ret;
 
38
    size_t len, size;
 
39
 
 
40
    len = strlen(s);
 
41
    len = (len > maxlen) ? maxlen : len;
 
42
    size = (len + 1) * sizeof(char);
 
43
    ret = (char*) malloc(size);
 
44
    strncpy(ret, s, len);
 
45
 
 
46
    /* ensure null termination */
 
47
    ret[len] = '\0';
 
48
 
 
49
    return ret;
 
50
}
 
51
#endif
 
52
 
 
53
 
 
54
/*
 
55
 * Handles "escaped" separator character. It allows separator character
 
56
 * to be treated as part of value string.
 
57
 */
 
58
static char* cleanup_sep(char *s, char sep)
 
59
{
 
60
    char *seppos;
 
61
    char sepstr[3] = {0};
 
62
 
 
63
    if (s == NULL) return s;
 
64
 
 
65
    sepstr[0] = '\\';
 
66
    sepstr[1] = sep;
 
67
 
 
68
    seppos = strstr(s, sepstr);
 
69
    while (seppos) {
 
70
        while (*seppos) seppos[0] = (seppos)[1];
 
71
        seppos++;
 
72
 
 
73
        seppos = strstr(s, sepstr);
 
74
    }
 
75
 
 
76
    return s;
 
77
}
 
78
 
 
79
 
 
80
/*
 
81
 * Splits a string into array of strings given separator character
 
82
 */
 
83
char** get_string_list(char *list, const char sep)
 
84
{
 
85
    char **ret;
 
86
    char *start, *end = NULL;
 
87
    int i, count = 1;
 
88
 
 
89
    /* count the elements */
 
90
    start = list;
 
91
    end = strchr(list, sep);
 
92
    while (end++) {
 
93
        end = strchr(end, sep);
 
94
 
 
95
        /* skip any "escaped" separator */
 
96
        if (end > start && *(end-1) == '\\') continue;
 
97
        count++;
 
98
    }
 
99
 
 
100
    ret = (char**) malloc(sizeof(char*) * (count + 1));
 
101
    if (!ret) return NULL;
 
102
 
 
103
    memset((void*)ret, 0, sizeof(char*) * (count + 1));
 
104
 
 
105
    /* copy elements to the array */
 
106
    start = list;
 
107
    for (i = 0; i < count; i++) {
 
108
        end = strchr(start, sep);
 
109
 
 
110
        /* skip any "escaped" separator */
 
111
        while (start && end > start && *(end-1) == '\\') {
 
112
            char *pos = (char*)(end+1);
 
113
            end = strchr(pos,sep);
 
114
        }
 
115
 
 
116
        if (end) {
 
117
            ret[i] = strndup(start, (size_t)(end - start));
 
118
            start = &end[1];
 
119
 
 
120
        } else if (strlen(start)) {
 
121
            ret[i] = strdup(start);
 
122
        }
 
123
 
 
124
        ret[i] = cleanup_sep(ret[i], sep);
 
125
    }
 
126
 
 
127
    return ret;
 
128
}
 
129
 
 
130
 
 
131
/*
 
132
 * Returns array of strings for multi-value parameters
 
133
 */
 
134
char** get_value_list(const char *list)
 
135
{
 
136
    const char start_list = '[';
 
137
    const char end_list = ']';
 
138
    const char element_sep = ':';
 
139
 
 
140
    size_t input_str_len = 0;
 
141
    char *str_list = NULL;
 
142
    const char *start = NULL;
 
143
    char **ret = NULL;
 
144
 
 
145
    /* List has to start with '[' char ... */
 
146
    if (list[0] != start_list) return NULL;
 
147
 
 
148
    /* ... and has to end with ']' char */
 
149
    input_str_len = strlen(list);
 
150
    if (list[input_str_len - 1] != end_list) return NULL;
 
151
 
 
152
    start = &(list[1]);
 
153
    str_list = strndup(start, strlen(start) - 1);
 
154
    if (str_list == NULL) return NULL;
 
155
 
 
156
    /* Split the list to array of values */
 
157
    ret = get_string_list(str_list, element_sep);
 
158
 
 
159
    free(str_list);
 
160
    return ret;
 
161
}
 
162
 
 
163
 
 
164
/*
 
165
 * Parses string of optional parameters (key=value pairs) into array
 
166
 * of structures.
 
167
 */
 
168
struct parameter* get_optional_params(char *opt, int *count)
 
169
{
 
170
    const char separator = ',';
 
171
    const char equal = '=';
 
172
    struct parameter *params;
 
173
    char **opts;
 
174
    int i;
 
175
 
 
176
    if (!opt) {
 
177
        if (count) *count = 0;
 
178
        return NULL;
 
179
    }
 
180
 
 
181
    if (!count) return NULL;
 
182
 
 
183
    *count = 0;
 
184
    i = 0;
 
185
 
 
186
    opts = get_string_list(opt, separator);
 
187
    if (opts == NULL) return NULL;
 
188
 
 
189
    while (opts[(*count)]) (*count)++;
 
190
 
 
191
    params = (struct parameter*) malloc(sizeof(struct parameter) * (*count));
 
192
    if (params == NULL) return NULL;
 
193
 
 
194
    while (opts[i]) {
 
195
        size_t key_size, val_size;
 
196
        char *param = opts[i];
 
197
        char *value = strchr(param, equal);
 
198
 
 
199
        if (param) {
 
200
            key_size = (size_t)(value - param);
 
201
            params[i].key = strndup(param, key_size);
 
202
 
 
203
            if (value) {
 
204
                val_size = strlen(param) - key_size - 1; /* equal char doesn't count */
 
205
                params[i].val = strndup((char*)(value + sizeof(char)), val_size);
 
206
 
 
207
            } else {
 
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");
 
211
            }
 
212
 
 
213
            i++;
 
214
        }
 
215
    }
 
216
 
 
217
    for (i = 0; i < (*count); i++) {
 
218
        free(opts[i]);
 
219
    }
 
220
    free(opts);
 
221
 
 
222
    return params;
 
223
}
 
224
 
 
225
 
 
226
const char* find_value(struct parameter *params, int count, const char *key)
 
227
{
 
228
    int i = 0;
 
229
    size_t sParamLen = 0;
 
230
    size_t sKeyLen = strlen(key);
 
231
 
 
232
    for (i = 0; i < count; i++)
 
233
    {
 
234
        sParamLen = strlen(params[i].key);
 
235
 
 
236
        if (sParamLen != sKeyLen)
 
237
        {
 
238
            continue;
 
239
        }
 
240
 
 
241
        if (memcmp(params[i].key, key, sKeyLen) == 0)
 
242
        {
 
243
            return params[i].val;
 
244
        }
 
245
    }
 
246
 
 
247
    return NULL;
 
248
}
 
249
 
 
250
 
 
251
/*
 
252
 * Converts array of strings to array of 2-byte unicode strings
 
253
 */
 
254
wchar16_t **create_wc16str_list(char **strlist)
 
255
{
 
256
    int list_len = 0;
 
257
    wchar16_t **wc16str_list = NULL;
 
258
    int i = 0;
 
259
 
 
260
    if (strlist == NULL) return NULL;
 
261
 
 
262
    /* count the elements (including terminating zero) */
 
263
    while (strlist[list_len++]);
 
264
 
 
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;
 
268
 
 
269
    memset((void*)wc16str_list, 0, sizeof(wchar16_t*) * list_len);
 
270
 
 
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) {
 
275
            i--;
 
276
            while (i >= 0) {
 
277
                free(wc16str_list[i--]);
 
278
            }
 
279
            free(wc16str_list);
 
280
 
 
281
            return NULL;
 
282
        }
 
283
 
 
284
    }
 
285
 
 
286
    return wc16str_list;
 
287
}
 
288
 
 
289
 
 
290
/*
 
291
 * Converts array of sid strings to array of sids
 
292
 */
 
293
PSID* create_sid_list(char **strlist)
 
294
{
 
295
    int list_len = 0;
 
296
    PSID* sid_list = NULL;
 
297
    int i = 0;
 
298
 
 
299
    if (strlist == NULL) return NULL;
 
300
 
 
301
    /* count the elements (including terminating zero) */
 
302
    while (strlist[list_len++]);
 
303
 
 
304
    /* allocate the wchar16_t strings array */
 
305
    sid_list = (PSID*) malloc(sizeof(PSID) * list_len);
 
306
    if (sid_list == NULL) return NULL;
 
307
 
 
308
    memset((void*)sid_list, 0, sizeof(PSID) * list_len);
 
309
 
 
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) {
 
314
            i--;
 
315
            while (i >= 0) {
 
316
                RTL_FREE(&sid_list[i--]);
 
317
            }
 
318
            free(sid_list);
 
319
 
 
320
            return NULL;
 
321
        }
 
322
    }
 
323
 
 
324
    return sid_list;
 
325
}
 
326
 
 
327
 
 
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)
 
331
{
 
332
    const char *value;
 
333
    NTSTATUS status;
 
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;
 
340
    PSID* valsid = NULL;
 
341
    PSID** valsid_list = NULL;
 
342
    char **strlist = NULL;
 
343
    enum param_err ret = perr_success;
 
344
    int i = 0;
 
345
 
 
346
    if (params && !key) return perr_nullptr_passed;
 
347
    if (!val) return perr_invalid_out_param;
 
348
 
 
349
    value = find_value(params, count, key);
 
350
    if (!value && !def) return perr_not_found;
 
351
 
 
352
    switch (type) {
 
353
    case pt_string:
 
354
        valstr = (char**)val;
 
355
        defstr = (char**)def;
 
356
        *valstr = (value) ? strdup(value) : strdup(*defstr);
 
357
        break;
 
358
 
 
359
    case pt_w16string:
 
360
        valw16str = (wchar16_t**)val;
 
361
        defstr = (char**)def;
 
362
        *valw16str = (value) ? ambstowc16s(value) : ambstowc16s(*defstr);
 
363
        break;
 
364
 
 
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;
 
371
        break;
 
372
 
 
373
    case pt_char:
 
374
        valchar = (char*)val;
 
375
        defchar = (char*)def;
 
376
        *valchar = (value) ? value[0] : *defchar;
 
377
        break;
 
378
 
 
379
    case pt_int32:
 
380
        valint = (int*)val;
 
381
        defint = (int*)def;
 
382
        *valint = (value) ? atoi(value) : *defint;
 
383
        break;
 
384
 
 
385
    case pt_uint32:
 
386
        valuint = (unsigned int*)val;
 
387
        defuint = (unsigned int*)def;
 
388
        *valuint = (unsigned int)((value) ? atol(value) : *defuint);
 
389
        break;
 
390
 
 
391
    case pt_sid:
 
392
        valsid = (PSID*)val;
 
393
        defstr = (char**)def;
 
394
        status = RtlAllocateSidFromCString(valsid,
 
395
                                    ((value) ? (const char*)value : *defstr));
 
396
        if (status != STATUS_SUCCESS) ret = perr_invalid_out_param;
 
397
        break;
 
398
 
 
399
    case pt_sid_list:
 
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;
 
405
        break;
 
406
 
 
407
    default:
 
408
        ret = perr_unknown_type;
 
409
        break;
 
410
    }
 
411
 
 
412
    if (strlist) {
 
413
        i = 0;
 
414
        while (strlist[i]) {
 
415
            free(strlist[i++]);
 
416
        }
 
417
 
 
418
        free(strlist);
 
419
    }
 
420
 
 
421
    return ret;
 
422
}
 
423
 
 
424
 
 
425
const char *param_errstr(enum param_err perr)
 
426
{
 
427
    const int errcount = sizeof(param_errstr_maps)/sizeof(struct param_errstr_map);
 
428
    int i = 0;
 
429
 
 
430
    while (i < errcount && perr != param_errstr_maps[i].perr) i++;
 
431
    return param_errstr_maps[i].desc;
 
432
}
 
433
 
 
434
 
 
435
#define CHECK_PARAM_INFO_PTR(v)                             \
 
436
    if ((v) == NULL) {                                      \
 
437
        printf("warning: Parameter value ptr is NULL!\n");  \
 
438
        return;                                             \
 
439
    }
 
440
 
 
441
 
 
442
static void ParamInfoStr(void *value)
 
443
{
 
444
    char *v = NULL;
 
445
 
 
446
    CHECK_PARAM_INFO_PTR(value);
 
447
 
 
448
    v = strdup((char*)value);
 
449
    if (!v) goto done;
 
450
 
 
451
    printf("(char*)\"%s\"\n", v);
 
452
 
 
453
done:
 
454
    free(v);
 
455
}
 
456
 
 
457
 
 
458
static void ParamInfoWc16Str(void *value)
 
459
{
 
460
    char *v = NULL;
 
461
 
 
462
    CHECK_PARAM_INFO_PTR(value);
 
463
 
 
464
    v = awc16stombs((wchar16_t*)value);
 
465
    if (!v) goto done;
 
466
 
 
467
    printf("(wchar16_t*)\"%s\"\n", v);
 
468
 
 
469
done:
 
470
    free(v);
 
471
}
 
472
 
 
473
 
 
474
static void ParamInfoChar(void *value)
 
475
{
 
476
    char *v = NULL;
 
477
 
 
478
    CHECK_PARAM_INFO_PTR(value);
 
479
 
 
480
    v = (char*)value;
 
481
    printf("(char)\'%c\'\n", (*v));
 
482
}
 
483
 
 
484
 
 
485
static void ParamInfoInt32(void *value)
 
486
{
 
487
    INT32 *v = NULL;
 
488
 
 
489
    CHECK_PARAM_INFO_PTR(value);
 
490
 
 
491
    v = (INT32*)value;
 
492
    printf("(int32) %d (0x%08x)\n", (*v), (unsigned int)(*v));
 
493
}
 
494
 
 
495
 
 
496
static void ParamInfoUInt32(void *value)
 
497
{
 
498
    UINT32 *v = NULL;
 
499
 
 
500
    CHECK_PARAM_INFO_PTR(value);
 
501
 
 
502
    v = (UINT32*)value;
 
503
    printf("(UINT32) %u (0x%08x)\n", (*v), (*v));
 
504
}
 
505
 
 
506
 
 
507
void ParamInfo(const char* name, enum param_type type, void *value)
 
508
{
 
509
    printf("# %s = ", name);
 
510
 
 
511
    switch (type) {
 
512
    case pt_string:
 
513
        ParamInfoStr(value);
 
514
        break;
 
515
 
 
516
    case pt_w16string:
 
517
        ParamInfoWc16Str(value);
 
518
        break;
 
519
 
 
520
    case pt_char:
 
521
        ParamInfoChar(value);
 
522
        break;
 
523
 
 
524
    case pt_int32:
 
525
        ParamInfoInt32(value);
 
526
 
 
527
    case pt_uint32:
 
528
        ParamInfoUInt32(value);
 
529
        break;
 
530
 
 
531
    default:
 
532
        printf("(unknown type)\n");
 
533
    }
 
534
}
 
535
 
 
536
 
 
537
/*
 
538
local variables:
 
539
mode: c
 
540
c-basic-offset: 4
 
541
indent-tabs-mode: nil
 
542
tab-width: 4
 
543
end:
 
544
*/