1 1.1 elric /* $NetBSD: gen_copy.c,v 1.3 2023/06/19 21:41:42 christos Exp $ */ 2 1.1 elric 3 1.1 elric /* 4 1.1 elric * Copyright (c) 1997 - 2005 Kungliga Tekniska Hgskolan 5 1.1 elric * (Royal Institute of Technology, Stockholm, Sweden). 6 1.1 elric * All rights reserved. 7 1.1 elric * 8 1.1 elric * Redistribution and use in source and binary forms, with or without 9 1.1 elric * modification, are permitted provided that the following conditions 10 1.1 elric * are met: 11 1.1 elric * 12 1.1 elric * 1. Redistributions of source code must retain the above copyright 13 1.1 elric * notice, this list of conditions and the following disclaimer. 14 1.1 elric * 15 1.1 elric * 2. Redistributions in binary form must reproduce the above copyright 16 1.1 elric * notice, this list of conditions and the following disclaimer in the 17 1.1 elric * documentation and/or other materials provided with the distribution. 18 1.1 elric * 19 1.1 elric * 3. Neither the name of the Institute nor the names of its contributors 20 1.1 elric * may be used to endorse or promote products derived from this software 21 1.1 elric * without specific prior written permission. 22 1.1 elric * 23 1.1 elric * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 24 1.1 elric * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25 1.1 elric * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 26 1.1 elric * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 27 1.1 elric * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28 1.1 elric * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 29 1.1 elric * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 30 1.1 elric * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 31 1.1 elric * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 32 1.1 elric * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33 1.1 elric * SUCH DAMAGE. 34 1.1 elric */ 35 1.1 elric 36 1.1 elric #include "gen_locl.h" 37 1.1 elric 38 1.1 elric __RCSID("$NetBSD: gen_copy.c,v 1.3 2023/06/19 21:41:42 christos Exp $"); 39 1.1 elric 40 1.1 elric static int used_fail; 41 1.1 elric 42 1.1 elric static void 43 1.1 elric copy_primitive (const char *typename, const char *from, const char *to) 44 1.1 elric { 45 1.1 elric fprintf (codefile, "if(der_copy_%s(%s, %s)) goto fail;\n", 46 1.1 elric typename, from, to); 47 1.1 elric used_fail++; 48 1.1 elric } 49 1.1 elric 50 1.1 elric static void 51 1.1 elric copy_type (const char *from, const char *to, const Type *t, int preserve) 52 1.1 elric { 53 1.1 elric switch (t->type) { 54 1.1 elric case TType: 55 1.1 elric #if 0 56 1.1 elric copy_type (from, to, t->symbol->type, preserve); 57 1.1 elric #endif 58 1.1 elric fprintf (codefile, "if(copy_%s(%s, %s)) goto fail;\n", 59 1.1 elric t->symbol->gen_name, from, to); 60 1.1 elric used_fail++; 61 1.1 elric break; 62 1.1 elric case TInteger: 63 1.1 elric if (t->range == NULL && t->members == NULL) { 64 1.1 elric copy_primitive ("heim_integer", from, to); 65 1.1 elric break; 66 1.1 elric } 67 1.3 christos /* fallthrough */ 68 1.1 elric case TBoolean: 69 1.1 elric case TEnumerated : 70 1.1 elric fprintf(codefile, "*(%s) = *(%s);\n", to, from); 71 1.1 elric break; 72 1.1 elric case TOctetString: 73 1.1 elric copy_primitive ("octet_string", from, to); 74 1.1 elric break; 75 1.1 elric case TBitString: 76 1.1 elric if (ASN1_TAILQ_EMPTY(t->members)) 77 1.1 elric copy_primitive ("bit_string", from, to); 78 1.1 elric else 79 1.1 elric fprintf(codefile, "*(%s) = *(%s);\n", to, from); 80 1.1 elric break; 81 1.1 elric case TSet: 82 1.1 elric case TSequence: 83 1.1 elric case TChoice: { 84 1.1 elric Member *m, *have_ellipsis = NULL; 85 1.1 elric 86 1.1 elric if(t->members == NULL) 87 1.1 elric break; 88 1.1 elric 89 1.1 elric if ((t->type == TSequence || t->type == TChoice) && preserve) { 90 1.1 elric fprintf(codefile, 91 1.1 elric "{ int ret;\n" 92 1.1 elric "ret = der_copy_octet_string(&(%s)->_save, &(%s)->_save);\n" 93 1.1 elric "if (ret) goto fail;\n" 94 1.1 elric "}\n", 95 1.1 elric from, to); 96 1.1 elric used_fail++; 97 1.1 elric } 98 1.1 elric 99 1.1 elric if(t->type == TChoice) { 100 1.1 elric fprintf(codefile, "(%s)->element = (%s)->element;\n", to, from); 101 1.1 elric fprintf(codefile, "switch((%s)->element) {\n", from); 102 1.1 elric } 103 1.1 elric 104 1.1 elric ASN1_TAILQ_FOREACH(m, t->members, members) { 105 1.1 elric char *fs; 106 1.1 elric char *ts; 107 1.1 elric 108 1.1 elric if (m->ellipsis) { 109 1.1 elric have_ellipsis = m; 110 1.1 elric continue; 111 1.1 elric } 112 1.1 elric 113 1.1 elric if(t->type == TChoice) 114 1.1 elric fprintf(codefile, "case %s:\n", m->label); 115 1.1 elric 116 1.1 elric if (asprintf (&fs, "%s(%s)->%s%s", 117 1.1 elric m->optional ? "" : "&", from, 118 1.1 elric t->type == TChoice ? "u." : "", m->gen_name) < 0) 119 1.1 elric errx(1, "malloc"); 120 1.1 elric if (fs == NULL) 121 1.1 elric errx(1, "malloc"); 122 1.1 elric if (asprintf (&ts, "%s(%s)->%s%s", 123 1.1 elric m->optional ? "" : "&", to, 124 1.1 elric t->type == TChoice ? "u." : "", m->gen_name) < 0) 125 1.1 elric errx(1, "malloc"); 126 1.1 elric if (ts == NULL) 127 1.1 elric errx(1, "malloc"); 128 1.1 elric if(m->optional){ 129 1.1 elric fprintf(codefile, "if(%s) {\n", fs); 130 1.1 elric fprintf(codefile, "%s = malloc(sizeof(*%s));\n", ts, ts); 131 1.1 elric fprintf(codefile, "if(%s == NULL) goto fail;\n", ts); 132 1.1 elric used_fail++; 133 1.1 elric } 134 1.1 elric copy_type (fs, ts, m->type, FALSE); 135 1.1 elric if(m->optional){ 136 1.1 elric fprintf(codefile, "}else\n"); 137 1.1 elric fprintf(codefile, "%s = NULL;\n", ts); 138 1.1 elric } 139 1.1 elric free (fs); 140 1.1 elric free (ts); 141 1.1 elric if(t->type == TChoice) 142 1.1 elric fprintf(codefile, "break;\n"); 143 1.1 elric } 144 1.1 elric if(t->type == TChoice) { 145 1.1 elric if (have_ellipsis) { 146 1.1 elric fprintf(codefile, "case %s: {\n" 147 1.1 elric "int ret;\n" 148 1.1 elric "ret=der_copy_octet_string(&(%s)->u.%s, &(%s)->u.%s);\n" 149 1.1 elric "if (ret) goto fail;\n" 150 1.1 elric "break;\n" 151 1.1 elric "}\n", 152 1.1 elric have_ellipsis->label, 153 1.1 elric from, have_ellipsis->gen_name, 154 1.1 elric to, have_ellipsis->gen_name); 155 1.1 elric used_fail++; 156 1.1 elric } 157 1.1 elric fprintf(codefile, "}\n"); 158 1.1 elric } 159 1.1 elric break; 160 1.1 elric } 161 1.1 elric case TSetOf: 162 1.1 elric case TSequenceOf: { 163 1.1 elric char *f = NULL, *T = NULL; 164 1.1 elric 165 1.1 elric fprintf (codefile, "if(((%s)->val = " 166 1.1 elric "malloc((%s)->len * sizeof(*(%s)->val))) == NULL && (%s)->len != 0)\n", 167 1.1 elric to, from, to, from); 168 1.1 elric fprintf (codefile, "goto fail;\n"); 169 1.1 elric used_fail++; 170 1.1 elric fprintf(codefile, 171 1.1 elric "for((%s)->len = 0; (%s)->len < (%s)->len; (%s)->len++){\n", 172 1.1 elric to, to, from, to); 173 1.1 elric if (asprintf(&f, "&(%s)->val[(%s)->len]", from, to) < 0) 174 1.1 elric errx(1, "malloc"); 175 1.1 elric if (f == NULL) 176 1.1 elric errx(1, "malloc"); 177 1.1 elric if (asprintf(&T, "&(%s)->val[(%s)->len]", to, to) < 0) 178 1.1 elric errx(1, "malloc"); 179 1.1 elric if (T == NULL) 180 1.1 elric errx(1, "malloc"); 181 1.1 elric copy_type(f, T, t->subtype, FALSE); 182 1.1 elric fprintf(codefile, "}\n"); 183 1.1 elric free(f); 184 1.1 elric free(T); 185 1.1 elric break; 186 1.1 elric } 187 1.1 elric case TGeneralizedTime: 188 1.1 elric fprintf(codefile, "*(%s) = *(%s);\n", to, from); 189 1.1 elric break; 190 1.1 elric case TGeneralString: 191 1.1 elric copy_primitive ("general_string", from, to); 192 1.1 elric break; 193 1.1 elric case TTeletexString: 194 1.1 elric copy_primitive ("general_string", from, to); 195 1.1 elric break; 196 1.1 elric case TUTCTime: 197 1.1 elric fprintf(codefile, "*(%s) = *(%s);\n", to, from); 198 1.1 elric break; 199 1.1 elric case TUTF8String: 200 1.1 elric copy_primitive ("utf8string", from, to); 201 1.1 elric break; 202 1.1 elric case TPrintableString: 203 1.1 elric copy_primitive ("printable_string", from, to); 204 1.1 elric break; 205 1.1 elric case TIA5String: 206 1.1 elric copy_primitive ("ia5_string", from, to); 207 1.1 elric break; 208 1.1 elric case TBMPString: 209 1.1 elric copy_primitive ("bmp_string", from, to); 210 1.1 elric break; 211 1.1 elric case TUniversalString: 212 1.1 elric copy_primitive ("universal_string", from, to); 213 1.1 elric break; 214 1.1 elric case TVisibleString: 215 1.1 elric copy_primitive ("visible_string", from, to); 216 1.1 elric break; 217 1.1 elric case TTag: 218 1.1 elric copy_type (from, to, t->subtype, preserve); 219 1.1 elric break; 220 1.1 elric case TOID: 221 1.1 elric copy_primitive ("oid", from, to); 222 1.1 elric break; 223 1.1 elric case TNull: 224 1.1 elric break; 225 1.1 elric default : 226 1.1 elric abort (); 227 1.1 elric } 228 1.1 elric } 229 1.1 elric 230 1.1 elric void 231 1.1 elric generate_type_copy (const Symbol *s) 232 1.1 elric { 233 1.1 elric int preserve = preserve_type(s->name) ? TRUE : FALSE; 234 1.1 elric 235 1.1 elric used_fail = 0; 236 1.1 elric 237 1.1 elric fprintf (codefile, "int ASN1CALL\n" 238 1.1 elric "copy_%s(const %s *from, %s *to)\n" 239 1.1 elric "{\n" 240 1.1 elric "memset(to, 0, sizeof(*to));\n", 241 1.1 elric s->gen_name, s->gen_name, s->gen_name); 242 1.1 elric copy_type ("from", "to", s->type, preserve); 243 1.1 elric fprintf (codefile, "return 0;\n"); 244 1.1 elric 245 1.1 elric if (used_fail) 246 1.1 elric fprintf (codefile, "fail:\n" 247 1.1 elric "free_%s(to);\n" 248 1.1 elric "return ENOMEM;\n", 249 1.1 elric s->gen_name); 250 1.1 elric 251 1.1 elric fprintf(codefile, 252 1.1 elric "}\n\n"); 253 1.1 elric } 254 1.1 elric 255