1 /* $NetBSD: msgcat.c,v 1.2 2024/08/18 20:47:15 christos Exp $ */ 2 3 /* 4 * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") 5 * Copyright (C) 1999-2001 Internet Software Consortium. 6 * 7 * Permission to use, copy, modify, and/or distribute this software for any 8 * purpose with or without fee is hereby granted, provided that the above 9 * copyright notice and this permission notice appear in all copies. 10 * 11 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH 12 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 13 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, 14 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 15 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 16 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 17 * PERFORMANCE OF THIS SOFTWARE. 18 */ 19 20 /* Id: msgcat.c,v 1.18 2007/06/19 23:47:18 tbox Exp */ 21 22 /*! \file msgcat.c 23 * 24 * \author Principal Author: Bob Halley 25 */ 26 27 #include <config.h> 28 29 #include <stddef.h> 30 #include <stdlib.h> 31 32 #include <isc/magic.h> 33 #include <isc/msgcat.h> 34 #include <isc/util.h> 35 36 #ifdef HAVE_CATGETS 37 #include <nl_types.h> /* Required for nl_catd. */ 38 #endif 39 40 /* 41 * Implementation Notes: 42 * 43 * We use malloc() and free() instead of isc_mem_get() and isc_mem_put() 44 * because we don't want to require a memory context to be specified 45 * in order to use a message catalog. 46 */ 47 48 struct isc_msgcat { 49 unsigned int magic; 50 #ifdef HAVE_CATGETS 51 nl_catd catalog; 52 #endif 53 }; 54 55 #define MSGCAT_MAGIC ISC_MAGIC('M', 'C', 'a', 't') 56 #define VALID_MSGCAT(m) ISC_MAGIC_VALID(m, MSGCAT_MAGIC) 57 58 void 59 isc_msgcat_open(const char *name, isc_msgcat_t **msgcatp) { 60 isc_msgcat_t *msgcat; 61 62 /* 63 * Open a message catalog. 64 */ 65 66 REQUIRE(name != NULL); 67 REQUIRE(msgcatp != NULL && *msgcatp == NULL); 68 69 msgcat = malloc(sizeof(*msgcat)); 70 if (msgcat == NULL) { 71 *msgcatp = NULL; 72 return; 73 } 74 75 #ifdef HAVE_CATGETS 76 /* 77 * We don't check if catopen() fails because we don't care. 78 * If it does fail, then when we call catgets(), it will use 79 * the default string. 80 */ 81 msgcat->catalog = catopen(name, 0); 82 #endif 83 msgcat->magic = MSGCAT_MAGIC; 84 85 *msgcatp = msgcat; 86 } 87 88 void 89 isc_msgcat_close(isc_msgcat_t **msgcatp) { 90 isc_msgcat_t *msgcat; 91 92 /* 93 * Close a message catalog. 94 */ 95 96 REQUIRE(msgcatp != NULL); 97 msgcat = *msgcatp; 98 REQUIRE(VALID_MSGCAT(msgcat) || msgcat == NULL); 99 100 if (msgcat != NULL) { 101 #ifdef HAVE_CATGETS 102 if (msgcat->catalog != (nl_catd)(-1)) 103 (void)catclose(msgcat->catalog); 104 #endif 105 msgcat->magic = 0; 106 free(msgcat); 107 } 108 109 *msgcatp = NULL; 110 } 111 112 const char * 113 isc_msgcat_get(isc_msgcat_t *msgcat, int set, int message, 114 const char *default_text) 115 { 116 /* 117 * Get message 'message' from message set 'set' in 'msgcat'. If it 118 * is not available, use 'default'. 119 */ 120 121 REQUIRE(VALID_MSGCAT(msgcat) || msgcat == NULL); 122 REQUIRE(set > 0); 123 REQUIRE(message > 0); 124 REQUIRE(default_text != NULL); 125 126 #ifdef HAVE_CATGETS 127 if (msgcat == NULL) 128 return (default_text); 129 return (catgets(msgcat->catalog, set, message, default_text)); 130 #else 131 return (default_text); 132 #endif 133 } 134