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 46struct 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 56void 57isc_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 86void 87isc_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 110const char * 111isc_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