int qatom_main(int argc, char **argv) { enum qatom_atom { _EXPLODE=0, _COMPARE, _PRINT } action = _EXPLODE; const char *format = QATOM_FORMAT; depend_atom *atom; depend_atom *atomc; int i; while ((i = GETOPT_LONG(QATOM, qatom, "")) != -1) { switch (i) { case 'F': format = optarg; break; case 'c': action = _COMPARE; break; case 'p': action = _PRINT; break; COMMON_GETOPTS_CASES(qatom) } } if (argc == optind) qatom_usage(EXIT_FAILURE); if (action == _COMPARE && (argc - optind) % 2) err("compare needs even number of arguments"); for (i = optind; i < argc; ++i) { atom = atom_explode(argv[i]); if (atom == NULL) { warnf("invalid atom: %s\n", argv[i]); continue; } switch (action) { case _COMPARE: i++; atomc = atom_explode(argv[i]); if (atomc == NULL) { warnf("invalid atom: %s\n", argv[i]); break; } printf("%s %s ", atom_to_string(atom), booga[atom_compare(atom, atomc)]); printf("%s\n", atom_to_string(atomc)); atom_implode(atomc); break; case _EXPLODE: qatom_printf(format, atom, verbose); putchar('\n'); break; case _PRINT: printf("%s\n", atom_to_string(atom)); break; } atom_implode(atom); } return EXIT_SUCCESS; }
static int x509_parse_subject(ErlNifEnv* env, ERL_NIF_TERM subject_tuple, int *num_subject_entries, x509_subject_entry **subject_entries){ int num_subject_tuple; unsigned num_subject_terms; ERL_NIF_TERM head, tail; int pair_arity; char *name; char *value; char *subject_string = NULL; const ERL_NIF_TERM* pair; int idx; x509_subject_entry* se; unsigned value_len; const ERL_NIF_TERM* subject_terms; *subject_entries = NULL; *num_subject_entries = 0; /* make sure this is a tuple with first term 'subject' */ if(!enif_get_tuple(env, subject_tuple, &num_subject_tuple, &subject_terms) || !atom_to_string(env, subject_terms[0], &subject_string) || strncmp(subject_string, SUBJECT_STR, subject_strlen)) { if(subject_string) free(subject_string); return 0; } free(subject_string); /* create room for the x509_subject_entry structs */ if(!enif_get_list_length(env, subject_terms[1], &num_subject_terms) || (NULL == (se = (x509_subject_entry*)malloc(num_subject_terms * sizeof(x509_subject_entry))))) return 0; /* get the first entry and prime the pump for walking the rest */ if(!enif_get_list_cell(env, subject_terms[1], &head, &tail) || !enif_get_tuple(env, head, &pair_arity, &pair) || pair_arity!=2) { return 0; } for(idx=0; idx<num_subject_terms; idx++){ atom_to_string(env, pair[0], &name); enif_get_list_length(env, pair[1], &value_len); value = (char*)malloc(value_len+1); enif_get_string(env, pair[1], value, value_len+1, ERL_NIF_LATIN1); (se+idx)->name = name; (se+idx)->value = value; if(!enif_get_list_cell(env, tail, &head, &tail) || !enif_get_tuple(env, head, &pair_arity, &pair) || pair_arity!=2) { break; } } *num_subject_entries = num_subject_terms; *subject_entries = se; return 1; }
/** * pull out the integer from a a tuple of the form {tuple_name, result_int}, * where the tuple_name is an atom and the result_int is an integer. * * so to parse: * {expiry, 1234} * * call as: * int expiry; * x509_parse_int_tuple(env, arg_terms[idx++], "expiry", &expiry); */ static int x509_parse_int_tuple(ErlNifEnv* env, ERL_NIF_TERM tuple, char* tuple_name, int *result_int){ int num_tuple; char *tuple_string = NULL; const ERL_NIF_TERM* tuple_terms; /* make sure this is a tuple with first term (tuple_name) */ if(!enif_get_tuple(env, tuple, &num_tuple, &tuple_terms) || num_tuple != 2 || !atom_to_string(env, tuple_terms[0], &tuple_string) || strncmp(tuple_string, tuple_name, strlen(tuple_name))) { if(NULL != tuple_string) free(tuple_string); return 0; } /* get the value */ enif_get_int(env, tuple_terms[1], result_int); return 1; }
static int x509_parse_issuer_cert(ErlNifEnv* env, ERL_NIF_TERM issuer_cert_tuple, char **issuer_cert_pem) { char *issuer_cert_atom_string = NULL; char *issuer_cert_pem_string = NULL; int num_issuer_terms; const ERL_NIF_TERM *issuer_terms; *issuer_cert_pem = NULL; if(NULL == issuer_cert_pem || !enif_get_tuple(env, issuer_cert_tuple, &num_issuer_terms, &issuer_terms)) return 0; if(!atom_to_string(env, issuer_terms[0], &issuer_cert_atom_string) || strncmp(issuer_cert_atom_string, ISSUER_CERT_STR, issuer_cert_strlen)) { if(NULL != issuer_cert_atom_string) free(issuer_cert_atom_string); return 0; } free(issuer_cert_atom_string); if(!binary_to_string(env, issuer_terms[1], &issuer_cert_pem_string)) return 0; *issuer_cert_pem = issuer_cert_pem_string; return 1; }
static int x509_parse_keypair(ErlNifEnv* env, const char* keypair_name, ERL_NIF_TERM key_tuple, char *keys[2]){ /* key_tuple := {keypair_name, {keypair , [{public_key, <<...>>}, {private_key, <<..>>}]}} */ unsigned atom_len = -1; int num_named_key_terms = -1; int num_keypair_terms = -1; int num_public_key_terms = -1; int num_private_key_terms = -1; const ERL_NIF_TERM *named_key_terms = NULL; const ERL_NIF_TERM *keypair_terms = NULL; const ERL_NIF_TERM *public_key_terms = NULL; const ERL_NIF_TERM *private_key_terms = NULL; char *keyname = NULL; char *keypair = NULL; char *private_key_str, *public_key_str; ERL_NIF_TERM head,tail; if ( NULL == keys || NULL == keypair_name){ return 0; } /* get the name of the key, which is given as an atom */ if(!enif_get_tuple(env, key_tuple, &num_named_key_terms, &named_key_terms) || !atom_to_string(env, named_key_terms[0], &keyname)){ if(NULL != keyname) free(keyname); return 0; } if(strncmp(keyname, keypair_name, atom_len)){ free(keyname); return 0; } /* get the tagged tuple representing the keypair */ if(!enif_get_tuple(env, named_key_terms[1], &num_keypair_terms, &keypair_terms)) return 0; /* get the atom 'keypair' and validate */ if(num_keypair_terms < 2) return 0; if(!atom_to_string(env, keypair_terms[0], &keypair) || strncmp(keypair, KEYPAIR_STR, atom_len)){ if(keypair) free(keypair); return 0; } /* keypair itself is a list of tuples, one member is the public key, the other is the private key */ enif_get_list_cell(env, keypair_terms[1], &head, &tail); enif_get_tuple(env, head, &num_public_key_terms, &public_key_terms); /* get the public key binary */ if(!atom_to_string(env, public_key_terms[0], &keyname) || strncmp(keyname, PUBLIC_KEY_STR, atom_len)){ if(NULL != keyname) free(keyname); return 0; } free(keyname); keyname = NULL; if(!binary_to_string(env, public_key_terms[1], &public_key_str)) return 0; enif_get_list_cell(env, tail, &head, &tail); enif_get_tuple(env, head, &num_private_key_terms, &private_key_terms); /* get the private key binary */ if(!atom_to_string(env, private_key_terms[0], &keyname) || strncmp(keyname, PRIVATE_KEY_STR, atom_len)){ if(NULL != keyname) free(keyname); return 0; } free(keyname); if(!binary_to_string(env, private_key_terms[1], &private_key_str)) return 0; keys[0] = public_key_str; keys[1] = private_key_str; return 1; }