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 * OSF DCE Version 1.0 79 */ 80/* 81** 82** NAME 83** 84** dce_error.c 85** 86** FACILITY: 87** 88** Distributed Computing Environment (DCE) 89** 90** ABSTRACT: 91** 92** Error status management routines. 93** 94** 95*/ 96 97#if HAVE_CONFIG_H 98#include <config.h> 99#endif 100 101#include <stdio.h> 102#include <stdarg.h> 103#include <string.h> 104#ifdef HAVE_NL_TYPES_H 105#include <nl_types.h> /* public types for NLS (I18N) routines */ 106#else 107#warning Message catalog support disabled 108#endif /* HAVE_NL_TYPES_H */ 109 110#include <dce/dce_error.h> 111 112#define FACILITY_CODE_MASK 0xF0000000 113#define FACILITY_CODE_SHIFT 28 114 115#define COMPONENT_CODE_MASK 0x0FFFF000 116#define COMPONENT_CODE_SHIFT 12 117 118#define STATUS_CODE_MASK 0x00000FFF 119#define STATUS_CODE_SHIFT 0 120 121#define NO_MESSAGE "THIS IS NOT A MESSAGE" 122 123/* 124 * The system-dependant location for the catalog files is defined in sysconf.h 125 */ 126 127#ifndef RPC_DEFAULT_NLSPATH 128#define RPC_DEFAULT_NLSPATH "/usr/lib/nls/msg/en_US.ISO8859-1/%s.cat" 129/* #error Define RPC_DEFAULT_NLSPATH in your sysconf.h file. */ 130#endif 131 132#ifndef RPC_NLS_FORMAT 133#define RPC_NLS_FORMAT "%s.cat" 134#endif 135 136#ifndef MAXPATHLEN 137#define MAXPATHLEN 1024 138#endif 139 140 141/* 142**++ 143** 144** ROUTINE NAME: dce_error_inq_text 145** 146** SCOPE: PUBLIC - declared in dce_error.h 147** 148** DESCRIPTION: 149** 150** Returns a text string in a user provided buffer associated with a given 151** error status code. In the case of errors a text string will also be 152** returned indicating the nature of the error. 153** 154** INPUTS: 155** 156** status_to_convert A DCE error status code to be converted to 157** text form. 158** 159** INPUTS/OUTPUTS: None. 160** 161** OUTPUTS: 162** 163** error_text A user provided buffer to hold the text 164** equivalent of status_to_convert or 165** a message indicating what error occurred. 166** 167** 168** status The result of the operation. One of: 169** 0 - success 170** -1 - failure 171** 172** IMPLICIT INPUTS: none 173** 174** IMPLICIT OUTPUTS: none 175** 176** FUNCTION VALUE: none 177** 178** SIDE EFFECTS: none 179** 180**-- 181**/ 182 183static void dce_get_msg( 184 unsigned long status_to_convert, 185 char *error_text, 186 size_t error_text_len, 187 char *fname, 188 char *cname, 189 int *status) 190{ 191 unsigned short facility_code; 192 unsigned short component_code; 193 unsigned short status_code; 194#ifdef HAVE_NL_TYPES_H 195 nl_catd catd; 196#endif 197 char component_name[4]; 198 const char *facility_name; 199 char filename_prefix[7]; 200 char nls_filename[MAXPATHLEN]; 201 char alt_filename[MAXPATHLEN]; 202 char *message; 203 static const char alphabet[] = "abcdefghijklmnopqrstuvwxyz_0123456789-+@"; 204 static const char *facility_names[] = { 205 "dce", 206 "dfs" 207 }; 208 209 /* 210 * set up output status for future error returns 211 */ 212 if (status != NULL) 213 { 214 *status = -1; 215 } 216 217 /* 218 * check for ok input status 219 */ 220 if (status_to_convert == 0) 221 { 222 if (status != NULL) 223 { 224 *status = 0; 225 } 226 strlcpy ((char *)error_text, "successful completion", error_text_len); 227 return; 228 } 229 230 /* 231 * extract the component, facility and status codes 232 */ 233 facility_code = (status_to_convert & FACILITY_CODE_MASK) 234 >> FACILITY_CODE_SHIFT; 235 236 component_code = (status_to_convert & COMPONENT_CODE_MASK) 237 >> COMPONENT_CODE_SHIFT; 238 239 status_code = (status_to_convert & STATUS_CODE_MASK) 240 >> STATUS_CODE_SHIFT; 241 242 /* 243 * see if this is a recognized facility 244 */ 245 if (facility_code == 0 || facility_code > sizeof (facility_names) / sizeof (char *)) 246 { 247 sprintf ((char *) error_text, "status %08lx (unknown facility)", status_to_convert); 248 return; 249 } 250 251 facility_name = facility_names[facility_code - 1]; 252 253 /* 254 * Convert component name from RAD-50 component code. (Mapping is: 255 * 0 => 'a', ..., 25 => 'z', 26 => '{', 27 => '0', ..., 36 => '9'.) 256 */ 257 258 component_name[3] = 0; 259 component_name[2] = alphabet[component_code % 40]; 260 component_code /= 40; 261 component_name[1] = alphabet[component_code % 40]; 262 component_name[0] = alphabet[component_code / 40]; 263 264 if (fname != NULL) 265 sprintf ((char*) fname, "%3s", facility_name); 266 if (cname != NULL) 267 sprintf ((char*) cname, "%3s", component_name); 268 269 sprintf ((char*) filename_prefix, "%3s%3s", facility_name, component_name); 270 271#if defined(CATALOG_DIR) 272 sprintf ((char*) nls_filename, 273 CATALOG_DIR "/" RPC_NLS_FORMAT, filename_prefix); 274#else 275 sprintf ((char*) nls_filename, RPC_NLS_FORMAT, filename_prefix); 276#endif 277 278 /* 279 * Open the message file 280 */ 281#ifdef HAVE_NL_TYPES_H 282 catd = (nl_catd) catopen (nls_filename, 0); 283 if (catd == (nl_catd) -1) 284 { 285 /* 286 * If we did not succeed in opening message file using NLSPATH, 287 * try to open the message file in a well-known default area 288 */ 289 290 sprintf (alt_filename, 291 RPC_DEFAULT_NLSPATH, 292 filename_prefix); 293 catd = (nl_catd) catopen (alt_filename, 0); 294 295 if (catd == (nl_catd) -1) 296 { 297 sprintf ((char *) error_text, "status %08lx", status_to_convert); 298 return; 299 } 300 } 301 302 /* 303 * try to get the specified message from the file 304 */ 305 message = (char *) catgets (catd, 1, status_code, NO_MESSAGE); 306 307 /* 308 * if everything went well, return the resulting message 309 */ 310 if (strcmp (message, NO_MESSAGE) != 0) 311 { 312 sprintf ((char *) error_text, "%s", message); 313 if (status != NULL) 314 { 315 *status = 0; 316 } 317 } 318 else 319 { 320 sprintf ((char *) error_text, "status %08lx", status_to_convert); 321 } 322 323 catclose (catd); 324#else 325 sprintf ((char *) error_text, "status %08lx", status_to_convert); 326#endif 327} 328void dce_error_inq_text ( 329unsigned long status_to_convert, 330dce_error_string_t error_text, 331int *status 332) 333{ 334 char cname[4]; 335 char fname[4]; 336 337 /* 338 * check for ok input status 339 */ 340 if (status_to_convert == 0) 341 { 342 if (status != NULL) 343 { 344 *status = 0; 345 } 346 strlcpy ((char *)error_text, "successful completion", dce_c_error_string_len); 347 return; 348 } 349 350 dce_get_msg (status_to_convert, (char *)error_text, dce_c_error_string_len, fname, cname, status); 351 strlcat ((char*) error_text, " (", dce_c_error_string_len); 352 strlcat ((char*) error_text, fname, dce_c_error_string_len); 353 strlcat ((char*) error_text, " / ", dce_c_error_string_len); 354 strlcat ((char*) error_text, cname, dce_c_error_string_len); 355 strlcat ((char*) error_text, ")", dce_c_error_string_len); 356} 357 358#if 0 359/* unused functions */ 360int dce_fprintf(FILE *f, unsigned long index, ...) 361{ 362 va_list ap; 363 int st; 364 int i; 365 char format[1024]; 366 367 dce_get_msg(index, format, sizeof (format), NULL, NULL, &st); 368 if (st != 0) return EOF; 369 370 va_start(ap, index); 371 i = vfprintf(f, format, ap); 372 va_end(ap); 373 return i; 374} 375int dce_printf(unsigned long index, ...) 376{ 377 va_list ap; 378 int st; 379 int i; 380 char format[1024]; 381 382 dce_get_msg(index, format, sizeof (format), NULL, NULL, &st); 383 if (st != 0) return EOF; 384 385 va_start(ap, index); 386 i = vfprintf(stdout, format, ap); 387 va_end(ap); 388 return i; 389} 390#endif 391 392#ifdef BUILD_STCODE 393main(int argc, char **argv) 394{ 395 long code; 396 int i; 397 int _; 398 dce_error_string_t message; 399 400 if (argc <= 1) { 401 printf("Usage: stcode {0x<hex status code> | <decimal status code>}\n"); 402 exit(1); 403 } 404 405 for (i=1; i < argc; i++) { 406 if(strncmp(argv[i], "0x", 2) == 0) 407 sscanf(argv[i], "%x", &code); 408 else 409 sscanf(argv[i], "%d", &code); 410 dce_error_inq_text(code, message, &_); 411 printf("%d (decimal), %x (hex): %s\n", code, code, message); 412 } 413} 414#endif 415