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#include "config.h"
78#include <ctype.h>
79#include <commonp.h>
80#include <string.h>
81#include <rpcsvc.h>
82#include <stdarg.h>
83
84#if HAVE_CRASHREPORTERCLIENT_H
85
86#include <CrashReporterClient.h>
87
88#elif defined(__APPLE__)
89
90/*
91 * The following symbol is reference by Crash Reporter symbolicly
92 * (instead of through undefined references. To get strip(1) to know
93 * this symbol is not to be stripped it needs to have the
94 * REFERENCED_DYNAMICALLY bit (0x10) set.  This would have been done
95 * automaticly by ld(1) if this symbol were referenced through undefined
96 * symbols.
97 *
98 * NOTE: this is an unsupported interface and the CrashReporter team reserve
99 * the right to change it at any time.
100 */
101char *__crashreporter_info__ = NULL;
102asm(".desc ___crashreporter_info__, 0x10");
103
104#define CRSetCrashLogMessage(msg) do { \
105    __crashreporter_info__ = (msg); \
106} while (0)
107
108#else
109
110/* No CrashReporter support, spit it out to stderr and hope someone is
111 * watching.
112 */
113#define CRSetCrashLogMessage(msg) do { \
114    write(STDERR_FILENO, strlen(msg), msg); \
115} while (0)
116
117#endif
118
119/*
120dce_svc_handle_t rpc_g_svc_handle;
121*/
122//DCE_SVC_DEFINE_HANDLE(rpc_g_svc_handle, rpc_g_svc_table, "rpc")
123
124//#define RPC_DCE_SVC_PRINTF(args) rpc_dce_svc_printf(args)
125
126void rpc_dce_svc_printf (
127                        const char* file,
128                        unsigned int line,
129                        const char *format,
130                        unsigned32 dbg_switch ATTRIBUTE_UNUSED,
131                        unsigned32 sev_action_flags,
132                        unsigned32 error_code,
133                        ... )
134{
135    char buff[1024];
136    char *s = buff;
137    size_t remain = sizeof(buff);
138    va_list arg_ptr;
139    int cs;
140
141    snprintf (s, remain, "[file %s, line %d] ", file, line);
142    s = &buff[strlen(buff)];
143    remain = sizeof(buff) - (s - buff);
144
145    snprintf (s, remain, "[flags: 0x%x] ", (unsigned int) sev_action_flags);
146    s = &buff[strlen(buff)];
147    remain = sizeof(buff) - (s - buff);
148
149    snprintf (s, remain, "[error: 0x%x] ", (unsigned int) error_code);
150    s = &buff[strlen(buff)];
151    remain = sizeof(buff) - (s - buff);
152
153    va_start (arg_ptr, error_code);
154    vsnprintf (s, remain, format, arg_ptr);
155    va_end (arg_ptr);
156
157    if ( (sev_action_flags & svc_c_action_abort) ||
158        (sev_action_flags & svc_c_action_exit_bad) )
159    {
160        CRSetCrashLogMessage(buff);
161        abort();
162    }
163    else
164    {
165        cs = dcethread_enableinterrupt_throw(0);
166        dcethread_write (2, buff, strlen (buff));
167        dcethread_enableinterrupt_throw(cs);
168    }
169}
170
171#if 0
172/*
173 * R P C _ _ S V C _ E P R I N T F
174 *
175 * Format and print arguments as a serviceability
176 * debug message.
177 */
178
179PRIVATE int rpc__svc_eprintf ( char *fmt, ... )
180{
181    char	buf[RPC__SVC_DBG_MSG_SZ];
182    va_list	arg_ptr;
183
184    va_start (arg_ptr, fmt);
185    vsprintf (buf, fmt, arg_ptr);
186    va_end (arg_ptr);
187    DCE_SVC_DEBUG((RPC__SVC_HANDLE, rpc_svc_general, RPC__SVC_DBG_LEVEL(0), buf));
188    return(0);
189}
190
191
192/*
193 * R P C _ _ S V C _ I N I T
194 *
195 * Do initialization required for serviceability
196 */
197
198PRIVATE void rpc__svc_init ( void )
199{
200    error_status_t status;
201
202    /*
203     * Currently, all we have to do is return, since
204     * everything is statically registered.
205     *
206     * But someday we might do something like turn
207     * on debug levels corresponding to things set
208     * in rpc_g_dbg_switches[], or ...
209     */
210
211    /*
212     * This silliness is a placeholder, so that we
213     * remember to do things differently in the kernel
214     * if we ever decide to do more than just return
215     * out of this routine.
216     */
217    return;
218}
219
220/*
221 * R P C _ _ S V C _ F M T _ D B G _ M S G
222 *
223 * This routine takes the printf "pargs" passed to
224 * the RPC_DBG_PRINTF() macro and formats them
225 * into a string that can be handed to DCE_SVC_DEBUG.
226 *
227 * This is necessary because the pargs are passed
228 * in as a single, parenthesized argument -- which
229 * also requires that the resulting string be passed
230 * back as a pointer return value.
231 *
232 * The returned pointer must be free()'ed by the
233 * caller (see comments at malloc() below).  This
234 * should be fairly safe, since this routine should
235 * only ever be called by RPC_DBG_PRINTF.
236 */
237
238PRIVATE char * rpc__svc_fmt_dbg_msg (char *format, ...)
239{
240    char            *bptr;
241    va_list         arg_ptr;
242
243    /*
244     * Using malloc here is ugly but necessary.  The formatted
245     * string must be passed back as a pointer return value.  The
246     * possibility of recursive calls due to evaluation of pargs
247     * (where, e.g., one of the pargs is a call to a routine that
248     * calls RPC_DBG_PRINTF) preclude an implementation using a
249     * mutex to protect a static buffer.  The potential for infinite
250     * recursion precludes allocating memory using internal RPC
251     * interfaces, since those interfaces call RPC_DBG_PRINTF.
252     */
253
254    if( (bptr = malloc(RPC__SVC_DBG_MSG_SZ*sizeof(char))) == NULL )
255    {
256        /* die horribly */
257        abort();
258    }
259
260    va_start (arg_ptr, format);
261    vsprintf (bptr, format, arg_ptr);
262    va_end (arg_ptr);
263
264    return( bptr );
265}
266#endif	/* DEBUG */
267