diff options
author | Hans Insulander <hin@cvs.openbsd.org> | 2003-05-11 21:36:34 +0000 |
---|---|---|
committer | Hans Insulander <hin@cvs.openbsd.org> | 2003-05-11 21:36:34 +0000 |
commit | c78150a12d3479dccfded58f1a4fcafdbff68146 (patch) | |
tree | b4b29b00ca76dd03e9fef5283b7a8979d66284d2 | |
parent | 516a12bfc498d29181db609ad1a42af093fef04f (diff) |
asn1_compile, made independant from libroken and the rest of the
kerberosV stuff.
Suggested by deraadt@
-rw-r--r-- | usr.bin/asn1_compile/Makefile | 16 | ||||
-rw-r--r-- | usr.bin/asn1_compile/gen.c | 464 | ||||
-rw-r--r-- | usr.bin/asn1_compile/gen_copy.c | 153 | ||||
-rw-r--r-- | usr.bin/asn1_compile/gen_decode.c | 396 | ||||
-rw-r--r-- | usr.bin/asn1_compile/gen_encode.c | 267 | ||||
-rw-r--r-- | usr.bin/asn1_compile/gen_free.c | 137 | ||||
-rw-r--r-- | usr.bin/asn1_compile/gen_glue.c | 141 | ||||
-rw-r--r-- | usr.bin/asn1_compile/gen_length.c | 173 | ||||
-rw-r--r-- | usr.bin/asn1_compile/gen_locl.h | 73 | ||||
-rw-r--r-- | usr.bin/asn1_compile/getarg.c | 601 | ||||
-rw-r--r-- | usr.bin/asn1_compile/getarg.h | 91 | ||||
-rw-r--r-- | usr.bin/asn1_compile/hash.c | 209 | ||||
-rw-r--r-- | usr.bin/asn1_compile/hash.h | 87 | ||||
-rw-r--r-- | usr.bin/asn1_compile/lex.h | 39 | ||||
-rw-r--r-- | usr.bin/asn1_compile/lex.l | 122 | ||||
-rw-r--r-- | usr.bin/asn1_compile/main.c | 95 | ||||
-rw-r--r-- | usr.bin/asn1_compile/parse.y | 265 | ||||
-rw-r--r-- | usr.bin/asn1_compile/symbol.c | 92 | ||||
-rw-r--r-- | usr.bin/asn1_compile/symbol.h | 83 |
19 files changed, 3504 insertions, 0 deletions
diff --git a/usr.bin/asn1_compile/Makefile b/usr.bin/asn1_compile/Makefile new file mode 100644 index 00000000000..ce1e2acb764 --- /dev/null +++ b/usr.bin/asn1_compile/Makefile @@ -0,0 +1,16 @@ +# $OpenBSD: Makefile,v 1.1 2003/05/11 21:36:33 hin Exp $ + +PROG= asn1_compile +NOMAN= +SRCS= parse.c lex.l main.c hash.c symbol.c gen.c \ + gen_encode.c gen_decode.c gen_free.c gen_length.c gen_copy.c \ + gen_glue.c getarg.c + +CFLAGS+=-I. -DFALSE=0 -DTRUE=1 + +CLEANFILES= parse.[ch] lex.c + +parse.h parse.c: parse.y + ${YACC} -d -o parse.c ${.ALLSRC} + +.include <bsd.prog.mk> diff --git a/usr.bin/asn1_compile/gen.c b/usr.bin/asn1_compile/gen.c new file mode 100644 index 00000000000..922d9317f08 --- /dev/null +++ b/usr.bin/asn1_compile/gen.c @@ -0,0 +1,464 @@ +/* + * Copyright (c) 1997 - 2002 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "gen_locl.h" + +/* +RCSID("$KTH: gen.c,v 1.50 2003/04/17 07:09:18 lha Exp $"); +*/ + +FILE *headerfile, *codefile, *logfile; + +#define STEM "asn1" + +static const char *orig_filename; +static char *header; +static char *headerbase = STEM; + +/* + * list of all IMPORTs + */ + +struct import { + const char *module; + struct import *next; +}; + +static struct import *imports = NULL; + +void +add_import (const char *module) +{ + struct import *tmp = malloc (sizeof(*tmp)); + if(tmp == NULL) + errx(1, "Out of memory"); + + tmp->module = module; + tmp->next = imports; + imports = tmp; +} + +const char * +filename (void) +{ + return orig_filename; +} + +void +init_generate (const char *filename, const char *base) +{ + orig_filename = filename; + if(base) + asprintf(&headerbase, "%s", base); + asprintf(&header, "%s.h", headerbase); + headerfile = fopen (header, "w"); + if (headerfile == NULL) + err (1, "open %s", header); + fprintf (headerfile, + "/* Generated from %s */\n" + "/* Do not edit */\n\n", + filename); + fprintf (headerfile, + "#ifndef __%s_h__\n" + "#define __%s_h__\n\n", headerbase, headerbase); + fprintf (headerfile, + "#include <stddef.h>\n" + "#include <time.h>\n\n"); +#ifndef HAVE_TIMEGM + fprintf (headerfile, "time_t timegm (struct tm*);\n\n"); +#endif + fprintf (headerfile, + "#ifndef __asn1_common_definitions__\n" + "#define __asn1_common_definitions__\n\n"); + fprintf (headerfile, + "typedef struct octet_string {\n" + " size_t length;\n" + " void *data;\n" + "} octet_string;\n\n"); + fprintf (headerfile, + "typedef char *general_string;\n\n" + ); + fprintf (headerfile, + "typedef struct oid {\n" + " size_t length;\n" + " unsigned *components;\n" + "} oid;\n\n"); + fputs("#define ASN1_MALLOC_ENCODE(T, B, BL, S, L, R) \\\n" + " do { \\\n" + " (BL) = length_##T((S)); \\\n" + " (B) = malloc((BL)); \\\n" + " if((B) == NULL) { \\\n" + " (R) = ENOMEM; \\\n" + " } else { \\\n" + " (R) = encode_##T(((unsigned char*)(B)) + (BL) - 1, (BL), \\\n" + " (S), (L)); \\\n" + " if((R) != 0) { \\\n" + " free((B)); \\\n" + " (B) = NULL; \\\n" + " } \\\n" + " } \\\n" + " } while (0)\n\n", + headerfile); + fprintf (headerfile, "#endif\n\n"); + logfile = fopen(STEM "_files", "w"); + if (logfile == NULL) + err (1, "open " STEM "_files"); +} + +void +close_generate (void) +{ + fprintf (headerfile, "#endif /* __%s_h__ */\n", headerbase); + + fclose (headerfile); + fprintf (logfile, "\n"); + fclose (logfile); +} + +void +generate_constant (const Symbol *s) +{ + fprintf (headerfile, "enum { %s = %d };\n\n", + s->gen_name, s->constant); +} + +static void +space(int level) +{ + while(level-- > 0) + fprintf(headerfile, " "); +} + +static void +define_asn1 (int level, Type *t) +{ + switch (t->type) { + case TType: + space(level); + fprintf (headerfile, "%s", t->symbol->name); + break; + case TInteger: + space(level); + fprintf (headerfile, "INTEGER"); + break; + case TUInteger: + space(level); + fprintf (headerfile, "UNSIGNED INTEGER"); + break; + case TOctetString: + space(level); + fprintf (headerfile, "OCTET STRING"); + break; + case TOID : + space(level); + fprintf(headerfile, "OBJECT IDENTIFIER"); + break; + case TBitString: { + Member *m; + int tag = -1; + + space(level); + fprintf (headerfile, "BIT STRING {\n"); + for (m = t->members; m && m->val != tag; m = m->next) { + if (tag == -1) + tag = m->val; + space(level + 1); + fprintf (headerfile, "%s(%d)%s\n", m->name, m->val, + m->next->val == tag?"":","); + + } + space(level); + fprintf (headerfile, "}"); + break; + } + case TEnumerated : { + Member *m; + int tag = -1; + + space(level); + fprintf (headerfile, "ENUMERATED {\n"); + for (m = t->members; m && m->val != tag; m = m->next) { + if (tag == -1) + tag = m->val; + space(level + 1); + fprintf (headerfile, "%s(%d)%s\n", m->name, m->val, + m->next->val == tag?"":","); + + } + space(level); + fprintf (headerfile, "}"); + break; + } + case TSequence: { + Member *m; + int tag; + int max_width = 0; + + space(level); + fprintf (headerfile, "SEQUENCE {\n"); + for (m = t->members, tag = -1; m && m->val != tag; m = m->next) { + if (tag == -1) + tag = m->val; + if(strlen(m->name) + (m->val > 9) > max_width) + max_width = strlen(m->name) + (m->val > 9); + } + max_width += 3 + 2; + if(max_width < 16) max_width = 16; + for (m = t->members, tag = -1 ; m && m->val != tag; m = m->next) { + int width; + if (tag == -1) + tag = m->val; + space(level + 1); + fprintf(headerfile, "%s[%d]", m->name, m->val); + width = max_width - strlen(m->name) - 3 - (m->val > 9) - 2; + fprintf(headerfile, "%*s", width, ""); + define_asn1(level + 1, m->type); + if(m->optional) + fprintf(headerfile, " OPTIONAL"); + if(m->next->val != tag) + fprintf (headerfile, ","); + fprintf (headerfile, "\n"); + } + space(level); + fprintf (headerfile, "}"); + break; + } + case TSequenceOf: { + space(level); + fprintf (headerfile, "SEQUENCE OF "); + define_asn1 (0, t->subtype); + break; + } + case TGeneralizedTime: + space(level); + fprintf (headerfile, "GeneralizedTime"); + break; + case TGeneralString: + space(level); + fprintf (headerfile, "GeneralString"); + break; + case TApplication: + fprintf (headerfile, "[APPLICATION %d] ", t->application); + define_asn1 (level, t->subtype); + break; + default: + abort (); + } +} + +static void +define_type (int level, char *name, Type *t, int typedefp) +{ + switch (t->type) { + case TType: + space(level); + fprintf (headerfile, "%s %s;\n", t->symbol->gen_name, name); + break; + case TInteger: + space(level); + if(t->members == NULL) { + fprintf (headerfile, "int %s;\n", name); + } else { + Member *m; + int tag = -1; + fprintf (headerfile, "enum %s {\n", typedefp ? name : ""); + for (m = t->members; m && m->val != tag; m = m->next) { + if(tag == -1) + tag = m->val; + space (level + 1); + fprintf(headerfile, "%s = %d%s\n", m->gen_name, m->val, + m->next->val == tag ? "" : ","); + } + fprintf (headerfile, "} %s;\n", name); + } + break; + case TUInteger: + space(level); + fprintf (headerfile, "unsigned int %s;\n", name); + break; + case TOctetString: + space(level); + fprintf (headerfile, "octet_string %s;\n", name); + break; + case TOID : + space(level); + fprintf (headerfile, "oid %s;\n", name); + break; + case TBitString: { + Member *m; + Type i; + int tag = -1; + + i.type = TUInteger; + space(level); + fprintf (headerfile, "struct %s {\n", typedefp ? name : ""); + for (m = t->members; m && m->val != tag; m = m->next) { + char *n; + + asprintf (&n, "%s:1", m->gen_name); + define_type (level + 1, n, &i, FALSE); + free (n); + if (tag == -1) + tag = m->val; + } + space(level); + fprintf (headerfile, "} %s;\n\n", name); + break; + } + case TEnumerated: { + Member *m; + int tag = -1; + + space(level); + fprintf (headerfile, "enum %s {\n", typedefp ? name : ""); + for (m = t->members; m && m->val != tag; m = m->next) { + if (tag == -1) + tag = m->val; + space(level + 1); + fprintf (headerfile, "%s = %d%s\n", m->gen_name, m->val, + m->next->val == tag ? "" : ","); + } + space(level); + fprintf (headerfile, "} %s;\n\n", name); + break; + } + case TSequence: { + Member *m; + int tag = -1; + + space(level); + fprintf (headerfile, "struct %s {\n", typedefp ? name : ""); + for (m = t->members; m && m->val != tag; m = m->next) { + if (m->optional) { + char *n; + + asprintf (&n, "*%s", m->gen_name); + define_type (level + 1, n, m->type, FALSE); + free (n); + } else + define_type (level + 1, m->gen_name, m->type, FALSE); + if (tag == -1) + tag = m->val; + } + space(level); + fprintf (headerfile, "} %s;\n", name); + break; + } + case TSequenceOf: { + Type i; + + i.type = TUInteger; + i.application = 0; + + space(level); + fprintf (headerfile, "struct %s {\n", typedefp ? name : ""); + define_type (level + 1, "len", &i, FALSE); + define_type (level + 1, "*val", t->subtype, FALSE); + space(level); + fprintf (headerfile, "} %s;\n", name); + break; + } + case TGeneralizedTime: + space(level); + fprintf (headerfile, "time_t %s;\n", name); + break; + case TGeneralString: + space(level); + fprintf (headerfile, "general_string %s;\n", name); + break; + case TApplication: + define_type (level, name, t->subtype, FALSE); + break; + default: + abort (); + } +} + +static void +generate_type_header (const Symbol *s) +{ + fprintf (headerfile, "/*\n"); + fprintf (headerfile, "%s ::= ", s->name); + define_asn1 (0, s->type); + fprintf (headerfile, "\n*/\n\n"); + + fprintf (headerfile, "typedef "); + define_type (0, s->gen_name, s->type, TRUE); + + fprintf (headerfile, "\n"); +} + + +void +generate_type (const Symbol *s) +{ + struct import *i; + char *filename; + + asprintf (&filename, "%s_%s.x", STEM, s->gen_name); + codefile = fopen (filename, "w"); + if (codefile == NULL) + err (1, "fopen %s", filename); + fprintf(logfile, "%s ", filename); + free(filename); + fprintf (codefile, + "/* Generated from %s */\n" + "/* Do not edit */\n\n" + "#include <stdio.h>\n" + "#include <stdlib.h>\n" + "#include <time.h>\n" + "#include <string.h>\n" + "#include <errno.h>\n", + orig_filename); + + for (i = imports; i != NULL; i = i->next) + fprintf (codefile, + "#include <%s_asn1.h>\n", + i->module); + fprintf (codefile, + "#include <%s.h>\n", + headerbase); + fprintf (codefile, + "#include <asn1_err.h>\n" + "#include <der.h>\n" + "#include <parse_units.h>\n\n"); + generate_type_header (s); + generate_type_encode (s); + generate_type_decode (s); + generate_type_free (s); + generate_type_length (s); + generate_type_copy (s); + generate_glue (s); + fprintf(headerfile, "\n\n"); + fclose(codefile); +} diff --git a/usr.bin/asn1_compile/gen_copy.c b/usr.bin/asn1_compile/gen_copy.c new file mode 100644 index 00000000000..c52e5d8defc --- /dev/null +++ b/usr.bin/asn1_compile/gen_copy.c @@ -0,0 +1,153 @@ +/* + * Copyright (c) 1997 - 2000 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "gen_locl.h" + +/* +RCSID("$KTH: gen_copy.c,v 1.12 2001/09/25 13:39:26 assar Exp $"); +*/ + +static void +copy_primitive (const char *typename, const char *from, const char *to) +{ + fprintf (codefile, "if(copy_%s(%s, %s)) return ENOMEM;\n", + typename, from, to); +} + +static void +copy_type (const char *from, const char *to, const Type *t) +{ + switch (t->type) { + case TType: +#if 0 + copy_type (from, to, t->symbol->type); +#endif + fprintf (codefile, "if(copy_%s(%s, %s)) return ENOMEM;\n", + t->symbol->gen_name, from, to); + break; + case TInteger: + case TUInteger: + case TEnumerated : + fprintf(codefile, "*(%s) = *(%s);\n", to, from); + break; + case TOctetString: + copy_primitive ("octet_string", from, to); + break; + case TOID: + copy_primitive ("oid", from, to); + break; + case TBitString: { + fprintf(codefile, "*(%s) = *(%s);\n", to, from); + break; + } + case TSequence: { + Member *m; + int tag = -1; + + if (t->members == NULL) + break; + + for (m = t->members; m && tag != m->val; m = m->next) { + char *f; + char *t; + + asprintf (&f, "%s(%s)->%s", + m->optional ? "" : "&", from, m->gen_name); + asprintf (&t, "%s(%s)->%s", + m->optional ? "" : "&", to, m->gen_name); + if(m->optional){ + fprintf(codefile, "if(%s) {\n", f); + fprintf(codefile, "%s = malloc(sizeof(*%s));\n", t, t); + fprintf(codefile, "if(%s == NULL) return ENOMEM;\n", t); + } + copy_type (f, t, m->type); + if(m->optional){ + fprintf(codefile, "}else\n"); + fprintf(codefile, "%s = NULL;\n", t); + } + if (tag == -1) + tag = m->val; + free (f); + free (t); + } + break; + } + case TSequenceOf: { + char *f; + char *T; + + fprintf (codefile, "if(((%s)->val = " + "malloc((%s)->len * sizeof(*(%s)->val))) == NULL && (%s)->len != 0)\n", + to, from, to, from); + fprintf (codefile, "return ENOMEM;\n"); + fprintf(codefile, + "for((%s)->len = 0; (%s)->len < (%s)->len; (%s)->len++){\n", + to, to, from, to); + asprintf(&f, "&(%s)->val[(%s)->len]", from, to); + asprintf(&T, "&(%s)->val[(%s)->len]", to, to); + copy_type(f, T, t->subtype); + fprintf(codefile, "}\n"); + free(f); + free(T); + break; + } + case TGeneralizedTime: + fprintf(codefile, "*(%s) = *(%s);\n", to, from); + break; + case TGeneralString: + copy_primitive ("general_string", from, to); + break; + case TApplication: + copy_type (from, to, t->subtype); + break; + default : + abort (); + } +} + +void +generate_type_copy (const Symbol *s) +{ + fprintf (headerfile, + "int copy_%s (const %s *, %s *);\n", + s->gen_name, s->gen_name, s->gen_name); + + fprintf (codefile, "int\n" + "copy_%s(const %s *from, %s *to)\n" + "{\n", + s->gen_name, s->gen_name, s->gen_name); + + copy_type ("from", "to", s->type); + fprintf (codefile, "return 0;\n}\n\n"); +} + diff --git a/usr.bin/asn1_compile/gen_decode.c b/usr.bin/asn1_compile/gen_decode.c new file mode 100644 index 00000000000..27881adc431 --- /dev/null +++ b/usr.bin/asn1_compile/gen_decode.c @@ -0,0 +1,396 @@ +/* + * Copyright (c) 1997 - 2001 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "gen_locl.h" + +/* +RCSID("$KTH: gen_decode.c,v 1.18 2002/08/09 15:37:34 joda Exp $"); +*/ + +static void +decode_primitive (const char *typename, const char *name) +{ + fprintf (codefile, + "e = decode_%s(p, len, %s, &l);\n" + "FORW;\n", + typename, + name); +} + +static void +decode_type (const char *name, const Type *t) +{ + switch (t->type) { + case TType: +#if 0 + decode_type (name, t->symbol->type); +#endif + fprintf (codefile, + "e = decode_%s(p, len, %s, &l);\n" + "FORW;\n", + t->symbol->gen_name, name); + break; + case TInteger: + if(t->members == NULL) + decode_primitive ("integer", name); + else { + char *s; + asprintf(&s, "(int*)%s", name); + if(s == NULL) + errx (1, "out of memory"); + decode_primitive ("integer", s); + free(s); + } + break; + case TUInteger: + decode_primitive ("unsigned", name); + break; + case TEnumerated: + decode_primitive ("enumerated", name); + break; + case TOctetString: + decode_primitive ("octet_string", name); + break; + case TOID : + decode_primitive ("oid", name); + break; + case TBitString: { + Member *m; + int tag = -1; + int pos; + + fprintf (codefile, + "e = der_match_tag_and_length (p, len, UNIV, PRIM, UT_BitString," + "&reallen, &l);\n" + "FORW;\n" + "if(len < reallen)\n" + "return ASN1_OVERRUN;\n" + "p++;\n" + "len--;\n" + "reallen--;\n" + "ret++;\n"); + pos = 0; + for (m = t->members; m && tag != m->val; m = m->next) { + while (m->val / 8 > pos / 8) { + fprintf (codefile, + "p++; len--; reallen--; ret++;\n"); + pos += 8; + } + fprintf (codefile, + "%s->%s = (*p >> %d) & 1;\n", + name, m->gen_name, 7 - m->val % 8); + if (tag == -1) + tag = m->val; + } + fprintf (codefile, + "p += reallen; len -= reallen; ret += reallen;\n"); + break; + } + case TSequence: { + Member *m; + int tag = -1; + + if (t->members == NULL) + break; + + fprintf (codefile, + "e = der_match_tag_and_length (p, len, UNIV, CONS, UT_Sequence," + "&reallen, &l);\n" + "FORW;\n" + "{\n" + "int dce_fix;\n" + "if((dce_fix = fix_dce(reallen, &len)) < 0)\n" + "return ASN1_BAD_FORMAT;\n"); + + for (m = t->members; m && tag != m->val; m = m->next) { + char *s; + + asprintf (&s, "%s(%s)->%s", m->optional ? "" : "&", name, m->gen_name); + if (0 && m->type->type == TType){ + if(m->optional) + fprintf (codefile, + "%s = malloc(sizeof(*%s));\n" + "if(%s == NULL) return ENOMEM;\n", s, s, s); + fprintf (codefile, + "e = decode_seq_%s(p, len, %d, %d, %s, &l);\n", + m->type->symbol->gen_name, + m->val, + m->optional, + s); + if(m->optional) + fprintf (codefile, + "if (e == ASN1_MISSING_FIELD) {\n" + "free(%s);\n" + "%s = NULL;\n" + "e = l = 0;\n" + "}\n", + s, s); + + fprintf (codefile, "FORW;\n"); + + }else{ + fprintf (codefile, "{\n" + "size_t newlen, oldlen;\n\n" + "e = der_match_tag (p, len, CONTEXT, CONS, %d, &l);\n", + m->val); + fprintf (codefile, + "if (e)\n"); + if(m->optional) + /* XXX should look at e */ + fprintf (codefile, + "%s = NULL;\n", s); + else + fprintf (codefile, + "return e;\n"); + fprintf (codefile, + "else {\n"); + fprintf (codefile, + "p += l;\n" + "len -= l;\n" + "ret += l;\n" + "e = der_get_length (p, len, &newlen, &l);\n" + "FORW;\n" + "{\n" + + "int dce_fix;\n" + "oldlen = len;\n" + "if((dce_fix = fix_dce(newlen, &len)) < 0)" + "return ASN1_BAD_FORMAT;\n"); + if (m->optional) + fprintf (codefile, + "%s = malloc(sizeof(*%s));\n" + "if(%s == NULL) return ENOMEM;\n", s, s, s); + decode_type (s, m->type); + fprintf (codefile, + "if(dce_fix){\n" + "e = der_match_tag_and_length (p, len, " + "(Der_class)0, (Der_type)0, 0, &reallen, &l);\n" + "FORW;\n" + "}else \n" + "len = oldlen - newlen;\n" + "}\n" + "}\n"); + fprintf (codefile, + "}\n"); + } + if (tag == -1) + tag = m->val; + free (s); + } + fprintf(codefile, + "if(dce_fix){\n" + "e = der_match_tag_and_length (p, len, " + "(Der_class)0, (Der_type)0, 0, &reallen, &l);\n" + "FORW;\n" + "}\n" + "}\n"); + + break; + } + case TSequenceOf: { + char *n; + + fprintf (codefile, + "e = der_match_tag_and_length (p, len, UNIV, CONS, UT_Sequence," + "&reallen, &l);\n" + "FORW;\n" + "if(len < reallen)\n" + "return ASN1_OVERRUN;\n" + "len = reallen;\n"); + + fprintf (codefile, + "{\n" + "size_t origlen = len;\n" + "int oldret = ret;\n" + "ret = 0;\n" + "(%s)->len = 0;\n" + "(%s)->val = NULL;\n" + "while(ret < origlen) {\n" + "(%s)->len++;\n" + "(%s)->val = realloc((%s)->val, sizeof(*((%s)->val)) * (%s)->len);\n", + name, name, name, name, name, name, name); + asprintf (&n, "&(%s)->val[(%s)->len-1]", name, name); + decode_type (n, t->subtype); + fprintf (codefile, + "len = origlen - ret;\n" + "}\n" + "ret += oldret;\n" + "}\n"); + free (n); + break; + } + case TGeneralizedTime: + decode_primitive ("generalized_time", name); + break; + case TGeneralString: + decode_primitive ("general_string", name); + break; + case TApplication: + fprintf (codefile, + "e = der_match_tag_and_length (p, len, APPL, CONS, %d, " + "&reallen, &l);\n" + "FORW;\n" + "{\n" + "int dce_fix;\n" + "if((dce_fix = fix_dce(reallen, &len)) < 0)\n" + "return ASN1_BAD_FORMAT;\n", + t->application); + decode_type (name, t->subtype); + fprintf(codefile, + "if(dce_fix){\n" + "e = der_match_tag_and_length (p, len, " + "(Der_class)0, (Der_type)0, 0, &reallen, &l);\n" + "FORW;\n" + "}\n" + "}\n"); + + break; + default : + abort (); + } +} + +void +generate_type_decode (const Symbol *s) +{ + fprintf (headerfile, + "int " + "decode_%s(const unsigned char *, size_t, %s *, size_t *);\n", + s->gen_name, s->gen_name); + + fprintf (codefile, "#define FORW " + "if(e) goto fail; " + "p += l; " + "len -= l; " + "ret += l\n\n"); + + + fprintf (codefile, "int\n" + "decode_%s(const unsigned char *p," + " size_t len, %s *data, size_t *size)\n" + "{\n", + s->gen_name, s->gen_name); + + switch (s->type->type) { + case TInteger: + case TUInteger: + case TOctetString: + case TOID: + case TGeneralizedTime: + case TGeneralString: + case TBitString: + case TSequence: + case TSequenceOf: + case TApplication: + case TType: + fprintf (codefile, + "size_t ret = 0, reallen;\n" + "size_t l;\n" + "int e;\n\n"); + fprintf (codefile, "memset(data, 0, sizeof(*data));\n"); + fprintf (codefile, "reallen = 0;\n"); /* hack to avoid `unused variable' */ + + decode_type ("data", s->type); + fprintf (codefile, + "if(size) *size = ret;\n" + "return 0;\n"); + fprintf (codefile, + "fail:\n" + "free_%s(data);\n" + "return e;\n", + s->gen_name); + break; + default: + abort (); + } + fprintf (codefile, "}\n\n"); +} + +void +generate_seq_type_decode (const Symbol *s) +{ + fprintf (headerfile, + "int decode_seq_%s(const unsigned char *, size_t, int, int, " + "%s *, size_t *);\n", + s->gen_name, s->gen_name); + + fprintf (codefile, "int\n" + "decode_seq_%s(const unsigned char *p, size_t len, int tag, " + "int optional, %s *data, size_t *size)\n" + "{\n", + s->gen_name, s->gen_name); + + fprintf (codefile, + "size_t newlen, oldlen;\n" + "size_t l, ret = 0;\n" + "int e;\n" + "int dce_fix;\n"); + + fprintf (codefile, + "e = der_match_tag(p, len, CONTEXT, CONS, tag, &l);\n" + "if (e)\n" + "return e;\n"); + fprintf (codefile, + "p += l;\n" + "len -= l;\n" + "ret += l;\n" + "e = der_get_length(p, len, &newlen, &l);\n" + "if (e)\n" + "return e;\n" + "p += l;\n" + "len -= l;\n" + "ret += l;\n" + "oldlen = len;\n" + "if ((dce_fix = fix_dce(newlen, &len)) < 0)\n" + "return ASN1_BAD_FORMAT;\n" + "e = decode_%s(p, len, data, &l);\n" + "if (e)\n" + "return e;\n" + "p += l;\n" + "len -= l;\n" + "ret += l;\n" + "if (dce_fix) {\n" + "size_t reallen;\n\n" + "e = der_match_tag_and_length(p, len, " + "(Der_class)0, (Der_type)0, 0, &reallen, &l);\n" + "if (e)\n" + "return e;\n" + "ret += l;\n" + "}\n", + s->gen_name); + fprintf (codefile, + "if(size) *size = ret;\n" + "return 0;\n"); + + fprintf (codefile, "}\n\n"); +} diff --git a/usr.bin/asn1_compile/gen_encode.c b/usr.bin/asn1_compile/gen_encode.c new file mode 100644 index 00000000000..8e27d5dba4a --- /dev/null +++ b/usr.bin/asn1_compile/gen_encode.c @@ -0,0 +1,267 @@ +/* + * Copyright (c) 1997 - 2001 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "gen_locl.h" + +/* +RCSID("$KTH: gen_encode.c,v 1.12 2001/09/25 13:39:26 assar Exp $"); +*/ + +static void +encode_primitive (const char *typename, const char *name) +{ + fprintf (codefile, + "e = encode_%s(p, len, %s, &l);\n" + "BACK;\n", + typename, + name); +} + +static void +encode_type (const char *name, const Type *t) +{ + switch (t->type) { + case TType: +#if 0 + encode_type (name, t->symbol->type); +#endif + fprintf (codefile, + "e = encode_%s(p, len, %s, &l);\n" + "BACK;\n", + t->symbol->gen_name, name); + break; + case TInteger: + if(t->members == NULL) + encode_primitive ("integer", name); + else { + char *s; + asprintf(&s, "(const int*)%s", name); + if(s == NULL) + errx(1, "out of memory"); + encode_primitive ("integer", s); + free(s); + } + break; + case TUInteger: + encode_primitive ("unsigned", name); + break; + case TOctetString: + encode_primitive ("octet_string", name); + break; + case TOID : + encode_primitive ("oid", name); + break; + case TBitString: { + Member *m; + int pos; + int rest; + int tag = -1; + + if (t->members == NULL) + break; + + fprintf (codefile, "{\n" + "unsigned char c = 0;\n"); + pos = t->members->prev->val; + /* fix for buggy MIT (and OSF?) code */ + if (pos > 31) + abort (); + /* + * It seems that if we do not always set pos to 31 here, the MIT + * code will do the wrong thing. + * + * I hate ASN.1 (and DER), but I hate it even more when everybody + * has to screw it up differently. + */ + pos = 31; + rest = 7 - (pos % 8); + + for (m = t->members->prev; m && tag != m->val; m = m->prev) { + while (m->val / 8 < pos / 8) { + fprintf (codefile, + "*p-- = c; len--; ret++;\n" + "c = 0;\n"); + pos -= 8; + } + fprintf (codefile, + "if(%s->%s) c |= 1<<%d;\n", name, m->gen_name, + 7 - m->val % 8); + + if (tag == -1) + tag = m->val; + } + + fprintf (codefile, + "*p-- = c;\n" + "*p-- = %d;\n" + "len -= 2;\n" + "ret += 2;\n" + "}\n\n" + "e = der_put_length_and_tag (p, len, ret, UNIV, PRIM," + "UT_BitString, &l);\n" + "BACK;\n", + rest); + break; + } + case TEnumerated : { + encode_primitive ("enumerated", name); + break; + } + case TSequence: { + Member *m; + int tag = -1; + + if (t->members == NULL) + break; + + for (m = t->members->prev; m && tag != m->val; m = m->prev) { + char *s; + + asprintf (&s, "%s(%s)->%s", m->optional ? "" : "&", name, m->gen_name); + if (m->optional) + fprintf (codefile, + "if(%s)\n", + s); +#if 1 + fprintf (codefile, "{\n" + "int oldret = ret;\n" + "ret = 0;\n"); +#endif + encode_type (s, m->type); + fprintf (codefile, + "e = der_put_length_and_tag (p, len, ret, CONTEXT, CONS, " + "%d, &l);\n" + "BACK;\n", + m->val); +#if 1 + fprintf (codefile, + "ret += oldret;\n" + "}\n"); +#endif + if (tag == -1) + tag = m->val; + free (s); + } + fprintf (codefile, + "e = der_put_length_and_tag (p, len, ret, UNIV, CONS, UT_Sequence, &l);\n" + "BACK;\n"); + break; + } + case TSequenceOf: { + char *n; + + fprintf (codefile, + "for(i = (%s)->len - 1; i >= 0; --i) {\n" +#if 1 + "int oldret = ret;\n" + "ret = 0;\n", +#else + , +#endif + name); + asprintf (&n, "&(%s)->val[i]", name); + encode_type (n, t->subtype); + fprintf (codefile, +#if 1 + "ret += oldret;\n" +#endif + "}\n" + "e = der_put_length_and_tag (p, len, ret, UNIV, CONS, UT_Sequence, &l);\n" + "BACK;\n"); + free (n); + break; + } + case TGeneralizedTime: + encode_primitive ("generalized_time", name); + break; + case TGeneralString: + encode_primitive ("general_string", name); + break; + case TApplication: + encode_type (name, t->subtype); + fprintf (codefile, + "e = der_put_length_and_tag (p, len, ret, APPL, CONS, %d, &l);\n" + "BACK;\n", + t->application); + break; + default: + abort (); + } +} + +void +generate_type_encode (const Symbol *s) +{ + fprintf (headerfile, + "int " + "encode_%s(unsigned char *, size_t, const %s *, size_t *);\n", + s->gen_name, s->gen_name); + + fprintf (codefile, "#define BACK if (e) return e; p -= l; len -= l; ret += l\n\n"); + + + fprintf (codefile, "int\n" + "encode_%s(unsigned char *p, size_t len," + " const %s *data, size_t *size)\n" + "{\n", + s->gen_name, s->gen_name); + + switch (s->type->type) { + case TInteger: + case TUInteger: + case TOctetString: + case TGeneralizedTime: + case TGeneralString: + case TBitString: + case TEnumerated: + case TOID: + case TSequence: + case TSequenceOf: + case TApplication: + case TType: + fprintf (codefile, + "size_t ret = 0;\n" + "size_t l;\n" + "int i, e;\n\n"); + fprintf(codefile, "i = 0;\n"); /* hack to avoid `unused variable' */ + + encode_type("data", s->type); + + fprintf (codefile, "*size = ret;\n" + "return 0;\n"); + break; + default: + abort (); + } + fprintf (codefile, "}\n\n"); +} diff --git a/usr.bin/asn1_compile/gen_free.c b/usr.bin/asn1_compile/gen_free.c new file mode 100644 index 00000000000..56612e6b9df --- /dev/null +++ b/usr.bin/asn1_compile/gen_free.c @@ -0,0 +1,137 @@ +/* + * Copyright (c) 1997 - 2000 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "gen_locl.h" + +/* +RCSID("$KTH: gen_free.c,v 1.9 2001/09/25 13:39:26 assar Exp $"); +*/ + +static void +free_primitive (const char *typename, const char *name) +{ + fprintf (codefile, "free_%s(%s);\n", typename, name); +} + +static void +free_type (const char *name, const Type *t) +{ + switch (t->type) { + case TType: +#if 0 + free_type (name, t->symbol->type); +#endif + fprintf (codefile, "free_%s(%s);\n", t->symbol->gen_name, name); + break; + case TInteger: + case TUInteger: + case TEnumerated : + break; + case TOctetString: + free_primitive ("octet_string", name); + break; + case TOID : + free_primitive ("oid", name); + break; + case TBitString: { + break; + } + case TSequence: { + Member *m; + int tag = -1; + + if (t->members == NULL) + break; + + for (m = t->members; m && tag != m->val; m = m->next) { + char *s; + + asprintf (&s, "%s(%s)->%s", + m->optional ? "" : "&", name, m->gen_name); + if(m->optional) + fprintf(codefile, "if(%s) {\n", s); + free_type (s, m->type); + if(m->optional) + fprintf(codefile, + "free(%s);\n" + "}\n",s); + if (tag == -1) + tag = m->val; + free (s); + } + break; + } + case TSequenceOf: { + char *n; + + fprintf (codefile, "while((%s)->len){\n", name); + asprintf (&n, "&(%s)->val[(%s)->len-1]", name, name); + free_type(n, t->subtype); + fprintf(codefile, + "(%s)->len--;\n" + "}\n", + name); + fprintf(codefile, + "free((%s)->val);\n", name); + free(n); + break; + } + case TGeneralizedTime: + break; + case TGeneralString: + free_primitive ("general_string", name); + break; + case TApplication: + free_type (name, t->subtype); + break; + default : + abort (); + } +} + +void +generate_type_free (const Symbol *s) +{ + fprintf (headerfile, + "void free_%s (%s *);\n", + s->gen_name, s->gen_name); + + fprintf (codefile, "void\n" + "free_%s(%s *data)\n" + "{\n", + s->gen_name, s->gen_name); + + free_type ("data", s->type); + fprintf (codefile, "}\n\n"); +} + diff --git a/usr.bin/asn1_compile/gen_glue.c b/usr.bin/asn1_compile/gen_glue.c new file mode 100644 index 00000000000..84e964f27e8 --- /dev/null +++ b/usr.bin/asn1_compile/gen_glue.c @@ -0,0 +1,141 @@ +/* + * Copyright (c) 1997, 1999 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "gen_locl.h" + +/* +RCSID("$KTH: gen_glue.c,v 1.7 1999/12/02 17:05:02 joda Exp $"); +*/ + +static void +generate_2int (const Symbol *s) +{ + Type *t = s->type; + Member *m; + int tag = -1; + + fprintf (headerfile, + "unsigned %s2int(%s);\n", + s->gen_name, s->gen_name); + + fprintf (codefile, + "unsigned %s2int(%s f)\n" + "{\n" + "unsigned r = 0;\n", + s->gen_name, s->gen_name); + + for (m = t->members; m && m->val != tag; m = m->next) { + fprintf (codefile, "if(f.%s) r |= (1U << %d);\n", + m->gen_name, m->val); + + if (tag == -1) + tag = m->val; + } + fprintf (codefile, "return r;\n" + "}\n\n"); +} + +static void +generate_int2 (const Symbol *s) +{ + Type *t = s->type; + Member *m; + int tag = -1; + + fprintf (headerfile, + "%s int2%s(unsigned);\n", + s->gen_name, s->gen_name); + + fprintf (codefile, + "%s int2%s(unsigned n)\n" + "{\n" + "\t%s flags;\n\n", + s->gen_name, s->gen_name, s->gen_name); + + for (m = t->members; m && m->val != tag; m = m->next) { + fprintf (codefile, "\tflags.%s = (n >> %d) & 1;\n", + m->gen_name, m->val); + + if (tag == -1) + tag = m->val; + } + fprintf (codefile, "\treturn flags;\n" + "}\n\n"); +} + +/* + * This depends on the bit string being declared in increasing order + */ + +static void +generate_units (const Symbol *s) +{ + Type *t = s->type; + Member *m; + int tag = -1; + + fprintf (headerfile, + "extern struct units %s_units[];", + s->gen_name); + + fprintf (codefile, + "struct units %s_units[] = {\n", + s->gen_name); + + if(t->members) + for (m = t->members->prev; m && m->val != tag; m = m->prev) { + fprintf (codefile, + "\t{\"%s\",\t1U << %d},\n", m->gen_name, m->val); + + if (tag == -1) + tag = m->val; + } + + fprintf (codefile, + "\t{NULL,\t0}\n" + "};\n\n"); +} + +void +generate_glue (const Symbol *s) +{ + switch(s->type->type) { + case TBitString : + generate_2int (s); + generate_int2 (s); + generate_units (s); + break; + default : + break; + } +} diff --git a/usr.bin/asn1_compile/gen_length.c b/usr.bin/asn1_compile/gen_length.c new file mode 100644 index 00000000000..02cbefcc7b2 --- /dev/null +++ b/usr.bin/asn1_compile/gen_length.c @@ -0,0 +1,173 @@ +/* + * Copyright (c) 1997 - 2000 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "gen_locl.h" + +/* +RCSID("$KTH: gen_length.c,v 1.11 2001/09/25 13:39:26 assar Exp $"); +*/ + +static void +length_primitive (const char *typename, + const char *name, + const char *variable) +{ + fprintf (codefile, "%s += length_%s(%s);\n", variable, typename, name); +} + +static void +length_type (const char *name, const Type *t, const char *variable) +{ + switch (t->type) { + case TType: +#if 0 + length_type (name, t->symbol->type); +#endif + fprintf (codefile, "%s += length_%s(%s);\n", + variable, t->symbol->gen_name, name); + break; + case TInteger: + if(t->members == NULL) + length_primitive ("integer", name, variable); + else { + char *s; + asprintf(&s, "(const int*)%s", name); + if(s == NULL) + errx (1, "out of memory"); + length_primitive ("integer", s, variable); + free(s); + } + break; + case TUInteger: + length_primitive ("unsigned", name, variable); + break; + case TEnumerated : + length_primitive ("enumerated", name, variable); + break; + case TOctetString: + length_primitive ("octet_string", name, variable); + break; + case TOID : + length_primitive ("oid", name, variable); + break; + case TBitString: { + /* + * XXX - Hope this is correct + * look at TBitString case in `encode_type' + */ + fprintf (codefile, "%s += 7;\n", variable); + break; + } + case TSequence: { + Member *m; + int tag = -1; + + if (t->members == NULL) + break; + + for (m = t->members; m && tag != m->val; m = m->next) { + char *s; + + asprintf (&s, "%s(%s)->%s", + m->optional ? "" : "&", name, m->gen_name); + if (m->optional) + fprintf (codefile, "if(%s)", s); + fprintf (codefile, "{\n" + "int oldret = %s;\n" + "%s = 0;\n", variable, variable); + length_type (s, m->type, "ret"); + fprintf (codefile, "%s += 1 + length_len(%s) + oldret;\n", + variable, variable); + fprintf (codefile, "}\n"); + if (tag == -1) + tag = m->val; + free (s); + } + fprintf (codefile, + "%s += 1 + length_len(%s);\n", variable, variable); + break; + } + case TSequenceOf: { + char *n; + + fprintf (codefile, + "{\n" + "int oldret = %s;\n" + "int i;\n" + "%s = 0;\n", + variable, variable); + + fprintf (codefile, "for(i = (%s)->len - 1; i >= 0; --i){\n", name); + asprintf (&n, "&(%s)->val[i]", name); + length_type(n, t->subtype, variable); + fprintf (codefile, "}\n"); + + fprintf (codefile, + "%s += 1 + length_len(%s) + oldret;\n" + "}\n", variable, variable); + free(n); + break; + } + case TGeneralizedTime: + length_primitive ("generalized_time", name, variable); + break; + case TGeneralString: + length_primitive ("general_string", name, variable); + break; + case TApplication: + length_type (name, t->subtype, variable); + fprintf (codefile, "ret += 1 + length_len (ret);\n"); + break; + default : + abort (); + } +} + +void +generate_type_length (const Symbol *s) +{ + fprintf (headerfile, + "size_t length_%s(const %s *);\n", + s->gen_name, s->gen_name); + + fprintf (codefile, + "size_t\n" + "length_%s(const %s *data)\n" + "{\n" + "size_t ret = 0;\n", + s->gen_name, s->gen_name); + + length_type ("data", s->type, "ret"); + fprintf (codefile, "return ret;\n}\n\n"); +} + diff --git a/usr.bin/asn1_compile/gen_locl.h b/usr.bin/asn1_compile/gen_locl.h new file mode 100644 index 00000000000..f1be2fb43f4 --- /dev/null +++ b/usr.bin/asn1_compile/gen_locl.h @@ -0,0 +1,73 @@ +/* + * Copyright (c) 1997 - 2001 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* $KTH: gen_locl.h,v 1.9 2001/09/27 16:21:47 assar Exp $ */ + +#ifndef __GEN_LOCL_H__ +#define __GEN_LOCL_H__ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include <assert.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <limits.h> +#include <ctype.h> +#include <time.h> +#include <errno.h> +#include <err.h> +#include "hash.h" +#include "symbol.h" + +void generate_type (const Symbol *); +void generate_constant (const Symbol *); +void generate_type_encode (const Symbol *s); +void generate_type_decode (const Symbol *s); +void generate_seq_type_decode (const Symbol *s); +void generate_type_free (const Symbol *s); +void generate_type_length (const Symbol *s); +void generate_type_copy (const Symbol *s); +void generate_type_maybe (const Symbol *s); +void generate_glue (const Symbol *s); + +void init_generate (const char *filename, const char *basename); +const char *filename (void); +void close_generate(void); +void add_import(const char *module); +int yyparse(void); + +extern FILE *headerfile, *codefile, *logfile; + +#endif /* __GEN_LOCL_H__ */ diff --git a/usr.bin/asn1_compile/getarg.c b/usr.bin/asn1_compile/getarg.c new file mode 100644 index 00000000000..65e9a604d12 --- /dev/null +++ b/usr.bin/asn1_compile/getarg.c @@ -0,0 +1,601 @@ +/* + * Copyright (c) 1997 - 2002 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +RCSID("$KTH: getarg.c,v 1.46 2002/08/20 16:23:07 joda Exp $"); +#endif + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include "getarg.h" + +#define ISFLAG(X) ((X).type == arg_flag || (X).type == arg_negative_flag) + +extern char *__progname; + +static size_t +print_arg (char *string, size_t len, int mdoc, int longp, struct getargs *arg) +{ + const char *s; + + *string = '\0'; + + if (ISFLAG(*arg) || (!longp && arg->type == arg_counter)) + return 0; + + if(mdoc){ + if(longp) + strlcat(string, "= Ns", len); + strlcat(string, " Ar ", len); + } else { + if (longp) + strlcat (string, "=", len); + else + strlcat (string, " ", len); + } + + if (arg->arg_help) + s = arg->arg_help; + else if (arg->type == arg_integer || arg->type == arg_counter) + s = "integer"; + else if (arg->type == arg_string) + s = "string"; + else if (arg->type == arg_strings) + s = "strings"; + else if (arg->type == arg_double) + s = "float"; + else + s = "<undefined>"; + + strlcat(string, s, len); + return 1 + strlen(s); +} + +#if 0 +static void +mandoc_template(struct getargs *args, + size_t num_args, + const char *progname, + const char *extra_string) +{ + int i; + char timestr[64], cmd[64]; + char buf[128]; + const char *p; + time_t t; + + printf(".\\\" Things to fix:\n"); + printf(".\\\" * correct section, and operating system\n"); + printf(".\\\" * remove Op from mandatory flags\n"); + printf(".\\\" * use better macros for arguments (like .Pa for files)\n"); + printf(".\\\"\n"); + t = time(NULL); + strftime(timestr, sizeof(timestr), "%B %e, %Y", localtime(&t)); + printf(".Dd %s\n", timestr); + p = strrchr(progname, '/'); + if(p) p++; else p = progname; + strlcpy(cmd, p, sizeof(cmd)); + strupr(cmd); + + printf(".Dt %s SECTION\n", cmd); + printf(".Os OPERATING_SYSTEM\n"); + printf(".Sh NAME\n"); + printf(".Nm %s\n", p); + printf(".Nd\n"); + printf("in search of a description\n"); + printf(".Sh SYNOPSIS\n"); + printf(".Nm\n"); + for(i = 0; i < num_args; i++){ + /* we seem to hit a limit on number of arguments if doing + short and long flags with arguments -- split on two lines */ + if(ISFLAG(args[i]) || + args[i].short_name == 0 || args[i].long_name == NULL) { + printf(".Op "); + + if(args[i].short_name) { + print_arg(buf, sizeof(buf), 1, 0, args + i); + printf("Fl %c%s", args[i].short_name, buf); + if(args[i].long_name) + printf(" | "); + } + if(args[i].long_name) { + print_arg(buf, sizeof(buf), 1, 1, args + i); + printf("Fl -%s%s%s", + args[i].type == arg_negative_flag ? "no-" : "", + args[i].long_name, buf); + } + printf("\n"); + } else { + print_arg(buf, sizeof(buf), 1, 0, args + i); + printf(".Oo Fl %c%s \\*(Ba Xo\n", args[i].short_name, buf); + print_arg(buf, sizeof(buf), 1, 1, args + i); + printf(".Fl -%s%s\n.Xc\n.Oc\n", args[i].long_name, buf); + } + /* + if(args[i].type == arg_strings) + fprintf (stderr, "..."); + */ + } + if (extra_string && *extra_string) + printf (".Ar %s\n", extra_string); + printf(".Sh DESCRIPTION\n"); + printf("Supported options:\n"); + printf(".Bl -tag -width Ds\n"); + for(i = 0; i < num_args; i++){ + printf(".It Xo\n"); + if(args[i].short_name){ + printf(".Fl %c", args[i].short_name); + print_arg(buf, sizeof(buf), 1, 0, args + i); + printf("%s", buf); + if(args[i].long_name) + printf(" ,"); + printf("\n"); + } + if(args[i].long_name){ + printf(".Fl -%s%s", + args[i].type == arg_negative_flag ? "no-" : "", + args[i].long_name); + print_arg(buf, sizeof(buf), 1, 1, args + i); + printf("%s\n", buf); + } + printf(".Xc\n"); + if(args[i].help) + printf("%s\n", args[i].help); + /* + if(args[i].type == arg_strings) + fprintf (stderr, "..."); + */ + } + printf(".El\n"); + printf(".\\\".Sh ENVIRONMENT\n"); + printf(".\\\".Sh FILES\n"); + printf(".\\\".Sh EXAMPLES\n"); + printf(".\\\".Sh DIAGNOSTICS\n"); + printf(".\\\".Sh SEE ALSO\n"); + printf(".\\\".Sh STANDARDS\n"); + printf(".\\\".Sh HISTORY\n"); + printf(".\\\".Sh AUTHORS\n"); + printf(".\\\".Sh BUGS\n"); +} +#endif + +static int +check_column(FILE *f, int col, int len, int columns) +{ + if(col + len > columns) { + fprintf(f, "\n"); + col = fprintf(f, " "); + } + return col; +} + +void +arg_printusage (struct getargs *args, + size_t num_args, + const char *progname, + const char *extra_string) +{ + int i; + size_t max_len = 0; + char buf[128]; + int col = 0, columns; +#if 0 + struct winsize ws; +#endif + + if (progname == NULL) + progname = __progname; + +#if 0 + if(getenv("GETARGMANDOC")){ + mandoc_template(args, num_args, progname, extra_string); + return; + } +#endif +#if 0 + if(get_window_size(2, &ws) == 0) + columns = ws.ws_col; + else +#endif + columns = 80; + col = 0; + col += fprintf (stderr, "Usage: %s", progname); + buf[0] = '\0'; + for (i = 0; i < num_args; ++i) { + if(args[i].short_name && ISFLAG(args[i])) { + char s[2]; + if(buf[0] == '\0') + strlcpy(buf, "[-", sizeof(buf)); + s[0] = args[i].short_name; + s[1] = '\0'; + strlcat(buf, s, sizeof(buf)); + } + } + if(buf[0] != '\0') { + strlcat(buf, "]", sizeof(buf)); + col = check_column(stderr, col, strlen(buf) + 1, columns); + col += fprintf(stderr, " %s", buf); + } + + for (i = 0; i < num_args; ++i) { + size_t len = 0; + + if (args[i].long_name) { + buf[0] = '\0'; + strlcat(buf, "[--", sizeof(buf)); + len += 2; + if(args[i].type == arg_negative_flag) { + strlcat(buf, "no-", sizeof(buf)); + len += 3; + } + strlcat(buf, args[i].long_name, sizeof(buf)); + len += strlen(args[i].long_name); + len += print_arg(buf + strlen(buf), sizeof(buf) - strlen(buf), + 0, 1, &args[i]); + strlcat(buf, "]", sizeof(buf)); + if(args[i].type == arg_strings) + strlcat(buf, "...", sizeof(buf)); + col = check_column(stderr, col, strlen(buf) + 1, columns); + col += fprintf(stderr, " %s", buf); + } + if (args[i].short_name && !ISFLAG(args[i])) { + snprintf(buf, sizeof(buf), "[-%c", args[i].short_name); + len += 2; + len += print_arg(buf + strlen(buf), sizeof(buf) - strlen(buf), + 0, 0, &args[i]); + strlcat(buf, "]", sizeof(buf)); + if(args[i].type == arg_strings) + strlcat(buf, "...", sizeof(buf)); + col = check_column(stderr, col, strlen(buf) + 1, columns); + col += fprintf(stderr, " %s", buf); + } + if (args[i].long_name && args[i].short_name) + len += 2; /* ", " */ +#if 0 + max_len = max(max_len, len); +#else + if(len > max_len) + max_len = len; +#endif + } + if (extra_string) { + col = check_column(stderr, col, strlen(extra_string) + 1, columns); + fprintf (stderr, " %s\n", extra_string); + } else + fprintf (stderr, "\n"); + for (i = 0; i < num_args; ++i) { + if (args[i].help) { + size_t count = 0; + + if (args[i].short_name) { + count += fprintf (stderr, "-%c", args[i].short_name); + print_arg (buf, sizeof(buf), 0, 0, &args[i]); + count += fprintf(stderr, "%s", buf); + } + if (args[i].short_name && args[i].long_name) + count += fprintf (stderr, ", "); + if (args[i].long_name) { + count += fprintf (stderr, "--"); + if (args[i].type == arg_negative_flag) + count += fprintf (stderr, "no-"); + count += fprintf (stderr, "%s", args[i].long_name); + print_arg (buf, sizeof(buf), 0, 1, &args[i]); + count += fprintf(stderr, "%s", buf); + } + while(count++ <= max_len) + putc (' ', stderr); + fprintf (stderr, "%s\n", args[i].help); + } + } +} + +static void +add_string(getarg_strings *s, char *value) +{ + s->strings = realloc(s->strings, (s->num_strings + 1) * sizeof(*s->strings)); + s->strings[s->num_strings] = value; + s->num_strings++; +} + +static int +arg_match_long(struct getargs *args, size_t num_args, + char *argv, int argc, char **rargv, int *goptind) +{ + int i; + char *goptarg = NULL; + int negate = 0; + int partial_match = 0; + struct getargs *partial = NULL; + struct getargs *current = NULL; + int argv_len; + char *p; + int p_len; + + argv_len = strlen(argv); + p = strchr (argv, '='); + if (p != NULL) + argv_len = p - argv; + + for (i = 0; i < num_args; ++i) { + if(args[i].long_name) { + int len = strlen(args[i].long_name); + p = argv; + p_len = argv_len; + negate = 0; + + for (;;) { + if (strncmp (args[i].long_name, p, p_len) == 0) { + if(p_len == len) + current = &args[i]; + else { + ++partial_match; + partial = &args[i]; + } + goptarg = p + p_len; + } else if (ISFLAG(args[i]) && strncmp (p, "no-", 3) == 0) { + negate = !negate; + p += 3; + p_len -= 3; + continue; + } + break; + } + if (current) + break; + } + } + if (current == NULL) { + if (partial_match == 1) + current = partial; + else + return ARG_ERR_NO_MATCH; + } + + if(*goptarg == '\0' + && !ISFLAG(*current) + && current->type != arg_collect + && current->type != arg_counter) + return ARG_ERR_NO_MATCH; + switch(current->type){ + case arg_integer: + { + int tmp; + if(sscanf(goptarg + 1, "%d", &tmp) != 1) + return ARG_ERR_BAD_ARG; + *(int*)current->value = tmp; + return 0; + } + case arg_string: + { + *(char**)current->value = goptarg + 1; + return 0; + } + case arg_strings: + { + add_string((getarg_strings*)current->value, goptarg + 1); + return 0; + } + case arg_flag: + case arg_negative_flag: + { + int *flag = current->value; + if(*goptarg == '\0' || + strcmp(goptarg + 1, "yes") == 0 || + strcmp(goptarg + 1, "true") == 0){ + *flag = !negate; + return 0; + } else if (*goptarg && strcmp(goptarg + 1, "maybe") == 0) { +#ifdef HAVE_RANDOM + *flag = random() & 1; +#else + *flag = rand() & 1; +#endif + } else { + *flag = negate; + return 0; + } + return ARG_ERR_BAD_ARG; + } + case arg_counter : + { + int val; + + if (*goptarg == '\0') + val = 1; + else if(sscanf(goptarg + 1, "%d", &val) != 1) + return ARG_ERR_BAD_ARG; + *(int *)current->value += val; + return 0; + } + case arg_double: + { + double tmp; + if(sscanf(goptarg + 1, "%lf", &tmp) != 1) + return ARG_ERR_BAD_ARG; + *(double*)current->value = tmp; + return 0; + } + case arg_collect:{ + struct getarg_collect_info *c = current->value; + int o = argv - rargv[*goptind]; + return (*c->func)(FALSE, argc, rargv, goptind, &o, c->data); + } + + default: + abort (); + } +} + +static int +arg_match_short (struct getargs *args, size_t num_args, + char *argv, int argc, char **rargv, int *goptind) +{ + int j, k; + + for(j = 1; j > 0 && j < strlen(rargv[*goptind]); j++) { + for(k = 0; k < num_args; k++) { + char *goptarg; + + if(args[k].short_name == 0) + continue; + if(argv[j] == args[k].short_name) { + if(args[k].type == arg_flag) { + *(int*)args[k].value = 1; + break; + } + if(args[k].type == arg_negative_flag) { + *(int*)args[k].value = 0; + break; + } + if(args[k].type == arg_counter) { + ++*(int *)args[k].value; + break; + } + if(args[k].type == arg_collect) { + struct getarg_collect_info *c = args[k].value; + + if((*c->func)(TRUE, argc, rargv, goptind, &j, c->data)) + return ARG_ERR_BAD_ARG; + break; + } + + if(argv[j + 1]) + goptarg = &argv[j + 1]; + else { + ++*goptind; + goptarg = rargv[*goptind]; + } + if(goptarg == NULL) { + --*goptind; + return ARG_ERR_NO_ARG; + } + if(args[k].type == arg_integer) { + int tmp; + if(sscanf(goptarg, "%d", &tmp) != 1) + return ARG_ERR_BAD_ARG; + *(int*)args[k].value = tmp; + return 0; + } else if(args[k].type == arg_string) { + *(char**)args[k].value = goptarg; + return 0; + } else if(args[k].type == arg_strings) { + add_string((getarg_strings*)args[k].value, goptarg); + return 0; + } else if(args[k].type == arg_double) { + double tmp; + if(sscanf(goptarg, "%lf", &tmp) != 1) + return ARG_ERR_BAD_ARG; + *(double*)args[k].value = tmp; + return 0; + } + return ARG_ERR_BAD_ARG; + } + } + if (k == num_args) + return ARG_ERR_NO_MATCH; + } + return 0; +} + +int +getarg(struct getargs *args, size_t num_args, + int argc, char **argv, int *goptind) +{ + int i; + int ret = 0; + +#if defined(HAVE_SRANDOMDEV) + srandomdev(); +#elif defined(HAVE_RANDOM) + srandom(time(NULL)); +#else + srand (time(NULL)); +#endif + (*goptind)++; + for(i = *goptind; i < argc; i++) { + if(argv[i][0] != '-') + break; + if(argv[i][1] == '-'){ + if(argv[i][2] == 0){ + i++; + break; + } + ret = arg_match_long (args, num_args, argv[i] + 2, + argc, argv, &i); + } else { + ret = arg_match_short (args, num_args, argv[i], + argc, argv, &i); + } + if(ret) + break; + } + *goptind = i; + return ret; +} + +void +free_getarg_strings (getarg_strings *s) +{ + free (s->strings); +} + +#if TEST +int foo_flag = 2; +int flag1 = 0; +int flag2 = 0; +int bar_int; +char *baz_string; + +struct getargs args[] = { + { NULL, '1', arg_flag, &flag1, "one", NULL }, + { NULL, '2', arg_flag, &flag2, "two", NULL }, + { "foo", 'f', arg_negative_flag, &foo_flag, "foo", NULL }, + { "bar", 'b', arg_integer, &bar_int, "bar", "seconds"}, + { "baz", 'x', arg_string, &baz_string, "baz", "name" }, +}; + +int main(int argc, char **argv) +{ + int goptind = 0; + while(getarg(args, 5, argc, argv, &goptind)) + printf("Bad arg: %s\n", argv[goptind]); + printf("flag1 = %d\n", flag1); + printf("flag2 = %d\n", flag2); + printf("foo_flag = %d\n", foo_flag); + printf("bar_int = %d\n", bar_int); + printf("baz_flag = %s\n", baz_string); + arg_printusage (args, 5, argv[0], "nothing here"); +} +#endif diff --git a/usr.bin/asn1_compile/getarg.h b/usr.bin/asn1_compile/getarg.h new file mode 100644 index 00000000000..5224a1a4bee --- /dev/null +++ b/usr.bin/asn1_compile/getarg.h @@ -0,0 +1,91 @@ +/* + * Copyright (c) 1997 - 2002 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* $KTH: getarg.h,v 1.12 2002/04/18 08:50:08 joda Exp $ */ + +#ifndef __GETARG_H__ +#define __GETARG_H__ + +#include <stddef.h> + +struct getargs{ + const char *long_name; + char short_name; + enum { arg_integer, + arg_string, + arg_flag, + arg_negative_flag, + arg_strings, + arg_double, + arg_collect, + arg_counter + } type; + void *value; + const char *help; + const char *arg_help; +}; + +enum { + ARG_ERR_NO_MATCH = 1, + ARG_ERR_BAD_ARG, + ARG_ERR_NO_ARG +}; + +typedef struct getarg_strings { + int num_strings; + char **strings; +} getarg_strings; + +typedef int (*getarg_collect_func)(int short_opt, + int argc, + char **argv, + int *goptind, + int *goptarg, + void *data); + +typedef struct getarg_collect_info { + getarg_collect_func func; + void *data; +} getarg_collect_info; + +int getarg(struct getargs *args, size_t num_args, + int argc, char **argv, int *goptind); + +void arg_printusage (struct getargs *args, + size_t num_args, + const char *progname, + const char *extra_string); + +void free_getarg_strings (getarg_strings *); + +#endif /* __GETARG_H__ */ diff --git a/usr.bin/asn1_compile/hash.c b/usr.bin/asn1_compile/hash.c new file mode 100644 index 00000000000..4616d947a71 --- /dev/null +++ b/usr.bin/asn1_compile/hash.c @@ -0,0 +1,209 @@ +/* + * Copyright (c) 1997 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* + * Hash table functions + */ + +#include "gen_locl.h" + +/* +RCSID("$KTH: hash.c,v 1.8 1999/12/02 17:05:02 joda Exp $"); +*/ + +static Hashentry *_search(Hashtab * htab, /* The hash table */ + void *ptr); /* And key */ + +Hashtab * +hashtabnew(int sz, + int (*cmp) (void *, void *), + unsigned (*hash) (void *)) +{ + Hashtab *htab; + int i; + + assert(sz > 0); + + htab = (Hashtab *) malloc(sizeof(Hashtab) + (sz - 1) * sizeof(Hashentry *)); + for (i = 0; i < sz; ++i) + htab->tab[i] = NULL; + + if (htab == NULL) { + return NULL; + } else { + htab->cmp = cmp; + htab->hash = hash; + htab->sz = sz; + return htab; + } +} + +/* Intern search function */ + +static Hashentry * +_search(Hashtab * htab, void *ptr) +{ + Hashentry *hptr; + + assert(htab && ptr); + + for (hptr = htab->tab[(*htab->hash) (ptr) % htab->sz]; + hptr; + hptr = hptr->next) + if ((*htab->cmp) (ptr, hptr->ptr) == 0) + break; + return hptr; +} + +/* Search for element in hash table */ + +void * +hashtabsearch(Hashtab * htab, void *ptr) +{ + Hashentry *tmp; + + tmp = _search(htab, ptr); + return tmp ? tmp->ptr : tmp; +} + +/* add element to hash table */ +/* if already there, set new value */ +/* !NULL if succesful */ + +void * +hashtabadd(Hashtab * htab, void *ptr) +{ + Hashentry *h = _search(htab, ptr); + Hashentry **tabptr; + + assert(htab && ptr); + + if (h) + free((void *) h->ptr); + else { + h = (Hashentry *) malloc(sizeof(Hashentry)); + if (h == NULL) { + return NULL; + } + tabptr = &htab->tab[(*htab->hash) (ptr) % htab->sz]; + h->next = *tabptr; + *tabptr = h; + h->prev = tabptr; + if (h->next) + h->next->prev = &h->next; + } + h->ptr = ptr; + return h; +} + +/* delete element with key key. Iff freep, free Hashentry->ptr */ + +int +_hashtabdel(Hashtab * htab, void *ptr, int freep) +{ + Hashentry *h; + + assert(htab && ptr); + + h = _search(htab, ptr); + if (h) { + if (freep) + free(h->ptr); + if ((*(h->prev) = h->next)) + h->next->prev = h->prev; + free(h); + return 0; + } else + return -1; +} + +/* Do something for each element */ + +void +hashtabforeach(Hashtab * htab, int (*func) (void *ptr, void *arg), + void *arg) +{ + Hashentry **h, *g; + + assert(htab); + + for (h = htab->tab; h < &htab->tab[htab->sz]; ++h) + for (g = *h; g; g = g->next) + if ((*func) (g->ptr, arg)) + return; +} + +/* standard hash-functions for strings */ + +unsigned +hashadd(const char *s) +{ /* Standard hash function */ + unsigned i; + + assert(s); + + for (i = 0; *s; ++s) + i += *s; + return i; +} + +unsigned +hashcaseadd(const char *s) +{ /* Standard hash function */ + unsigned i; + + assert(s); + + for (i = 0; *s; ++s) + i += toupper(*s); + return i; +} + +#define TWELVE (sizeof(unsigned)) +#define SEVENTYFIVE (6*sizeof(unsigned)) +#define HIGH_BITS (~((unsigned)(~0) >> TWELVE)) + +unsigned +hashjpw(const char *ss) +{ /* another hash function */ + unsigned h = 0; + unsigned g; + const unsigned char *s = (const unsigned char *)ss; + + for (; *s; ++s) { + h = (h << TWELVE) + *s; + if ((g = h & HIGH_BITS)) + h = (h ^ (g >> SEVENTYFIVE)) & ~HIGH_BITS; + } + return h; +} diff --git a/usr.bin/asn1_compile/hash.h b/usr.bin/asn1_compile/hash.h new file mode 100644 index 00000000000..a9a965194e2 --- /dev/null +++ b/usr.bin/asn1_compile/hash.h @@ -0,0 +1,87 @@ +/* + * Copyright (c) 1997 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* + * hash.h. Header file for hash table functions + */ + +/* $KTH: hash.h,v 1.3 1999/12/02 17:05:02 joda Exp $ */ + +struct hashentry { /* Entry in bucket */ + struct hashentry **prev; + struct hashentry *next; + void *ptr; +}; + +typedef struct hashentry Hashentry; + +struct hashtab { /* Hash table */ + int (*cmp)(void *, void *); /* Compare function */ + unsigned (*hash)(void *); /* hash function */ + int sz; /* Size */ + Hashentry *tab[1]; /* The table */ +}; + +typedef struct hashtab Hashtab; + +/* prototypes */ + +Hashtab *hashtabnew(int sz, + int (*cmp)(void *, void *), + unsigned (*hash)(void *)); /* Make new hash table */ + +void *hashtabsearch(Hashtab *htab, /* The hash table */ + void *ptr); /* The key */ + + +void *hashtabadd(Hashtab *htab, /* The hash table */ + void *ptr); /* The element */ + +int _hashtabdel(Hashtab *htab, /* The table */ + void *ptr, /* Key */ + int freep); /* Free data part? */ + +void hashtabforeach(Hashtab *htab, + int (*func)(void *ptr, void *arg), + void *arg); + +unsigned hashadd(const char *s); /* Standard hash function */ +unsigned hashcaseadd(const char *s); /* Standard hash function */ +unsigned hashjpw(const char *s); /* another hash function */ + +/* macros */ + + /* Don't free space */ +#define hashtabdel(htab,key) _hashtabdel(htab,key,FALSE) + +#define hashtabfree(htab,key) _hashtabdel(htab,key,TRUE) /* Do! */ diff --git a/usr.bin/asn1_compile/lex.h b/usr.bin/asn1_compile/lex.h new file mode 100644 index 00000000000..335f3af86d8 --- /dev/null +++ b/usr.bin/asn1_compile/lex.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 1997 - 2000 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* $KTH: lex.h,v 1.5 2000/07/01 20:21:34 assar Exp $ */ + +void error_message (const char *, ...) +__attribute__ ((format (printf, 1, 2))); + +int yylex(void); diff --git a/usr.bin/asn1_compile/lex.l b/usr.bin/asn1_compile/lex.l new file mode 100644 index 00000000000..a21243ecf4a --- /dev/null +++ b/usr.bin/asn1_compile/lex.l @@ -0,0 +1,122 @@ +%{ +/* + * Copyright (c) 1997 - 2001 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* $KTH: lex.l,v 1.19 2001/09/25 23:28:03 assar Exp $ */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include <stdio.h> +#include <stdarg.h> +#include <stdlib.h> +#include <string.h> +#ifdef HAVE_UNISTD_H +#include <unistd.h> +#endif +#undef ECHO +#include "symbol.h" +#include "parse.h" +#include "lex.h" +#include "gen_locl.h" + +static unsigned lineno = 1; + +#define YY_NO_UNPUT + +#undef ECHO + +%} + + +%% +INTEGER { return INTEGER; } +IMPORTS { return IMPORTS; } +FROM { return FROM; } +SEQUENCE { return SEQUENCE; } +OF { return OF; } +OCTET { return OCTET; } +STRING { return STRING; } +GeneralizedTime { return GeneralizedTime; } +GeneralString { return GeneralString; } +BIT { return BIT; } +APPLICATION { return APPLICATION; } +OPTIONAL { return OPTIONAL; } +BEGIN { return TBEGIN; } +END { return END; } +DEFINITIONS { return DEFINITIONS; } +ENUMERATED { return ENUMERATED; } +EXTERNAL { return EXTERNAL; } +OBJECT { return OBJECT; } +IDENTIFIER { return IDENTIFIER; } +[,;{}()|] { return *yytext; } +"[" { return *yytext; } +"]" { return *yytext; } +::= { return EEQUAL; } +--[^\n]*\n { ++lineno; } +-?(0x)?[0-9]+ { char *e, *y = yytext; + yylval.constant = strtol((const char *)yytext, + &e, 0); + if(e == y) + error_message("malformed constant (%s)", yytext); + else + return CONSTANT; + } +[A-Za-z][-A-Za-z0-9_]* { + yylval.name = strdup ((const char *)yytext); + return IDENT; + } +[ \t] ; +\n { ++lineno; } +\.\. { return DOTDOT; } +. { error_message("Ignoring char(%c)\n", *yytext); } +%% + +#ifndef yywrap /* XXX */ +int +yywrap () +{ + return 1; +} +#endif + +void +error_message (const char *format, ...) +{ + va_list args; + + va_start (args, format); + fprintf (stderr, "%s:%d: ", filename(), lineno); + vfprintf (stderr, format, args); + va_end (args); +} diff --git a/usr.bin/asn1_compile/main.c b/usr.bin/asn1_compile/main.c new file mode 100644 index 00000000000..a000087ac28 --- /dev/null +++ b/usr.bin/asn1_compile/main.c @@ -0,0 +1,95 @@ +/* + * Copyright (c) 1997, 1998, 1999 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "gen_locl.h" +#include <getarg.h> + +/* +RCSID("$KTH: main.c,v 1.11 2001/02/20 01:44:52 assar Exp $"); +*/ + +extern FILE *yyin; + +int version_flag; +int help_flag; +struct getargs args[] = { + { "version", 0, arg_flag, &version_flag }, + { "help", 0, arg_flag, &help_flag } +}; +int num_args = sizeof(args) / sizeof(args[0]); + +static void +usage(int code) +{ + arg_printusage(args, num_args, NULL, "[asn1-file [name]]"); + exit(code); +} + +int +main(int argc, char **argv) +{ + int ret; + char *file; + char *name = NULL; + int optind = 0; + + if(getarg(args, num_args, argc, argv, &optind)) + usage(1); + if(help_flag) + usage(0); + if(version_flag) { +#if 0 + print_version(NULL); +#else + printf("asn1_compile from heimdal-0.6\n"); +#endif + exit(0); + } + if (argc == optind) { + file = "stdin"; + name = "stdin"; + yyin = stdin; + } else { + file = argv[optind]; + yyin = fopen (file, "r"); + if (yyin == NULL) + err (1, "open %s", file); + name = argv[optind + 1]; + } + + init_generate (file, name); + initsym (); + ret = yyparse (); + close_generate (); + return ret; +} diff --git a/usr.bin/asn1_compile/parse.y b/usr.bin/asn1_compile/parse.y new file mode 100644 index 00000000000..1d445cb22a3 --- /dev/null +++ b/usr.bin/asn1_compile/parse.y @@ -0,0 +1,265 @@ +/* + * Copyright (c) 1997 - 2001 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* $KTH: parse.y,v 1.19 2001/09/27 16:21:47 assar Exp $ */ + +%{ +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include "symbol.h" +#include "lex.h" +#include "gen_locl.h" + +/* +RCSID("$KTH: parse.y,v 1.19 2001/09/27 16:21:47 assar Exp $"); +*/ + +static Type *new_type (Typetype t); +void yyerror (char *); + +static void append (Member *l, Member *r); + +%} + +%union { + int constant; + char *name; + Type *type; + Member *member; +} + +%token INTEGER SEQUENCE OF OCTET STRING GeneralizedTime GeneralString +%token BIT APPLICATION OPTIONAL EEQUAL TBEGIN END DEFINITIONS ENUMERATED +%token EXTERNAL +%token DOTDOT +%token IMPORTS FROM +%token OBJECT IDENTIFIER +%token <name> IDENT +%token <constant> CONSTANT + +%type <constant> constant optional2 +%type <type> type +%type <member> memberdecls memberdecl bitdecls bitdecl + +%start envelope + +%% + +envelope : IDENT DEFINITIONS EEQUAL TBEGIN specification END {} + ; + +specification : + | specification declaration + ; + +declaration : imports_decl + | type_decl + | constant_decl + ; + +referencenames : IDENT ',' referencenames + { + Symbol *s = addsym($1); + s->stype = Stype; + } + | IDENT + { + Symbol *s = addsym($1); + s->stype = Stype; + } + ; + +imports_decl : IMPORTS referencenames FROM IDENT ';' + { add_import($4); } + ; + +type_decl : IDENT EEQUAL type + { + Symbol *s = addsym ($1); + s->stype = Stype; + s->type = $3; + generate_type (s); + } + ; + +constant_decl : IDENT type EEQUAL constant + { + Symbol *s = addsym ($1); + s->stype = SConstant; + s->constant = $4; + generate_constant (s); + } + ; + +type : INTEGER { $$ = new_type(TInteger); } + | INTEGER '(' constant DOTDOT constant ')' { + if($3 != 0) + error_message("Only 0 supported as low range"); + if($5 != INT_MIN && $5 != UINT_MAX && $5 != INT_MAX) + error_message("Only %u supported as high range", + UINT_MAX); + $$ = new_type(TUInteger); + } + | INTEGER '{' bitdecls '}' + { + $$ = new_type(TInteger); + $$->members = $3; + } + | OBJECT IDENTIFIER { $$ = new_type(TOID); } + | ENUMERATED '{' bitdecls '}' + { + $$ = new_type(TEnumerated); + $$->members = $3; + } + | OCTET STRING { $$ = new_type(TOctetString); } + | GeneralString { $$ = new_type(TGeneralString); } + | GeneralizedTime { $$ = new_type(TGeneralizedTime); } + | SEQUENCE OF type + { + $$ = new_type(TSequenceOf); + $$->subtype = $3; + } + | SEQUENCE '{' memberdecls '}' + { + $$ = new_type(TSequence); + $$->members = $3; + } + | BIT STRING '{' bitdecls '}' + { + $$ = new_type(TBitString); + $$->members = $4; + } + | IDENT + { + Symbol *s = addsym($1); + $$ = new_type(TType); + if(s->stype != Stype) + error_message ("%s is not a type\n", $1); + else + $$->symbol = s; + } + | '[' APPLICATION constant ']' type + { + $$ = new_type(TApplication); + $$->subtype = $5; + $$->application = $3; + } + ; + +memberdecls : { $$ = NULL; } + | memberdecl { $$ = $1; } + | memberdecls ',' memberdecl { $$ = $1; append($$, $3); } + ; + +memberdecl : IDENT '[' constant ']' type optional2 + { + $$ = malloc(sizeof(*$$)); + $$->name = $1; + $$->gen_name = strdup($1); + output_name ($$->gen_name); + $$->val = $3; + $$->optional = $6; + $$->type = $5; + $$->next = $$->prev = $$; + } + ; + +optional2 : { $$ = 0; } + | OPTIONAL { $$ = 1; } + ; + +bitdecls : { $$ = NULL; } + | bitdecl { $$ = $1; } + | bitdecls ',' bitdecl { $$ = $1; append($$, $3); } + ; + +bitdecl : IDENT '(' constant ')' + { + $$ = malloc(sizeof(*$$)); + $$->name = $1; + $$->gen_name = strdup($1); + output_name ($$->gen_name); + $$->val = $3; + $$->optional = 0; + $$->type = NULL; + $$->prev = $$->next = $$; + } + ; + +constant : CONSTANT { $$ = $1; } + | IDENT { + Symbol *s = addsym($1); + if(s->stype != SConstant) + error_message ("%s is not a constant\n", + s->name); + else + $$ = s->constant; + } + ; +%% + +void +yyerror (char *s) +{ + error_message ("%s\n", s); +} + +static Type * +new_type (Typetype tt) +{ + Type *t = malloc(sizeof(*t)); + if (t == NULL) { + error_message ("out of memory in malloc(%lu)", + (unsigned long)sizeof(*t)); + exit (1); + } + t->type = tt; + t->application = 0; + t->members = NULL; + t->subtype = NULL; + t->symbol = NULL; + return t; +} + +static void +append (Member *l, Member *r) +{ + l->prev->next = r; + r->prev = l->prev; + l->prev = r; + r->next = l; +} diff --git a/usr.bin/asn1_compile/symbol.c b/usr.bin/asn1_compile/symbol.c new file mode 100644 index 00000000000..1be1dfd544f --- /dev/null +++ b/usr.bin/asn1_compile/symbol.c @@ -0,0 +1,92 @@ +/* + * Copyright (c) 1997 - 2001 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "gen_locl.h" + +/* +RCSID("$KTH: symbol.c,v 1.9 2001/09/25 13:39:27 assar Exp $"); +*/ + +static Hashtab *htab; + +static int +cmp (void *a, void *b) +{ + Symbol *s1 = (Symbol *)a; + Symbol *s2 = (Symbol *)b; + + return strcmp (s1->name, s2->name); +} + +static unsigned +hash (void *a) +{ + Symbol *s = (Symbol *)a; + + return hashjpw (s->name); +} + +void +initsym (void) +{ + htab = hashtabnew (101, cmp, hash); +} + + +void +output_name (char *s) +{ + char *p; + + for (p = s; *p; ++p) + if (*p == '-') + *p = '_'; +} + +Symbol* +addsym (char *name) +{ + Symbol key, *s; + + key.name = name; + s = (Symbol *)hashtabsearch (htab, (void *)&key); + if (s == NULL) { + s = (Symbol *)malloc (sizeof (*s)); + s->name = name; + s->gen_name = strdup(name); + output_name (s->gen_name); + s->stype = SUndefined; + hashtabadd (htab, s); + } + return s; +} diff --git a/usr.bin/asn1_compile/symbol.h b/usr.bin/asn1_compile/symbol.h new file mode 100644 index 00000000000..9bc7e48603c --- /dev/null +++ b/usr.bin/asn1_compile/symbol.h @@ -0,0 +1,83 @@ +/* + * Copyright (c) 1997 - 2001 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* $KTH: symbol.h,v 1.6 2001/09/25 13:39:27 assar Exp $ */ + +#ifndef _SYMBOL_H +#define _SYMBOL_H + +enum typetype { TInteger, TOctetString, TBitString, TSequence, TSequenceOf, + TGeneralizedTime, TGeneralString, TApplication, TType, + TUInteger, TEnumerated, TOID }; + +typedef enum typetype Typetype; + +struct type; + +struct member { + char *name; + char *gen_name; + int val; + int optional; + struct type *type; + struct member *next, *prev; +}; + +typedef struct member Member; + +struct symbol; + +struct type { + Typetype type; + int application; + Member *members; + struct type *subtype; + struct symbol *symbol; +}; + +typedef struct type Type; + +struct symbol { + char *name; + char *gen_name; + enum { SUndefined, SConstant, Stype } stype; + int constant; + Type *type; +}; + +typedef struct symbol Symbol; + +void initsym (void); +Symbol *addsym (char *); +void output_name (char *); +#endif |