1/* 2 * Copyright (c) 2010 Apple Inc. All rights reserved. 3 * 4 * @APPLE_LICENSE_HEADER_START@ 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. Neither the name of Apple Inc. ("Apple") nor the names of its 16 * contributors may be used to endorse or promote products derived from 17 * this software without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY 20 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY 23 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 24 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 26 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 * 30 * Portions of this software have been released under the following terms: 31 * 32 * (c) Copyright 1989-1993 OPEN SOFTWARE FOUNDATION, INC. 33 * (c) Copyright 1989-1993 HEWLETT-PACKARD COMPANY 34 * (c) Copyright 1989-1993 DIGITAL EQUIPMENT CORPORATION 35 * 36 * To anyone who acknowledges that this file is provided "AS IS" 37 * without any express or implied warranty: 38 * permission to use, copy, modify, and distribute this file for any 39 * purpose is hereby granted without fee, provided that the above 40 * copyright notices and this notice appears in all source code copies, 41 * and that none of the names of Open Software Foundation, Inc., Hewlett- 42 * Packard Company or Digital Equipment Corporation be used 43 * in advertising or publicity pertaining to distribution of the software 44 * without specific, written prior permission. Neither Open Software 45 * Foundation, Inc., Hewlett-Packard Company nor Digital 46 * Equipment Corporation makes any representations about the suitability 47 * of this software for any purpose. 48 * 49 * Copyright (c) 2007, Novell, Inc. All rights reserved. 50 * Redistribution and use in source and binary forms, with or without 51 * modification, are permitted provided that the following conditions 52 * are met: 53 * 54 * 1. Redistributions of source code must retain the above copyright 55 * notice, this list of conditions and the following disclaimer. 56 * 2. Redistributions in binary form must reproduce the above copyright 57 * notice, this list of conditions and the following disclaimer in the 58 * documentation and/or other materials provided with the distribution. 59 * 3. Neither the name of Novell Inc. nor the names of its contributors 60 * may be used to endorse or promote products derived from this 61 * this software without specific prior written permission. 62 * 63 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 64 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 65 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 66 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY 67 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 68 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 69 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 70 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 71 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 72 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 73 * 74 * @APPLE_LICENSE_HEADER_END@ 75 */ 76 77/* 78** 79** NAME 80** 81** cs_s_reg.c 82** 83** FACILITY: 84** 85** Remote Procedure Call (RPC) OSF Code Set Registry Access routines 86** 87** ABSTRACT: 88** 89** Code set interoperability requires a common way to recognize the 90** supported code sets for client and server. OSF code set registry 91** provides that functionality. OSF code set registry is a binary file 92** which is produced by 'csrc' (Code set registry compiler). 93** 94*/ 95 96#include <stdio.h> 97#include <stdlib.h> 98#include <dce/rpc.h> 99#include <dce/csrc.h> 100#include <unistd.h> 101#include <fcntl.h> 102#include <commonp.h> 103#include <dce/dce_cf.h> /* Access to the backing store library */ 104#include <langinfo.h> 105 106 107/* 108** Local globals for code set registry access. 109** Code set registry is pointed by rpc_g_codesets_list. 110*/ 111static boolean rpc_g_codesets_did_read; 112static dcethread_mutex rpc_g_codesets_mutex; 113static dcethread_oncectl rpc_g_codesets_once_block = DCETHREAD_ONCE_INIT; 114static entry_t *rpc_g_codesets_list; 115static entry_t *rpc_g_codesets_effective_ids; 116static entry_t **rpc_g_codesets_sort_by_priority; 117static entry_t **rpc_g_codesets_sort_by_name; 118static entry_t **rpc_g_codesets_sort_by_id; 119static int rpc_g_codesets_entry_count; 120static int rpc_g_codesets_effective_count; 121static error_status_t rpc_g_codesets_status; 122 123/* 124** 125** Iterative Insertion Sort for code set name. 126** 127*/ 128PRIVATE 129void name_sort 130( 131 entry_t **codesets, 132 int entry_count 133) 134{ 135 int i, j, k; 136 entry_t *temp; 137 138 if (entry_count <= 1) 139 return; 140 141 for (i = 1; i < entry_count; i++) 142 { 143 temp = codesets[i]; 144 j = i - 1; 145 while (j >= 0) 146 { 147 if ((k = strcoll(codesets[j]->code_set_name, (const char *)temp->code_set_name)) > 0) 148 { 149 codesets[j + 1] = codesets[j]; 150 codesets[j] = temp; 151 } 152 j--; 153 } 154 } 155} 156 157/* 158** 159** Iterative Insertion Sort for priority 160** 161*/ 162PRIVATE 163void priority_sort 164( 165 entry_t **codesets, 166 int entry_count 167) 168{ 169 int i, j, k; 170 entry_t *temp; 171 172 if (entry_count <= 1) 173 return; 174 175 for (i = 1; i < entry_count; i++) 176 { 177 temp = codesets[i]; 178 j = i - 1; 179 while (j >= 0) 180 { 181 if (codesets[j]->priority > temp->priority) 182 { 183 codesets[j + 1] = codesets[j]; 184 codesets[j] = temp; 185 } 186 j--; 187 } 188 } 189} 190 191/* 192** 193** Binary Search for code set value 194** 195*/ 196PRIVATE 197void c_binary_search 198( 199 entry_t **codesets, 200 int low, 201 int high, 202 long key_value, 203 entry_t **code_entry 204) 205{ 206 int middle; 207 long code1, code2; 208 209 if (key_value < 0) /* little trick for large number */ 210 code1 = key_value * -1; 211 else 212 code1 = key_value; 213 214 if (low <= high) 215 { 216 middle = (low + high) / 2; 217 218 if (codesets[middle]->code_set < 0) 219 code2 = codesets[middle]->code_set * -1; 220 else 221 code2 = codesets[middle]->code_set; 222 223 if (code1 == code2) 224 { 225 *code_entry = codesets[middle]; 226 return; 227 } 228 else 229 { 230 if (code1 < code2) 231 c_binary_search(codesets, low, middle-1, key_value, code_entry); 232 else 233 c_binary_search(codesets, middle+1, high, key_value, code_entry); 234 } 235 } 236} 237 238/* 239** 240** Binary Search for code set name 241** 242*/ 243PRIVATE 244void n_binary_search 245( 246 entry_t **codesets, 247 int low, 248 int high, 249 char *key_name, 250 entry_t **code_entry 251) 252{ 253 int middle, k; 254 255 if (low <= high) 256 { 257 middle = (low + high) / 2; 258 259 if ((k = strcoll(key_name, codesets[middle]->code_set_name)) == 0) 260 { 261 *code_entry = codesets[middle]; 262 return; 263 } 264 else 265 { 266 if (k < 0) 267 n_binary_search(codesets, low, middle-1, key_name, code_entry); 268 else 269 n_binary_search(codesets, middle+1, high, key_name, code_entry); 270 } 271 } 272} 273 274 275/* 276**++ 277** ROUTINE NAME: rpc__codesets_really_read_file 278** 279** SCOPE: PRIVATE 280** 281** DESCRIPTION: 282** 283** Internal routine to read OSF code set registry data into a memory. 284** To avoid the unnecessary overhead, this routine only read the code set 285** registry data once, when code set registry is first accessed. 286** This function takes no arguments and returns no data. 287** 288**-- 289*/ 290PRIVATE 291rpc__codesets_really_read_file 292( 293 void 294) 295{ 296 int i, j, k; 297 entry_t *ep; 298 entry_t *effective_ep; 299 int CsrFile; 300 char *code_set_registry_file; 301 302 /* 303 ** Open the code set registry file. The default path is 304 ** "/usr/lib/nls/csr/code_set_registry.db" 305 */ 306 dce_cf_get_csrgy_filename(&code_set_registry_file, &rpc_g_codesets_status); 307 if (rpc_g_codesets_status != dce_cf_st_ok) 308 { 309 return; 310 } 311 312 CsrFile = open(code_set_registry_file, O_RDONLY, 0); 313 free (code_set_registry_file); 314 if (CsrFile == -1) 315 { 316 rpc_g_codesets_status = dce_cs_c_cannot_open_file; 317 return; 318 } 319 320 if ((read (CsrFile, (char *)(&rpc_g_codesets_entry_count), sizeof(rpc_g_codesets_entry_count))) == -1) 321 { 322 rpc_g_codesets_status = dce_cs_c_cannot_read_file; 323 return; 324 } 325 326 if ((read (CsrFile, (char *)(&rpc_g_codesets_effective_count), sizeof(rpc_g_codesets_entry_count))) == -1) 327 { 328 rpc_g_codesets_status = dce_cs_c_cannot_read_file; 329 return; 330 } 331 332 if ((rpc_g_codesets_list = (entry_t *)malloc(sizeof(entry_t) * rpc_g_codesets_entry_count)) == NULL) 333 { 334 rpc_g_codesets_status = dce_cs_c_cannot_allocate_memory; 335 return; 336 } 337 338 if ((rpc_g_codesets_effective_ids = (entry_t *)malloc(sizeof(entry_t) * rpc_g_codesets_effective_count)) == NULL) 339 { 340 rpc_g_codesets_status = dce_cs_c_cannot_allocate_memory; 341 return; 342 } 343 344 ep = rpc_g_codesets_list; 345 i = rpc_g_codesets_entry_count; 346 effective_ep = rpc_g_codesets_effective_ids; 347 348 while (i--) 349 { 350 if ((read (CsrFile, (char *)(&ep->code_set), sizeof(ep->code_set))) == -1) 351 { 352 rpc_g_codesets_status = dce_cs_c_cannot_read_file; 353 return; 354 } 355 356 if ((read (CsrFile, (char *)(&ep->code_name_len), sizeof(ep->code_name_len))) == -1) 357 { 358 rpc_g_codesets_status = dce_cs_c_cannot_read_file; 359 return; 360 } 361 362 if ((ep->code_set_name = (char *)malloc(ep->code_name_len + 1)) == NULL) 363 { 364 rpc_g_codesets_status = dce_cs_c_cannot_allocate_memory; 365 return; 366 } 367 368 if ((read (CsrFile, (char *)ep->code_set_name, ep->code_name_len + 1)) == -1) 369 { 370 rpc_g_codesets_status = dce_cs_c_cannot_read_file; 371 return; 372 } 373 374 if ((read (CsrFile, (char *)(&ep->char_sets_num), sizeof(ep->char_sets_num))) == -1) 375 { 376 rpc_g_codesets_status = dce_cs_c_cannot_read_file; 377 return; 378 } 379 380 for (j = 0; j < ep->char_sets_num; j++) 381 { 382 if ((read (CsrFile, (char *)(&ep->char_sets[j]), sizeof(ep->char_sets[j]))) == -1) 383 { 384 rpc_g_codesets_status = dce_cs_c_cannot_read_file; 385 return; 386 } 387 } 388 389 if ((read (CsrFile, (char *)(&ep->max_bytes), sizeof(ep->max_bytes))) == -1) 390 { 391 rpc_g_codesets_status = dce_cs_c_cannot_read_file; 392 return; 393 } 394 395 if ((read (CsrFile, (char *)(&ep->priority), sizeof(ep->priority))) == -1) 396 { 397 rpc_g_codesets_status = dce_cs_c_cannot_read_file; 398 return; 399 } 400 401 if ((k = strcoll(ep->code_set_name, "NONE")) != 0) 402 { 403 effective_ep->code_set = ep->code_set; 404 effective_ep->code_name_len = ep->code_name_len; 405 effective_ep->code_set_name = ep->code_set_name; 406 effective_ep->char_sets_num = ep->char_sets_num; 407 for (j = 0; j < ep->char_sets_num; j++) 408 effective_ep->char_sets[j] = ep->char_sets[j]; 409 effective_ep->max_bytes = ep->max_bytes; 410 effective_ep->priority = ep->priority; 411 412 effective_ep++; 413 } 414 415 ep++; 416 } 417 418 close (CsrFile); 419 420 rpc_g_codesets_status = rpc_s_ok; 421 422 rpc_g_codesets_did_read = TRUE; 423} 424 425/* 426**++ 427** ROUTINE NAME: rpc__codesets_read_registry_file 428** 429** SCOPE: PRIVATE 430** 431** DESCRIPTION: 432** 433** Internal routine to allocate OSF code set registry data into a memory. 434** rpc__codesets_really_read_file() is called to actually perform 435** reading data from a registry file. Code set registry is sorted by 436** code set id and code set name. Local global pointers point to each 437** sorted memory. 438** 439**-- 440*/ 441PRIVATE 442rpc__codesets_read_registry_file 443( 444 error_status_t *status 445) 446{ 447 entry_t **sort_name_codesets; 448 entry_t **sort_name_save; 449 entry_t **sort_id_codesets; 450 entry_t **sort_id_save; 451 entry_t **sort_priority_codesets; 452 entry_t **sort_priority_save; 453 int i; 454 entry_t *ep; 455 456 if (!rpc_g_codesets_did_read) 457 { 458 dcethread_once_throw(&rpc_g_codesets_once_block, 459 (dcethread_initroutine)rpc__codesets_really_read_file); 460 461 if (rpc_g_codesets_status != rpc_s_ok) 462 { 463 *status = rpc_g_codesets_status; 464 return; 465 } 466 } 467 468 /* 469 ** Sort the code set registry file by code set name 470 **/ 471 if ((sort_name_save = (entry_t **)malloc(sizeof(entry_t *) * rpc_g_codesets_entry_count)) == NULL) 472 { 473 *status = dce_cs_c_cannot_allocate_memory; 474 return; 475 } 476 477 ep = rpc_g_codesets_list; 478 i = rpc_g_codesets_entry_count; 479 sort_name_codesets = sort_name_save; 480 while (i--) 481 { 482 *sort_name_codesets++ = ep++; 483 } 484 rpc_g_codesets_sort_by_name = sort_name_save; 485 sort_name_codesets = sort_name_save; 486 name_sort(sort_name_codesets, rpc_g_codesets_entry_count); 487 488 /* 489 ** Sort the effective code set by priority 490 **/ 491 if ((sort_priority_save = (entry_t **)malloc(sizeof(entry_t *) * rpc_g_codesets_effective_count)) == NULL) 492 { 493 *status = dce_cs_c_cannot_allocate_memory; 494 return; 495 } 496 ep = rpc_g_codesets_effective_ids; 497 i = rpc_g_codesets_effective_count; 498 sort_priority_codesets = sort_priority_save; 499 while (i--) 500 { 501 *sort_priority_codesets++ = ep++; 502 } 503 rpc_g_codesets_sort_by_priority = sort_priority_save; 504 sort_priority_codesets = sort_priority_save; 505 priority_sort(sort_priority_codesets, rpc_g_codesets_effective_count); 506 507 /* 508 ** Allocate an array for pointers to entry_t. Code set registry 509 ** is already sorted by code set id value. 510 */ 511 if ((sort_id_save = (entry_t **)malloc(sizeof(entry_t *) * rpc_g_codesets_entry_count)) == NULL) 512 { 513 *status = dce_cs_c_cannot_allocate_memory; 514 return; 515 } 516 ep = rpc_g_codesets_list; 517 i = rpc_g_codesets_entry_count; 518 sort_id_codesets = sort_id_save; 519 while (i--) 520 { 521 *sort_id_codesets++ = ep++; 522 } 523 rpc_g_codesets_sort_by_id = sort_id_save; 524 525 *status = rpc_s_ok; 526 527} 528 529 530/* 531**++ 532** ROUTINE NAME: dce_cs_loc_to_rgy 533** 534** SCOPE: PUBLIC - declared in rpc.idl 535** 536** DESCRIPTION: 537** 538** Convert code set name (in string) to code set id (integer). 539** When rgy_char_sets_number is NULL, no character sets values 540** will be returned. Character sets are mainly used to evaluate 541** code set compatibility. 542** 543** INPUTS: 544** 545** local_code_set_name OS specific name for the code set 546** 547** 548** INPUT/OUPUTS: NONE 549** 550** 551** OUTPUTS: 552** 553** rgy_code_set_value Registerd code set id 554** 555** rgy_char_sets_number Number of character sets supported by 556** the code set 557** 558** rgy_char_sets_value Array of character set IDs supported by 559** the code set 560** 561** status The result of the operation. One of: 562** dce_cs_c_ok 563** dce_cs_c_notfound 564** dce_cs_c_cannot_allocate_memory 565** status from rpc__codesets_read_registry_file 566** 567** IMPLICIT INPUTS: none 568** 569** IMPLICIT OUTPUTS: none 570** 571** FUNCTION VALUE: void 572** 573** SIDE EFFECTS: none 574** 575**-- 576*/ 577 578PUBLIC 579void dce_cs_loc_to_rgy 580( 581 idl_char *local_code_set_name, 582 unsigned32 *rgy_code_set_value, 583 unsigned16 *rgy_char_sets_number, 584 unsigned16 **rgy_char_sets_value, 585 error_status_t *status 586) 587{ 588 entry_t **epp; 589 entry_t *found = NULL; 590 int i; 591 unsigned16 *char_array; 592 593 CODING_ERROR (status); 594 595 rpc__codesets_read_registry_file(status); 596 if (*status != rpc_s_ok) 597 { 598 return; 599 } 600 601 epp = rpc_g_codesets_sort_by_name; 602 603 /* binary search */ 604 n_binary_search(epp, 0, rpc_g_codesets_entry_count-1, (char *)local_code_set_name, &found); 605 606 if (found == NULL) 607 { 608 *status = dce_cs_c_unknown; 609 return; 610 } 611 612 if (rgy_char_sets_number != NULL) 613 { 614 *rgy_char_sets_number = found->char_sets_num; 615 } 616 617 if (rgy_char_sets_value != NULL) 618 { 619 if ((char_array = (unsigned16 *)malloc(sizeof(unsigned16) * found->char_sets_num)) == NULL) 620 { 621 *status = dce_cs_c_cannot_allocate_memory; 622 return; 623 } 624 625 *rgy_char_sets_value = char_array; 626 627 for (i = 0; i < found->char_sets_num; i++) 628 { 629 *char_array++ = found->char_sets[i]; 630 } 631 } 632 *rgy_code_set_value = (unsigned32)found->code_set; 633 634 *status = dce_cs_c_ok; 635 return; 636} 637 638 639/* 640**++ 641** ROUTINE NAME: dce_cs_rgy_to_loc 642** 643** SCOPE: PUBLIC - declared in rpc.idl 644** 645** DESCRIPTION: 646** 647** Convert code set id (integer) to code set name (in string). 648** When rgy_char_sets_number is NULL, no character sets values 649** will be returned. Character sets are mainly used to evaluate 650** code set compatibility. 651** 652** INPUTS: 653** 654** rgy_code_set_value Registerd code set id 655** 656** 657** INPUT/OUPUTS: NONE 658** 659** 660** OUTPUTS: 661** 662** local_code_set_name OS specific name for the code set 663** 664** rgy_char_sets_number Number of character sets supported by 665** the code set 666** 667** rgy_char_sets_value Array of character set IDs supported by 668** the code set 669** 670** status The result of the operation. One of: 671** dce_cs_c_ok 672** dce_cs_c_notfound 673** dce_cs_c_cannot_allocate_memory 674** status from rpc__codesets_read_registry_file 675** 676** IMPLICIT INPUTS: none 677** 678** IMPLICIT OUTPUTS: none 679** 680** FUNCTION VALUE: void 681** 682** SIDE EFFECTS: none 683** 684**-- 685*/ 686 687PUBLIC 688void dce_cs_rgy_to_loc 689( 690 unsigned32 rgy_code_set_value, 691 idl_char **local_code_set_name, 692 unsigned16 *rgy_char_sets_number, 693 unsigned16 **rgy_char_sets_value, 694 error_status_t *status 695) 696{ 697 entry_t **epp; 698 entry_t *found = NULL; 699 int i; 700 unsigned16 *char_array; 701 702 CODING_ERROR (status); 703 704 rpc__codesets_read_registry_file(status); 705 if (*status != rpc_s_ok) 706 { 707 return; 708 } 709 710 epp = rpc_g_codesets_sort_by_id; 711 i = rpc_g_codesets_entry_count; 712 713 /* binary search */ 714 c_binary_search(epp, 0, rpc_g_codesets_entry_count-1, rgy_code_set_value, &found); 715 716 if (found == NULL) 717 { 718 *status = dce_cs_c_unknown; 719 return; 720 } 721 722 if ((i = strcoll(found->code_set_name, "NONE")) == 0) 723 { 724 *status = dce_cs_c_notfound; 725 return; 726 } 727 728 if (rgy_char_sets_number != NULL) 729 { 730 *rgy_char_sets_number = found->char_sets_num; 731 } 732 733 if (rgy_char_sets_value != NULL) 734 { 735 if ((char_array = (unsigned16 *)malloc(sizeof(unsigned16) * found->char_sets_num)) == NULL) 736 { 737 *status = dce_cs_c_cannot_allocate_memory; 738 return; 739 } 740 741 *rgy_char_sets_value = char_array; 742 743 for (i = 0; i < found->char_sets_num; i++) 744 { 745 *char_array++ = found->char_sets[i]; 746 } 747 } 748 *local_code_set_name = (idl_char *)found->code_set_name; 749 750 *status = dce_cs_c_ok; 751 return; 752} 753 754 755/* 756**++ 757** ROUTINE NAME: rpc_rgy_get_max_bytes 758** 759** SCOPE: PUBLIC - declared in rpc.idl 760** 761** DESCRIPTION: 762** 763** Search maximum number of bytes for a tag specified. The tag 764** is the code set id number from OSF code set registry. 765** This routine is mainly used by a stub to calculate a size of 766** necessary conversion buffer. 767** 768** INPUTS: 769** 770** tag Registerd code set id 771** 772** 773** INPUT/OUPUTS: NONE 774** 775** 776** OUTPUTS: 777** 778** max_bytes Maximum number of bytes needed to encode 779** a character in the code set 780** 781** status The result of the operation. One of: 782** rpc_s_ok 783** dce_cs_c_notfound 784** status from rpc__codesets_read_registry_file 785** 786** IMPLICIT INPUTS: none 787** 788** IMPLICIT OUTPUTS: none 789** 790** FUNCTION VALUE: void 791** 792** SIDE EFFECTS: none 793** 794**-- 795*/ 796 797PUBLIC 798void rpc_rgy_get_max_bytes 799( 800 unsigned32 tag, 801 unsigned16 *max_bytes, 802 error_status_t *status 803) 804{ 805 entry_t **epp; 806 entry_t *found = NULL; 807 int i; 808 unsigned16 *char_array; 809 810 CODING_ERROR (status); 811 812 rpc__codesets_read_registry_file(status); 813 if (*status != rpc_s_ok) 814 { 815 return; 816 } 817 818 epp = rpc_g_codesets_sort_by_id; 819 i = rpc_g_codesets_entry_count; 820 821 /* binary search */ 822 c_binary_search(epp, 0, rpc_g_codesets_entry_count-1, tag, &found); 823 824 if (found == NULL) 825 { 826 *status = dce_cs_c_unknown; 827 return; 828 } 829 830 if ((i = strcoll(found->code_set_name, "NONE")) == 0) 831 { 832 *status = dce_cs_c_notfound; 833 return; 834 } 835 836 *max_bytes = found->max_bytes; 837 838 *status = rpc_s_ok; 839 return; 840} 841 842/* 843**++ 844** ROUTINE NAME: rpc_rgy_get_codesets 845** 846** SCOPE: PUBLIC - declared in rpc.idl 847** 848** DESCRIPTION: 849** 850** This an OS dependent routine. It will determine which code sets 851** are supported by a current machine, and returns a list of code sets. 852** The first code set in a list should be a current locale's code set. 853** 854** 855** INPUTS: none 856** 857** INPUT/OUPUTS: 858** 859** args Actually points to 'rpc_cs_codeset_i14y_data_p' 860** data type. 861** 862** OUTPUTS: none 863** 864** IMPLICIT INPUTS: none 865** 866** IMPLICIT OUTPUTS: none 867** 868** FUNCTION VALUE: void 869** 870** SIDE EFFECTS: none 871** 872**-- 873*/ 874 875PUBLIC 876void rpc_rgy_get_codesets 877( 878 rpc_codeset_mgmt_p_t *codesets_p, 879 error_status_t *status 880) 881{ 882 int i; 883 entry_t **epp; 884 char *current_codeset; 885 unsigned32 current_rgy_codeset; 886 887 CODING_ERROR (status); 888 889 rpc__codesets_read_registry_file(status); 890 if (*status != rpc_s_ok) 891 { 892 return; 893 } 894 895 epp = rpc_g_codesets_sort_by_priority; 896 897 RPC_MEM_ALLOC ( 898 *codesets_p, 899 rpc_codeset_mgmt_p_t, 900 sizeof(rpc_codeset_mgmt_t) + 901 (sizeof(rpc_cs_c_set_t) * (rpc_g_codesets_effective_count - 1)), 902 RPC_C_MEM_CDS_ATTR, 903 RPC_C_MEM_WAITOK); 904 905 (*codesets_p)->count = rpc_g_codesets_effective_count; 906 907 current_codeset = nl_langinfo(CODESET); 908 dce_cs_loc_to_rgy( 909 (unsigned_char_p_t)current_codeset, 910 ¤t_rgy_codeset, 911 NULL, NULL, 912 status); 913 914 if (*status != dce_cs_c_ok) 915 { 916 /* codeset registry error */ 917 *status = rpc_s_ok; 918 return; 919 } 920 921 /* 922 * The top of the list is current locale's code set 923 */ 924 (*codesets_p)->codesets[0].c_set = current_rgy_codeset; 925 926 for (i = 1; i < rpc_g_codesets_effective_count; i++) 927 { 928 /* 929 ** This logic assumes current locale's code set is one of 930 ** the supported code set. It should be. 931 */ 932 if ((*epp)->code_set != (*codesets_p)->codesets[0].c_set) 933 { 934 (*codesets_p)->codesets[i].c_set = (*epp)->code_set; 935 936 (*codesets_p)->codesets[i].c_max_bytes = (*epp)->max_bytes; 937 } 938 else 939 { 940 (*codesets_p)->codesets[0].c_max_bytes = (*epp)->max_bytes; 941 i--; 942 } 943 944 epp++; 945 } 946 947 *status = rpc_s_ok; 948} 949