10Sstevel@tonic-gate /*
20Sstevel@tonic-gate * CDDL HEADER START
30Sstevel@tonic-gate *
40Sstevel@tonic-gate * The contents of this file are subject to the terms of the
5*6812Sraf * Common Development and Distribution License (the "License").
6*6812Sraf * You may not use this file except in compliance with the License.
70Sstevel@tonic-gate *
80Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
90Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
100Sstevel@tonic-gate * See the License for the specific language governing permissions
110Sstevel@tonic-gate * and limitations under the License.
120Sstevel@tonic-gate *
130Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
140Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
150Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
160Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
170Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
180Sstevel@tonic-gate *
190Sstevel@tonic-gate * CDDL HEADER END
200Sstevel@tonic-gate */
21*6812Sraf
220Sstevel@tonic-gate /*
23*6812Sraf * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
240Sstevel@tonic-gate * Use is subject to license terms.
250Sstevel@tonic-gate */
260Sstevel@tonic-gate
270Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI"
280Sstevel@tonic-gate
290Sstevel@tonic-gate /*
300Sstevel@tonic-gate * catgets.c
310Sstevel@tonic-gate */
320Sstevel@tonic-gate
33*6812Sraf #pragma weak _catgets = catgets
340Sstevel@tonic-gate
35*6812Sraf #include "lint.h"
360Sstevel@tonic-gate #include <sys/types.h>
370Sstevel@tonic-gate #include <nl_types.h>
380Sstevel@tonic-gate #include <errno.h>
390Sstevel@tonic-gate #include "nlspath_checks.h"
400Sstevel@tonic-gate
410Sstevel@tonic-gate char *
catgets(nl_catd catd_st,int set_id,int msg_id,const char * def_str)42*6812Sraf catgets(nl_catd catd_st, int set_id, int msg_id, const char *def_str)
430Sstevel@tonic-gate {
440Sstevel@tonic-gate int hi, lo, mid;
450Sstevel@tonic-gate struct _cat_hdr *p;
460Sstevel@tonic-gate struct _cat_set_hdr *q;
470Sstevel@tonic-gate struct _cat_msg_hdr *r;
480Sstevel@tonic-gate void *catd;
490Sstevel@tonic-gate
500Sstevel@tonic-gate if ((catd_st == NULL) || (catd_st == (nl_catd)-1)) {
510Sstevel@tonic-gate /* invalid message catalog descriptor */
520Sstevel@tonic-gate errno = EBADF;
530Sstevel@tonic-gate return ((char *)def_str);
540Sstevel@tonic-gate }
550Sstevel@tonic-gate
560Sstevel@tonic-gate if ((catd_st->__content == NULL) &&
57*6812Sraf (catd_st->__size == 0) && (catd_st->__trust == 1)) {
580Sstevel@tonic-gate /* special message catalog descriptor for C locale */
590Sstevel@tonic-gate return ((char *)def_str);
600Sstevel@tonic-gate } else if ((catd_st->__content == NULL) || (catd_st->__size == 0)) {
610Sstevel@tonic-gate /* invalid message catalog descriptor */
620Sstevel@tonic-gate errno = EBADF;
630Sstevel@tonic-gate return ((char *)def_str);
640Sstevel@tonic-gate }
650Sstevel@tonic-gate
660Sstevel@tonic-gate catd = catd_st->__content;
670Sstevel@tonic-gate p = (struct _cat_hdr *)catd_st->__content;
680Sstevel@tonic-gate hi = p->__nsets - 1;
690Sstevel@tonic-gate lo = 0;
700Sstevel@tonic-gate /*
710Sstevel@tonic-gate * Two while loops will perform binary search.
720Sstevel@tonic-gate * Outer loop searches the set and inner loop searches
730Sstevel@tonic-gate * message id
740Sstevel@tonic-gate */
750Sstevel@tonic-gate while (hi >= lo) {
760Sstevel@tonic-gate mid = (hi + lo) / 2;
770Sstevel@tonic-gate q = (struct _cat_set_hdr *)
78*6812Sraf ((uintptr_t)catd
79*6812Sraf + _CAT_HDR_SIZE
80*6812Sraf + _CAT_SET_HDR_SIZE * mid);
810Sstevel@tonic-gate if (q->__set_no == set_id) {
820Sstevel@tonic-gate lo = q->__first_msg_hdr;
830Sstevel@tonic-gate hi = lo + q->__nmsgs - 1;
840Sstevel@tonic-gate while (hi >= lo) {
850Sstevel@tonic-gate mid = (hi + lo) / 2;
860Sstevel@tonic-gate r = (struct _cat_msg_hdr *)
87*6812Sraf ((uintptr_t)catd
88*6812Sraf + _CAT_HDR_SIZE
89*6812Sraf + p->__msg_hdr_offset
90*6812Sraf + _CAT_MSG_HDR_SIZE * mid);
910Sstevel@tonic-gate if (r->__msg_no == msg_id) {
920Sstevel@tonic-gate char *msg = (char *)catd
93*6812Sraf + _CAT_HDR_SIZE
94*6812Sraf + p->__msg_text_offset
95*6812Sraf + r->__msg_offset;
960Sstevel@tonic-gate
970Sstevel@tonic-gate if (!catd_st->__trust) {
98*6812Sraf int errno_save = errno;
99*6812Sraf char *cmsg = check_format(
100*6812Sraf def_str, msg, 0);
1010Sstevel@tonic-gate if (cmsg == def_str) {
1020Sstevel@tonic-gate /* security */
1030Sstevel@tonic-gate return ((char *)
104*6812Sraf def_str);
1050Sstevel@tonic-gate } else {
1060Sstevel@tonic-gate errno = errno_save;
1070Sstevel@tonic-gate return (msg);
1080Sstevel@tonic-gate }
1090Sstevel@tonic-gate } else {
1100Sstevel@tonic-gate return (msg);
1110Sstevel@tonic-gate }
1120Sstevel@tonic-gate } else if (r->__msg_no < msg_id)
1130Sstevel@tonic-gate lo = mid + 1;
1140Sstevel@tonic-gate else
1150Sstevel@tonic-gate hi = mid - 1;
1160Sstevel@tonic-gate } /* while */
1170Sstevel@tonic-gate
1180Sstevel@tonic-gate /* In case set number not found */
1190Sstevel@tonic-gate errno = ENOMSG;
1200Sstevel@tonic-gate return ((char *)def_str);
1210Sstevel@tonic-gate } else if (q->__set_no < set_id)
1220Sstevel@tonic-gate lo = mid + 1;
1230Sstevel@tonic-gate else
1240Sstevel@tonic-gate hi = mid - 1;
1250Sstevel@tonic-gate } /* while */
1260Sstevel@tonic-gate
1270Sstevel@tonic-gate /* In case msg_id not found. */
1280Sstevel@tonic-gate errno = ENOMSG;
1290Sstevel@tonic-gate return ((char *)def_str);
1300Sstevel@tonic-gate }
131