blob: 405c880f7a09e5274c59cfdc7899c780415d7fbf [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 Walkind370e9f2006-03-16 10:03:35 +00003#include <stdlib.h>
Lev Walkinf15320b2004-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);
Lev Walkin070a52d2004-08-22 03:19:54 +000021static int _asn1p_fix_modules(asn1p_t *a, const char *fname);
Lev Walkinf15320b2004-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)
Lev Walkin4efbfb72005-02-25 14:20:30 +000039 size = (int)strlen(buffer);
Lev Walkinf15320b2004-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);
Bi-Ruei, Chiu3dcf05b2017-05-04 21:45:05 +080056 if(_asn1p_fix_modules(a, "-")) {
57 asn1p_delete(a);
Lev Walkinf15320b2004-06-03 03:38:44 +000058 return NULL; /* FIXME: destroy (a) */
Bi-Ruei, Chiu3dcf05b2017-05-04 21:45:05 +080059 }
Lev Walkin4cd43042005-04-08 10:14:30 +000060 } else if(a) {
Lev Walkin9b5df842006-09-12 04:21:30 +000061 asn1p_delete(a);
Lev Walkin4cd43042005-04-08 10:14:30 +000062 a = NULL;
Lev Walkinf15320b2004-06-03 03:38:44 +000063 }
64
65 return a;
66}
67
68
69/*
70 * Parse the file identified by its name.
71 */
72asn1p_t *
73asn1p_parse_file(const char *filename, enum asn1p_flags flags) {
Lev Walkin93659562010-11-20 09:47:13 -080074#ifndef _WIN32
Lev Walkinf15320b2004-06-03 03:38:44 +000075 struct stat sb;
Lev Walkin4efbfb72005-02-25 14:20:30 +000076#endif
Lev Walkinf15320b2004-06-03 03:38:44 +000077 asn1p_t *a = 0;
78 void *ap;
79 FILE *fp;
80 int ret;
81
82 if(_asn1p_set_flags(flags)) {
83 /* EINVAL */
84 return 0;
85 }
86
87 fp = fopen(filename, "r");
88 if(fp == NULL) {
89 perror(filename);
90 return NULL;
91 }
92
Lev Walkin93659562010-11-20 09:47:13 -080093#ifndef _WIN32
Lev Walkinf15320b2004-06-03 03:38:44 +000094 if(fstat(fileno(fp), &sb)
95 || !S_ISREG(sb.st_mode)) {
96 fclose(fp);
97 fprintf(stderr, "%s file not recognized: Bad file format\n",
98 filename);
99 errno = EINVAL;
100 return NULL;
101 }
Lev Walkin93659562010-11-20 09:47:13 -0800102#endif /* _WIN32 */
Lev Walkinf15320b2004-06-03 03:38:44 +0000103
104 asn1p_lineno = 1;
105
106 asn1p_restart(fp);
107
108 ap = (void *)&a;
109 ret = asn1p_parse(ap);
110
111 fclose(fp);
112
113 if(ret == 0) {
114 assert(a);
Bi-Ruei, Chiu3dcf05b2017-05-04 21:45:05 +0800115 if(_asn1p_fix_modules(a, filename)) {
116 asn1p_delete(a);
Lev Walkinf15320b2004-06-03 03:38:44 +0000117 return NULL; /* FIXME: destroy (a) */
Bi-Ruei, Chiu3dcf05b2017-05-04 21:45:05 +0800118 }
Lev Walkin4cd43042005-04-08 10:14:30 +0000119 } else if(a) {
Lev Walkin9b5df842006-09-12 04:21:30 +0000120 asn1p_delete(a);
Lev Walkinc16cf432005-04-08 10:12:40 +0000121 a = NULL;
Lev Walkinf15320b2004-06-03 03:38:44 +0000122 }
123
124 return a;
125}
126
127extern int asn1p_lexer_types_year;
128extern int asn1p_lexer_constructs_year;
129extern int asn1p__flex_debug;
130
131static int
132_asn1p_set_flags(enum asn1p_flags flags) {
133
134 asn1p_lexer_types_year = 0;
135 asn1p_lexer_constructs_year = 0;
136 asn1p__flex_debug = 0;
137
138 /*
139 * Enable debugging in lexer.
140 */
141 if(flags & A1P_LEXER_DEBUG) {
142 flags &= ~A1P_LEXER_DEBUG;
143 asn1p__flex_debug = 1;
144 }
145
146 /*
Lev Walkinf15320b2004-06-03 03:38:44 +0000147 * Check that we haven't missed an unknown flag.
148 */
149 if(flags) {
150 errno = EINVAL;
151 return -1;
152 }
153
154 return 0;
155}
156
157static int
Lev Walkin070a52d2004-08-22 03:19:54 +0000158_asn1p_fix_modules(asn1p_t *a, const char *fname) {
Lev Walkinf15320b2004-06-03 03:38:44 +0000159 asn1p_module_t *mod;
160 TQ_FOR(mod, &(a->modules), mod_next) {
Lev Walkinb1107e62004-09-27 20:54:44 +0000161 mod->source_file_name = strdup(fname);
Lev Walkinf15320b2004-06-03 03:38:44 +0000162 if(mod->source_file_name == NULL)
163 return -1;
Lev Walkina9532f42006-09-17 04:52:50 +0000164 mod->asn1p = a;
Lev Walkinf15320b2004-06-03 03:38:44 +0000165 }
166 return 0;
167}