1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #pragma ident "%Z%%M% %I% %E% SMI" 28 29 /* 30 * catgets.c 31 */ 32 33 #pragma weak _catgets = catgets 34 35 #include "lint.h" 36 #include <sys/types.h> 37 #include <nl_types.h> 38 #include <errno.h> 39 #include "nlspath_checks.h" 40 41 char * 42 catgets(nl_catd catd_st, int set_id, int msg_id, const char *def_str) 43 { 44 int hi, lo, mid; 45 struct _cat_hdr *p; 46 struct _cat_set_hdr *q; 47 struct _cat_msg_hdr *r; 48 void *catd; 49 50 if ((catd_st == NULL) || (catd_st == (nl_catd)-1)) { 51 /* invalid message catalog descriptor */ 52 errno = EBADF; 53 return ((char *)def_str); 54 } 55 56 if ((catd_st->__content == NULL) && 57 (catd_st->__size == 0) && (catd_st->__trust == 1)) { 58 /* special message catalog descriptor for C locale */ 59 return ((char *)def_str); 60 } else if ((catd_st->__content == NULL) || (catd_st->__size == 0)) { 61 /* invalid message catalog descriptor */ 62 errno = EBADF; 63 return ((char *)def_str); 64 } 65 66 catd = catd_st->__content; 67 p = (struct _cat_hdr *)catd_st->__content; 68 hi = p->__nsets - 1; 69 lo = 0; 70 /* 71 * Two while loops will perform binary search. 72 * Outer loop searches the set and inner loop searches 73 * message id 74 */ 75 while (hi >= lo) { 76 mid = (hi + lo) / 2; 77 q = (struct _cat_set_hdr *) 78 ((uintptr_t)catd 79 + _CAT_HDR_SIZE 80 + _CAT_SET_HDR_SIZE * mid); 81 if (q->__set_no == set_id) { 82 lo = q->__first_msg_hdr; 83 hi = lo + q->__nmsgs - 1; 84 while (hi >= lo) { 85 mid = (hi + lo) / 2; 86 r = (struct _cat_msg_hdr *) 87 ((uintptr_t)catd 88 + _CAT_HDR_SIZE 89 + p->__msg_hdr_offset 90 + _CAT_MSG_HDR_SIZE * mid); 91 if (r->__msg_no == msg_id) { 92 char *msg = (char *)catd 93 + _CAT_HDR_SIZE 94 + p->__msg_text_offset 95 + r->__msg_offset; 96 97 if (!catd_st->__trust) { 98 int errno_save = errno; 99 char *cmsg = check_format( 100 def_str, msg, 0); 101 if (cmsg == def_str) { 102 /* security */ 103 return ((char *) 104 def_str); 105 } else { 106 errno = errno_save; 107 return (msg); 108 } 109 } else { 110 return (msg); 111 } 112 } else if (r->__msg_no < msg_id) 113 lo = mid + 1; 114 else 115 hi = mid - 1; 116 } /* while */ 117 118 /* In case set number not found */ 119 errno = ENOMSG; 120 return ((char *)def_str); 121 } else if (q->__set_no < set_id) 122 lo = mid + 1; 123 else 124 hi = mid - 1; 125 } /* while */ 126 127 /* In case msg_id not found. */ 128 errno = ENOMSG; 129 return ((char *)def_str); 130 } 131