1/* $NetBSD: msgcat.c,v 1.1.1.1 2009/12/13 16:54:31 kardel 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 48struct 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 58void 59isc_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 88void 89isc_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 112const char * 113isc_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