1 /*
2  * libwbxml, the WBXML Library.
3  * Copyright (C) 2002-2008 Aymerick Jehanne <aymerick@jehanne.org>
4  * Copyright (C) 2011 Michael Bell <michael.bell@opensync.org>
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
19  *
20  * LGPL v2.1: http://www.gnu.org/copyleft/lesser.txt
21  *
22  * Contact: aymerick@jehanne.org
23  * Home: http://libwbxml.aymerick.com
24  */
25 
26 /**
27  * @file wbxml2xml_tool.c
28  * @ingroup wbxml2xml_tool
29  *
30  * @author Aymerick Jehanne <aymerick@jehanne.org>
31  * @date 03/02/22
32  *
33  * @brief WBXML to XML Converter Tool
34  *
35  */
36 
37 #if !defined ( __SYMBIAN32__ )
38 #include <memory.h>
39 #endif /* ! __SYMBIAN32__ */
40 
41 /* The real libwbxml include is:
42  *
43  * #include <wbxml/wbxml.h>
44  *
45  * We must use a direct reference to enforce the correct include.
46  */
47 #include "../src/wbxml.h"
48 
49 #ifdef WBXML_USE_LEAKTRACKER
50 #include "src/wbxml_mem.h"
51 #endif
52 
53 #include "getopt.h"
54 
55 /*
56  * This sytem include is here instead of the *.c files because
57  * we want it to be included AFTER 'e32def.h' (in 'wbxml.h') on Symbian.
58  * If not so, Warnings are displayed ('NULL' : macro redefinition)
59  */
60 #include <stdio.h>
61 
62 
63 #define INPUT_BUFFER_SIZE 1000
64 
get_lang(const WB_TINY * lang)65 static WBXMLLanguage get_lang(const WB_TINY *lang)
66 {
67 #if defined( WBXML_SUPPORT_WML )
68     if (WBXML_STRCMP(lang, "WML10") == 0)
69         return WBXML_LANG_WML10;
70     if (WBXML_STRCMP(lang, "WML11") == 0)
71         return WBXML_LANG_WML11;
72     if (WBXML_STRCMP(lang, "WML12") == 0)
73         return WBXML_LANG_WML12;
74     if (WBXML_STRCMP(lang, "WML13") == 0)
75         return WBXML_LANG_WML13;
76 #endif /* WBXML_SUPPORT_WML */
77 
78 #if defined( WBXML_SUPPORT_WTA )
79     if (WBXML_STRCMP(lang, "WTA10") == 0)
80         return WBXML_LANG_WTA10;
81     if (WBXML_STRCMP(lang, "WTAWML12") == 0)
82         return WBXML_LANG_WTAWML12;
83     if (WBXML_STRCMP(lang, "CHANNEL11") == 0)
84         return WBXML_LANG_CHANNEL11;
85     if (WBXML_STRCMP(lang, "CHANNEL12") == 0)
86         return WBXML_LANG_CHANNEL12;
87 #endif /* WBXML_SUPPORT_WTA */
88 
89 #if defined( WBXML_SUPPORT_SI )
90     if (WBXML_STRCMP(lang, "SI10") == 0)
91         return WBXML_LANG_SI10;
92 #endif /* WBXML_SUPPORT_SI */
93 
94 #if defined( WBXML_SUPPORT_SL )
95     if (WBXML_STRCMP(lang, "SL10") == 0)
96         return WBXML_LANG_SL10;
97 #endif /* WBXML_SUPPORT_SL */
98 
99 #if defined( WBXML_SUPPORT_CO )
100     if (WBXML_STRCMP(lang, "CO10") == 0)
101         return WBXML_LANG_CO10;
102 #endif /* WBXML_SUPPORT_CO */
103 
104 #if defined( WBXML_SUPPORT_PROV )
105     if (WBXML_STRCMP(lang, "PROV10") == 0)
106         return WBXML_LANG_PROV10;
107 #endif /* WBXML_SUPPORT_PROV */
108 
109 #if defined( WBXML_SUPPORT_EMN )
110     if (WBXML_STRCMP(lang, "EMN10") == 0)
111         return WBXML_LANG_EMN10;
112 #endif /* WBXML_SUPPORT_EMN */
113 
114 #if defined( WBXML_SUPPORT_DRMREL )
115     if (WBXML_STRCMP(lang, "DRMREL10") == 0)
116         return WBXML_LANG_DRMREL10;
117 #endif /* WBXML_SUPPORT_DRMREL */
118 
119 #if defined( WBXML_SUPPORT_OTA_SETTINGS )
120     if (WBXML_STRCMP(lang, "OTA") == 0)
121         return WBXML_LANG_OTA_SETTINGS;
122 #endif /* WBXML_SUPPORT_OTA_SETTINGS */
123 
124 #if defined( WBXML_SUPPORT_SYNCML )
125     if (WBXML_STRCMP(lang, "SYNCML10") == 0)
126         return WBXML_LANG_SYNCML_SYNCML10;
127     if (WBXML_STRCMP(lang, "DEVINF10") == 0)
128         return WBXML_LANG_SYNCML_DEVINF10;
129     if (WBXML_STRCMP(lang, "SYNCML11") == 0)
130         return WBXML_LANG_SYNCML_SYNCML11;
131     if (WBXML_STRCMP(lang, "DEVINF11") == 0)
132         return WBXML_LANG_SYNCML_DEVINF11;
133     if (WBXML_STRCMP(lang, "METINF11") == 0)
134         return WBXML_LANG_SYNCML_METINF11;
135     if (WBXML_STRCMP(lang, "SYNCML12") == 0)
136         return WBXML_LANG_SYNCML_SYNCML12;
137     if (WBXML_STRCMP(lang, "DEVINF12") == 0)
138         return WBXML_LANG_SYNCML_DEVINF12;
139     if (WBXML_STRCMP(lang, "METINF12") == 0)
140         return WBXML_LANG_SYNCML_METINF12;
141     if (WBXML_STRCMP(lang, "DMDDF12") == 0)
142         return WBXML_LANG_SYNCML_DMDDF12;
143 #endif /* WBXML_SUPPORT_SYNCML */
144 
145 #if defined( WBXML_SUPPORT_WV )
146     if (WBXML_STRCMP(lang, "CSP11") == 0)
147         return WBXML_LANG_WV_CSP11;
148     if (WBXML_STRCMP(lang, "CSP12") == 0)
149         return WBXML_LANG_WV_CSP12;
150 #endif /* WBXML_SUPPORT_WV */
151 
152 #if defined( WBXML_SUPPORT_AIRSYNC )
153     if (WBXML_STRCMP(lang, "AIRSYNC") == 0)
154         return WBXML_LANG_AIRSYNC;
155     if (WBXML_STRCMP(lang, "ACTIVESYNC") == 0)
156         return WBXML_LANG_ACTIVESYNC;
157 #endif /* WBXML_SUPPORT_AIRSYNC */
158 
159 #if defined( WBXML_SUPPORT_CONML )
160     if (WBXML_STRCMP(lang, "CONML") == 0)
161         return WBXML_LANG_CONML;
162 #endif /* WBXML_SUPPORT_CONML */
163 
164     return WBXML_LANG_UNKNOWN;
165 }
166 
167 
get_charset(const WB_TINY * charset)168 static WBXMLCharsetMIBEnum get_charset(const WB_TINY *charset)
169 {
170     /* The good old ASCII */
171 
172     if (WBXML_STRCMP(charset, "ASCII") == 0)
173         return WBXML_CHARSET_US_ASCII;
174 
175     /* ISO-8859 character sets */
176 
177     if (WBXML_STRCMP(charset, "ISO-8859-1") == 0)
178         return WBXML_CHARSET_ISO_8859_1;
179     if (WBXML_STRCMP(charset, "ISO-8859-2") == 0)
180         return WBXML_CHARSET_ISO_8859_2;
181     if (WBXML_STRCMP(charset, "ISO-8859-3") == 0)
182         return WBXML_CHARSET_ISO_8859_3;
183     if (WBXML_STRCMP(charset, "ISO-8859-4") == 0)
184         return WBXML_CHARSET_ISO_8859_4;
185     if (WBXML_STRCMP(charset, "ISO-8859-5") == 0)
186         return WBXML_CHARSET_ISO_8859_5;
187     if (WBXML_STRCMP(charset, "ISO-8859-6") == 0)
188         return WBXML_CHARSET_ISO_8859_6;
189     if (WBXML_STRCMP(charset, "ISO-8859-7") == 0)
190         return WBXML_CHARSET_ISO_8859_7;
191     if (WBXML_STRCMP(charset, "ISO-8859-8") == 0)
192         return WBXML_CHARSET_ISO_8859_8;
193     if (WBXML_STRCMP(charset, "ISO-8859-9") == 0)
194         return WBXML_CHARSET_ISO_8859_9;
195     if (WBXML_STRCMP(charset, "ISO-10646-UCS-2") == 0)
196         return WBXML_CHARSET_ISO_10646_UCS_2;
197 
198     /* Chinese character set */
199 
200     if (WBXML_STRCMP(charset, "SHIFT_JIS") == 0)
201         return WBXML_CHARSET_SHIFT_JIS;
202 
203     /* Japanese character set */
204 
205     if (WBXML_STRCMP(charset, "BIG5") == 0)
206         return WBXML_CHARSET_BIG5;
207 
208     /* Unicode character sets */
209 
210     if (WBXML_STRCMP(charset, "UTF-8") == 0)
211         return WBXML_CHARSET_UTF_8;
212     if (WBXML_STRCMP(charset, "UTF-16") == 0)
213         return WBXML_CHARSET_UTF_16;
214 
215     return WBXML_CHARSET_UNKNOWN;
216 }
217 
218 
help(void)219 static void help(void)
220 {
221     fprintf(stderr, "wbxml2xml [libwbxml %s] by OpenSync\n", WBXML_LIB_VERSION);
222     fprintf(stderr, "This library was originally written by Aymerick Jehanne <aymerick@jehanne.org>\n");
223     fprintf(stderr, "If you use this tool, please send feedbacks to opensync-users@opensync.org\n");
224     fprintf(stderr, "http://libwbxml.opensync.org/\n");
225 #if defined( HAVE_EXPAT )
226     fprintf(stderr, "This tool is linked with Expat (http://expat.sourceforge.net)\n\n");
227 #endif /* HAVE_EXPAT */
228     fprintf(stderr, "Usage: \n");
229     fprintf(stderr, "  wbxml2xml -o output.xml input.wbxml\n");
230     fprintf(stderr, "  wbxml2xml -i 4 -l CSP12 -o output.xml input.wbxml\n\n");
231     fprintf(stderr, "Options: \n");
232     fprintf(stderr, "    -o output.xml : output file\n");
233     fprintf(stderr, "    -m X (Generation mode - Default: 1) with:\n");
234     fprintf(stderr, "       0: Compact Generation\n");
235     fprintf(stderr, "       1: Indent Generation\n");
236     fprintf(stderr, "       2: Canonical Generation\n");
237     fprintf(stderr, "    -i X (Indent delta when using mode '1' - Default: 1)\n");
238     fprintf(stderr, "    -k (Keep Ignorable Whitespaces - Default: FALSE)\n");
239     fprintf(stderr, "    -l X (Force Language Type of document to parse)\n");
240 #if defined( WBXML_SUPPORT_WML )
241     fprintf(stderr, "       WML10 : WML 1.0\n");
242     fprintf(stderr, "       WML11 : WML 1.1\n");
243     fprintf(stderr, "       WML12 : WML 1.2\n");
244     fprintf(stderr, "       WML13 : WML 1.3\n");
245 #endif /* WBXML_SUPPORT_WML */
246 #if defined( WBXML_SUPPORT_WTA )
247     fprintf(stderr, "       WTA10 : WTA 1.0\n");
248     fprintf(stderr, "       WTAWML12 : WTAWML 1.2\n");
249     fprintf(stderr, "       CHANNEL11 : CHANNEL 1.1\n");
250     fprintf(stderr, "       CHANNEL12 : CHANNEL 1.2\n");
251 #endif /* WBXML_SUPPORT_WTA */
252 #if defined( WBXML_SUPPORT_SI )
253     fprintf(stderr, "       SI10 : SI 1.0\n");
254 #endif /* WBXML_SUPPORT_SI */
255 #if defined( WBXML_SUPPORT_SL )
256     fprintf(stderr, "       SL10 : SL 1.0\n");
257 #endif /* WBXML_SUPPORT_SL */
258 #if defined( WBXML_SUPPORT_CO )
259     fprintf(stderr, "       CO10 : CO 1.0\n");
260 #endif /* WBXML_SUPPORT_CO */
261 #if defined( WBXML_SUPPORT_PROV )
262     fprintf(stderr, "       PROV10 : PROV 1.0\n");
263 #endif /* WBXML_SUPPORT_PROV */
264 #if defined( WBXML_SUPPORT_EMN )
265     fprintf(stderr, "       EMN10 : EMN 1.0\n");
266 #endif /* WBXML_SUPPORT_EMN */
267 #if defined( WBXML_SUPPORT_DRMREL )
268     fprintf(stderr, "       DRMREL10 : DRMREL 1.0\n");
269 #endif /* WBXML_SUPPORT_DRMREL */
270 #if defined( WBXML_SUPPORT_OTA_SETTINGS )
271     fprintf(stderr, "       OTA : OTA Settings\n");
272 #endif /* WBXML_SUPPORT_OTA_SETTINGS */
273 #if defined( WBXML_SUPPORT_SYNCML )
274     fprintf(stderr, "       SYNCML10 : SYNCML 1.0\n");
275     fprintf(stderr, "       DEVINF10 : DEVINF 1.0\n");
276     fprintf(stderr, "       SYNCML11 : SYNCML 1.1\n");
277     fprintf(stderr, "       DEVINF11 : DEVINF 1.1\n");
278     fprintf(stderr, "       METINF11 : METINF 1.1\n");
279     fprintf(stderr, "       SYNCML12 : SYNCML 1.2\n");
280     fprintf(stderr, "       DEVINF12 : DEVINF 1.2\n");
281     fprintf(stderr, "       METINF12 : METINF 1.2\n");
282     fprintf(stderr, "       DMDDF12  : DMDDF  1.2\n");
283 #endif /* WBXML_SUPPORT_SYNCML */
284 #if defined( WBXML_SUPPORT_WV )
285     fprintf(stderr, "       CSP11 : WV CSP 1.1\n");
286     fprintf(stderr, "       CSP12 : WV CSP 1.2\n");
287 #endif /* WBXML_SUPPORT_WV */
288 #if defined( WBXML_SUPPORT_AIRSYNC )
289     fprintf(stderr, "       AIRSYNC    : Microsoft AirSync    (SynCE namespaces) \n");
290     fprintf(stderr, "       ACTIVESYNC : Microsoft ActiveSync (original namespaces)\n");
291 #endif /* WBXML_SUPPORT_AIRSYNC */
292 #if defined( WBXML_SUPPORT_CONML )
293     fprintf(stderr, "       CONML : Nokia ConML\n");
294 #endif /* WBXML_SUPPORT_CONML */
295     fprintf(stderr, "    -c X (Set character set if the document does not specify one)\n");
296     fprintf(stderr, "       ASCII           : US ASCII\n");
297     fprintf(stderr, "       ISO-8859-1      : ISO-8859-1 (Western European)\n");
298     fprintf(stderr, "       ISO-8859-2      : ISO-8859-2 (Central European)\n");
299     fprintf(stderr, "       ISO-8859-3      : ISO-8859-3 (South European)\n");
300     fprintf(stderr, "       ISO-8859-4      : ISO-8859-4 (North European)\n");
301     fprintf(stderr, "       ISO-8859-5      : ISO-8859-5 (Latin/Cyrillic)\n");
302     fprintf(stderr, "       ISO-8859-6      : ISO-8859-6 (Latin/Arabic)\n");
303     fprintf(stderr, "       ISO-8859-7      : ISO-8859-7 (Latin/Greek)\n");
304     fprintf(stderr, "       ISO-8859-8      : ISO-8859-8 (Latin/Hebrew)\n");
305     fprintf(stderr, "       ISO-8859-9      : ISO-8859-9 (Latin/Turkish)\n");
306     fprintf(stderr, "       ISO-10646-UCS-2 : UCS-2\n");
307     fprintf(stderr, "       SHIFT_JIS       : Shift JIS (Japanese character set)\n");
308     fprintf(stderr, "       BIG5            : Big5 (Chinese character set)\n");
309     fprintf(stderr, "       UTF-8           : UTF-8\n");
310     fprintf(stderr, "       UTF-16          : UTF-16\n");
311     fprintf(stderr, "\nNote: '-' can be used to mean stdin on input or stdout on output\n\n");
312 }
313 
314 
main(WB_LONG argc,WB_TINY ** argv)315 WB_LONG main(WB_LONG argc, WB_TINY **argv)
316 {
317     WB_UTINY *wbxml = NULL, *output = NULL, *xml = NULL;
318     FILE *input_file = NULL, *output_file = NULL;
319     WB_LONG count = 0, wbxml_len = 0, total = 0;
320     WB_ULONG xml_len = 0;
321     WB_TINY opt;
322     WBXMLError ret = WBXML_OK;
323     WB_UTINY input_buffer[INPUT_BUFFER_SIZE + 1];
324     WBXMLConvWBXML2XML *conv = NULL;
325 
326     ret = wbxml_conv_wbxml2xml_create(&conv);
327     if (ret != WBXML_OK)
328     {
329         fprintf(stderr, "wbxml2xml failed: %s\n", wbxml_errors_string(ret));
330         goto clean_up;
331     }
332 
333     while ((opt = (WB_TINY) wbxml_getopt(argc, argv, "kh?o:m:i:l:c:")) != EOF)
334     {
335         switch (opt) {
336         case 'k':
337             wbxml_conv_wbxml2xml_enable_preserve_whitespaces(conv);
338             break;
339         case 'i':
340             wbxml_conv_wbxml2xml_set_indent(conv, (WB_TINY) atoi((const WB_TINY*)optarg));
341             break;
342         case 'l':
343             wbxml_conv_wbxml2xml_set_language(conv, get_lang((const WB_TINY*)optarg));
344             break;
345         case 'c':
346             wbxml_conv_wbxml2xml_set_charset(conv, get_charset((const WB_TINY*)optarg));
347             break;
348         case 'm':
349             switch (atoi((const WB_TINY*)optarg)) {
350             case 0:
351                 wbxml_conv_wbxml2xml_set_gen_type(conv, WBXML_GEN_XML_COMPACT);
352                 break;
353             case 1:
354                 wbxml_conv_wbxml2xml_set_gen_type(conv, WBXML_GEN_XML_INDENT);
355                 break;
356             case 2:
357                 wbxml_conv_wbxml2xml_set_gen_type(conv, WBXML_GEN_XML_CANONICAL);
358                 break;
359             default:
360                 wbxml_conv_wbxml2xml_set_gen_type(conv, WBXML_GEN_XML_INDENT);
361             }
362             break;
363         case 'o':
364             output = (WB_UTINY*) optarg;
365             break;
366         case 'h':
367         case '?':
368         default:
369             help();
370             goto clean_up;
371         }
372     }
373 
374     if (optind >= argc) {
375         fprintf(stderr, "Missing arguments\n");
376         help();
377         goto clean_up;
378     }
379 
380 #ifdef WBXML_USE_LEAKTRACKER
381     lt_init_mem();
382     lt_log_open_file("wbxml2xml.log");
383     lt_log(0, "\n***************************\n Converting file: %s", argv[optind]);
384 #endif
385 
386     /**********************************
387      *  Read the WBXML Document
388      */
389 
390     if (WBXML_STRCMP(argv[optind], "-") == 0) {
391         input_file = stdin;
392     } else {
393         /* Open WBXML document */
394         input_file = fopen(argv[optind], "rb");
395         if (input_file == NULL) {
396             fprintf(stderr, "Failed to open %s\n", argv[optind]);
397             goto clean_up;
398         }
399     }
400 
401     /* Read WBXML document */
402     while(!feof(input_file))    {
403         count = fread(input_buffer, sizeof(WB_UTINY), INPUT_BUFFER_SIZE, input_file);
404         if (ferror(input_file))      {
405             fprintf(stderr, "Error while reading from file %s\n", argv[optind]);
406             if (input_file != stdin)
407                 fclose(input_file);
408             if (wbxml != NULL)
409 #ifdef WBXML_USE_LEAKTRACKER
410                 wbxml_free(wbxml);
411 #else
412                 free(wbxml);
413 #endif
414             goto clean_up;
415         }
416 
417         total += count;
418 #ifdef WBXML_USE_LEAKTRACKER
419         wbxml = wbxml_realloc(wbxml, total);
420 #else
421         wbxml = realloc(wbxml, total);
422 #endif
423         if (wbxml == NULL) {
424             fprintf(stderr, "Not enought memory\n");
425             if (input_file != stdin)
426                 fclose(input_file);
427             if (wbxml != NULL)
428 #ifdef WBXML_USE_LEAKTRACKER
429                 wbxml_free(wbxml);
430 #else
431                 free(wbxml);
432 #endif
433             goto clean_up;
434         }
435 
436         memcpy(wbxml + wbxml_len, input_buffer, count);
437         wbxml_len += count;
438     }
439 
440     if (input_file != stdin)
441         fclose(input_file);
442 
443     /* Convert WBXML document */
444     ret = wbxml_conv_wbxml2xml_run(conv, wbxml, wbxml_len, &xml, &xml_len);
445     if (ret != WBXML_OK) {
446         fprintf(stderr, "wbxml2xml failed: %s\n", wbxml_errors_string(ret));
447     }
448     else {
449         /* fprintf(stderr, "wbxml2xml succeded: \n%s\n", xml); */
450         fprintf(stderr, "wbxml2xml succeded\n");
451 
452         if (output != NULL) {
453             if (WBXML_STRCMP(output, "-") == 0) {
454                 output_file = stdout;
455             } else {
456                 /* Open Output File */
457                 output_file = fopen((const WB_TINY*) output, "w");
458             }
459 
460             if (output_file == NULL) {
461                 fprintf(stderr, "Failed to open output file: %s\n", output);
462             }
463 
464             /* Write to Output File */
465             if (fwrite(xml, sizeof(WB_UTINY), xml_len, output_file) < xml_len)
466                 fprintf(stderr, "Error while writing to file: %s\n", output);
467             /*
468             else
469                 fprintf(stderr, "Written %u bytes to file: %s\n", xml_len, output);
470             */
471 
472             if (output_file != stdout)
473                 fclose(output_file);
474         }
475 
476         /* Clean-up */
477 #ifdef WBXML_USE_LEAKTRACKER
478         wbxml_free(xml);
479 #else
480         free(xml);
481 #endif
482     }
483 
484 #ifdef WBXML_USE_LEAKTRACKER
485     wbxml_free(wbxml);
486 #else
487     free(wbxml);
488 #endif
489 
490 clean_up:
491 
492     if (conv)
493         wbxml_conv_wbxml2xml_destroy(conv);
494 
495 #ifdef WBXML_USE_LEAKTRACKER
496     lt_check_leaks();
497     lt_shutdown_mem();
498     lt_log_close_file();
499 #endif
500 
501     return ret;
502 }
503