1 1.14 christos /* $NetBSD: textdomain.c,v 1.14 2015/05/29 12:26:28 christos Exp $ */ 2 1.1 itojun 3 1.1 itojun /*- 4 1.5 minoura * Copyright (c) 2000, 2001 Citrus Project, 5 1.1 itojun * All rights reserved. 6 1.1 itojun * 7 1.1 itojun * Redistribution and use in source and binary forms, with or without 8 1.1 itojun * modification, are permitted provided that the following conditions 9 1.1 itojun * are met: 10 1.1 itojun * 1. Redistributions of source code must retain the above copyright 11 1.1 itojun * notice, this list of conditions and the following disclaimer. 12 1.1 itojun * 2. Redistributions in binary form must reproduce the above copyright 13 1.1 itojun * notice, this list of conditions and the following disclaimer in the 14 1.1 itojun * documentation and/or other materials provided with the distribution. 15 1.1 itojun * 16 1.1 itojun * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 17 1.1 itojun * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 1.1 itojun * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 1.1 itojun * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 20 1.1 itojun * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 1.1 itojun * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22 1.1 itojun * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 1.1 itojun * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 1.1 itojun * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 1.1 itojun * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 1.1 itojun * SUCH DAMAGE. 27 1.1 itojun */ 28 1.1 itojun 29 1.1 itojun #include <sys/cdefs.h> 30 1.14 christos __RCSID("$NetBSD: textdomain.c,v 1.14 2015/05/29 12:26:28 christos Exp $"); 31 1.1 itojun 32 1.1 itojun #include <sys/param.h> 33 1.1 itojun 34 1.1 itojun #include <stdio.h> 35 1.1 itojun #include <string.h> 36 1.4 itojun #include <stdlib.h> 37 1.1 itojun #include <libintl.h> 38 1.1 itojun #include "libintl_local.h" 39 1.1 itojun #include "pathnames.h" 40 1.1 itojun 41 1.5 minoura static struct domainbinding __default_binding = { 42 1.13 matt .path = { _PATH_TEXTDOMAIN }, 43 1.13 matt .domainname = { DEFAULT_DOMAINNAME }, 44 1.5 minoura }; 45 1.5 minoura struct domainbinding *__bindings = &__default_binding; 46 1.5 minoura char __current_domainname[PATH_MAX] = DEFAULT_DOMAINNAME; 47 1.1 itojun 48 1.12 junyoung static struct domainbinding *domainbinding_lookup(const char *, int); 49 1.10 yamt 50 1.1 itojun /* 51 1.1 itojun * set the default domainname for dcngettext() and friends. 52 1.1 itojun */ 53 1.1 itojun char * 54 1.12 junyoung textdomain(const char *domainname) 55 1.1 itojun { 56 1.1 itojun 57 1.2 itojun /* NULL pointer gives the current setting */ 58 1.4 itojun if (!domainname) 59 1.5 minoura return __current_domainname; 60 1.2 itojun 61 1.2 itojun /* empty string sets the value back to the default */ 62 1.4 itojun if (!*domainname) { 63 1.5 minoura strlcpy(__current_domainname, DEFAULT_DOMAINNAME, 64 1.5 minoura sizeof(__current_domainname)); 65 1.4 itojun } else { 66 1.5 minoura strlcpy(__current_domainname, domainname, 67 1.5 minoura sizeof(__current_domainname)); 68 1.4 itojun } 69 1.5 minoura return __current_domainname; 70 1.1 itojun } 71 1.1 itojun 72 1.1 itojun char * 73 1.12 junyoung bindtextdomain(const char *domainname, const char *dirname) 74 1.1 itojun { 75 1.4 itojun struct domainbinding *p; 76 1.2 itojun 77 1.2 itojun /* NULL pointer or empty string returns NULL with no operation */ 78 1.2 itojun if (!domainname || !*domainname) 79 1.2 itojun return NULL; 80 1.1 itojun 81 1.8 drochner if (dirname && (strlen(dirname) + 1 > sizeof(p->path))) 82 1.1 itojun return NULL; 83 1.6 yamt 84 1.6 yamt #if 0 85 1.1 itojun /* disallow relative path */ 86 1.1 itojun if (dirname[0] != '/') 87 1.1 itojun return NULL; 88 1.6 yamt #endif 89 1.1 itojun 90 1.4 itojun if (strlen(domainname) + 1 > sizeof(p->domainname)) 91 1.1 itojun return NULL; 92 1.1 itojun 93 1.10 yamt p = domainbinding_lookup(domainname, (dirname != NULL)); 94 1.8 drochner 95 1.8 drochner if (!dirname) { 96 1.8 drochner if (p) 97 1.8 drochner return (p->path); 98 1.8 drochner else 99 1.11 tshiozak return (char *)__UNCONST(_PATH_TEXTDOMAIN); 100 1.8 drochner } 101 1.8 drochner 102 1.4 itojun strlcpy(p->path, dirname, sizeof(p->path)); 103 1.5 minoura p->mohandle.mo.mo_magic = 0; /* invalidate current mapping */ 104 1.1 itojun 105 1.8 drochner return (p->path); 106 1.1 itojun } 107 1.1 itojun 108 1.1 itojun char * 109 1.12 junyoung bind_textdomain_codeset(const char *domainname, const char *codeset) 110 1.1 itojun { 111 1.10 yamt struct domainbinding *p; 112 1.10 yamt 113 1.10 yamt p = domainbinding_lookup(domainname, (codeset != NULL)); 114 1.10 yamt if (p == NULL) 115 1.10 yamt return NULL; 116 1.10 yamt 117 1.10 yamt if (codeset) { 118 1.14 christos free(p->codeset); 119 1.10 yamt p->codeset = strdup(codeset); 120 1.10 yamt } 121 1.10 yamt 122 1.10 yamt return p->codeset; 123 1.10 yamt } 124 1.10 yamt 125 1.10 yamt /* 126 1.10 yamt * lookup binding for the domainname 127 1.10 yamt */ 128 1.10 yamt static struct domainbinding * 129 1.12 junyoung domainbinding_lookup(const char *domainname, int alloc) 130 1.10 yamt { 131 1.10 yamt struct domainbinding *p; 132 1.10 yamt 133 1.10 yamt for (p = __bindings; p; p = p->next) 134 1.10 yamt if (strcmp(p->domainname, domainname) == 0) 135 1.10 yamt break; 136 1.10 yamt 137 1.10 yamt if (!p && alloc) { 138 1.10 yamt p = (struct domainbinding *)malloc(sizeof(*p)); 139 1.10 yamt if (!p) 140 1.10 yamt return NULL; 141 1.10 yamt memset(p, 0, sizeof(*p)); 142 1.10 yamt p->next = __bindings; 143 1.10 yamt strlcpy(p->domainname, domainname, sizeof(p->domainname)); 144 1.10 yamt __bindings = p; 145 1.10 yamt } 146 1.1 itojun 147 1.10 yamt return p; 148 1.1 itojun } 149