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