Go to most recent revision | Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
2 | daniel-mar | 1 | /*################################################################### |
2 | ### ### |
||
3 | ### Object ID converter. Matthias Gaertner, 06/1999 ### |
||
4 | ### Converted to plain 'C' 07/2001 ### |
||
5 | ### ### |
||
6 | ### Enhanced version by Daniel Marschall, ViaThinkSoft 06/2011 ### |
||
7 | ### -- NEW 1.2: 2.48 can also be encoded! ### |
||
8 | ### -- NEW 1.2: UUIDs (128-bit) are now supported! ### |
||
9 | ### (requires GMPLib) ### |
||
10 | ### -- NEW 1.3: Length can now have more than 1 byte ### |
||
11 | ### -- NEW 1.4: No command line limitation anymore. ### |
||
12 | ### -- AS WELL AS SEVERAL BUG FIXES ### |
||
13 | ### ### |
||
14 | ### To compile with gcc simply use: ### |
||
15 | ### gcc -O2 -o oid oid.c -lgmp -lm ### |
||
16 | ### ### |
||
17 | ### To compile using cl, use: ### |
||
18 | ### cl -DWIN32 -O1 oid.c (+ include gmp library) ### |
||
19 | ### ### |
||
20 | ### Freeware - do with it whatever you want. ### |
||
21 | ### Use at your own risk. No warranty of any kind. ### |
||
22 | ### ### |
||
23 | ###################################################################*/ |
||
24 | /* $Version: 1.4$ */ |
||
25 | |||
26 | // MINOR PROBLEMS: |
||
27 | // - A wrong error message is shown when trying to encode "-0.0" or "x" |
||
28 | |||
29 | // NICE TO HAVE: |
||
30 | // - makefile / linuxpackage |
||
31 | // - better make functions instead of putting everything in main() with fprintf... |
||
32 | |||
33 | // NICE TO HAVE (INFINITY-IDEA - NOT IMPORTANT): |
||
34 | // - Is it possible to detect integer overflows and therefore output errors? |
||
35 | |||
36 | // ------------------------------------------------------- |
||
37 | |||
38 | // Allows OIDs which are bigger than "long" |
||
39 | // Compile with "gcc oid.c -lgmp -lm" |
||
40 | #define is_gmp |
||
41 | |||
42 | #include <stdio.h> |
||
43 | #include <string.h> |
||
44 | #include <stdlib.h> |
||
45 | |||
46 | #ifdef is_gmp |
||
47 | #include <gmp.h> |
||
48 | #endif |
||
49 | |||
50 | #include <stdbool.h> |
||
51 | |||
52 | #ifndef __STRNICMP_LOCAL |
||
53 | #ifdef WIN32 |
||
54 | #define __STRNICMP_LOCAL strnicmp |
||
55 | #else |
||
56 | #define __STRNICMP_LOCAL strncasecmp |
||
57 | #endif |
||
58 | #endif |
||
59 | |||
60 | // char abCommandLine[4096]; |
||
61 | const unsigned int CLI_INITIAL_SIZE = 1024; |
||
62 | const unsigned int CLI_EXPANSION_SIZE = 1024; |
||
63 | unsigned int cli_size; |
||
64 | char * abCommandLine; |
||
65 | |||
66 | // unsigned char abBinary[128]; |
||
67 | const unsigned int ABB_INITIAL_SIZE = 1024; |
||
68 | const unsigned int ABB_EXPANSION_SIZE = 1024; |
||
69 | unsigned int abb_size; |
||
70 | unsigned char * abBinary; |
||
71 | |||
72 | unsigned int nBinary = 0; |
||
73 | |||
74 | |||
75 | #ifdef is_gmp |
||
76 | static void MakeBase128( mpz_t l, int first ) { |
||
77 | if ( mpz_cmp_si(l, 127) > 0 ) { |
||
78 | mpz_t l2; |
||
79 | mpz_init(l2); |
||
80 | mpz_div_ui(l2, l, 128); |
||
81 | MakeBase128( l2 , 0 ); |
||
82 | } |
||
83 | mpz_mod_ui(l, l, 128); |
||
84 | |||
85 | if (nBinary+1 >= abb_size) { |
||
86 | abb_size += ABB_EXPANSION_SIZE; |
||
87 | abBinary = (unsigned char*) realloc(abBinary, abb_size); |
||
88 | if (abBinary == NULL) { |
||
89 | fprintf(stderr, "Memory reallocation failure!\n"); |
||
90 | exit(EXIT_FAILURE); |
||
91 | } |
||
92 | } |
||
93 | |||
94 | if ( first ) { |
||
95 | abBinary[nBinary++] = mpz_get_ui(l); |
||
96 | } else { |
||
97 | abBinary[nBinary++] = 0x80 | mpz_get_ui(l); |
||
98 | } |
||
99 | } |
||
100 | #else |
||
101 | static void MakeBase128( unsigned long l, int first ) { |
||
102 | if ( l > 127 ) { |
||
103 | MakeBase128( l / 128, 0 ); |
||
104 | } |
||
105 | l %= 128; |
||
106 | |||
107 | if (nBinary+1 >= abb_size) { |
||
108 | abb_size += ABB_EXPANSION_SIZE; |
||
109 | abBinary = (unsigned char*) realloc(abBinary, abb_size); |
||
110 | if (abBinary == NULL) { |
||
111 | fprintf(stderr, "Memory reallocation failure!\n"); |
||
112 | exit(EXIT_FAILURE); |
||
113 | } |
||
114 | } |
||
115 | |||
116 | if ( first ) { |
||
117 | abBinary[nBinary++] = (unsigned char)l; |
||
118 | } else { |
||
119 | abBinary[nBinary++] = 0x80 | (unsigned char)l; |
||
120 | } |
||
121 | } |
||
122 | #endif |
||
123 | |||
124 | int main( int argc, char **argv ) { |
||
125 | cli_size = CLI_INITIAL_SIZE; |
||
126 | abCommandLine = (char*) malloc(cli_size * sizeof(char*)); |
||
127 | if (abCommandLine == NULL) { |
||
128 | fprintf(stderr, "Memory allocation failure!\n"); |
||
129 | return EXIT_FAILURE; |
||
130 | } |
||
131 | |||
132 | abb_size = ABB_INITIAL_SIZE; |
||
133 | abBinary = (unsigned char*) malloc(abb_size * sizeof(unsigned char*)); |
||
134 | if (abBinary == NULL) { |
||
135 | fprintf(stderr, "Memory allocation failure!\n"); |
||
136 | return EXIT_FAILURE; |
||
137 | } |
||
138 | |||
139 | |||
140 | char *fOutName = NULL; |
||
141 | char *fInName = NULL; |
||
142 | FILE *fOut = NULL; |
||
143 | |||
144 | int n = 1; |
||
145 | int nMode = 0; /* dotted->hex */ |
||
146 | int nCHex = 0; |
||
147 | int nAfterOption = 0; |
||
148 | |||
149 | if ( argc == 1 ) { |
||
150 | fprintf( stderr, |
||
151 | "OID encoder/decoder 1.4 - Matthias Gaertner 1999/2001, Daniel Marschall 2011 - Freeware\n" |
||
152 | #ifdef is_gmp |
||
153 | "GMP Edition\n" |
||
154 | #endif |
||
155 | "\nUsage:\n" |
||
156 | " OID [-C] [-o<outfile>] {-i<infile>|2.999.1}\n" |
||
157 | " converts dotted form to ASCII HEX DER output.\n" |
||
158 | " OID -x [-o<outfile>] {-i<infile>|hex-digits}\n" |
||
159 | " decodes ASCII HEX DER and gives dotted form.\n" ); |
||
160 | return 1; |
||
161 | } |
||
162 | |||
163 | while ( n < argc ) { |
||
164 | if ( !nAfterOption && argv[n][0] == '-' ) { |
||
165 | if ( argv[n][1] == 'x' ) { |
||
166 | nMode = 1; /* hex->dotted */ |
||
167 | if ( argv[n][2] != '\0' ) { |
||
168 | argv[n--] += 2; |
||
169 | nAfterOption = 1; |
||
170 | } |
||
171 | } else if ( argv[n][1] == 'C' ) { |
||
172 | nMode = 0; |
||
173 | nCHex = 1; |
||
174 | |||
175 | if ( argv[n][2] != '\0' ) { |
||
176 | argv[n--] += 2; |
||
177 | nAfterOption = 1; |
||
178 | } |
||
179 | } else if ( argv[n][1] == 'o' ) { |
||
180 | if ( argv[n][2] != '\0' ) { |
||
181 | fOutName = &argv[n][2]; |
||
182 | } else if ( n < argc-1 ) { |
||
183 | fOutName = argv[++n]; |
||
184 | } else { |
||
185 | fprintf(stderr,"Incomplete command line.\n"); |
||
186 | } |
||
187 | } else if ( argv[n][1] == 'i' ) { |
||
188 | if ( argv[n][2] != '\0' ) { |
||
189 | fInName = &argv[n][2]; |
||
190 | } else if ( n < argc-1 ) { |
||
191 | fInName = argv[++n]; |
||
192 | } else { |
||
193 | fprintf(stderr,"Incomplete command line.\n"); |
||
194 | } |
||
195 | } |
||
196 | } else { |
||
197 | if ( fInName != NULL ) { |
||
198 | break; |
||
199 | } |
||
200 | |||
201 | nAfterOption = 1; |
||
202 | if ( strlen( argv[n] ) + strlen( abCommandLine ) >= sizeof(abCommandLine)-2 ) { |
||
203 | // fprintf(stderr,"Command line too long.\n"); |
||
204 | // return 2; |
||
205 | |||
206 | cli_size += CLI_EXPANSION_SIZE + strlen( argv[n] ) + 1; // 1 = "." |
||
207 | abCommandLine = (char*) realloc(abCommandLine, cli_size); |
||
208 | if (abCommandLine == NULL) { |
||
209 | fprintf(stderr, "Memory reallocation failure!\n"); |
||
210 | return EXIT_FAILURE; |
||
211 | } |
||
212 | // TODO: (Unklar) Wer garantiert, dass es mit "\0" abschließt? |
||
213 | } |
||
214 | strcat( abCommandLine, argv[n] ); |
||
215 | if ( n != argc - 1 && nMode != 1 ) { |
||
216 | strcat( abCommandLine, "." ); |
||
217 | } |
||
218 | } |
||
219 | n++; |
||
220 | } |
||
221 | |||
222 | if ( fInName != NULL && nMode == 1 ) { |
||
223 | FILE *fIn = fopen( fInName, "rb" ); |
||
224 | size_t nRead = 0; |
||
225 | if ( fIn == NULL ) { |
||
226 | fprintf(stderr,"Unable to open input file %s.\n", fInName ); |
||
227 | return 11; |
||
228 | } |
||
229 | nRead = fread( abCommandLine, 1, sizeof(abCommandLine), fIn ); |
||
230 | abCommandLine[nRead] = '\0'; |
||
231 | fclose( fIn ); |
||
232 | } else if ( fInName != NULL && nMode == 0 ) { |
||
233 | FILE *fIn = fopen( fInName, "rt" ); |
||
234 | if ( fIn == NULL ) { |
||
235 | fprintf(stderr,"Unable to open input file %s.\n", fInName ); |
||
236 | return 11; |
||
237 | } |
||
238 | fgets( abCommandLine, sizeof(abCommandLine), fIn ); |
||
239 | fclose( fIn ); |
||
240 | } |
||
241 | |||
242 | while ( nMode == 1 ) /* better if */ |
||
243 | { |
||
244 | /* hex->dotted */ |
||
245 | /*printf("Hex-In: %s\n", abCommandLine );*/ |
||
246 | |||
247 | char *p = abCommandLine; |
||
248 | char *q = p; |
||
249 | |||
250 | unsigned char *pb = NULL; |
||
251 | unsigned int nn = 0; |
||
252 | #ifdef is_gmp |
||
253 | mpz_t ll; |
||
254 | mpz_init(ll); |
||
255 | #else |
||
256 | unsigned long ll = 0; |
||
257 | #endif |
||
258 | bool fOK = false; |
||
259 | int fSub = 0; // Subtract value from next number output. Used when encoding {2 48} and up |
||
260 | |||
261 | while ( *p ) { |
||
262 | if ( *p != '.' && *p != '\r' && *p != '\n' && *p != '\x20' && *p != '\t') { |
||
263 | *q++ = *p; |
||
264 | } |
||
265 | p++; |
||
266 | } |
||
267 | *q = '\0'; |
||
268 | |||
269 | if ( strlen( abCommandLine ) % 2 != 0 ) { |
||
270 | fprintf(stderr, "Encoded OID must have even number of hex digits!\n" ); |
||
271 | return 2; |
||
272 | } |
||
273 | |||
274 | if ( strlen( abCommandLine ) < 3 ) { |
||
275 | fprintf(stderr, "Encoded OID must have at least three bytes!\n" ); |
||
276 | return 2; |
||
277 | } |
||
278 | |||
279 | nBinary = 0; |
||
280 | p = abCommandLine; |
||
281 | |||
282 | while ( *p ) { |
||
283 | unsigned char b; |
||
284 | |||
285 | // Interpret upper nibble |
||
286 | if ( p[0] >= 'A' && p[0] <= 'F' ) { |
||
287 | b = (p[0] - 'A' + 10) * 16; |
||
288 | } else if ( p[0] >= 'a' && p[0] <= 'f' ) { |
||
289 | b = (p[0] - 'a' + 10) * 16; |
||
290 | } else if ( p[0] >= '0' && p[0] <= '9' ) { |
||
291 | b = (p[0] - '0') * 16; |
||
292 | } else { |
||
293 | fprintf(stderr, "Must have hex digits only!\n" ); |
||
294 | return 2; |
||
295 | } |
||
296 | |||
297 | // Interpret lower nibble |
||
298 | if ( p[1] >= 'A' && p[1] <= 'F' ) { |
||
299 | b += (p[1] - 'A' + 10); |
||
300 | } else if ( p[1] >= 'a' && p[1] <= 'f' ) { |
||
301 | b += (p[1] - 'a' + 10); |
||
302 | } else if ( p[1] >= '0' && p[1] <= '9' ) { |
||
303 | b += (p[1] - '0'); |
||
304 | } else { |
||
305 | fprintf(stderr, "Must have hex digits only!\n" ); |
||
306 | return 2; |
||
307 | } |
||
308 | |||
309 | if (nBinary+1 >= abb_size) { |
||
310 | abb_size += ABB_EXPANSION_SIZE; |
||
311 | abBinary = (unsigned char*) realloc(abBinary, abb_size); |
||
312 | if (abBinary == NULL) { |
||
313 | fprintf(stderr, "Memory reallocation failure!\n"); |
||
314 | return EXIT_FAILURE; |
||
315 | } |
||
316 | } |
||
317 | |||
318 | abBinary[nBinary++] = b; |
||
319 | p += 2; |
||
320 | } |
||
321 | |||
322 | /*printf("Hex-In: %s\n", abCommandLine );*/ |
||
323 | |||
324 | if ( fOutName != NULL ) { |
||
325 | fOut = fopen( fOutName, "wt" ); |
||
326 | if ( fOut == NULL ) { |
||
327 | fprintf(stderr,"Unable to open output file %s\n", fOutName ); |
||
328 | return 33; |
||
329 | } |
||
330 | } else { |
||
331 | fOut = stdout; |
||
332 | } |
||
333 | |||
334 | pb = abBinary; |
||
335 | nn = 0; |
||
336 | #ifdef is_gmp |
||
337 | mpz_init(ll); |
||
338 | #else |
||
339 | ll = 0; |
||
340 | #endif |
||
341 | fOK = false; |
||
342 | fSub = 0; |
||
343 | |||
344 | // 0 = Universal Class Identifier Tag |
||
345 | // 1 = Length part (may have more than 1 byte!) |
||
346 | // 2 = First two arc encoding |
||
347 | // 3 = Encoding of arc three and higher |
||
348 | unsigned char part = 0; |
||
349 | |||
350 | unsigned char lengthbyte_count = 0; |
||
351 | unsigned char lengthbyte_pos = 0; |
||
352 | bool lengthfinished = false; |
||
353 | |||
354 | while ( nn < nBinary ) { |
||
355 | if ( part == 0 ) { // Class Tag |
||
356 | unsigned char cl = ((*pb & 0xC0) >> 6) & 0x03; |
||
357 | switch ( cl ) { |
||
358 | default: |
||
359 | case 0: fprintf(fOut,"UNIVERSAL"); break; |
||
360 | case 1: fprintf(fOut,"APPLICATION"); break; |
||
361 | case 2: fprintf(fOut,"CONTEXT"); break; |
||
362 | case 3: fprintf(fOut,"PRIVATE"); break; |
||
363 | } |
||
364 | fprintf(fOut," OID"); |
||
365 | part++; |
||
366 | } else if ( part == 1 ) { // Length |
||
367 | |||
368 | // Find out the length and save it into ll |
||
369 | |||
370 | // 2nd Byte |
||
371 | // 0x00 .. 0x7F => The actual length |
||
372 | // 0x80 + n => The length is spread over the following 'n' bytes |
||
373 | // (Unknown: Is 'n' limited or can it be until 0xFF is reached?) |
||
374 | // (Unknown: How is length=0x80 (=0 following bytes define the length) defined? Is it the same as 0x00?) |
||
375 | |||
376 | if (nn == 1) { // The first length byte |
||
377 | lengthbyte_pos = 0; |
||
378 | if ( (*pb & 0x80) != 0 ) { |
||
379 | // 0x80 + n => The length is spread over the following 'n' bytes |
||
380 | lengthfinished = false; |
||
381 | lengthbyte_count = *pb & 0x7F; |
||
382 | fOK = false; |
||
383 | } else { |
||
384 | // 0x00 .. 0x7F => The actual length |
||
385 | #ifdef is_gmp |
||
386 | mpz_set_ui(ll, *pb); |
||
387 | #else |
||
388 | ll = *pb; |
||
389 | #endif |
||
390 | lengthfinished = true; |
||
391 | lengthbyte_count = 0; |
||
392 | fOK = true; |
||
393 | } |
||
394 | } else { |
||
395 | if (lengthbyte_count > lengthbyte_pos) { |
||
396 | #ifdef is_gmp |
||
397 | mpz_mul_ui(ll, ll, 0x100); |
||
398 | mpz_add_ui(ll, ll, *pb); |
||
399 | #else |
||
400 | ll *= 0x100; |
||
401 | ll += *pb; |
||
402 | #endif |
||
403 | lengthbyte_pos++; |
||
404 | } |
||
405 | |||
406 | if (lengthbyte_count == lengthbyte_pos) { |
||
407 | lengthfinished = true; |
||
408 | fOK = true; |
||
409 | } |
||
410 | } |
||
411 | |||
412 | if (lengthfinished) { // The length is now in ll |
||
413 | #ifdef is_gmp |
||
414 | if ( mpz_cmp_ui(ll, nBinary - 2 - lengthbyte_count) != 0 ) { |
||
415 | fprintf(fOut,"\n"); |
||
416 | if ( fOut != stdout ) { |
||
417 | fclose( fOut ); |
||
418 | } |
||
419 | fprintf(stderr,"\nInvalid length (%d entered, but %s expected)\n", nBinary - 2, mpz_get_str(NULL, 10, ll) ); |
||
420 | return 3; |
||
421 | } |
||
422 | mpz_set_ui(ll, 0); // reset for later usage |
||
423 | #else |
||
424 | if ( ll != nBinary - 2 - lengthbyte_count ) { |
||
425 | fprintf(fOut,"\n"); |
||
426 | if ( fOut != stdout ) { |
||
427 | fclose( fOut ); |
||
428 | } |
||
429 | fprintf(stderr,"\nInvalid length (%d entered, but %d expected)\n", nBinary - 2, ll ); |
||
430 | return 3; |
||
431 | } |
||
432 | ll = 0; // reset for later usage |
||
433 | #endif |
||
434 | fOK = true; |
||
435 | part++; |
||
436 | } |
||
437 | } else if ( part == 2 ) { // First two arcs |
||
438 | int first = *pb / 40; |
||
439 | int second = *pb % 40; |
||
440 | if (first > 2) { |
||
441 | first = 2; |
||
442 | fprintf(fOut,".%d", first ); |
||
443 | |||
444 | if ( (*pb & 0x80) != 0 ) { |
||
445 | // 2.48 and up => 2+ octets |
||
446 | #ifdef is_gmp |
||
447 | mpz_add_ui(ll, ll, (*pb & 0x7F)); |
||
448 | #else |
||
449 | ll += (*pb & 0x7F); |
||
450 | #endif |
||
451 | fSub = 80; |
||
452 | fOK = false; |
||
453 | } else { |
||
454 | // 2.0 till 2.47 => 1 octet |
||
455 | second = *pb - 80; |
||
456 | fprintf(fOut,".%d",second); |
||
457 | fOK = true; |
||
458 | #ifdef is_gmp |
||
459 | mpz_set_ui(ll, 0); |
||
460 | #else |
||
461 | ll = 0; |
||
462 | #endif |
||
463 | } |
||
464 | } else { |
||
465 | // 0.0 till 0.37 => 1 octet |
||
466 | // 1.0 till 1.37 => 1 octet |
||
467 | fprintf(fOut,".%d.%d", first, second ); |
||
468 | fOK = true; |
||
469 | #ifdef is_gmp |
||
470 | mpz_set_ui(ll, 0); |
||
471 | #else |
||
472 | ll = 0; |
||
473 | #endif |
||
474 | } |
||
475 | part++; |
||
476 | } else if ( part == 3 ) { // Arc three and higher |
||
477 | if ( (*pb & 0x80) != 0 ) { |
||
478 | #ifdef is_gmp |
||
479 | mpz_mul_ui(ll, ll, 128); |
||
480 | mpz_add_ui(ll, ll, (*pb & 0x7F)); |
||
481 | #else |
||
482 | ll *= 128; |
||
483 | ll += (*pb & 0x7F); |
||
484 | #endif |
||
485 | fOK = false; |
||
486 | } else { |
||
487 | #ifdef is_gmp |
||
488 | mpz_mul_ui(ll, ll, 128); |
||
489 | mpz_add_ui(ll, ll, *pb); |
||
490 | mpz_sub_ui(ll, ll, fSub); |
||
491 | fprintf(fOut,".%s", mpz_get_str(NULL, 10, ll) ); |
||
492 | mpz_set_ui(ll, 0); |
||
493 | #else |
||
494 | ll *= 128; |
||
495 | ll += *pb; |
||
496 | ll -= fSub; |
||
497 | fprintf(fOut,".%lu", ll ); |
||
498 | ll = 0; |
||
499 | #endif |
||
500 | fSub = 0; |
||
501 | fOK = true; |
||
502 | } |
||
503 | } |
||
504 | |||
505 | pb++; |
||
506 | nn++; |
||
507 | } |
||
508 | |||
509 | if ( !fOK ) { |
||
510 | fprintf(fOut,"\n"); |
||
511 | if ( fOut != stdout ) { |
||
512 | fclose( fOut ); |
||
513 | } |
||
514 | fprintf(stderr,"\nEncoding error. The OID is not constructed properly.\n"); |
||
515 | return 4; |
||
516 | } else { |
||
517 | fprintf(fOut,"\n"); |
||
518 | } |
||
519 | |||
520 | if ( fOut != stdout ) { |
||
521 | fclose( fOut ); |
||
522 | } |
||
523 | break; |
||
524 | }; |
||
525 | |||
526 | while ( nMode == 0 ) /* better if */ |
||
527 | { |
||
528 | /* dotted->hex */ |
||
529 | /* printf("OID.%s\n", abCommandLine ); */ |
||
530 | |||
531 | char *p = abCommandLine; |
||
532 | unsigned char cl = 0x00; |
||
533 | char *q = NULL; |
||
534 | int nPieces = 1; |
||
535 | int n = 0; |
||
536 | unsigned char b = 0; |
||
537 | unsigned int nn = 0; |
||
538 | #ifdef is_gmp |
||
539 | mpz_t l; |
||
540 | #else |
||
541 | unsigned long l = 0; |
||
542 | #endif |
||
543 | bool isjoint = false; |
||
544 | |||
545 | if ( __STRNICMP_LOCAL( p, "UNIVERSAL.", 10 ) == 0 ) { |
||
546 | p+=10; |
||
547 | } else if ( __STRNICMP_LOCAL( p, "APPLICATION.", 12 ) == 0 ) { |
||
548 | cl = 0x40; |
||
549 | p+=12; |
||
550 | } else if ( __STRNICMP_LOCAL( p, "CONTEXT.", 8 ) == 0 ) { |
||
551 | cl = 0x80; |
||
552 | p+=8; |
||
553 | } else if ( __STRNICMP_LOCAL( p, "PRIVATE.", 8 ) == 0 ) { |
||
554 | cl = 0xC0; |
||
555 | p+=8; |
||
556 | } |
||
557 | |||
558 | if ( __STRNICMP_LOCAL( p, "OID.", 4 ) == 0 ) { |
||
559 | p+=4; |
||
560 | } |
||
561 | |||
562 | q = p; |
||
563 | nPieces = 1; |
||
564 | while ( *p ) { |
||
565 | if ( *p == '.' ) { |
||
566 | nPieces++; |
||
567 | } |
||
568 | p++; |
||
569 | } |
||
570 | |||
571 | n = 0; |
||
572 | b = 0; |
||
573 | p = q; |
||
574 | while ( n < nPieces ) { |
||
575 | q = p; |
||
576 | while ( *p ) { |
||
577 | if ( *p == '.' ) { |
||
578 | break; |
||
579 | } |
||
580 | p++; |
||
581 | } |
||
582 | |||
583 | #ifdef is_gmp |
||
584 | mpz_init(l); |
||
585 | #else |
||
586 | l = 0; |
||
587 | #endif |
||
588 | if ( *p == '.' ) { |
||
589 | *p = 0; |
||
590 | #ifdef is_gmp |
||
591 | mpz_set_str(l, q, 10); |
||
592 | #else |
||
593 | l = (unsigned long) atoi( q ); |
||
594 | #endif |
||
595 | q = p+1; |
||
596 | p = q; |
||
597 | } else { |
||
598 | #ifdef is_gmp |
||
599 | mpz_set_str(l, q, 10); |
||
600 | #else |
||
601 | l = (unsigned long) atoi( q ); |
||
602 | #endif |
||
603 | q = p; |
||
604 | } |
||
605 | |||
606 | /* Digit is in l. */ |
||
607 | if ( n == 0 ) { |
||
608 | #ifdef is_gmp |
||
609 | if (mpz_cmp_ui(l, 2) > 0) { |
||
610 | #else |
||
611 | if (l > 2) { |
||
612 | #endif |
||
613 | fprintf(stderr,"\nEncoding error. The top arc is limited to 0, 1 and 2.\n"); |
||
614 | return 5; |
||
615 | } |
||
616 | #ifdef is_gmp |
||
617 | b += 40 * mpz_get_ui(l); |
||
618 | isjoint = mpz_cmp_ui(l, 2) == 0; |
||
619 | #else |
||
620 | b = 40 * ((unsigned char)l); |
||
621 | isjoint = l == 2; |
||
622 | #endif |
||
623 | } else if ( n == 1 ) { |
||
624 | #ifdef is_gmp |
||
625 | if ((mpz_cmp_ui(l, 39) > 0) && (!isjoint)) { |
||
626 | #else |
||
627 | if ((l > 39) && (!isjoint)) { |
||
628 | #endif |
||
629 | fprintf(stderr,"\nEncoding error. The second level is limited to 0..39 for top level arcs 0 and 1.\n"); |
||
630 | return 5; |
||
631 | } |
||
632 | |||
633 | #ifdef is_gmp |
||
634 | if (mpz_cmp_ui(l, 47) > 0) { |
||
635 | mpz_add_ui(l, l, 80); |
||
636 | MakeBase128( l, 1 ); |
||
637 | } else { |
||
638 | b += mpz_get_ui(l); |
||
639 | if (nBinary+1 >= abb_size) { |
||
640 | abb_size += ABB_EXPANSION_SIZE; |
||
641 | abBinary = (unsigned char*) realloc(abBinary, abb_size); |
||
642 | if (abBinary == NULL) { |
||
643 | fprintf(stderr, "Memory reallocation failure!\n"); |
||
644 | return EXIT_FAILURE; |
||
645 | } |
||
646 | } |
||
647 | abBinary[nBinary++] = b; |
||
648 | } |
||
649 | #else |
||
650 | if (l > 47) { |
||
651 | l += 80; |
||
652 | MakeBase128( l, 1 ); |
||
653 | } else { |
||
654 | b += ((unsigned char) l); |
||
655 | if (nBinary+1 >= abb_size) { |
||
656 | abb_size += ABB_EXPANSION_SIZE; |
||
657 | abBinary = (unsigned char*) realloc(abBinary, abb_size); |
||
658 | if (abBinary == NULL) { |
||
659 | fprintf(stderr, "Memory reallocation failure!\n"); |
||
660 | return EXIT_FAILURE; |
||
661 | } |
||
662 | } |
||
663 | abBinary[nBinary++] = b; |
||
664 | } |
||
665 | #endif |
||
666 | } else { |
||
667 | MakeBase128( l, 1 ); |
||
668 | } |
||
669 | n++; |
||
670 | } |
||
671 | |||
672 | if (n < 2) { |
||
673 | fprintf(stderr,"\nEncoding error. The minimum depth of an encodeable OID is 2. (e.g. 2.999)\n"); |
||
674 | return 5; |
||
675 | } |
||
676 | |||
677 | if ( fOutName != NULL ) { |
||
678 | fOut = fopen( fOutName, "wt" ); |
||
679 | if ( fOut == NULL ) { |
||
680 | fprintf(stderr,"Unable to open output file %s\n", fOutName ); |
||
681 | return 33; |
||
682 | } |
||
683 | } else { |
||
684 | fOut = stdout; |
||
685 | } |
||
686 | |||
687 | if ( nCHex ) { |
||
688 | fprintf(fOut,"\"\\x%02X\\x%02X", cl | 6, nBinary ); |
||
689 | } else { |
||
690 | fprintf(fOut,"%02X %02X ", cl | 6, nBinary ); |
||
691 | } |
||
692 | nn = 0; |
||
693 | while ( nn < nBinary ) { |
||
694 | unsigned char b = abBinary[nn++]; |
||
695 | if ( nn == nBinary ) { |
||
696 | if ( nCHex ) { |
||
697 | fprintf(fOut,"\\x%02X\"\n", b ); |
||
698 | } else { |
||
699 | fprintf(fOut,"%02X\n", b ); |
||
700 | } |
||
701 | } else { |
||
702 | if ( nCHex ) { |
||
703 | fprintf(fOut,"\\x%02X", b ); |
||
704 | } else { |
||
705 | fprintf(fOut,"%02X ", b ); |
||
706 | } |
||
707 | } |
||
708 | } |
||
709 | if ( fOut != stdout ) { |
||
710 | fclose( fOut ); |
||
711 | } |
||
712 | break; |
||
713 | } |
||
714 | |||
715 | free(abCommandLine); |
||
716 | free(abBinary); |
||
717 | |||
718 | return 0; |
||
719 | } |
||
720 | |||
721 | /* */ |
||
722 |