1 /*
2 NETWIB
3 Network library
4 Copyright(c) 1999-2010 Laurent Constantin
5 -----
6
7 Main server : http://www.laurentconstantin.com/
8 Backup server : http://laurentconstantin.free.fr/
9 [my current email address is on the web servers]
10
11 -----
12 This file is part of Netwib.
13
14 Netwib is free software: you can redistribute it and/or modify
15 it under the terms of the GNU General Public License version 3
16 as published by the Free Software Foundation.
17
18 Netwib is distributed in the hope that it will be useful,
19 but WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 GNU General Public License for more details (http://www.gnu.org/).
22
23 ------------------------------------------------------------------------
24 */
25
26 #include <netwib/inc/maininc.h>
27
28 /*
29 IMPORTANT
30 Function netwib_priv_buf_append_vfmt2 must be independent, and
31 work even if netwib is not initialized : it is used in netwib_init
32 to display error. Of course, this is only valid if the buffer
33 is an external array (ie not allocated).
34 */
35
36 /*-------------------------------------------------------------*/
netwib_priv_buf_append_vfmt_error(netwib_conststring msg)37 static netwib_err netwib_priv_buf_append_vfmt_error(netwib_conststring msg)
38 {
39 netwib_bool canuseglo;
40
41 netwib_er(netwib_priv_glovars_canuse(&canuseglo));
42 if (canuseglo) {
43 netwib_er(netwib_priv_errmsg_string(msg));
44 }
45
46 return(NETWIB_ERR_OK);
47 }
48
49 /*-------------------------------------------------------------*/
netwib_priv_buf_append_vfmt_error2(netwib_conststring msg,netwib_conststring badfmt)50 static netwib_err netwib_priv_buf_append_vfmt_error2(netwib_conststring msg,
51 netwib_conststring badfmt)
52 {
53 netwib_buf buf;
54 netwib_bool canuseglo;
55
56 netwib_er(netwib_priv_glovars_canuse(&canuseglo));
57 if (canuseglo) {
58 netwib_er(netwib_buf_init_mallocdefault(&buf));
59 netwib_er(netwib_buf_append_string(msg, &buf));
60 netwib_er(netwib_buf_append_string(" in \"...%", &buf));
61 netwib_er(netwib_buf_append_string(badfmt, &buf));
62 netwib_er(netwib_buf_append_string("\"", &buf));
63 netwib_er(netwib_priv_errmsg_buf(&buf));
64 netwib_er(netwib_buf_close(&buf));
65 }
66
67 return(NETWIB_ERR_OK);
68 }
69
70
71 /*-------------------------------------------------------------*/
72 /*-------------------------------------------------------------*/
73 /*-------------------------------------------------------------*/
74 /*-------------------------------------------------------------*/
75 /*-------------------------------------------------------------*/
76
77 /*-------------------------------------------------------------*/
78 #define NETWIB_PRIV_FMT_FIELD_MAXSIZE 20
79
80 typedef enum {
81 NETWIB_PRIV_FMT_ALIGNTYPE_LEFT = 1,
82 NETWIB_PRIV_FMT_ALIGNTYPE_CENTER,
83 NETWIB_PRIV_FMT_ALIGNTYPE_RIGHT
84 } netwib_priv_fmt_aligntype;
85
86 typedef struct {
87 netwib_bool altformat;
88 netwib_uint32 minsize;
89 netwib_uint32 base;
90 } netwib_priv_fmt_spec_uint;
91
92 typedef struct {
93 netwib_bool sign;
94 netwib_uint32 minsize;
95 } netwib_priv_fmt_spec_int;
96
97 typedef struct {
98 netwib_char type;
99 } netwib_priv_fmt_spec_bool;
100
101 typedef struct {
102 netwib_char type;
103 } netwib_priv_fmt_spec_cmp;
104
105 typedef struct {
106 netwib_bool useglob;
107 } netwib_priv_fmt_spec_buf;
108
109 typedef struct {
110 netwib_bool useglob;
111 } netwib_priv_fmt_spec_s;
112
113 typedef enum {
114 NETWIB_PRIV_FMT_FIELDTYPE_PERCENT = 1,
115 NETWIB_PRIV_FMT_FIELDTYPE_C,
116 NETWIB_PRIV_FMT_FIELDTYPE_S,
117 NETWIB_PRIV_FMT_FIELDTYPE_P,
118 NETWIB_PRIV_FMT_FIELDTYPE_END,
119 NETWIB_PRIV_FMT_FIELDTYPE_UINT64,
120 NETWIB_PRIV_FMT_FIELDTYPE_UINT32,
121 NETWIB_PRIV_FMT_FIELDTYPE_UINT16,
122 NETWIB_PRIV_FMT_FIELDTYPE_UINT8,
123 NETWIB_PRIV_FMT_FIELDTYPE_UINTMAX,
124 NETWIB_PRIV_FMT_FIELDTYPE_UINTPTR,
125 NETWIB_PRIV_FMT_FIELDTYPE_BYTE,
126 NETWIB_PRIV_FMT_FIELDTYPE_INT64,
127 NETWIB_PRIV_FMT_FIELDTYPE_INT32,
128 NETWIB_PRIV_FMT_FIELDTYPE_INT16,
129 NETWIB_PRIV_FMT_FIELDTYPE_INT8,
130 NETWIB_PRIV_FMT_FIELDTYPE_INTMAX,
131 NETWIB_PRIV_FMT_FIELDTYPE_INTPTR,
132 NETWIB_PRIV_FMT_FIELDTYPE_BOOL,
133 NETWIB_PRIV_FMT_FIELDTYPE_CMP,
134 NETWIB_PRIV_FMT_FIELDTYPE_BUF,
135 NETWIB_PRIV_FMT_FIELDTYPE_ETH,
136 NETWIB_PRIV_FMT_FIELDTYPE_IP,
137 NETWIB_PRIV_FMT_FIELDTYPE_PORT,
138 NETWIB_PRIV_FMT_FIELDTYPE_ETHS,
139 NETWIB_PRIV_FMT_FIELDTYPE_IPS,
140 NETWIB_PRIV_FMT_FIELDTYPE_PORTS
141 } netwib_priv_fmt_fieldtype;
142
143 typedef struct {
144 netwib_uint32 skipsize;
145 netwib_priv_fmt_fieldtype fieldtype;
146 /* below are not always set */
147 netwib_bool geneset;
148 struct {
149 netwib_priv_fmt_aligntype align;
150 netwib_char padchar;
151 netwib_uint32 minsize;
152 netwib_bool skipfield;
153 } gene;
154 netwib_bool specset;
155 union {
156 netwib_priv_fmt_spec_uint specuint;
157 netwib_priv_fmt_spec_int specint;
158 netwib_priv_fmt_spec_bool specbool;
159 netwib_priv_fmt_spec_cmp speccmp;
160 netwib_priv_fmt_spec_buf specbuf;
161 netwib_priv_fmt_spec_s specs;
162 } spec;
163 } netwib_priv_fmtinfos;
164
165 /*-------------------------------------------------------------*/
netwib_priv_fmt_analyze_type(netwib_conststring fmt,netwib_conststring type,netwib_priv_fmtinfos * pinfos)166 static netwib_err netwib_priv_fmt_analyze_type(netwib_conststring fmt,
167 netwib_conststring type,
168 netwib_priv_fmtinfos *pinfos)
169 {
170
171 netwib_uint32 datasize;
172 netwib_char firstchar;
173
174 datasize = netwib_c_strlen(type);
175 if (datasize == 0) {
176 return(NETWIB_ERR_PAFMT);
177 }
178
179 #define netwib__priv_fmt_analyze_type_cmp(txt,val) if (!netwib_c_memcmp(type, txt, datasize)) { pinfos->fieldtype = val; return(NETWIB_ERR_OK); }
180 firstchar = type[0];
181 switch(firstchar) {
182 case 'b' :
183 switch (datasize) {
184 case 3 :
185 netwib__priv_fmt_analyze_type_cmp("buf",
186 NETWIB_PRIV_FMT_FIELDTYPE_BUF);
187 break;
188 case 4 :
189 netwib__priv_fmt_analyze_type_cmp("bool",
190 NETWIB_PRIV_FMT_FIELDTYPE_BOOL);
191 netwib__priv_fmt_analyze_type_cmp("byte",
192 NETWIB_PRIV_FMT_FIELDTYPE_BYTE);
193 break;
194 }
195 break;
196 case 'c' :
197 switch (datasize) {
198 case 1 :
199 pinfos->fieldtype = NETWIB_PRIV_FMT_FIELDTYPE_C;
200 return(NETWIB_ERR_OK);
201 break;
202 case 3 :
203 netwib__priv_fmt_analyze_type_cmp("cmp",
204 NETWIB_PRIV_FMT_FIELDTYPE_CMP);
205 break;
206 }
207 break;
208 case 'e' :
209 switch (datasize) {
210 case 3 :
211 netwib__priv_fmt_analyze_type_cmp("eth",
212 NETWIB_PRIV_FMT_FIELDTYPE_ETH);
213 break;
214 case 4 :
215 netwib__priv_fmt_analyze_type_cmp("eths",
216 NETWIB_PRIV_FMT_FIELDTYPE_ETHS);
217 break;
218 }
219 break;
220 case 'i' :
221 switch (datasize) {
222 case 2 :
223 netwib__priv_fmt_analyze_type_cmp("ip",
224 NETWIB_PRIV_FMT_FIELDTYPE_IP);
225 break;
226 case 3 :
227 netwib__priv_fmt_analyze_type_cmp("ips",
228 NETWIB_PRIV_FMT_FIELDTYPE_IPS);
229 break;
230 case 4 :
231 netwib__priv_fmt_analyze_type_cmp("int8",
232 NETWIB_PRIV_FMT_FIELDTYPE_INT8);
233 break;
234 case 5 :
235 netwib__priv_fmt_analyze_type_cmp("int32",
236 NETWIB_PRIV_FMT_FIELDTYPE_INT32);
237 netwib__priv_fmt_analyze_type_cmp("int16",
238 NETWIB_PRIV_FMT_FIELDTYPE_INT16);
239 netwib__priv_fmt_analyze_type_cmp("int64",
240 NETWIB_PRIV_FMT_FIELDTYPE_INT64);
241 break;
242 case 6 :
243 netwib__priv_fmt_analyze_type_cmp("intmax",
244 NETWIB_PRIV_FMT_FIELDTYPE_INTMAX);
245 netwib__priv_fmt_analyze_type_cmp("intptr",
246 NETWIB_PRIV_FMT_FIELDTYPE_INTPTR);
247 break;
248 }
249 break;
250 case 'p' :
251 switch (datasize) {
252 case 1 :
253 pinfos->fieldtype = NETWIB_PRIV_FMT_FIELDTYPE_P;
254 return(NETWIB_ERR_OK);
255 break;
256 case 4 :
257 netwib__priv_fmt_analyze_type_cmp("port",
258 NETWIB_PRIV_FMT_FIELDTYPE_PORT);
259 break;
260 case 5 :
261 netwib__priv_fmt_analyze_type_cmp("ports",
262 NETWIB_PRIV_FMT_FIELDTYPE_PORTS);
263 break;
264 }
265 break;
266 case 's' :
267 switch (datasize) {
268 case 1 :
269 pinfos->fieldtype = NETWIB_PRIV_FMT_FIELDTYPE_S;
270 return(NETWIB_ERR_OK);
271 break;
272 }
273 break;
274 case 'u' :
275 switch (datasize) {
276 case 5 :
277 netwib__priv_fmt_analyze_type_cmp("uint8",
278 NETWIB_PRIV_FMT_FIELDTYPE_UINT8);
279 break;
280 case 6 :
281 netwib__priv_fmt_analyze_type_cmp("uint32",
282 NETWIB_PRIV_FMT_FIELDTYPE_UINT32);
283 netwib__priv_fmt_analyze_type_cmp("uint16",
284 NETWIB_PRIV_FMT_FIELDTYPE_UINT16);
285 netwib__priv_fmt_analyze_type_cmp("uint64",
286 NETWIB_PRIV_FMT_FIELDTYPE_UINT64);
287 break;
288 case 7 :
289 netwib__priv_fmt_analyze_type_cmp("uintmax",
290 NETWIB_PRIV_FMT_FIELDTYPE_UINTMAX);
291 netwib__priv_fmt_analyze_type_cmp("uintptr",
292 NETWIB_PRIV_FMT_FIELDTYPE_UINTPTR);
293 break;
294 }
295 break;
296 }
297
298 netwib_er(netwib_priv_buf_append_vfmt_error2("type not recognized", fmt));
299 return(NETWIB_ERR_PAFMT);
300 }
301
302 /*-------------------------------------------------------------*/
netwib_priv_fmt_analyze_gene(netwib_conststring fmt,netwib_conststring gene,netwib_priv_fmtinfos * pinfos)303 static netwib_err netwib_priv_fmt_analyze_gene(netwib_conststring fmt,
304 netwib_conststring gene,
305 netwib_priv_fmtinfos *pinfos)
306 {
307 netwib_conststring pgene;
308
309 /* set default values */
310 pinfos->geneset = NETWIB_TRUE;
311 pinfos->gene.align = NETWIB_PRIV_FMT_ALIGNTYPE_LEFT;
312 pinfos->gene.padchar = ' ';
313 pinfos->gene.minsize = 0;
314 pinfos->gene.skipfield = NETWIB_FALSE;
315
316 /* decode pgene expressed as a regexp : "[*]{0,1}[lcr].[1-9][0-9]{0,1}"
317 or simply "[*]{0,1}" */
318 pgene = gene;
319
320 if (*pgene == '*') {
321 pinfos->gene.skipfield = NETWIB_TRUE;
322 pgene++;
323 if (*pgene == '\0') {
324 /* stop here */
325 return(NETWIB_ERR_OK);
326 }
327 }
328
329 switch(*pgene) {
330 case 'l' :
331 pinfos->gene.align = NETWIB_PRIV_FMT_ALIGNTYPE_LEFT;
332 break;
333 case 'c' :
334 pinfos->gene.align = NETWIB_PRIV_FMT_ALIGNTYPE_CENTER;
335 break;
336 case 'r' :
337 pinfos->gene.align = NETWIB_PRIV_FMT_ALIGNTYPE_RIGHT;
338 break;
339 default :
340 netwib_er(netwib_priv_buf_append_vfmt_error2("generic should start with l, c or r",
341 fmt));
342 return(NETWIB_ERR_PAFMT);
343 }
344 pgene++;
345
346 /* obtain padding */
347 if (*pgene == '\0') {
348 netwib_er(netwib_priv_buf_append_vfmt_error2("the padding char is missing",
349 fmt));
350 return(NETWIB_ERR_PAFMT);
351 }
352 pinfos->gene.padchar = *pgene++;
353
354 /* obtain minsize */
355 if (!netwib_c2_isdigit(*pgene)) {
356 netwib_er(netwib_priv_buf_append_vfmt_error2("the size is missing", fmt));
357 return(NETWIB_ERR_PAFMT);
358 }
359 pinfos->gene.minsize = netwib_c2_cto9(*pgene);
360 pgene++;
361 if (netwib_c2_isdigit(*pgene)) {
362 pinfos->gene.minsize *= 10;
363 pinfos->gene.minsize += netwib_c2_cto9(*pgene);
364 pgene++;
365 }
366
367 if (*pgene != '\0') {
368 netwib_er(netwib_priv_buf_append_vfmt_error2("specific parameter is too long",
369 fmt));
370 return(NETWIB_ERR_PAFMT);
371 }
372
373 return(NETWIB_ERR_OK);
374 }
375
376 /*-------------------------------------------------------------*/
netwib_priv_fmt_analyze_spec_s(netwib_conststring fmt,netwib_conststring spec,netwib_priv_fmt_spec_s * ps)377 static netwib_err netwib_priv_fmt_analyze_spec_s(netwib_conststring fmt,
378 netwib_conststring spec,
379 netwib_priv_fmt_spec_s *ps)
380 {
381
382 /* set default values */
383 ps->useglob = NETWIB_FALSE;
384
385 if (spec == NULL) {
386 return(NETWIB_ERR_OK);
387 }
388
389 if (!netwib_c_strcmp(spec, "glob")) {
390 ps->useglob = NETWIB_TRUE;
391 } else {
392 netwib_er(netwib_priv_buf_append_vfmt_error2("specific is not recognized",
393 fmt));
394 return(NETWIB_ERR_PAFMT);
395 }
396
397 return(NETWIB_ERR_OK);
398 }
399
400 /*-------------------------------------------------------------*/
netwib_priv_fmt_analyze_spec_uint(netwib_conststring fmt,netwib_conststring spec,netwib_priv_fmt_spec_uint * ps)401 static netwib_err netwib_priv_fmt_analyze_spec_uint(netwib_conststring fmt,
402 netwib_conststring spec,
403 netwib_priv_fmt_spec_uint *ps)
404 {
405 netwib_conststring pspec;
406
407 /* set default values */
408 ps->altformat = NETWIB_FALSE;
409 ps->minsize = 0;
410 ps->base = 10;
411
412 if (spec == NULL) {
413 return(NETWIB_ERR_OK);
414 }
415 pspec = spec;
416
417 /* analyze pspec which should contain "[0]{0,1}[0-9]{0,2}[bouxX]" */
418
419 /* set alternative format */
420 if (*pspec == '#') {
421 ps->altformat = NETWIB_TRUE;
422 pspec++;
423 }
424
425 /* set minsize */
426 if (netwib_c2_isdigit(*pspec)) {
427 ps->minsize = netwib_c2_cto9(*pspec);
428 pspec++;
429 }
430 if (netwib_c2_isdigit(*pspec)) {
431 ps->minsize *= 10;
432 ps->minsize += netwib_c2_cto9(*pspec);
433 pspec++;
434 }
435
436 /* set base */
437 switch (*pspec) {
438 case 'b' :
439 ps->base = 2;
440 pspec++;
441 break;
442 case 'o' :
443 ps->base = 8;
444 pspec++;
445 break;
446 case 'u' :
447 ps->base = 10;
448 pspec++;
449 break;
450 case 'x' :
451 ps->base = 16;
452 pspec++;
453 break;
454 case 'X' :
455 ps->base = 17;
456 pspec++;
457 break;
458 case '\0' :
459 break;
460 default :
461 netwib_er(netwib_priv_buf_append_vfmt_error2("specific base is not b, o, u, x or X", fmt));
462 return(NETWIB_ERR_PAFMT);
463 }
464
465 /* now, should be empty */
466 if (*pspec != '\0') {
467 netwib_er(netwib_priv_buf_append_vfmt_error2("specific base is not recognized", fmt));
468 return(NETWIB_ERR_PAFMT);
469 }
470
471 return(NETWIB_ERR_OK);
472 }
473
474 /*-------------------------------------------------------------*/
netwib_priv_fmt_analyze_spec_int(netwib_conststring fmt,netwib_conststring spec,netwib_priv_fmt_spec_int * ps)475 static netwib_err netwib_priv_fmt_analyze_spec_int(netwib_conststring fmt,
476 netwib_conststring spec,
477 netwib_priv_fmt_spec_int *ps)
478 {
479 netwib_conststring pspec;
480
481 /* set default values */
482 ps->sign = NETWIB_FALSE;
483 ps->minsize = 0;
484
485 if (spec == NULL) {
486 return(NETWIB_ERR_OK);
487 }
488 pspec = spec;
489
490 /* analyze pspec which should contain "[+]{0,1}[0-9]{0,2}" */
491
492 /* set sign */
493 if (*pspec == '+') {
494 ps->sign = NETWIB_TRUE;
495 pspec++;
496 }
497
498 /* set minsize */
499 if (netwib_c2_isdigit(*pspec)) {
500 ps->minsize = netwib_c2_cto9(*pspec);
501 pspec++;
502 }
503 if (netwib_c2_isdigit(*pspec)) {
504 ps->minsize *= 10;
505 ps->minsize += netwib_c2_cto9(*pspec);
506 pspec++;
507 }
508
509 /* now, should be empty */
510 if (*pspec != '\0') {
511 netwib_er(netwib_priv_buf_append_vfmt_error2("specific base is not recognized", fmt));
512 return(NETWIB_ERR_PAFMT);
513 }
514
515 return(NETWIB_ERR_OK);
516 }
517
518 /*-------------------------------------------------------------*/
netwib_priv_fmt_analyze_spec_bool(netwib_conststring fmt,netwib_conststring spec,netwib_priv_fmt_spec_bool * ps)519 static netwib_err netwib_priv_fmt_analyze_spec_bool(netwib_conststring fmt,
520 netwib_conststring spec,
521 netwib_priv_fmt_spec_bool *ps)
522 {
523 netwib_conststring pspec;
524
525 /* set default value */
526 ps->type = 't';
527
528 if (spec == NULL) {
529 return(NETWIB_ERR_OK);
530 }
531 pspec = spec;
532
533 /* analyze pspec which should contain "[0tTyYsS]{0,1}" */
534 switch(*pspec) {
535 case '0' :
536 case 't' :
537 case 'T' :
538 case 'y' :
539 case 'Y' :
540 case 's' :
541 case 'S' :
542 ps->type = *pspec;
543 break;
544 default :
545 netwib_er(netwib_priv_buf_append_vfmt_error2("specific is not 0, t, T, y, Y, s or S", fmt));
546 return(NETWIB_ERR_PAFMT);
547 break;
548 }
549
550 return(NETWIB_ERR_OK);
551 }
552
553 /*-------------------------------------------------------------*/
netwib_priv_fmt_analyze_spec_cmp(netwib_conststring fmt,netwib_conststring spec,netwib_priv_fmt_spec_cmp * ps)554 static netwib_err netwib_priv_fmt_analyze_spec_cmp(netwib_conststring fmt,
555 netwib_conststring spec,
556 netwib_priv_fmt_spec_cmp *ps)
557 {
558 netwib_conststring pspec;
559
560 /* set default value */
561 ps->type = 't';
562
563 if (spec == NULL) {
564 return(NETWIB_ERR_OK);
565 }
566 pspec = spec;
567
568 /* analyze pspec which should contain "[=0e]{0,1}" */
569 switch(*pspec) {
570 case '=' :
571 case '0' :
572 case 'e' :
573 ps->type = *pspec;
574 break;
575 default :
576 netwib_er(netwib_priv_buf_append_vfmt_error2("specific is not =, 0 or e",
577 fmt));
578 return(NETWIB_ERR_PAFMT);
579 break;
580 }
581
582 return(NETWIB_ERR_OK);
583 }
584
585 /*-------------------------------------------------------------*/
netwib_priv_fmt_analyze_spec_buf(netwib_conststring fmt,netwib_conststring spec,netwib_priv_fmt_spec_buf * ps)586 static netwib_err netwib_priv_fmt_analyze_spec_buf(netwib_conststring fmt,
587 netwib_conststring spec,
588 netwib_priv_fmt_spec_buf *ps)
589 {
590
591 /* set default values */
592 ps->useglob = NETWIB_FALSE;
593
594 if (spec == NULL) {
595 return(NETWIB_ERR_OK);
596 }
597
598 if (!netwib_c_strcmp(spec, "glob")) {
599 ps->useglob = NETWIB_TRUE;
600 } else {
601 netwib_er(netwib_priv_buf_append_vfmt_error2("specific is not recognized",
602 fmt));
603 return(NETWIB_ERR_PAFMT);
604 }
605
606 return(NETWIB_ERR_OK);
607 }
608
609 /*-------------------------------------------------------------*/
netwib_priv_fmt_analyze2(netwib_conststring fmt,netwib_priv_fmtinfos * pinfos)610 static netwib_err netwib_priv_fmt_analyze2(netwib_conststring fmt,
611 netwib_priv_fmtinfos *pinfos)
612 {
613 netwib_char array[3][NETWIB_PRIV_FMT_FIELD_MAXSIZE+1];
614 netwib_conststring pfmt;
615 netwib_string pgene, ptype, pspec;
616 netwib_char c;
617 netwib_uint32 setsize, storeinarray;
618 netwib_bool continuetoloop;
619
620 /*
621 Decompose generalformat;type:specificformat :
622 %{type}
623 %{generalformat;type:specificformat}
624 %{generalformat;type}
625 %{type:specificformat}
626 */
627
628 pfmt = fmt + 1;
629 setsize = 0;
630 storeinarray = 0;
631 pgene = NULL;
632 ptype = NULL;
633 pspec = NULL;
634 continuetoloop = NETWIB_TRUE;
635 while (continuetoloop) {
636 c = *pfmt++;
637 switch (c) {
638 case '\0' :
639 netwib_er(netwib_priv_buf_append_vfmt_error2("character '}' not found",
640 fmt));
641 return(NETWIB_ERR_PAFMT);
642 case '}' :
643 array[storeinarray][setsize] = '\0';
644 if (storeinarray == 0) {
645 ptype = (netwib_string)&(array[storeinarray]);
646 } else if (storeinarray == 1) {
647 if (ptype == NULL) {
648 ptype = (netwib_string)&(array[storeinarray]);
649 } else {
650 pspec = (netwib_string)&(array[storeinarray]);
651 }
652 } else {
653 pspec = (netwib_string)&(array[storeinarray]);
654 }
655 continuetoloop = NETWIB_FALSE;
656 break;
657 case ';' :
658 array[storeinarray][setsize] = '\0';
659 if (storeinarray == 0) {
660 pgene = (netwib_string)&(array[storeinarray]);
661 storeinarray++;
662 setsize = 0;
663 } else {
664 netwib_er(netwib_priv_buf_append_vfmt_error2("char ';' found too late", fmt));
665 return(NETWIB_ERR_PAFMT);
666 }
667 break;
668 case ':' :
669 array[storeinarray][setsize] = '\0';
670 if (storeinarray == 2) {
671 netwib_er(netwib_priv_buf_append_vfmt_error2("char ':' found too late", fmt));
672 return(NETWIB_ERR_PAFMT);
673 } else {
674 ptype = (netwib_string)&(array[storeinarray]);
675 storeinarray++;
676 setsize = 0;
677 }
678 break;
679 default :
680 array[storeinarray][setsize++] = c;
681 }
682 if (setsize > NETWIB_PRIV_FMT_FIELD_MAXSIZE) {
683 netwib_er(netwib_priv_buf_append_vfmt_error2("format is too long", fmt));
684 return(NETWIB_ERR_PAFMT);
685 }
686 }
687
688 /* reset pointers if string are empty */
689 if (pgene != NULL && pgene[0] == '\0') pgene = NULL;
690 if (ptype != NULL && ptype[0] == '\0') ptype = NULL;
691 if (pspec != NULL && pspec[0] == '\0') pspec = NULL;
692
693 /* set info values */
694 pinfos->skipsize = pfmt - fmt;
695
696 if (ptype == NULL) {
697 netwib_er(netwib_priv_buf_append_vfmt_error2("format type must be present",
698 fmt));
699 return(NETWIB_ERR_PAFMT);
700 }
701 netwib_er(netwib_priv_fmt_analyze_type(fmt, ptype, pinfos));
702
703 if (pgene == NULL) {
704 pinfos->geneset = NETWIB_FALSE;
705 } else {
706 netwib_er(netwib_priv_fmt_analyze_gene(fmt, pgene, pinfos));
707 }
708
709 switch(pinfos->fieldtype) {
710 case NETWIB_PRIV_FMT_FIELDTYPE_UINT32 :
711 case NETWIB_PRIV_FMT_FIELDTYPE_UINT16 :
712 case NETWIB_PRIV_FMT_FIELDTYPE_UINT8 :
713 case NETWIB_PRIV_FMT_FIELDTYPE_UINT64 :
714 case NETWIB_PRIV_FMT_FIELDTYPE_UINTMAX :
715 case NETWIB_PRIV_FMT_FIELDTYPE_UINTPTR :
716 case NETWIB_PRIV_FMT_FIELDTYPE_BYTE :
717 netwib_er(netwib_priv_fmt_analyze_spec_uint(fmt, pspec,
718 &pinfos->spec.specuint));
719 pinfos->specset = NETWIB_TRUE;
720 break;
721 case NETWIB_PRIV_FMT_FIELDTYPE_INT32 :
722 case NETWIB_PRIV_FMT_FIELDTYPE_INT16 :
723 case NETWIB_PRIV_FMT_FIELDTYPE_INT8 :
724 case NETWIB_PRIV_FMT_FIELDTYPE_INT64 :
725 case NETWIB_PRIV_FMT_FIELDTYPE_INTMAX :
726 case NETWIB_PRIV_FMT_FIELDTYPE_INTPTR :
727 netwib_er(netwib_priv_fmt_analyze_spec_int(fmt, pspec,
728 &pinfos->spec.specint));
729 pinfos->specset = NETWIB_TRUE;
730 break;
731 case NETWIB_PRIV_FMT_FIELDTYPE_BOOL :
732 if (pspec == NULL) {
733 pinfos->specset = NETWIB_FALSE;
734 } else {
735 netwib_er(netwib_priv_fmt_analyze_spec_bool(fmt, pspec,
736 &pinfos->spec.specbool));
737 pinfos->specset = NETWIB_TRUE;
738 }
739 break;
740 case NETWIB_PRIV_FMT_FIELDTYPE_CMP :
741 if (pspec == NULL) {
742 pinfos->specset = NETWIB_FALSE;
743 } else {
744 netwib_er(netwib_priv_fmt_analyze_spec_cmp(fmt, pspec,
745 &pinfos->spec.speccmp));
746 pinfos->specset = NETWIB_TRUE;
747 }
748 break;
749 case NETWIB_PRIV_FMT_FIELDTYPE_S :
750 netwib_er(netwib_priv_fmt_analyze_spec_s(fmt, pspec,
751 &pinfos->spec.specs));
752 pinfos->specset = NETWIB_TRUE;
753 break;
754 case NETWIB_PRIV_FMT_FIELDTYPE_BUF :
755 netwib_er(netwib_priv_fmt_analyze_spec_buf(fmt, pspec,
756 &pinfos->spec.specbuf));
757 pinfos->specset = NETWIB_TRUE;
758 break;
759 case NETWIB_PRIV_FMT_FIELDTYPE_C :
760 case NETWIB_PRIV_FMT_FIELDTYPE_P :
761 case NETWIB_PRIV_FMT_FIELDTYPE_ETH :
762 case NETWIB_PRIV_FMT_FIELDTYPE_IP :
763 case NETWIB_PRIV_FMT_FIELDTYPE_PORT :
764 case NETWIB_PRIV_FMT_FIELDTYPE_ETHS :
765 case NETWIB_PRIV_FMT_FIELDTYPE_IPS :
766 case NETWIB_PRIV_FMT_FIELDTYPE_PORTS :
767 if (pspec == NULL) {
768 pinfos->specset = NETWIB_FALSE;
769 } else {
770 netwib_er(netwib_priv_buf_append_vfmt_error2("there should be no specific parameter", fmt));
771 return(NETWIB_ERR_PAFMT);
772 }
773 break;
774 case NETWIB_PRIV_FMT_FIELDTYPE_PERCENT :
775 case NETWIB_PRIV_FMT_FIELDTYPE_END :
776 return(NETWIB_ERR_LOINTERNALERROR);
777 break;
778 }
779
780 return(NETWIB_ERR_OK);
781 }
782
783 /*-------------------------------------------------------------*/
netwib_priv_fmt_analyze(netwib_conststring fmt,netwib_priv_fmtinfos * pinfos)784 static netwib_err netwib_priv_fmt_analyze(netwib_conststring fmt,
785 netwib_priv_fmtinfos *pinfos)
786 {
787 char fmtfirstchar;
788
789 fmtfirstchar = *fmt;
790
791 pinfos->geneset = NETWIB_FALSE;
792 pinfos->specset = NETWIB_FALSE;
793
794 /* fmt ends */
795 if (fmtfirstchar == '\0') {
796 netwib_er(netwib_priv_buf_append_vfmt_error("format ends with '%'"));
797 return(NETWIB_ERR_PAFMT);
798 }
799
800 /* character '%' */
801 if (fmtfirstchar == '%') {
802 pinfos->fieldtype = NETWIB_PRIV_FMT_FIELDTYPE_PERCENT;
803 pinfos->skipsize = 1;
804 return(NETWIB_ERR_OK);
805 }
806
807 /* char */
808 if (fmtfirstchar == 'c') {
809 pinfos->fieldtype = NETWIB_PRIV_FMT_FIELDTYPE_C;
810 pinfos->skipsize = 1;
811 return(NETWIB_ERR_OK);
812 }
813
814 /* string */
815 if (fmtfirstchar == 's') {
816 pinfos->fieldtype = NETWIB_PRIV_FMT_FIELDTYPE_S;
817 pinfos->skipsize = 1;
818 return(NETWIB_ERR_OK);
819 }
820
821 /* pointer */
822 if (fmtfirstchar == 'p') {
823 pinfos->fieldtype = NETWIB_PRIV_FMT_FIELDTYPE_P;
824 pinfos->skipsize = 1;
825 return(NETWIB_ERR_OK);
826 }
827
828 /* end */
829 if (fmtfirstchar == '$') {
830 pinfos->fieldtype = NETWIB_PRIV_FMT_FIELDTYPE_END;
831 pinfos->skipsize = 1;
832 return(NETWIB_ERR_OK);
833 }
834
835 /* specific type */
836 if (fmtfirstchar == '{') {
837 netwib_er(netwib_priv_fmt_analyze2(fmt, pinfos));
838 return(NETWIB_ERR_OK);
839 }
840
841 netwib_er(netwib_priv_buf_append_vfmt_error2("format is not recognized",
842 fmt));
843 return(NETWIB_ERR_PAFMT);
844 }
845
846
847 /*-------------------------------------------------------------*/
848 /*-------------------------------------------------------------*/
849 /*-------------------------------------------------------------*/
850 /*-------------------------------------------------------------*/
851
852 /*-------------------------------------------------------------*/
853 /* 99 + '\0' = 100 characters. Do not define NETWIB_PRIV_FMT_ARR_SIZE
854 to less than 100 (not checked). */
855 #define NETWIB_PRIV_FMT_ARR_SIZE 100
856
857 /*-------------------------------------------------------------*/
858 static netwib_uint64 netwib_priv_fmt_ui64_unused;
859 #define netwib_priv_fmt_append_uintmax(uimax,ps,array) netwib_priv_fmt_append_uint(NETWIB_TRUE,uimax,netwib_priv_fmt_ui64_unused,ps,array)
860 #if NETWIB_INT64_FAKE == 0
861 #define netwib_priv_fmt_append_uint64(ui64,ps,array) netwib_priv_fmt_append_uint(NETWIB_TRUE,ui64,netwib_priv_fmt_ui64_unused,ps,array)
862 #else
863 #define netwib_priv_fmt_append_uint64(ui64,ps,array) netwib_priv_fmt_append_uint(NETWIB_FALSE,0,ui64,ps,array)
864 #endif
netwib_priv_fmt_append_uint(netwib_bool usemax,netwib_uintmax uimax,netwib_uint64 ui64,netwib_priv_fmt_spec_uint * ps,netwib_string array)865 static netwib_err netwib_priv_fmt_append_uint(netwib_bool usemax,
866 netwib_uintmax uimax,
867 netwib_uint64 ui64,
868 netwib_priv_fmt_spec_uint *ps,
869 netwib_string array)
870 {
871 netwib_char localarray[NETWIB_PRIV_FMT_ARR_SIZE], *ploc, c;
872 netwib_string pout;
873 netwib_uint32 nbdigit, nbzeroes, c32, base32;
874 netwib_uint64 zero;
875
876 netwib__uint64_init_uint32(0, zero);
877
878 nbdigit = 0;
879 base32 = ps->base;
880 if (ps->base == 17) base32 = 16;
881 if (usemax && uimax != 0) {
882 netwib_uintmax uidivbase, uidivbaseperbase;
883 do {
884 uidivbase = uimax / base32;
885 uidivbaseperbase = uidivbase * base32;
886 c32 = (netwib_uint32)(uimax - uidivbaseperbase);
887 if (ps->base == 17) {
888 c = netwib_c2_16toC(c32);
889 } else {
890 c = netwib_c2_16toc(c32);
891 }
892 localarray[nbdigit++] = c;
893 uimax = uidivbase;
894 } while (uimax != 0);
895 } else if (!usemax && netwib__uint64_cmp_ne(ui64, zero)) {
896 netwib_uint64 base64, uidivbase, uidivbaseperbase, c64, remainder;
897 netwib__uint64_init_uint32(base32, base64);
898 do {
899 netwib__uint64_div(ui64, base64, &uidivbase, &remainder);
900 netwib__uint64_mul(uidivbase, base64, &uidivbaseperbase);
901 netwib__uint64_sub(ui64, uidivbaseperbase, c64);
902 netwib__uint32_init_uint64(c64, c32);
903 if (ps->base == 17) {
904 c = netwib_c2_16toC(c32);
905 } else {
906 c = netwib_c2_16toc(c32);
907 }
908 localarray[nbdigit++] = c;
909 ui64 = uidivbase;
910 } while (netwib__uint64_cmp_ne(ui64, zero));
911 } else {
912 localarray[nbdigit++] = '0';
913 }
914 localarray[nbdigit] = '\0';
915
916 if (ps->minsize == 0) {
917 nbzeroes = 0;
918 } else {
919 if (nbdigit >= ps->minsize) {
920 nbzeroes = 0;
921 } else {
922 nbzeroes = ps->minsize - nbdigit;
923 }
924 }
925
926 ploc = localarray + nbdigit;
927 pout = array;
928 switch(ps->base) {
929 case 2 :
930 if (ps->altformat) {
931 *pout++ = 'b';
932 }
933 while (nbzeroes) {
934 *pout++ = '0';
935 nbzeroes--;
936 }
937 break;
938 case 8 :
939 if (ps->altformat) {
940 *pout++ = '0';
941 }
942 while (nbzeroes) {
943 *pout++ = '0';
944 nbzeroes--;
945 }
946 break;
947 case 10 :
948 while (nbzeroes) {
949 *pout++ = ' ';
950 nbzeroes--;
951 }
952 break;
953 case 16 :
954 case 17 :
955 if (ps->altformat) {
956 *pout++ = '0';
957 *pout++ = 'x';
958 }
959 while (nbzeroes) {
960 *pout++ = '0';
961 nbzeroes--;
962 }
963 break;
964 default :
965 return(NETWIB_ERR_LOINTERNALERROR);
966 }
967 while (nbdigit) {
968 *pout++ = *--ploc;
969 nbdigit--;
970 }
971 *pout++ = '\0';
972
973 return(NETWIB_ERR_OK);
974 }
975
976 /*-------------------------------------------------------------*/
977 #define netwib_priv_fmt_append_intmax(imax,ps,array) netwib_priv_fmt_append_int(NETWIB_TRUE,imax,netwib_priv_fmt_ui64_unused,ps,array)
978 #if NETWIB_INT64_FAKE == 0
979 #define netwib_priv_fmt_append_int64(i64,ps,array) netwib_priv_fmt_append_int(NETWIB_TRUE,i64,netwib_priv_fmt_ui64_unused,ps,array)
980 #else
981 #define netwib_priv_fmt_append_int64(i64,ps,array) netwib_priv_fmt_append_int(NETWIB_FALSE,0,i64,ps,array)
982 #endif
netwib_priv_fmt_append_int(netwib_bool usemax,netwib_intmax imax,netwib_int64 i64,netwib_priv_fmt_spec_int * ps,netwib_string array)983 static netwib_err netwib_priv_fmt_append_int(netwib_bool usemax,
984 netwib_intmax imax,
985 netwib_int64 i64,
986 netwib_priv_fmt_spec_int *ps,
987 netwib_string array)
988 {
989 netwib_priv_fmt_spec_uint su;
990 netwib_uint32 startat;
991 netwib_uintmax uimax=0;
992 netwib_uint64 ui64, zero;
993 netwib_cmp cmp;
994
995 netwib__uint64_init_uint32(0, ui64);
996
997 cmp = NETWIB_CMP_LT;
998 if (usemax) {
999 if (imax == 0) {
1000 cmp = NETWIB_CMP_EQ;
1001 } else if (imax > 0) {
1002 cmp = NETWIB_CMP_GT;
1003 }
1004 } else {
1005 netwib__uint64_init_uint32(0, zero);
1006 if (netwib__int64_cmp_eq(i64, zero)) {
1007 cmp = NETWIB_CMP_EQ;
1008 } else if (netwib__int64_cmp_gt(i64, zero)) {
1009 cmp = NETWIB_CMP_GT;
1010 }
1011 }
1012
1013 /* eventually put a sign */
1014 startat = 0;
1015 if (cmp == NETWIB_CMP_LT) {
1016 if (usemax) {
1017 uimax = (netwib_uintmax)-imax;
1018 } else {
1019 netwib__int64_neg(i64, ui64);
1020 }
1021 /* put a '-' */
1022 array[0] = '-';
1023 startat = 1;
1024 } else {
1025 if (usemax) {
1026 uimax = (netwib_uintmax)imax;
1027 } else {
1028 ui64 = (netwib_uint64)i64;
1029 }
1030 /* eventually put a '+' (nothing for zero) */
1031 if (ps->sign && cmp == NETWIB_CMP_GT) {
1032 array[0] = '+';
1033 startat = 1;
1034 }
1035 }
1036 if (startat) {
1037 /* shrink minsize */
1038 if (ps->minsize) {
1039 ps->minsize--;
1040 }
1041 }
1042
1043 su.altformat = NETWIB_FALSE;
1044 su.minsize = ps->minsize;
1045 su.base = 10;
1046 netwib_er(netwib_priv_fmt_append_uint(usemax, uimax, ui64,
1047 &su, array+startat));
1048
1049 return(NETWIB_ERR_OK);
1050 }
1051
1052 /*-------------------------------------------------------------*/
netwib_priv_fmt_append_eth(netwib_consteth * peth,netwib_string array)1053 static netwib_err netwib_priv_fmt_append_eth(netwib_consteth *peth,
1054 netwib_string array)
1055 {
1056 netwib_string parray;
1057 netwib_uint32 ethbyte, ethquartet;
1058 netwib_uint32 i;
1059
1060 parray = array;
1061 for (i = 0; i < 6; i++) {
1062 ethbyte = peth->b[i];
1063 ethquartet = (ethbyte>>4) & 0x0F;
1064 *parray++ = netwib_c2_16toC(ethquartet);
1065 ethquartet = ethbyte & 0x0F;
1066 *parray++ = netwib_c2_16toC(ethquartet);
1067 if (i != 5) {
1068 *parray++ = ':';
1069 }
1070 }
1071 *parray ='\0';
1072
1073 return(NETWIB_ERR_OK);
1074 }
1075
1076 /*-------------------------------------------------------------*/
netwib_priv_fmt_append_gene(netwib_conststring str,netwib_priv_fmtinfos * pinfos,netwib_buf * pbuf)1077 static netwib_err netwib_priv_fmt_append_gene(netwib_conststring str,
1078 netwib_priv_fmtinfos *pinfos,
1079 netwib_buf *pbuf)
1080 {
1081 netwib_char localarray[NETWIB_PRIV_FMT_ARR_SIZE], *ploc;
1082 netwib_conststring pstr;
1083 netwib_uint32 strlenstr, nbpad, nbpadl, nbpadr;
1084 netwib_err ret;
1085
1086 if (pinfos->gene.minsize > NETWIB_PRIV_FMT_ARR_SIZE-1) {
1087 return(NETWIB_ERR_LOINTERNALERROR);
1088 }
1089
1090 /* simple case */
1091 strlenstr = netwib_c_strlen(str);
1092 if (pinfos->gene.minsize <= strlenstr) {
1093 netwib_er(netwib_buf_append_string(str, pbuf));
1094 return(NETWIB_ERR_OK);
1095 }
1096
1097 /* compute padding */
1098 nbpadl = 0; /* for compiler warning */
1099 nbpadr = 0; /* for compiler warning */
1100 nbpad = pinfos->gene.minsize - strlenstr;
1101 switch (pinfos->gene.align) {
1102 case NETWIB_PRIV_FMT_ALIGNTYPE_LEFT :
1103 nbpadl = 0;
1104 nbpadr = nbpad;
1105 break;
1106 case NETWIB_PRIV_FMT_ALIGNTYPE_CENTER :
1107 nbpadl = nbpad >> 1;
1108 nbpadr = nbpadl;
1109 if (nbpad&1) nbpadr++; /* if odd, one more at right */
1110 break;
1111 case NETWIB_PRIV_FMT_ALIGNTYPE_RIGHT :
1112 nbpadl = nbpad;
1113 nbpadr = 0;
1114 break;
1115 }
1116
1117 /* generate string */
1118 ploc = localarray;
1119 pstr = str;
1120 while (nbpadl) {
1121 *ploc++ = pinfos->gene.padchar;
1122 nbpadl--;
1123 }
1124 while (strlenstr) {
1125 *ploc++ = *pstr++;
1126 strlenstr--;
1127 }
1128 while (nbpadr) {
1129 *ploc++ = pinfos->gene.padchar;
1130 nbpadr--;
1131 }
1132 *ploc = '\0';
1133
1134 /* add it */
1135 ret = netwib_buf_append_string(localarray, pbuf);
1136 netwib__localarray_ifbuf_wipe(pbuf, localarray);
1137 return(ret);
1138 }
1139
1140 /*-------------------------------------------------------------*/
netwib_priv_fmt_append(netwib_buf * pbuf,netwib_conststring fmt,va_list * pap,netwib_priv_fmtinfos * pinfos)1141 static netwib_err netwib_priv_fmt_append(netwib_buf *pbuf,
1142 netwib_conststring fmt,
1143 va_list *pap,
1144 netwib_priv_fmtinfos *pinfos)
1145 {
1146 netwib_char array[NETWIB_PRIV_FMT_ARR_SIZE];
1147 netwib_buf localbuf;
1148 netwib_string localstring;
1149 netwib_err ret;
1150
1151 /* check if everything is fine for append */
1152 if (pinfos->geneset && pinfos->gene.skipfield) {
1153 netwib_er(netwib_priv_buf_append_vfmt_error2("an '*' is forbidden for append", fmt));
1154 return(NETWIB_ERR_PAFMT);
1155 }
1156
1157 netwib_er(netwib_buf_init_ext_storagearraysizeof(array, &localbuf));
1158
1159 /* append depending on type */
1160 switch(pinfos->fieldtype) {
1161 case NETWIB_PRIV_FMT_FIELDTYPE_END :
1162 netwib_er(netwib_priv_buf_append_vfmt_error2("a %$ is forbidden for append", fmt));
1163 return(NETWIB_ERR_PAFMT);
1164 break;
1165 case NETWIB_PRIV_FMT_FIELDTYPE_PERCENT :
1166 netwib_er(netwib_buf_append_byte('%', pbuf));
1167 /* leave here */
1168 return(NETWIB_ERR_OK);
1169 break;
1170 case NETWIB_PRIV_FMT_FIELDTYPE_C :
1171 {
1172 char c;
1173 /* Note : on some systems, there is a "cast increases required
1174 alignment size" warning here. It can be ignored */
1175 c = (char)va_arg(*pap, int);
1176 if (pinfos->geneset) {
1177 array[0] = c;
1178 array[1] = '\0';
1179 netwib_er(netwib_priv_fmt_append_gene(array, pinfos, pbuf));
1180 } else {
1181 netwib_er(netwib_buf_append_byte(c, pbuf));
1182 }
1183 }
1184 break;
1185 case NETWIB_PRIV_FMT_FIELDTYPE_BOOL :
1186 {
1187 netwib_bool b;
1188 netwib_conststring pstr;
1189 b = va_arg(*pap, netwib_bool);
1190 pstr = b?"true":"false";
1191 if (pinfos->specset) {
1192 switch(pinfos->spec.specbool.type) {
1193 case '0' : pstr = b?"1":"0"; break;
1194 case 'T' : pstr = b?"TRUE":"FALSE"; break;
1195 case 'y' : pstr = b?"yes":"no"; break;
1196 case 'Y' : pstr = b?"YES":"NO"; break;
1197 case 's' : pstr = b?"set":"unset"; break;
1198 case 'S' : pstr = b?"SET":"UNSET"; break;
1199 }
1200 }
1201 if (pinfos->geneset) {
1202 netwib_er(netwib_priv_fmt_append_gene(pstr, pinfos, pbuf));
1203 } else {
1204 netwib_er(netwib_buf_append_string(pstr, pbuf));
1205 }
1206 }
1207 break;
1208 case NETWIB_PRIV_FMT_FIELDTYPE_CMP :
1209 {
1210 netwib_cmp cmp;
1211 netwib_conststring pstr;
1212 cmp = va_arg(*pap, netwib_cmp);
1213 pstr = (cmp==NETWIB_CMP_LT)?"<":((cmp==NETWIB_CMP_EQ)?"=":">");
1214 if (pinfos->specset) {
1215 switch(pinfos->spec.specbool.type) {
1216 case '0' :
1217 pstr = (cmp==NETWIB_CMP_LT)?"-":((cmp==NETWIB_CMP_EQ)?"0":"+");
1218 break;
1219 case 'e' :
1220 pstr = (cmp==NETWIB_CMP_LT)?"lt":((cmp==NETWIB_CMP_EQ)?"eq":"gt");
1221 break;
1222 }
1223 }
1224 if (pinfos->geneset) {
1225 netwib_er(netwib_priv_fmt_append_gene(pstr, pinfos, pbuf));
1226 } else {
1227 netwib_er(netwib_buf_append_string(pstr, pbuf));
1228 }
1229 }
1230 break;
1231 case NETWIB_PRIV_FMT_FIELDTYPE_S :
1232 {
1233 netwib_char *pc;
1234 if (pinfos->specset && pinfos->spec.specs.useglob) {
1235 netwib_er(netwib_priv_buf_append_vfmt_error2("glob is forbidden for append", fmt));
1236 return(NETWIB_ERR_PAFMT);
1237 }
1238 pc = va_arg(*pap, netwib_char*);
1239 if (pinfos->geneset) {
1240 netwib_er(netwib_priv_fmt_append_gene(pc, pinfos, pbuf));
1241 } else {
1242 netwib_er(netwib_buf_append_string(pc, pbuf));
1243 }
1244 }
1245 break;
1246 case NETWIB_PRIV_FMT_FIELDTYPE_P :
1247 {
1248 netwib_priv_fmt_spec_uint su;
1249 void *p;
1250 p = va_arg(*pap, void*);
1251 array[0] = '0';
1252 array[1] = 'x';
1253 su.altformat = NETWIB_FALSE;
1254 su.minsize = 2*sizeof(void*);
1255 su.base = 16;
1256 netwib_er(netwib_priv_fmt_append_uintmax((netwib_uintptr)p, &su,
1257 array+2));
1258 if (pinfos->geneset) {
1259 netwib_er(netwib_priv_fmt_append_gene(array, pinfos, pbuf));
1260 } else {
1261 netwib_er(netwib_buf_append_string(array, pbuf));
1262 }
1263 }
1264 break;
1265 case NETWIB_PRIV_FMT_FIELDTYPE_UINT32 :
1266 case NETWIB_PRIV_FMT_FIELDTYPE_UINT16 :
1267 case NETWIB_PRIV_FMT_FIELDTYPE_UINT8 :
1268 case NETWIB_PRIV_FMT_FIELDTYPE_BYTE :
1269 case NETWIB_PRIV_FMT_FIELDTYPE_UINTMAX :
1270 case NETWIB_PRIV_FMT_FIELDTYPE_UINTPTR :
1271 {
1272 netwib_uintmax ui=0;
1273 switch(pinfos->fieldtype) {
1274 case NETWIB_PRIV_FMT_FIELDTYPE_UINTMAX :
1275 ui = va_arg(*pap, netwib_uintmax);
1276 break;
1277 case NETWIB_PRIV_FMT_FIELDTYPE_UINTPTR :
1278 ui = va_arg(*pap, netwib_uintptr);
1279 break;
1280 default :
1281 ui = va_arg(*pap, netwib_uint32);
1282 break;
1283 }
1284 netwib_er(netwib_priv_fmt_append_uintmax(ui, &pinfos->spec.specuint,
1285 array));
1286 if (pinfos->geneset) {
1287 netwib_er(netwib_priv_fmt_append_gene(array, pinfos, pbuf));
1288 } else {
1289 netwib_er(netwib_buf_append_string(array, pbuf));
1290 }
1291 }
1292 break;
1293 case NETWIB_PRIV_FMT_FIELDTYPE_UINT64 :
1294 {
1295 netwib_uint64 ui;
1296 ui = va_arg(*pap, netwib_uint64);
1297 netwib_er(netwib_priv_fmt_append_uint64(ui, &pinfos->spec.specuint,
1298 array));
1299 if (pinfos->geneset) {
1300 netwib_er(netwib_priv_fmt_append_gene(array, pinfos, pbuf));
1301 } else {
1302 netwib_er(netwib_buf_append_string(array, pbuf));
1303 }
1304 }
1305 break;
1306 case NETWIB_PRIV_FMT_FIELDTYPE_INT32 :
1307 case NETWIB_PRIV_FMT_FIELDTYPE_INT16 :
1308 case NETWIB_PRIV_FMT_FIELDTYPE_INT8 :
1309 case NETWIB_PRIV_FMT_FIELDTYPE_INTMAX :
1310 case NETWIB_PRIV_FMT_FIELDTYPE_INTPTR :
1311 {
1312 netwib_intmax i=0;
1313 switch(pinfos->fieldtype) {
1314 case NETWIB_PRIV_FMT_FIELDTYPE_INTMAX :
1315 i = va_arg(*pap, netwib_intmax);
1316 break;
1317 case NETWIB_PRIV_FMT_FIELDTYPE_INTPTR :
1318 i = va_arg(*pap, netwib_intptr);
1319 break;
1320 default :
1321 i = va_arg(*pap, netwib_int32);
1322 break;
1323 }
1324 netwib_er(netwib_priv_fmt_append_intmax(i, &pinfos->spec.specint,
1325 array));
1326 if (pinfos->geneset) {
1327 netwib_er(netwib_priv_fmt_append_gene(array, pinfos, pbuf));
1328 } else {
1329 netwib_er(netwib_buf_append_string(array, pbuf));
1330 }
1331 }
1332 break;
1333 case NETWIB_PRIV_FMT_FIELDTYPE_INT64 :
1334 {
1335 netwib_int64 i;
1336 i = va_arg(*pap, netwib_int64);
1337 netwib_er(netwib_priv_fmt_append_int64(i, &pinfos->spec.specint,
1338 array));
1339 if (pinfos->geneset) {
1340 netwib_er(netwib_priv_fmt_append_gene(array, pinfos, pbuf));
1341 } else {
1342 netwib_er(netwib_buf_append_string(array, pbuf));
1343 }
1344 }
1345 break;
1346 case NETWIB_PRIV_FMT_FIELDTYPE_BUF :
1347 {
1348 netwib_buf *pfmtbuf;
1349 if (pinfos->specset && pinfos->spec.specbuf.useglob) {
1350 netwib_er(netwib_priv_buf_append_vfmt_error2("glob is forbidden for append", fmt));
1351 return(NETWIB_ERR_PAFMT);
1352 }
1353 pfmtbuf = va_arg(*pap, netwib_buf*);
1354 /* do the transfer now because needed in netwib_priv_fmt_append_gene */
1355 netwib__buf_transfersensitive(pfmtbuf, pbuf);
1356 if (pinfos->geneset) {
1357 ret = netwib_constbuf_ref_string(pfmtbuf, &localstring);
1358 if (ret != NETWIB_ERR_OK) {
1359 netwib_er(netwib_buf_append_buf(pfmtbuf, &localbuf));
1360 netwib_er(netwib_buf_ref_string(&localbuf, &localstring));
1361 }
1362 netwib_er(netwib_priv_fmt_append_gene(localstring, pinfos, pbuf));
1363 } else {
1364 netwib_er(netwib_buf_append_buf(pfmtbuf, pbuf));
1365 }
1366 }
1367 break;
1368 case NETWIB_PRIV_FMT_FIELDTYPE_ETH :
1369 {
1370 netwib_eth *peth;
1371 peth = va_arg(*pap, netwib_eth*);
1372 netwib_er(netwib_priv_fmt_append_eth(peth, array));
1373 if (pinfos->geneset) {
1374 netwib_er(netwib_priv_fmt_append_gene(array, pinfos, pbuf));
1375 } else {
1376 netwib_er(netwib_buf_append_string(array, pbuf));
1377 }
1378 }
1379 break;
1380 case NETWIB_PRIV_FMT_FIELDTYPE_IP :
1381 {
1382 netwib_ip *pip;
1383 pip = va_arg(*pap, netwib_ip*);
1384 if (pinfos->geneset) {
1385 netwib_er(netwib_buf_append_ip(pip, NETWIB_IP_ENCODETYPE_IP,
1386 &localbuf));
1387 netwib_er(netwib_buf_ref_string(&localbuf, &localstring));
1388 netwib_er(netwib_priv_fmt_append_gene(localstring, pinfos, pbuf));
1389 } else {
1390 netwib_er(netwib_buf_append_ip(pip, NETWIB_IP_ENCODETYPE_IP,
1391 pbuf));
1392 }
1393 }
1394 break;
1395 case NETWIB_PRIV_FMT_FIELDTYPE_PORT :
1396 {
1397 netwib_priv_fmt_spec_uint su;
1398 netwib_port ui;
1399 ui = va_arg(*pap, netwib_port);
1400 su.altformat = NETWIB_FALSE;
1401 su.minsize = 0;
1402 su.base = 10;
1403 netwib_er(netwib_priv_fmt_append_uintmax(ui, &su, array));
1404 if (pinfos->geneset) {
1405 netwib_er(netwib_priv_fmt_append_gene(array, pinfos, pbuf));
1406 } else {
1407 netwib_er(netwib_buf_append_string(array, pbuf));
1408 }
1409 }
1410 break;
1411 case NETWIB_PRIV_FMT_FIELDTYPE_ETHS :
1412 {
1413 netwib_eths *peths;
1414 peths = va_arg(*pap, netwib_eths*);
1415 if (pinfos->geneset) {
1416 netwib_er(netwib_buf_append_eths(peths, &localbuf));
1417 netwib_er(netwib_buf_ref_string(&localbuf, &localstring));
1418 netwib_er(netwib_priv_fmt_append_gene(localstring, pinfos, pbuf));
1419 } else {
1420 netwib_er(netwib_buf_append_eths(peths, pbuf));
1421 }
1422 }
1423 break;
1424 case NETWIB_PRIV_FMT_FIELDTYPE_IPS :
1425 {
1426 netwib_ips *pips;
1427 pips = va_arg(*pap, netwib_ips*);
1428 if (pinfos->geneset) {
1429 netwib_er(netwib_buf_append_ips(pips, NETWIB_IPS_ENCODETYPE_BEST,
1430 &localbuf));
1431 netwib_er(netwib_buf_ref_string(&localbuf, &localstring));
1432 netwib_er(netwib_priv_fmt_append_gene(localstring, pinfos, pbuf));
1433 } else {
1434 netwib_er(netwib_buf_append_ips(pips, NETWIB_IPS_ENCODETYPE_BEST,
1435 pbuf));
1436 }
1437 }
1438 break;
1439 case NETWIB_PRIV_FMT_FIELDTYPE_PORTS :
1440 {
1441 netwib_ports *pports;
1442 pports = va_arg(*pap, netwib_ports*);
1443 if (pinfos->geneset) {
1444 netwib_er(netwib_buf_append_ports(pports, &localbuf));
1445 netwib_er(netwib_buf_ref_string(&localbuf, &localstring));
1446 netwib_er(netwib_priv_fmt_append_gene(localstring, pinfos, pbuf));
1447 } else {
1448 netwib_er(netwib_buf_append_ports(pports, pbuf));
1449 }
1450 }
1451 break;
1452 }
1453
1454 netwib_er(netwib_buf_close(&localbuf));
1455
1456 return(NETWIB_ERR_OK);
1457 }
1458
1459 /*-------------------------------------------------------------*/
netwib_priv_buf_append_vfmt(netwib_buf * pbuf,netwib_conststring fmt,va_list * pap)1460 netwib_err netwib_priv_buf_append_vfmt(netwib_buf *pbuf,
1461 netwib_conststring fmt,
1462 va_list *pap)
1463 {
1464 netwib_conststring pfmt, ppercent;
1465 netwib_priv_fmtinfos infos;
1466 netwib_uint32 savedsize=0;
1467 netwib_err ret;
1468
1469 /* save position in case of error */
1470 if (pbuf != NULL) {
1471 savedsize = netwib__buf_ref_data_size(pbuf);
1472 }
1473
1474 /* main loop */
1475 pfmt = fmt;
1476 ret = NETWIB_ERR_LOINTERNALERROR;
1477 while (NETWIB_TRUE) {
1478 /* search '%' */
1479 ppercent = netwib_c_strchr(pfmt, '%');
1480 if (ppercent == NULL) {
1481 /* not found, so copy the end of format */
1482 ret = netwib_buf_append_string(pfmt, pbuf);
1483 break;
1484 } else {
1485 /* first append data before '%' */
1486 ret = netwib_buf_append_data((netwib_constdata)pfmt, ppercent-pfmt,
1487 pbuf);
1488 if (ret != NETWIB_ERR_OK) {
1489 break;
1490 }
1491 /* analyze format and complete */
1492 pfmt = ppercent + 1;
1493 ret = netwib_priv_fmt_analyze(pfmt, &infos);
1494 if (ret != NETWIB_ERR_OK) {
1495 break;
1496 }
1497 ret = netwib_priv_fmt_append(pbuf, pfmt, pap, &infos);
1498 if (ret != NETWIB_ERR_OK) {
1499 break;
1500 }
1501 pfmt += infos.skipsize;
1502 }
1503 }
1504
1505 /* on error, restore first pos */
1506 if (ret != NETWIB_ERR_OK) {
1507 if (pbuf != NULL) {
1508 pbuf->endoffset = pbuf->beginoffset + savedsize;
1509 }
1510 }
1511
1512 /* leave */
1513 return(ret);
1514 }
1515
1516 /*-------------------------------------------------------------*/
netwib_buf_append_fmt(netwib_buf * pbuf,netwib_conststring fmt,...)1517 netwib_err netwib_buf_append_fmt(netwib_buf *pbuf,
1518 netwib_conststring fmt,
1519 ...)
1520 {
1521 va_list ap;
1522 netwib_err ret;
1523
1524 va_start(ap, fmt);
1525 ret = netwib_priv_buf_append_vfmt(pbuf, fmt, &ap);
1526 va_end(ap);
1527 return(ret);
1528 }
1529
1530
1531 /*-------------------------------------------------------------*/
1532 /*-------------------------------------------------------------*/
1533 /*-------------------------------------------------------------*/
1534 /*-------------------------------------------------------------*/
1535
1536 /*-------------------------------------------------------------*/
1537 typedef struct {
1538 netwib_priv_fmtinfos fmtinfos;
1539 netwib_ptr ptr;
1540 } netwib_priv_fmt_scanitem;
1541
1542 /*-------------------------------------------------------------*/
netwib_priv_fmt_regexp(netwib_buf * pbuf,netwib_priv_fmtinfos * pinfos)1543 static netwib_err netwib_priv_fmt_regexp(netwib_buf *pbuf,
1544 netwib_priv_fmtinfos *pinfos)
1545 {
1546 netwib_bool skipfield;
1547
1548 if (pinfos->geneset) {
1549 if (pinfos->gene.minsize) {
1550 if (pinfos->gene.align != NETWIB_PRIV_FMT_ALIGNTYPE_LEFT) {
1551 netwib_byte array[4];
1552 array[0] = '[';
1553 array[1] = pinfos->gene.padchar;
1554 array[2] = ']';
1555 array[3] = '*';
1556 netwib_er(netwib_buf_append_data(array, 4, pbuf));
1557 }
1558 }
1559 }
1560
1561 skipfield = NETWIB_FALSE;
1562 if (pinfos->geneset) {
1563 if (pinfos->gene.skipfield) {
1564 skipfield = NETWIB_TRUE;
1565 }
1566 }
1567
1568 if (!skipfield) {
1569 /* those cases can easily be encapsulated by parenthesis */
1570 switch(pinfos->fieldtype) {
1571 case NETWIB_PRIV_FMT_FIELDTYPE_C :
1572 case NETWIB_PRIV_FMT_FIELDTYPE_P :
1573 case NETWIB_PRIV_FMT_FIELDTYPE_INT32 :
1574 case NETWIB_PRIV_FMT_FIELDTYPE_INT16 :
1575 case NETWIB_PRIV_FMT_FIELDTYPE_INT8 :
1576 case NETWIB_PRIV_FMT_FIELDTYPE_INT64 :
1577 case NETWIB_PRIV_FMT_FIELDTYPE_INTMAX :
1578 case NETWIB_PRIV_FMT_FIELDTYPE_INTPTR :
1579 case NETWIB_PRIV_FMT_FIELDTYPE_BOOL :
1580 case NETWIB_PRIV_FMT_FIELDTYPE_CMP :
1581 case NETWIB_PRIV_FMT_FIELDTYPE_ETH :
1582 case NETWIB_PRIV_FMT_FIELDTYPE_IP :
1583 case NETWIB_PRIV_FMT_FIELDTYPE_PORT :
1584 case NETWIB_PRIV_FMT_FIELDTYPE_ETHS :
1585 case NETWIB_PRIV_FMT_FIELDTYPE_IPS :
1586 case NETWIB_PRIV_FMT_FIELDTYPE_PORTS :
1587 netwib_er(netwib_buf_append_byte('(', pbuf));
1588 break;
1589 default :
1590 break;
1591 }
1592 }
1593
1594 switch(pinfos->fieldtype) {
1595 case NETWIB_PRIV_FMT_FIELDTYPE_PERCENT :
1596 netwib_er(netwib_buf_append_string("[%]", pbuf));
1597 break;
1598 case NETWIB_PRIV_FMT_FIELDTYPE_END :
1599 netwib_er(netwib_buf_append_byte('$', pbuf));
1600 break;
1601 case NETWIB_PRIV_FMT_FIELDTYPE_C :
1602 netwib_er(netwib_buf_append_byte('.', pbuf));
1603 break;
1604 case NETWIB_PRIV_FMT_FIELDTYPE_S :
1605 if (pinfos->specset && pinfos->spec.specs.useglob) {
1606 if (skipfield) {
1607 netwib_er(netwib_buf_append_string(".+", pbuf));
1608 } else {
1609 netwib_er(netwib_buf_append_string("(.+)", pbuf));
1610 }
1611 } else {
1612 if (skipfield) {
1613 netwib_er(netwib_buf_append_string("[ \t]*[^ \t]+[ \t]*", pbuf));
1614 } else {
1615 netwib_er(netwib_buf_append_string("[ \t]*([^ \t]+)[ \t]*", pbuf));
1616 }
1617 }
1618 break;
1619 case NETWIB_PRIV_FMT_FIELDTYPE_BUF :
1620 if (pinfos->specset && pinfos->spec.specbuf.useglob) {
1621 if (skipfield) {
1622 netwib_er(netwib_buf_append_string(".+", pbuf));
1623 } else {
1624 netwib_er(netwib_buf_append_string("(.+)", pbuf));
1625 }
1626 } else {
1627 if (skipfield) {
1628 netwib_er(netwib_buf_append_string("[ \t]*[^ \t]+[ \t]*", pbuf));
1629 } else {
1630 netwib_er(netwib_buf_append_string("[ \t]*([^ \t]+)[ \t]*", pbuf));
1631 }
1632 }
1633 break;
1634 case NETWIB_PRIV_FMT_FIELDTYPE_P :
1635 netwib_er(netwib_buf_append_string("[0-9a-fA-Fx]+", pbuf));
1636 break;
1637 case NETWIB_PRIV_FMT_FIELDTYPE_UINT32 :
1638 case NETWIB_PRIV_FMT_FIELDTYPE_UINT16 :
1639 case NETWIB_PRIV_FMT_FIELDTYPE_UINT8 :
1640 case NETWIB_PRIV_FMT_FIELDTYPE_UINT64 :
1641 case NETWIB_PRIV_FMT_FIELDTYPE_BYTE :
1642 case NETWIB_PRIV_FMT_FIELDTYPE_UINTMAX :
1643 case NETWIB_PRIV_FMT_FIELDTYPE_UINTPTR :
1644 if (pinfos->specset) {
1645 if (!skipfield) {
1646 netwib_er(netwib_buf_append_byte('(', pbuf));
1647 }
1648 switch(pinfos->spec.specuint.base) {
1649 case 2 :
1650 netwib_er(netwib_buf_append_string("b?[0-1]+", pbuf));
1651 break;
1652 case 8 :
1653 netwib_er(netwib_buf_append_string("[0-7+]+", pbuf));
1654 break;
1655 case 10 :
1656 netwib_er(netwib_buf_append_string("[0-9+]+", pbuf));
1657 break;
1658 case 16 :
1659 case 17 :
1660 netwib_er(netwib_buf_append_string("[0-9a-fA-Fx+]+", pbuf));
1661 break;
1662 }
1663 if (!skipfield) {
1664 netwib_er(netwib_buf_append_byte(')', pbuf));
1665 }
1666 } else {
1667 if (skipfield) {
1668 netwib_er(netwib_buf_append_string("[0-9a-fA-Fx+]+", pbuf));
1669 } else {
1670 netwib_er(netwib_buf_append_string("([0-9a-fA-Fx+]+)", pbuf));
1671 }
1672 }
1673 break;
1674 case NETWIB_PRIV_FMT_FIELDTYPE_INT32 :
1675 case NETWIB_PRIV_FMT_FIELDTYPE_INT16 :
1676 case NETWIB_PRIV_FMT_FIELDTYPE_INT8 :
1677 case NETWIB_PRIV_FMT_FIELDTYPE_INT64 :
1678 case NETWIB_PRIV_FMT_FIELDTYPE_INTMAX :
1679 case NETWIB_PRIV_FMT_FIELDTYPE_INTPTR :
1680 netwib_er(netwib_buf_append_string("[0-9+-]+", pbuf));
1681 break;
1682 case NETWIB_PRIV_FMT_FIELDTYPE_BOOL :
1683 if (pinfos->specset) {
1684 switch (pinfos->spec.specbool.type) {
1685 case '0' :
1686 netwib_er(netwib_buf_append_string("[01]", pbuf));
1687 break;
1688 case 't' :
1689 netwib_er(netwib_buf_append_string("[truefals]+", pbuf));
1690 break;
1691 case 'T' :
1692 netwib_er(netwib_buf_append_string("[TRUEFALS]+", pbuf));
1693 break;
1694 case 'y' :
1695 netwib_er(netwib_buf_append_string("[yesno]+", pbuf));
1696 break;
1697 case 'Y' :
1698 netwib_er(netwib_buf_append_string("[YESNO]+", pbuf));
1699 break;
1700 case 's' :
1701 netwib_er(netwib_buf_append_string("[unset]+", pbuf));
1702 break;
1703 case 'S' :
1704 netwib_er(netwib_buf_append_string("[UNSET]+", pbuf));
1705 break;
1706 }
1707 } else {
1708 netwib_er(netwib_buf_append_string("[01enorstuyENORSTUY]+", pbuf));
1709 }
1710 break;
1711 case NETWIB_PRIV_FMT_FIELDTYPE_CMP :
1712 if (pinfos->specset) {
1713 switch (pinfos->spec.speccmp.type) {
1714 case '=' :
1715 netwib_er(netwib_buf_append_string("[<=>]", pbuf));
1716 break;
1717 case '0' :
1718 netwib_er(netwib_buf_append_string("[+0-]", pbuf));
1719 break;
1720 case 'e' :
1721 netwib_er(netwib_buf_append_string("[egl][qt]", pbuf));
1722 break;
1723 }
1724 } else {
1725 netwib_er(netwib_buf_append_string("[<=>eglqt+0-]+", pbuf));
1726 }
1727 break;
1728 case NETWIB_PRIV_FMT_FIELDTYPE_ETH :
1729 netwib_er(netwib_buf_append_string("[0-9a-fA-F][0-9a-fA-F]?:[0-9a-fA-F][0-9a-fA-F]?:[0-9a-fA-F][0-9a-fA-F]?:[0-9a-fA-F][0-9a-fA-F]?:[0-9a-fA-F][0-9a-fA-F]?:[0-9a-fA-F][0-9a-fA-F]?", pbuf));
1730 break;
1731 case NETWIB_PRIV_FMT_FIELDTYPE_IP :
1732 netwib_er(netwib_buf_append_string("[0-9a-fA-F.:]+", pbuf));
1733 break;
1734 case NETWIB_PRIV_FMT_FIELDTYPE_PORT :
1735 netwib_er(netwib_buf_append_string("[0-9]+", pbuf));
1736 break;
1737 case NETWIB_PRIV_FMT_FIELDTYPE_ETHS :
1738 netwib_er(netwib_buf_append_string("[0-9a-fA-F:,-]+", pbuf));
1739 break;
1740 case NETWIB_PRIV_FMT_FIELDTYPE_IPS :
1741 netwib_er(netwib_buf_append_string("[0-9.:,-]+", pbuf));
1742 break;
1743 case NETWIB_PRIV_FMT_FIELDTYPE_PORTS :
1744 netwib_er(netwib_buf_append_string("[0-9,-]+", pbuf));
1745 break;
1746 }
1747
1748 if (!skipfield) {
1749 switch(pinfos->fieldtype) {
1750 case NETWIB_PRIV_FMT_FIELDTYPE_C :
1751 case NETWIB_PRIV_FMT_FIELDTYPE_P :
1752 case NETWIB_PRIV_FMT_FIELDTYPE_INT32 :
1753 case NETWIB_PRIV_FMT_FIELDTYPE_INT16 :
1754 case NETWIB_PRIV_FMT_FIELDTYPE_INT8 :
1755 case NETWIB_PRIV_FMT_FIELDTYPE_INT64 :
1756 case NETWIB_PRIV_FMT_FIELDTYPE_INTMAX :
1757 case NETWIB_PRIV_FMT_FIELDTYPE_INTPTR :
1758 case NETWIB_PRIV_FMT_FIELDTYPE_BOOL :
1759 case NETWIB_PRIV_FMT_FIELDTYPE_CMP :
1760 case NETWIB_PRIV_FMT_FIELDTYPE_ETH :
1761 case NETWIB_PRIV_FMT_FIELDTYPE_IP :
1762 case NETWIB_PRIV_FMT_FIELDTYPE_PORT :
1763 case NETWIB_PRIV_FMT_FIELDTYPE_ETHS :
1764 case NETWIB_PRIV_FMT_FIELDTYPE_IPS :
1765 case NETWIB_PRIV_FMT_FIELDTYPE_PORTS :
1766 netwib_er(netwib_buf_append_byte(')', pbuf));
1767 break;
1768 default :
1769 break;
1770 }
1771 }
1772
1773 if (pinfos->geneset) {
1774 if (pinfos->gene.minsize) {
1775 if (pinfos->gene.align != NETWIB_PRIV_FMT_ALIGNTYPE_RIGHT) {
1776 netwib_byte array[4];
1777 array[0] = '[';
1778 array[1] = pinfos->gene.padchar;
1779 array[2] = ']';
1780 array[3] = '*';
1781 netwib_er(netwib_buf_append_data(array, 4, pbuf));
1782 }
1783 }
1784 }
1785
1786 return(NETWIB_ERR_OK);
1787 }
1788
1789 /*-------------------------------------------------------------*/
netwib_priv_fmt_decode_uint32(netwib_constbuf * pbuf,netwib_uint32 base,netwib_uint32 * pnumber)1790 static netwib_err netwib_priv_fmt_decode_uint32(netwib_constbuf *pbuf,
1791 netwib_uint32 base,
1792 netwib_uint32 *pnumber)
1793 {
1794 netwib_string str;
1795 netwib_uintmax number;
1796 char *p;
1797
1798 /* obtain a reference to the string */
1799 netwib__constbuf_ref_string(pbuf, str, bufstorage,
1800 netwib_priv_fmt_decode_uint32(&bufstorage, base, pnumber));
1801
1802 /* special case */
1803 if (*str == '\0') {
1804 return(NETWIB_ERR_PAINT);
1805 }
1806
1807 /* base 2 starting with 'b' is not supported by strtoul */
1808 if (base == 2 && *str == 'b') {
1809 str++;
1810 }
1811
1812 /* find number */
1813 number = strtoul(str, &p, base);
1814 if (*p != '\0') {
1815 return(NETWIB_ERR_PAINT);
1816 }
1817
1818 /* number is too big */
1819 if (number == ULONG_MAX && errno == ERANGE) {
1820 errno = 0;
1821 return(NETWIB_ERR_PATOOHIGH);
1822 }
1823 #if NETWIB_INTMAX_BITS == 64
1824 if (number > 0xFFFFFFFFu) {
1825 return(NETWIB_ERR_PATOOHIGH);
1826 }
1827 #endif
1828
1829 if (pnumber != NULL) *pnumber = (netwib_uint32)number;
1830 return(NETWIB_ERR_OK);
1831 }
1832
1833 /*-------------------------------------------------------------*/
netwib_priv_fmt_decode_int32(netwib_constbuf * pbuf,netwib_int32 * pnumber)1834 static netwib_err netwib_priv_fmt_decode_int32(netwib_constbuf *pbuf,
1835 netwib_int32 *pnumber)
1836 {
1837 netwib_string str;
1838 netwib_intmax number;
1839 char *p;
1840
1841 /* obtain a reference to the string */
1842 netwib__constbuf_ref_string(pbuf, str, bufstorage,
1843 netwib_priv_fmt_decode_int32(&bufstorage, pnumber));
1844
1845 /* special case */
1846 if (*str == '\0') {
1847 return(NETWIB_ERR_PAINT);
1848 }
1849
1850 /* find number */
1851 number = strtol(str, &p, 10);
1852 if (*p != '\0') {
1853 return(NETWIB_ERR_PAINT);
1854 }
1855
1856 /* number is too big */
1857 if (errno == ERANGE) {
1858 errno = 0;
1859 if (number == LONG_MAX)
1860 return(NETWIB_ERR_PATOOHIGH);
1861 else if (number == LONG_MIN)
1862 return(NETWIB_ERR_PATOOLOW);
1863 }
1864 #if NETWIB_INTMAX_BITS == 64
1865 if (number > 0 && number > 0x7FFFFFFF) {
1866 return(NETWIB_ERR_PATOOHIGH);
1867 }
1868 if (number < 0 && number < -0x7FFFFFFF-1) {
1869 return(NETWIB_ERR_PATOOLOW);
1870 }
1871 #endif
1872
1873 if (pnumber != NULL) *pnumber = (netwib_int32)number;
1874 return(NETWIB_ERR_OK);
1875 }
1876
1877 /*-------------------------------------------------------------*/
netwib_priv_fmt_decode_uint64(netwib_constbuf * pbuf,netwib_uint32 base,netwib_uint64 * pnumber)1878 static netwib_err netwib_priv_fmt_decode_uint64(netwib_constbuf *pbuf,
1879 netwib_uint32 base,
1880 netwib_uint64 *pnumber)
1881 {
1882 netwib_uint64 base64, number, number2, c64;
1883 netwib_uint32 c32;
1884 netwib_string pc;
1885 netwib_char c;
1886
1887 /* obtain a reference to the string */
1888 netwib__constbuf_ref_string(pbuf, pc, bufstorage,
1889 netwib_priv_fmt_decode_uint64(&bufstorage, base, pnumber));
1890
1891 /* skip useless characters*/
1892 if (*pc == '+') {
1893 pc++;
1894 }
1895 switch(base) {
1896 case 2 :
1897 if (*pc == 'b') {
1898 pc++;
1899 }
1900 break;
1901 case 16 :
1902 if (*pc == '0' && *(pc+1) == 'x') {
1903 pc += 2;
1904 }
1905 break;
1906 case 0 : /* need to guess ; by default 10 (note: no way to detect binary) */
1907 base = 10;
1908 if (*pc == '0') {
1909 if (*(pc+1) == 'x') {
1910 pc += 2;
1911 base = 16;
1912 } else {
1913 /* do not increment pc to leave the '0' */
1914 base = 8;
1915 }
1916 }
1917 break;
1918 }
1919 if (*pc == '\0') {
1920 return(NETWIB_ERR_PAINT);
1921 }
1922
1923 /* loop and store in number */
1924 netwib__uint64_init_uint32(0, number);
1925 netwib__uint64_init_uint32(base, base64);
1926 while(NETWIB_TRUE) {
1927 c = *pc++;
1928 if (c == '\0') {
1929 break;
1930 }
1931 netwib_c2_cto16_if(c, c32) else {
1932 return(NETWIB_ERR_PAINT);
1933 }
1934 if (c32 >= base) {
1935 return(NETWIB_ERR_PAINT);
1936 }
1937 netwib__uint64_init_uint32(c32, c64);
1938 netwib__uint64_mul(number, base64, &number2);
1939 netwib__uint64_add(number2, c64, number2);
1940 if (netwib__uint64_cmp_lt(number2, number)) {
1941 /* an overflow occurred */
1942 return(NETWIB_ERR_PAINT);
1943 }
1944 number = number2;
1945 }
1946
1947 if (pnumber != NULL) *pnumber = number;
1948 return(NETWIB_ERR_OK);
1949 }
1950
1951 /*-------------------------------------------------------------*/
netwib_priv_fmt_decode_int64(netwib_constbuf * pbuf,netwib_int64 * pnumber)1952 static netwib_err netwib_priv_fmt_decode_int64(netwib_constbuf *pbuf,
1953 netwib_int64 *pnumber)
1954 {
1955 netwib_buf buf;
1956 netwib_data data;
1957 netwib_uint32 datasize;
1958 netwib_uint64 ui64, maxint64;
1959 netwib_bool ispos;
1960
1961 datasize = netwib__buf_ref_data_size(pbuf);
1962 if (datasize == 0) {
1963 return(NETWIB_ERR_PAINT);
1964 }
1965 data = netwib__buf_ref_data_ptr(pbuf);
1966
1967 /* check if a sign is present */
1968 ispos = NETWIB_TRUE;
1969 switch(*data) {
1970 case '-' :
1971 ispos = NETWIB_FALSE;
1972 data++;
1973 datasize--;
1974 break;
1975 case '+' :
1976 data++;
1977 datasize--;
1978 break;
1979 }
1980
1981 /* decode an unsigned */
1982 netwib_er(netwib_buf_init_ext_arrayfilled(data, datasize, &buf));
1983 netwib_er(netwib_priv_fmt_decode_uint64(&buf, 10, &ui64));
1984 netwib__uint64_init_32(0x80000000u, 0, maxint64);
1985 if (ispos) {
1986 if (netwib__uint64_cmp_gt(ui64, maxint64)) {
1987 return(NETWIB_ERR_PATOOHIGH);
1988 }
1989 *pnumber = ui64;
1990 } else {
1991 if (netwib__uint64_cmp_gt(ui64, maxint64)) {
1992 return(NETWIB_ERR_PATOOLOW);
1993 }
1994 netwib__int64_neg(ui64, *pnumber);
1995 }
1996
1997 return(NETWIB_ERR_OK);
1998 }
1999
2000 /*-------------------------------------------------------------*/
netwib_priv_fmt_decode_bool(netwib_constbuf * pbuf,netwib_bool * pb)2001 static netwib_err netwib_priv_fmt_decode_bool(netwib_constbuf *pbuf,
2002 netwib_bool *pb)
2003 {
2004 netwib_data data;
2005 netwib_uint32 datasize;
2006 netwib_char firstchar;
2007 netwib_bool b;
2008
2009 datasize = netwib__buf_ref_data_size(pbuf);
2010 if (datasize == 0) {
2011 return(NETWIB_ERR_PAINT);
2012 }
2013 data = netwib__buf_ref_data_ptr(pbuf);
2014
2015 #define netwib__priv_fmt_decode_bool_cmp(txt,val) if (!netwib_c_memcasecmp(data, (netwib_constdata)txt, datasize)) { b = val; break; }
2016 firstchar = data[0];
2017 switch(firstchar) {
2018 case '0' :
2019 if (datasize == 1) {
2020 b = NETWIB_FALSE;
2021 break;
2022 }
2023 return(NETWIB_ERR_PAINT);
2024 break;
2025 case '1' :
2026 if (datasize == 1) {
2027 b = NETWIB_TRUE;
2028 break;
2029 }
2030 return(NETWIB_ERR_PAINT);
2031 break;
2032 case 'f' :
2033 case 'F' :
2034 if (datasize == 5) {
2035 netwib__priv_fmt_decode_bool_cmp("false", NETWIB_FALSE);
2036 }
2037 return(NETWIB_ERR_PAINT);
2038 break;
2039 case 'n' :
2040 case 'N' :
2041 if (datasize == 2) {
2042 netwib__priv_fmt_decode_bool_cmp("no", NETWIB_FALSE);
2043 }
2044 return(NETWIB_ERR_PAINT);
2045 break;
2046 case 's' :
2047 case 'S' :
2048 if (datasize == 3) {
2049 netwib__priv_fmt_decode_bool_cmp("set", NETWIB_TRUE);
2050 }
2051 return(NETWIB_ERR_PAINT);
2052 break;
2053 case 't' :
2054 case 'T' :
2055 if (datasize == 4) {
2056 netwib__priv_fmt_decode_bool_cmp("true", NETWIB_TRUE);
2057 }
2058 return(NETWIB_ERR_PAINT);
2059 break;
2060 case 'u' :
2061 case 'U' :
2062 if (datasize == 5) {
2063 netwib__priv_fmt_decode_bool_cmp("unset", NETWIB_FALSE);
2064 }
2065 return(NETWIB_ERR_PAINT);
2066 break;
2067 case 'y' :
2068 case 'Y' :
2069 if (datasize == 3) {
2070 netwib__priv_fmt_decode_bool_cmp("yes", NETWIB_TRUE);
2071 }
2072 return(NETWIB_ERR_PAINT);
2073 break;
2074 default :
2075 return(NETWIB_ERR_PAINT);
2076 }
2077
2078 if (pb != NULL) *pb = b;
2079 return(NETWIB_ERR_OK);
2080 }
2081
2082 /*-------------------------------------------------------------*/
netwib_priv_fmt_decode_cmp(netwib_constbuf * pbuf,netwib_cmp * pcmp)2083 static netwib_err netwib_priv_fmt_decode_cmp(netwib_constbuf *pbuf,
2084 netwib_cmp *pcmp)
2085 {
2086 netwib_data data;
2087 netwib_uint32 datasize;
2088 netwib_char firstchar;
2089 netwib_cmp cmp;
2090
2091 datasize = netwib__buf_ref_data_size(pbuf);
2092 if (datasize == 0) {
2093 return(NETWIB_ERR_PAINT);
2094 }
2095 data = netwib__buf_ref_data_ptr(pbuf);
2096
2097 firstchar = data[0];
2098 switch(firstchar) {
2099 case '<' :
2100 if (datasize == 1) {
2101 cmp = NETWIB_CMP_LT;
2102 break;
2103 }
2104 return(NETWIB_ERR_PAINT);
2105 break;
2106 case '=' :
2107 if (datasize == 1) {
2108 cmp = NETWIB_CMP_EQ;
2109 break;
2110 }
2111 return(NETWIB_ERR_PAINT);
2112 break;
2113 case '>' :
2114 if (datasize == 1) {
2115 cmp = NETWIB_CMP_GT;
2116 break;
2117 }
2118 return(NETWIB_ERR_PAINT);
2119 break;
2120 case '-' :
2121 if (datasize == 1) {
2122 cmp = NETWIB_CMP_LT;
2123 break;
2124 }
2125 return(NETWIB_ERR_PAINT);
2126 break;
2127 case '0' :
2128 if (datasize == 1) {
2129 cmp = NETWIB_CMP_EQ;
2130 break;
2131 }
2132 return(NETWIB_ERR_PAINT);
2133 break;
2134 case '+' :
2135 if (datasize == 1) {
2136 cmp = NETWIB_CMP_GT;
2137 break;
2138 }
2139 return(NETWIB_ERR_PAINT);
2140 break;
2141 case 'e' :
2142 if (datasize == 2 && data[1] == 'q') {
2143 cmp = NETWIB_CMP_EQ;
2144 break;
2145 }
2146 return(NETWIB_ERR_PAINT);
2147 break;
2148 case 'g' :
2149 if (datasize == 2 && data[1] == 't') {
2150 cmp = NETWIB_CMP_GT;
2151 break;
2152 }
2153 return(NETWIB_ERR_PAINT);
2154 break;
2155 case 'l' :
2156 if (datasize == 2 && data[1] == 't') {
2157 cmp = NETWIB_CMP_LT;
2158 break;
2159 }
2160 return(NETWIB_ERR_PAINT);
2161 break;
2162 default :
2163 return(NETWIB_ERR_PAINT);
2164 }
2165
2166 if (pcmp != NULL) *pcmp = cmp;
2167 return(NETWIB_ERR_OK);
2168 }
2169
2170 /*-------------------------------------------------------------*/
netwib_priv_fmt_decode(netwib_constbuf * pbuf,const netwib_priv_fmt_scanitem * pscanitem)2171 static netwib_err netwib_priv_fmt_decode(netwib_constbuf *pbuf,
2172 const netwib_priv_fmt_scanitem *pscanitem)
2173 {
2174 netwib_uint64 ui64;
2175 netwib_uint32 ui32=0;
2176 netwib_int64 i64;
2177 netwib_int32 i32=0;
2178 netwib_uintptr uiptr=0;
2179 netwib_err ret;
2180
2181 if (pscanitem->ptr == NULL) {
2182 return(NETWIB_ERR_OK);
2183 }
2184
2185 switch(pscanitem->fmtinfos.fieldtype) {
2186 case NETWIB_PRIV_FMT_FIELDTYPE_PERCENT :
2187 return(NETWIB_ERR_LOINTERNALERROR);
2188 break;
2189 case NETWIB_PRIV_FMT_FIELDTYPE_C :
2190 {
2191 netwib_char *pc = (netwib_char *)pscanitem->ptr;
2192 *pc = *netwib__buf_ref_data_ptr(pbuf);
2193 }
2194 return(NETWIB_ERR_OK);
2195 break;
2196 case NETWIB_PRIV_FMT_FIELDTYPE_S :
2197 {
2198 netwib_char *pc = (netwib_char *)pscanitem->ptr;
2199 netwib_c_memcpy(pc, netwib__buf_ref_data_ptr(pbuf),
2200 netwib__buf_ref_data_size(pbuf));
2201 pc[netwib__buf_ref_data_size(pbuf)] = '\0';
2202 }
2203 return(NETWIB_ERR_OK);
2204 break;
2205 case NETWIB_PRIV_FMT_FIELDTYPE_BUF :
2206 {
2207 netwib_buf *p = (netwib_buf *)pscanitem->ptr;
2208 netwib_er(netwib_buf_append_buf(pbuf, p));
2209 }
2210 return(NETWIB_ERR_OK);
2211 break;
2212 default :
2213 break;
2214 }
2215
2216 /* initialize for integer conversions */
2217 ret = NETWIB_ERR_OK;
2218 netwib__uint64_init_uint32(0, ui64);
2219 netwib__int64_init_int32(0, i64);
2220 switch(pscanitem->fmtinfos.fieldtype) {
2221 case NETWIB_PRIV_FMT_FIELDTYPE_UINT32 :
2222 case NETWIB_PRIV_FMT_FIELDTYPE_UINT16 :
2223 case NETWIB_PRIV_FMT_FIELDTYPE_UINT8 :
2224 case NETWIB_PRIV_FMT_FIELDTYPE_BYTE :
2225 {
2226 netwib_uint32 base;
2227 base = 0;
2228 if (pscanitem->fmtinfos.specset) {
2229 base = pscanitem->fmtinfos.spec.specuint.base;
2230 if (base == 17) base = 16;
2231 }
2232 ret = netwib_priv_fmt_decode_uint32(pbuf, base, &ui32);
2233 }
2234 break;
2235 case NETWIB_PRIV_FMT_FIELDTYPE_UINT64 :
2236 case NETWIB_PRIV_FMT_FIELDTYPE_UINTMAX :
2237 case NETWIB_PRIV_FMT_FIELDTYPE_UINTPTR :
2238 {
2239 netwib_uint32 base;
2240 base = 0;
2241 if (pscanitem->fmtinfos.specset) {
2242 base = pscanitem->fmtinfos.spec.specuint.base;
2243 if (base == 17) base = 16;
2244 }
2245 ret = netwib_priv_fmt_decode_uint64(pbuf, base, &ui64);
2246 }
2247 break;
2248 case NETWIB_PRIV_FMT_FIELDTYPE_P :
2249 #if NETWIB_INTPTR_BITS == 64
2250 ret = netwib_priv_fmt_decode_uint64(pbuf, 16, &ui64);
2251 if (ret == NETWIB_ERR_OK) {
2252 netwib__uintptr_init_uint64(ui64, uiptr);
2253 }
2254 #else
2255 ret = netwib_priv_fmt_decode_uint32(pbuf, 16,
2256 (netwib_uint32*)&uiptr);
2257 #endif
2258 break;
2259 case NETWIB_PRIV_FMT_FIELDTYPE_INT32 :
2260 case NETWIB_PRIV_FMT_FIELDTYPE_INT16 :
2261 case NETWIB_PRIV_FMT_FIELDTYPE_INT8 :
2262 ret = netwib_priv_fmt_decode_int32(pbuf, &i32);
2263 break;
2264 case NETWIB_PRIV_FMT_FIELDTYPE_INT64 :
2265 case NETWIB_PRIV_FMT_FIELDTYPE_INTMAX :
2266 case NETWIB_PRIV_FMT_FIELDTYPE_INTPTR :
2267 ret = netwib_priv_fmt_decode_int64(pbuf, &i64);
2268 break;
2269 default :
2270 /* ui does not need to be initialized */
2271 break;
2272 }
2273
2274 if (ret == NETWIB_ERR_OK) {
2275 switch(pscanitem->fmtinfos.fieldtype) {
2276 case NETWIB_PRIV_FMT_FIELDTYPE_P :
2277 {
2278 netwib_ptr *p = (netwib_ptr *)pscanitem->ptr;
2279 *p = (netwib_ptr)uiptr;
2280 }
2281 break;
2282 case NETWIB_PRIV_FMT_FIELDTYPE_UINT32 :
2283 {
2284 netwib_uint32 *p = (netwib_uint32 *)pscanitem->ptr;
2285 *p = ui32;
2286 }
2287 break;
2288 case NETWIB_PRIV_FMT_FIELDTYPE_UINT16 :
2289 {
2290 netwib_uint16 *p = (netwib_uint16 *)pscanitem->ptr;
2291 if (ui32 > 0xFFFF) {
2292 ret = NETWIB_ERR_PATOOHIGH;
2293 } else {
2294 *p = (netwib_uint16)ui32;
2295 }
2296 }
2297 break;
2298 case NETWIB_PRIV_FMT_FIELDTYPE_UINT8 :
2299 {
2300 netwib_uint8 *p = (netwib_uint8 *)pscanitem->ptr;
2301 if (ui32 > 0xFF) {
2302 ret = NETWIB_ERR_PATOOHIGH;
2303 } else {
2304 *p = (netwib_uint8)ui32;
2305 }
2306 }
2307 break;
2308 case NETWIB_PRIV_FMT_FIELDTYPE_BYTE :
2309 {
2310 netwib_byte *p = (netwib_byte *)pscanitem->ptr;
2311 if (ui32 > 0xFF) {
2312 ret = NETWIB_ERR_PATOOHIGH;
2313 } else {
2314 *p = (netwib_byte)ui32;
2315 }
2316 }
2317 break;
2318 case NETWIB_PRIV_FMT_FIELDTYPE_UINT64 :
2319 {
2320 netwib_uint64 *p = (netwib_uint64 *)pscanitem->ptr;
2321 *p = ui64;
2322 }
2323 break;
2324 case NETWIB_PRIV_FMT_FIELDTYPE_UINTMAX :
2325 netwib__uintmax_init_uint64(ui64, *(netwib_uintmax*)pscanitem->ptr);
2326 break;
2327 case NETWIB_PRIV_FMT_FIELDTYPE_UINTPTR :
2328 netwib__uintptr_init_uint64(ui64, *(netwib_uintptr*)pscanitem->ptr);
2329 break;
2330 case NETWIB_PRIV_FMT_FIELDTYPE_INT32 :
2331 {
2332 netwib_int32 *p = (netwib_int32 *)pscanitem->ptr;
2333 *p = i32;
2334 }
2335 break;
2336 case NETWIB_PRIV_FMT_FIELDTYPE_INT16 :
2337 {
2338 netwib_int16 *p = (netwib_int16 *)pscanitem->ptr;
2339 if (i32 > 0 && i32 > 0xFFFF) {
2340 ret = NETWIB_ERR_PATOOHIGH;
2341 } else if (i32 < 0 && i32 < -0x8000) {
2342 ret = NETWIB_ERR_PATOOLOW;
2343 } else {
2344 *p = (netwib_int16)i32;
2345 }
2346 }
2347 break;
2348 case NETWIB_PRIV_FMT_FIELDTYPE_INT8 :
2349 {
2350 netwib_int8 *p = (netwib_int8 *)pscanitem->ptr;
2351 if (i32 > 0 && i32 > 0xFF) {
2352 ret = NETWIB_ERR_PATOOHIGH;
2353 } else if (i32 < 0 && i32 < -0x80) {
2354 ret = NETWIB_ERR_PATOOLOW;
2355 } else {
2356 *p = (netwib_int8)i32;
2357 }
2358 }
2359 break;
2360 case NETWIB_PRIV_FMT_FIELDTYPE_INT64 :
2361 {
2362 netwib_int64 *p = (netwib_int64 *)pscanitem->ptr;
2363 *p = i64;
2364 }
2365 break;
2366 case NETWIB_PRIV_FMT_FIELDTYPE_INTMAX :
2367 netwib__intmax_init_int64(i64, *(netwib_intmax*)pscanitem->ptr);
2368 break;
2369 case NETWIB_PRIV_FMT_FIELDTYPE_INTPTR :
2370 netwib__intptr_init_int64(ui64, *(netwib_intptr*)pscanitem->ptr);
2371 break;
2372 case NETWIB_PRIV_FMT_FIELDTYPE_BOOL :
2373 ret = netwib_priv_fmt_decode_bool(pbuf,
2374 (netwib_bool*)pscanitem->ptr);
2375 break;
2376 case NETWIB_PRIV_FMT_FIELDTYPE_CMP :
2377 ret = netwib_priv_fmt_decode_cmp(pbuf, (netwib_cmp*)pscanitem->ptr);
2378 break;
2379 case NETWIB_PRIV_FMT_FIELDTYPE_ETH :
2380 ret = netwib_eth_init_buf(pbuf, (netwib_eth*)pscanitem->ptr);
2381 break;
2382 case NETWIB_PRIV_FMT_FIELDTYPE_IP :
2383 ret = netwib_ip_init_buf(pbuf, NETWIB_IP_DECODETYPE_IP,
2384 (netwib_ip*)pscanitem->ptr);
2385 break;
2386 case NETWIB_PRIV_FMT_FIELDTYPE_PORT :
2387 ret = netwib_port_init_buf(pbuf, (netwib_port*)pscanitem->ptr);
2388 break;
2389 case NETWIB_PRIV_FMT_FIELDTYPE_ETHS :
2390 ret = netwib_eths_add_buf((netwib_eths*)pscanitem->ptr, pbuf);
2391 break;
2392 case NETWIB_PRIV_FMT_FIELDTYPE_IPS :
2393 ret = netwib_ips_add_buf((netwib_ips*)pscanitem->ptr, pbuf);
2394 break;
2395 case NETWIB_PRIV_FMT_FIELDTYPE_PORTS :
2396 ret = netwib_ports_add_buf((netwib_ports*)pscanitem->ptr, pbuf);
2397 break;
2398 default :
2399 return(NETWIB_ERR_LOINTERNALERROR);
2400 break;
2401 }
2402 }
2403
2404 return(ret);
2405 }
2406
2407 /*-------------------------------------------------------------*/
netwib_priv_buf_decode_vfmt(netwib_constbuf * pbuf,netwib_conststring fmt,va_list * pap)2408 static netwib_err netwib_priv_buf_decode_vfmt(netwib_constbuf *pbuf,
2409 netwib_conststring fmt,
2410 va_list *pap)
2411 {
2412 netwib_priv_fmt_scanitem scanitem[NETWIB_REGEXP_MAXLEN];
2413 netwib_conststring pfmt;
2414 netwib_priv_fmtinfos infos;
2415 netwib_regexp arrayfound;
2416 netwib_buf regexpbuf;
2417 netwib_uint32 numitems, i;
2418 netwib_char c;
2419 netwib_err ret;
2420
2421 netwib_er(netwib_buf_init_mallocdefault(®expbuf));
2422 netwib_er(netwib_buf_append_byte('^', ®expbuf));
2423
2424 /* analyze fmt, set regexp and array of addresses */
2425 pfmt = fmt;
2426 ret = NETWIB_ERR_OK;
2427 numitems = 0;
2428 while (NETWIB_TRUE) {
2429 c = *pfmt++;
2430 if (c == '\0') {
2431 break;
2432 } else if (c == '%') {
2433 ret = netwib_priv_fmt_analyze(pfmt, &infos);
2434 if (ret == NETWIB_ERR_OK) {
2435 pfmt += infos.skipsize;
2436 if (infos.fieldtype != NETWIB_PRIV_FMT_FIELDTYPE_PERCENT &&
2437 infos.fieldtype != NETWIB_PRIV_FMT_FIELDTYPE_END) {
2438 if (!infos.geneset || !infos.gene.skipfield) {
2439 if (numitems >= NETWIB_REGEXP_MAXLEN) {
2440 netwib_er(netwib_priv_buf_append_vfmt_error("There are too many items"));
2441 ret = NETWIB_ERR_PATOOHIGH;
2442 break;
2443 }
2444 scanitem[numitems].fmtinfos = infos;
2445 scanitem[numitems].ptr = va_arg(*pap, void*);
2446 numitems++;
2447 }
2448 }
2449 ret = netwib_priv_fmt_regexp(®expbuf, &infos);
2450 if (infos.fieldtype == NETWIB_PRIV_FMT_FIELDTYPE_END) {
2451 if (*pfmt != '\0') {
2452 netwib_er(netwib_priv_buf_append_vfmt_error("%$ must be the last one"));
2453 ret = NETWIB_ERR_PAFMT;
2454 break;
2455 }
2456 }
2457 }
2458 } else if (netwib_c2_isalnum(c)) {
2459 ret = netwib_buf_append_byte(c, ®expbuf);
2460 } else if (c == ' ') {
2461 ret = netwib_buf_append_string("[ \t]+", ®expbuf);
2462 } else {
2463 netwib_byte array[4];
2464 array[0] = '[';
2465 array[1] = c;
2466 array[2] = ']';
2467 ret = netwib_buf_append_data(array, 3, ®expbuf);
2468 }
2469 if (ret != NETWIB_ERR_OK) {
2470 break;
2471 }
2472 }
2473 if (ret != NETWIB_ERR_OK) {
2474 netwib_er(netwib_buf_close(®expbuf));
2475 return(ret);
2476 }
2477
2478 /* search regexp */
2479 ret = netwib_buf_search_regexp(pbuf, ®expbuf, NETWIB_TRUE, &arrayfound);
2480 if (ret == NETWIB_ERR_NOTFOUND) {
2481 ret = NETWIB_ERR_NOTCONVERTED;
2482 } else if (ret == NETWIB_ERR_OK) {
2483 for (i = 0; i < numitems; i++) {
2484 ret = netwib_priv_fmt_decode(&arrayfound.array[i+1], &scanitem[i]);
2485 if (ret != NETWIB_ERR_OK) {
2486 if (ret == NETWIB_ERR_PAINT) ret = NETWIB_ERR_NOTCONVERTED;
2487 if (ret == NETWIB_ERR_PATOOHIGH) ret = NETWIB_ERR_NOTCONVERTED;
2488 if (ret == NETWIB_ERR_PATOOLOW) ret = NETWIB_ERR_NOTCONVERTED;
2489 break;
2490 }
2491 }
2492 }
2493
2494 netwib_er(netwib_buf_close(®expbuf));
2495
2496 /* leave */
2497 return(ret);
2498 }
2499
2500 /*-------------------------------------------------------------*/
netwib_buf_decode_fmt(netwib_constbuf * pbuf,netwib_conststring fmt,...)2501 netwib_err netwib_buf_decode_fmt(netwib_constbuf *pbuf,
2502 netwib_conststring fmt,
2503 ...)
2504 {
2505 va_list ap;
2506 netwib_err ret;
2507
2508 va_start(ap, fmt);
2509 ret = netwib_priv_buf_decode_vfmt(pbuf, fmt, &ap);
2510 va_end(ap);
2511 return(ret);
2512 }
2513