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 /* 28 * catgets.c 29 */ 30 31 #pragma weak _catgets = catgets 32 33 #include "lint.h" 34 #include <sys/types.h> 35 #include <nl_types.h> 36 #include <errno.h> 37 #include "nlspath_checks.h" 38 39 char * 40 catgets(nl_catd catd_st, int set_id, int msg_id, const char *def_str) 41 { 42 int hi, lo, mid; 43 struct _cat_hdr *p; 44 struct _cat_set_hdr *q; 45 struct _cat_msg_hdr *r; 46 void *catd; 47 48 if ((catd_st == NULL) || (catd_st == (nl_catd)-1)) { 49 /* invalid message catalog descriptor */ 50 errno = EBADF; 51 return ((char *)def_str); 52 } 53 54 if ((catd_st->__content == NULL) && 55 (catd_st->__size == 0) && (catd_st->__trust == 1)) { 56 /* special message catalog descriptor for C locale */ 57 return ((char *)def_str); 58 } else if ((catd_st->__content == NULL) || (catd_st->__size == 0)) { 59 /* invalid message catalog descriptor */ 60 errno = EBADF; 61 return ((char *)def_str); 62 } 63 64 catd = catd_st->__content; 65 p = (struct _cat_hdr *)catd_st->__content; 66 hi = p->__nsets - 1; 67 lo = 0; 68 /* 69 * Two while loops will perform binary search. 70 * Outer loop searches the set and inner loop searches 71 * message id 72 */ 73 while (hi >= lo) { 74 mid = (hi + lo) / 2; 75 q = (struct _cat_set_hdr *) 76 ((uintptr_t)catd 77 + _CAT_HDR_SIZE 78 + _CAT_SET_HDR_SIZE * mid); 79 if (q->__set_no == set_id) { 80 lo = q->__first_msg_hdr; 81 hi = lo + q->__nmsgs - 1; 82 while (hi >= lo) { 83 mid = (hi + lo) / 2; 84 r = (struct _cat_msg_hdr *) 85 ((uintptr_t)catd 86 + _CAT_HDR_SIZE 87 + p->__msg_hdr_offset 88 + _CAT_MSG_HDR_SIZE * mid); 89 if (r->__msg_no == msg_id) { 90 char *msg = (char *)catd 91 + _CAT_HDR_SIZE 92 + p->__msg_text_offset 93 + r->__msg_offset; 94 95 if (!catd_st->__trust) { 96 int errno_save = errno; 97 char *cmsg = check_format( 98 def_str, msg, 0); 99 if (cmsg == def_str) { 100 /* security */ 101 return ((char *) 102 def_str); 103 } else { 104 errno = errno_save; 105 return (msg); 106 } 107 } else { 108 return (msg); 109 } 110 } else if (r->__msg_no < msg_id) 111 lo = mid + 1; 112 else 113 hi = mid - 1; 114 } /* while */ 115 116 /* In case set number not found */ 117 errno = ENOMSG; 118 return ((char *)def_str); 119 } else if (q->__set_no < set_id) 120 lo = mid + 1; 121 else 122 hi = mid - 1; 123 } /* while */ 124 125 /* In case msg_id not found. */ 126 errno = ENOMSG; 127 return ((char *)def_str); 128 } 129