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