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