blob: 7d9a88d7793b5b07445e145eefe7075c720e41d8 [file] [log] [blame]
vlmfa67ddc2004-06-03 03:38:44 +00001#include <stdio.h>
vlmfd2ee9e2004-09-27 20:54:44 +00002#include <string.h>
vlma6a84d72006-03-16 10:03:35 +00003#include <stdlib.h>
vlmfa67ddc2004-06-03 03:38:44 +00004#include <sys/types.h>
5#include <sys/stat.h>
6#include <assert.h>
7#include <errno.h>
8
9#include "asn1parser.h"
10#include "asn1p_list.h"
11
12int asn1p_parse(void **param);
13
14void *asn1p__scan_bytes(const char *, int len);
15void *asn1p__delete_buffer(void *);
16void *asn1p_restart(FILE *);
17
18extern int asn1p_lineno;
19
20static int _asn1p_set_flags(enum asn1p_flags flags);
vlmec8f6812004-08-22 03:19:54 +000021static int _asn1p_fix_modules(asn1p_t *a, const char *fname);
vlmfa67ddc2004-06-03 03:38:44 +000022
23/*
24 * Parse the given buffer.
25 */
26asn1p_t *
27asn1p_parse_buffer(const char *buffer, int size /* = -1 */, enum asn1p_flags flags) {
28 asn1p_t *a = 0;
29 void *ap;
30 void *ybuf;
31 int ret;
32
33 if(_asn1p_set_flags(flags)) {
34 /* EINVAL */
35 return 0;
36 }
37
38 if(size < 0)
vlm8a09e0f2005-02-25 14:20:30 +000039 size = (int)strlen(buffer);
vlmfa67ddc2004-06-03 03:38:44 +000040
41 ybuf = asn1p__scan_bytes(buffer, size);
42 if(!ybuf) {
43 assert(ybuf);
44 return 0;
45 }
46
47 asn1p_lineno = 1;
48
49 ap = (void *)&a;
50 ret = asn1p_parse(ap);
51
52 asn1p__delete_buffer(ybuf);
53
54 if(ret == 0) {
55 assert(a);
vlmec8f6812004-08-22 03:19:54 +000056 if(_asn1p_fix_modules(a, "-"))
vlmfa67ddc2004-06-03 03:38:44 +000057 return NULL; /* FIXME: destroy (a) */
vlm1bc75632005-04-08 10:14:30 +000058 } else if(a) {
vlm7ccbecc2006-09-12 04:21:30 +000059 asn1p_delete(a);
vlm1bc75632005-04-08 10:14:30 +000060 a = NULL;
vlmfa67ddc2004-06-03 03:38:44 +000061 }
62
63 return a;
64}
65
66
67/*
68 * Parse the file identified by its name.
69 */
70asn1p_t *
71asn1p_parse_file(const char *filename, enum asn1p_flags flags) {
vlm8a09e0f2005-02-25 14:20:30 +000072#ifndef WIN32
vlmfa67ddc2004-06-03 03:38:44 +000073 struct stat sb;
vlm8a09e0f2005-02-25 14:20:30 +000074#endif
vlmfa67ddc2004-06-03 03:38:44 +000075 asn1p_t *a = 0;
76 void *ap;
77 FILE *fp;
78 int ret;
79
80 if(_asn1p_set_flags(flags)) {
81 /* EINVAL */
82 return 0;
83 }
84
85 fp = fopen(filename, "r");
86 if(fp == NULL) {
87 perror(filename);
88 return NULL;
89 }
90
vlm8a09e0f2005-02-25 14:20:30 +000091#ifndef WIN32
vlmfa67ddc2004-06-03 03:38:44 +000092 if(fstat(fileno(fp), &sb)
93 || !S_ISREG(sb.st_mode)) {
94 fclose(fp);
95 fprintf(stderr, "%s file not recognized: Bad file format\n",
96 filename);
97 errno = EINVAL;
98 return NULL;
99 }
vlm8a09e0f2005-02-25 14:20:30 +0000100#endif /* WIN32 */
vlmfa67ddc2004-06-03 03:38:44 +0000101
102 asn1p_lineno = 1;
103
104 asn1p_restart(fp);
105
106 ap = (void *)&a;
107 ret = asn1p_parse(ap);
108
109 fclose(fp);
110
111 if(ret == 0) {
112 assert(a);
vlmec8f6812004-08-22 03:19:54 +0000113 if(_asn1p_fix_modules(a, filename))
vlmfa67ddc2004-06-03 03:38:44 +0000114 return NULL; /* FIXME: destroy (a) */
vlm1bc75632005-04-08 10:14:30 +0000115 } else if(a) {
vlm7ccbecc2006-09-12 04:21:30 +0000116 asn1p_delete(a);
vlm0b431122005-04-08 10:12:40 +0000117 a = NULL;
vlmfa67ddc2004-06-03 03:38:44 +0000118 }
119
120 return a;
121}
122
123extern int asn1p_lexer_types_year;
124extern int asn1p_lexer_constructs_year;
125extern int asn1p__flex_debug;
126
127static int
128_asn1p_set_flags(enum asn1p_flags flags) {
129
130 asn1p_lexer_types_year = 0;
131 asn1p_lexer_constructs_year = 0;
132 asn1p__flex_debug = 0;
133
134 /*
135 * Enable debugging in lexer.
136 */
137 if(flags & A1P_LEXER_DEBUG) {
138 flags &= ~A1P_LEXER_DEBUG;
139 asn1p__flex_debug = 1;
140 }
141
142 /*
vlmfa67ddc2004-06-03 03:38:44 +0000143 * Check that we haven't missed an unknown flag.
144 */
145 if(flags) {
146 errno = EINVAL;
147 return -1;
148 }
149
150 return 0;
151}
152
153static int
vlmec8f6812004-08-22 03:19:54 +0000154_asn1p_fix_modules(asn1p_t *a, const char *fname) {
vlmfa67ddc2004-06-03 03:38:44 +0000155 asn1p_module_t *mod;
156 TQ_FOR(mod, &(a->modules), mod_next) {
vlmfd2ee9e2004-09-27 20:54:44 +0000157 mod->source_file_name = strdup(fname);
vlmfa67ddc2004-06-03 03:38:44 +0000158 if(mod->source_file_name == NULL)
159 return -1;
vlm43c8ac52006-09-17 04:52:50 +0000160 mod->asn1p = a;
vlmfa67ddc2004-06-03 03:38:44 +0000161 }
162 return 0;
163}
vlmec8f6812004-08-22 03:19:54 +0000164
165
vlma6a84d72006-03-16 10:03:35 +0000166int
167asn1p_atoi(const char *ptr, asn1c_integer_t *value) {
168 errno = 0; /* Clear the error code */
169
170 if(sizeof(*value) <= sizeof(int)) {
171 *value = strtol(ptr, 0, 10);
172 } else {
173#ifdef HAVE_STRTOIMAX
174 *value = strtoimax(ptr, 0, 10);
175#elif HAVE_STRTOLL
176 *value = strtoll(ptr, 0, 10);
177#else
178 *value = strtol(ptr, 0, 10);
179#endif
180 }
181
182 return errno == 0 ? 0 : -1;
183}