blob: f6221a56551d3b762e23cb43fdca3c25d24d25b3 [file] [log] [blame]
Lev Walkinf15320b2004-06-03 03:38:44 +00001#include <stdio.h>
Lev Walkinb1107e62004-09-27 20:54:44 +00002#include <string.h>
Lev Walkinf15320b2004-06-03 03:38:44 +00003#include <sys/types.h>
4#include <sys/stat.h>
5#include <assert.h>
6#include <errno.h>
7
8#include "asn1parser.h"
9#include "asn1p_list.h"
10
11int asn1p_parse(void **param);
12
13void *asn1p__scan_bytes(const char *, int len);
14void *asn1p__delete_buffer(void *);
15void *asn1p_restart(FILE *);
16
17extern int asn1p_lineno;
18
19static int _asn1p_set_flags(enum asn1p_flags flags);
Lev Walkin070a52d2004-08-22 03:19:54 +000020static int _asn1p_fix_modules(asn1p_t *a, const char *fname);
Lev Walkinf15320b2004-06-03 03:38:44 +000021
22/*
23 * Parse the given buffer.
24 */
25asn1p_t *
26asn1p_parse_buffer(const char *buffer, int size /* = -1 */, enum asn1p_flags flags) {
27 asn1p_t *a = 0;
28 void *ap;
29 void *ybuf;
30 int ret;
31
32 if(_asn1p_set_flags(flags)) {
33 /* EINVAL */
34 return 0;
35 }
36
37 if(size < 0)
Lev Walkin4efbfb72005-02-25 14:20:30 +000038 size = (int)strlen(buffer);
Lev Walkinf15320b2004-06-03 03:38:44 +000039
40 ybuf = asn1p__scan_bytes(buffer, size);
41 if(!ybuf) {
42 assert(ybuf);
43 return 0;
44 }
45
46 asn1p_lineno = 1;
47
48 ap = (void *)&a;
49 ret = asn1p_parse(ap);
50
51 asn1p__delete_buffer(ybuf);
52
53 if(ret == 0) {
54 assert(a);
Lev Walkin070a52d2004-08-22 03:19:54 +000055 if(_asn1p_fix_modules(a, "-"))
Lev Walkinf15320b2004-06-03 03:38:44 +000056 return NULL; /* FIXME: destroy (a) */
Lev Walkin4cd43042005-04-08 10:14:30 +000057 } else if(a) {
58 asn1p_free(a);
59 a = NULL;
Lev Walkinf15320b2004-06-03 03:38:44 +000060 }
61
62 return a;
63}
64
65
66/*
67 * Parse the file identified by its name.
68 */
69asn1p_t *
70asn1p_parse_file(const char *filename, enum asn1p_flags flags) {
Lev Walkin4efbfb72005-02-25 14:20:30 +000071#ifndef WIN32
Lev Walkinf15320b2004-06-03 03:38:44 +000072 struct stat sb;
Lev Walkin4efbfb72005-02-25 14:20:30 +000073#endif
Lev Walkinf15320b2004-06-03 03:38:44 +000074 asn1p_t *a = 0;
75 void *ap;
76 FILE *fp;
77 int ret;
78
79 if(_asn1p_set_flags(flags)) {
80 /* EINVAL */
81 return 0;
82 }
83
84 fp = fopen(filename, "r");
85 if(fp == NULL) {
86 perror(filename);
87 return NULL;
88 }
89
Lev Walkin4efbfb72005-02-25 14:20:30 +000090#ifndef WIN32
Lev Walkinf15320b2004-06-03 03:38:44 +000091 if(fstat(fileno(fp), &sb)
92 || !S_ISREG(sb.st_mode)) {
93 fclose(fp);
94 fprintf(stderr, "%s file not recognized: Bad file format\n",
95 filename);
96 errno = EINVAL;
97 return NULL;
98 }
Lev Walkin4efbfb72005-02-25 14:20:30 +000099#endif /* WIN32 */
Lev Walkinf15320b2004-06-03 03:38:44 +0000100
101 asn1p_lineno = 1;
102
103 asn1p_restart(fp);
104
105 ap = (void *)&a;
106 ret = asn1p_parse(ap);
107
108 fclose(fp);
109
110 if(ret == 0) {
111 assert(a);
Lev Walkin070a52d2004-08-22 03:19:54 +0000112 if(_asn1p_fix_modules(a, filename))
Lev Walkinf15320b2004-06-03 03:38:44 +0000113 return NULL; /* FIXME: destroy (a) */
Lev Walkin4cd43042005-04-08 10:14:30 +0000114 } else if(a) {
115 asn1p_free(a);
Lev Walkinc16cf432005-04-08 10:12:40 +0000116 a = NULL;
Lev Walkinf15320b2004-06-03 03:38:44 +0000117 }
118
119 return a;
120}
121
122extern int asn1p_lexer_types_year;
123extern int asn1p_lexer_constructs_year;
124extern int asn1p__flex_debug;
125
126static int
127_asn1p_set_flags(enum asn1p_flags flags) {
128
129 asn1p_lexer_types_year = 0;
130 asn1p_lexer_constructs_year = 0;
131 asn1p__flex_debug = 0;
132
133 /*
134 * Enable debugging in lexer.
135 */
136 if(flags & A1P_LEXER_DEBUG) {
137 flags &= ~A1P_LEXER_DEBUG;
138 asn1p__flex_debug = 1;
139 }
140
141 /*
142 * Restrict embedded types to ASN.1:1988 version of standard.
143 */
144 if(flags & A1P_TYPES_RESTRICT_TO_1988) {
145 flags &= ~A1P_TYPES_RESTRICT_TO_1988;
146 asn1p_lexer_types_year = 1988;
147 }
148
149 /*
150 * Restrict embedded types to ASN.1:1988 version of standard.
151 */
152 if(flags & A1P_TYPES_RESTRICT_TO_1988) {
153 flags &= ~A1P_TYPES_RESTRICT_TO_1988;
154 asn1p_lexer_types_year = 1988;
155 }
156
157 /*
158 * Check that we haven't missed an unknown flag.
159 */
160 if(flags) {
161 errno = EINVAL;
162 return -1;
163 }
164
165 return 0;
166}
167
Lev Walkin070a52d2004-08-22 03:19:54 +0000168/*
169 * Perform last touches.
170 */
171static void
172_asn1p_apply_module2expr(asn1p_expr_t *expr, asn1p_module_t *mod) {
173 asn1p_expr_t *e;
174
175 expr->module = mod; /* This is a useful thing */
176
177 /*
178 * Do it to children also.
179 */
180 TQ_FOR(e, &(expr->members), next) {
181 _asn1p_apply_module2expr(e, mod);
182 }
183}
184
Lev Walkinf15320b2004-06-03 03:38:44 +0000185static int
Lev Walkin070a52d2004-08-22 03:19:54 +0000186_asn1p_fix_modules(asn1p_t *a, const char *fname) {
Lev Walkinf15320b2004-06-03 03:38:44 +0000187 asn1p_module_t *mod;
188 TQ_FOR(mod, &(a->modules), mod_next) {
Lev Walkin070a52d2004-08-22 03:19:54 +0000189 asn1p_expr_t *expr;
190
Lev Walkinb1107e62004-09-27 20:54:44 +0000191 mod->source_file_name = strdup(fname);
Lev Walkinf15320b2004-06-03 03:38:44 +0000192 if(mod->source_file_name == NULL)
193 return -1;
Lev Walkin070a52d2004-08-22 03:19:54 +0000194
195 TQ_FOR(expr, &(mod->members), next) {
196 _asn1p_apply_module2expr(expr, mod);
197 }
Lev Walkinf15320b2004-06-03 03:38:44 +0000198 }
199 return 0;
200}
Lev Walkin070a52d2004-08-22 03:19:54 +0000201
202