1 /* 2 * Copyright (c) 2004 Kungliga Tekniska Högskolan 3 * (Royal Institute of Technology, Stockholm, Sweden). 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 17 * 3. Neither the name of the Institute nor the names of its contributors 18 * may be used to endorse or promote products derived from this software 19 * without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 */ 33 34 #ifdef HAVE_CONFIG_H 35 #include <config.h> 36 #endif 37 #include <assert.h> 38 #include <err.h> 39 #include <netdb.h> 40 #include <stdio.h> 41 #include <stdlib.h> 42 #include <string.h> 43 #include <sys/socket.h> 44 #include <sys/types.h> 45 46 #include <getarg.h> 47 #include <roken.h> 48 49 #include "windlocl.h" 50 51 static int version_flag = 0; 52 static int help_flag = 0; 53 54 55 static int 56 is_separator(uint32_t u) 57 { 58 return u == 0x002E || u == 0x3002; 59 } 60 61 static void 62 lookup(const char *name) 63 { 64 unsigned i; 65 char encoded[1024]; 66 char *ep; 67 int ret; 68 struct addrinfo hints; 69 struct addrinfo *ai; 70 71 size_t u_len = strlen(name); 72 uint32_t *u = malloc(u_len * sizeof(uint32_t)); 73 size_t norm_len = u_len * 2; 74 uint32_t *norm = malloc(norm_len * sizeof(uint32_t)); 75 76 if (u == NULL && u_len != 0) 77 errx(1, "malloc failed"); 78 if (norm == NULL && norm_len != 0) 79 errx(1, "malloc failed"); 80 81 ret = wind_utf8ucs4(name, u, &u_len); 82 if (ret) 83 errx(1, "utf8 conversion failed"); 84 ret = wind_stringprep(u, u_len, norm, &norm_len, WIND_PROFILE_NAME); 85 if (ret) 86 errx(1, "stringprep failed"); 87 free(u); 88 89 ep = encoded; 90 for (i = 0; i < norm_len; ++i) { 91 unsigned j; 92 size_t len; 93 94 for (j = i; j < norm_len && !is_separator(norm[j]); ++j) 95 ; 96 len = sizeof(encoded) - (ep - encoded); 97 ret = wind_punycode_label_toascii(norm + i, j - i, ep, &len); 98 if (ret) 99 errx(1, "punycode failed"); 100 101 ep += len; 102 *ep++ = '.'; 103 i = j; 104 } 105 *ep = '\0'; 106 free(norm); 107 108 printf("Converted \"%s\" into \"%s\"\n", name, encoded); 109 110 memset(&hints, 0, sizeof(hints)); 111 hints.ai_flags = AI_CANONNAME; 112 ret = getaddrinfo(encoded, NULL, &hints, &ai); 113 if(ret) 114 errx(1, "getaddrinfo failed: %s", gai_strerror(ret)); 115 printf("canonical-name: %s\n", ai->ai_canonname); 116 freeaddrinfo(ai); 117 } 118 119 static struct getargs args[] = { 120 {"version", 0, arg_flag, &version_flag, 121 "print version", NULL }, 122 {"help", 0, arg_flag, &help_flag, 123 NULL, NULL } 124 }; 125 126 static void 127 usage (int ret) 128 { 129 arg_printusage(args, sizeof(args)/sizeof(args[0]), NULL, 130 "dns-names ..."); 131 exit (ret); 132 } 133 134 int 135 main(int argc, char **argv) 136 { 137 int optidx = 0; 138 unsigned i; 139 140 setprogname (argv[0]); 141 142 if(getarg(args, sizeof(args) / sizeof(args[0]), argc, argv, &optidx)) 143 usage(1); 144 145 if (help_flag) 146 usage (0); 147 148 if(version_flag){ 149 print_version(NULL); 150 exit(0); 151 } 152 153 argc -= optidx; 154 argv += optidx; 155 156 if (argc == 0) 157 usage(1); 158 159 for (i = 0; i < argc; ++i) 160 lookup(argv[i]); 161 return 0; 162 } 163