1 #include <stdio.h>
2 #include <string.h>
3 #include <stdlib.h>
4 #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
12 int asn1p_parse(void **param);
13
14 void *asn1p__scan_bytes(const char *, int len);
15 void *asn1p__delete_buffer(void *);
16 void *asn1p_restart(FILE *);
17
18 extern int asn1p_lineno;
19
20 static int _asn1p_set_flags(enum asn1p_flags flags);
21 static int _asn1p_fix_modules(asn1p_t *a, const char *fname);
22
23 /*
24 * Parse the given buffer.
25 */
26 asn1p_t *
asn1p_parse_buffer(const char * buffer,int size,enum asn1p_flags flags)27 asn1p_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)
39 size = (int)strlen(buffer);
40
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);
56 if(_asn1p_fix_modules(a, "-"))
57 return NULL; /* FIXME: destroy (a) */
58 } else if(a) {
59 asn1p_delete(a);
60 a = NULL;
61 }
62
63 return a;
64 }
65
66
67 /*
68 * Parse the file identified by its name.
69 */
70 asn1p_t *
asn1p_parse_file(const char * filename,enum asn1p_flags flags)71 asn1p_parse_file(const char *filename, enum asn1p_flags flags) {
72 #ifndef _WIN32
73 struct stat sb;
74 #endif
75 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
91 #ifndef _WIN32
92 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 }
100 #endif /* _WIN32 */
101
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);
113 if(_asn1p_fix_modules(a, filename))
114 return NULL; /* FIXME: destroy (a) */
115 } else if(a) {
116 asn1p_delete(a);
117 a = NULL;
118 }
119
120 return a;
121 }
122
123 extern int asn1p_lexer_types_year;
124 extern int asn1p_lexer_constructs_year;
125 extern int asn1p__flex_debug;
126
127 static int
_asn1p_set_flags(enum asn1p_flags flags)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 /*
143 * 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
153 static int
_asn1p_fix_modules(asn1p_t * a,const char * fname)154 _asn1p_fix_modules(asn1p_t *a, const char *fname) {
155 asn1p_module_t *mod;
156 TQ_FOR(mod, &(a->modules), mod_next) {
157 mod->source_file_name = strdup(fname);
158 if(mod->source_file_name == NULL)
159 return -1;
160 mod->asn1p = a;
161 }
162 return 0;
163 }
164
165
166 int
asn1p_atoi(const char * ptr,asn1c_integer_t * value)167 asn1p_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 }
184