xref: /netbsd-src/lib/libintl/textdomain.c (revision 5297022a794a4f3af98af437e2dd09b27681a478)
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