blob: 6a3477d109b9405cb0eec22d27dfd873fa1b36ca [file] [log] [blame]
vlmfa67ddc2004-06-03 03:38:44 +00001#include <stdio.h>
vlmfd2ee9e2004-09-27 20:54:44 +00002#include <string.h>
vlmfa67ddc2004-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);
vlmec8f6812004-08-22 03:19:54 +000020static int _asn1p_fix_modules(asn1p_t *a, const char *fname);
vlmfa67ddc2004-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)
38 size = strlen(buffer);
39
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);
vlmec8f6812004-08-22 03:19:54 +000055 if(_asn1p_fix_modules(a, "-"))
vlmfa67ddc2004-06-03 03:38:44 +000056 return NULL; /* FIXME: destroy (a) */
57 } else {
58 assert(a == NULL);
59 }
60
61 return a;
62}
63
64
65/*
66 * Parse the file identified by its name.
67 */
68asn1p_t *
69asn1p_parse_file(const char *filename, enum asn1p_flags flags) {
70 struct stat sb;
71 asn1p_t *a = 0;
72 void *ap;
73 FILE *fp;
74 int ret;
75
76 if(_asn1p_set_flags(flags)) {
77 /* EINVAL */
78 return 0;
79 }
80
81 fp = fopen(filename, "r");
82 if(fp == NULL) {
83 perror(filename);
84 return NULL;
85 }
86
87 if(fstat(fileno(fp), &sb)
88 || !S_ISREG(sb.st_mode)) {
89 fclose(fp);
90 fprintf(stderr, "%s file not recognized: Bad file format\n",
91 filename);
92 errno = EINVAL;
93 return NULL;
94 }
95
96 asn1p_lineno = 1;
97
98 asn1p_restart(fp);
99
100 ap = (void *)&a;
101 ret = asn1p_parse(ap);
102
103 fclose(fp);
104
105 if(ret == 0) {
106 assert(a);
vlmec8f6812004-08-22 03:19:54 +0000107 if(_asn1p_fix_modules(a, filename))
vlmfa67ddc2004-06-03 03:38:44 +0000108 return NULL; /* FIXME: destroy (a) */
109 } else {
110 assert(a == NULL);
111 }
112
113 return a;
114}
115
116extern int asn1p_lexer_types_year;
117extern int asn1p_lexer_constructs_year;
118extern int asn1p__flex_debug;
119
120static int
121_asn1p_set_flags(enum asn1p_flags flags) {
122
123 asn1p_lexer_types_year = 0;
124 asn1p_lexer_constructs_year = 0;
125 asn1p__flex_debug = 0;
126
127 /*
128 * Enable debugging in lexer.
129 */
130 if(flags & A1P_LEXER_DEBUG) {
131 flags &= ~A1P_LEXER_DEBUG;
132 asn1p__flex_debug = 1;
133 }
134
135 /*
136 * Restrict embedded types to ASN.1:1988 version of standard.
137 */
138 if(flags & A1P_TYPES_RESTRICT_TO_1988) {
139 flags &= ~A1P_TYPES_RESTRICT_TO_1988;
140 asn1p_lexer_types_year = 1988;
141 }
142
143 /*
144 * Restrict embedded types to ASN.1:1988 version of standard.
145 */
146 if(flags & A1P_TYPES_RESTRICT_TO_1988) {
147 flags &= ~A1P_TYPES_RESTRICT_TO_1988;
148 asn1p_lexer_types_year = 1988;
149 }
150
151 /*
152 * Check that we haven't missed an unknown flag.
153 */
154 if(flags) {
155 errno = EINVAL;
156 return -1;
157 }
158
159 return 0;
160}
161
vlmec8f6812004-08-22 03:19:54 +0000162/*
163 * Perform last touches.
164 */
165static void
166_asn1p_apply_module2expr(asn1p_expr_t *expr, asn1p_module_t *mod) {
167 asn1p_expr_t *e;
168
169 expr->module = mod; /* This is a useful thing */
170
171 /*
172 * Do it to children also.
173 */
174 TQ_FOR(e, &(expr->members), next) {
175 _asn1p_apply_module2expr(e, mod);
176 }
177}
178
vlmfa67ddc2004-06-03 03:38:44 +0000179static int
vlmec8f6812004-08-22 03:19:54 +0000180_asn1p_fix_modules(asn1p_t *a, const char *fname) {
vlmfa67ddc2004-06-03 03:38:44 +0000181 asn1p_module_t *mod;
182 TQ_FOR(mod, &(a->modules), mod_next) {
vlmec8f6812004-08-22 03:19:54 +0000183 asn1p_expr_t *expr;
184
vlmfd2ee9e2004-09-27 20:54:44 +0000185 mod->source_file_name = strdup(fname);
vlmfa67ddc2004-06-03 03:38:44 +0000186 if(mod->source_file_name == NULL)
187 return -1;
vlmec8f6812004-08-22 03:19:54 +0000188
189 TQ_FOR(expr, &(mod->members), next) {
190 _asn1p_apply_module2expr(expr, mod);
191 }
vlmfa67ddc2004-06-03 03:38:44 +0000192 }
193 return 0;
194}
vlmec8f6812004-08-22 03:19:54 +0000195
196