1168404Spjd/*
2168404Spjd * CDDL HEADER START
3168404Spjd *
4168404Spjd * The contents of this file are subject to the terms of the
5168404Spjd * Common Development and Distribution License, Version 1.0 only
6168404Spjd * (the "License").  You may not use this file except in compliance
7168404Spjd * with the License.
8168404Spjd *
9168404Spjd * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10168404Spjd * or http://www.opensolaris.org/os/licensing.
11168404Spjd * See the License for the specific language governing permissions
12168404Spjd * and limitations under the License.
13168404Spjd *
14168404Spjd * When distributing Covered Code, include this CDDL HEADER in each
15168404Spjd * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16168404Spjd * If applicable, add the following below this CDDL HEADER, with the
17168404Spjd * fields enclosed by brackets "[]" replaced with your own identifying
18168404Spjd * information: Portions Copyright [yyyy] [name of copyright owner]
19168404Spjd *
20168404Spjd * CDDL HEADER END
21168404Spjd */
22168404Spjd/*
23168404Spjd * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
24168404Spjd * Use is subject to license terms.
25168404Spjd */
26168404Spjd
27168404Spjd#pragma ident	"%Z%%M%	%I%	%E% SMI"
28168404Spjd
29168404Spjd#include "libuutil_common.h"
30168404Spjd
31168404Spjd#include <libintl.h>
32168404Spjd#include <limits.h>
33168404Spjd#include <string.h>
34168404Spjd#include <stdlib.h>
35168404Spjd#include <stdarg.h>
36168404Spjd#include <stdio.h>
37168404Spjd#include <errno.h>
38168404Spjd#include <wchar.h>
39168404Spjd#include <unistd.h>
40168404Spjd
41168404Spjdstatic const char PNAME_FMT[] = "%s: ";
42168404Spjdstatic const char ERRNO_FMT[] = ": %s\n";
43168404Spjd
44168404Spjdstatic const char *pname;
45168404Spjd
46168404Spjdstatic void
47168404Spjduu_die_internal(int status, const char *format, va_list alist) __NORETURN;
48168404Spjd
49168404Spjdint uu_exit_ok_value = EXIT_SUCCESS;
50168404Spjdint uu_exit_fatal_value = EXIT_FAILURE;
51168404Spjdint uu_exit_usage_value = 2;
52168404Spjd
53168404Spjdint *
54168404Spjduu_exit_ok(void)
55168404Spjd{
56168404Spjd	return (&uu_exit_ok_value);
57168404Spjd}
58168404Spjd
59168404Spjdint *
60168404Spjduu_exit_fatal(void)
61168404Spjd{
62168404Spjd	return (&uu_exit_fatal_value);
63168404Spjd}
64168404Spjd
65168404Spjdint *
66168404Spjduu_exit_usage(void)
67168404Spjd{
68168404Spjd	return (&uu_exit_usage_value);
69168404Spjd}
70168404Spjd
71168404Spjdvoid
72168404Spjduu_alt_exit(int profile)
73168404Spjd{
74168404Spjd	switch (profile) {
75168404Spjd	case UU_PROFILE_DEFAULT:
76168404Spjd		uu_exit_ok_value = EXIT_SUCCESS;
77168404Spjd		uu_exit_fatal_value = EXIT_FAILURE;
78168404Spjd		uu_exit_usage_value = 2;
79168404Spjd		break;
80168404Spjd	case UU_PROFILE_LAUNCHER:
81168404Spjd		uu_exit_ok_value = EXIT_SUCCESS;
82168404Spjd		uu_exit_fatal_value = 124;
83168404Spjd		uu_exit_usage_value = 125;
84168404Spjd		break;
85168404Spjd	}
86168404Spjd}
87168404Spjd
88168404Spjdstatic void
89168404Spjduu_warn_internal(int err, const char *format, va_list alist)
90168404Spjd{
91168404Spjd	if (pname != NULL)
92168404Spjd		(void) fprintf(stderr, PNAME_FMT, pname);
93168404Spjd
94168404Spjd	(void) vfprintf(stderr, format, alist);
95168404Spjd
96168404Spjd	if (strrchr(format, '\n') == NULL)
97168404Spjd		(void) fprintf(stderr, ERRNO_FMT, strerror(err));
98168404Spjd}
99168404Spjd
100168404Spjdvoid
101168404Spjduu_vwarn(const char *format, va_list alist)
102168404Spjd{
103168404Spjd	uu_warn_internal(errno, format, alist);
104168404Spjd}
105168404Spjd
106168404Spjd/*PRINTFLIKE1*/
107168404Spjdvoid
108168404Spjduu_warn(const char *format, ...)
109168404Spjd{
110168404Spjd	va_list alist;
111168404Spjd	va_start(alist, format);
112168404Spjd	uu_warn_internal(errno, format, alist);
113168404Spjd	va_end(alist);
114168404Spjd}
115168404Spjd
116168404Spjdstatic void
117168404Spjduu_die_internal(int status, const char *format, va_list alist)
118168404Spjd{
119168404Spjd	uu_warn_internal(errno, format, alist);
120168404Spjd#ifdef DEBUG
121168404Spjd	{
122168404Spjd		char *cp;
123168404Spjd
124168404Spjd		if (!issetugid()) {
125168404Spjd			cp = getenv("UU_DIE_ABORTS");
126168404Spjd			if (cp != NULL && *cp != '\0')
127168404Spjd				abort();
128168404Spjd		}
129168404Spjd	}
130168404Spjd#endif
131168404Spjd	exit(status);
132168404Spjd}
133168404Spjd
134168404Spjdvoid
135168404Spjduu_vdie(const char *format, va_list alist)
136168404Spjd{
137168404Spjd	uu_die_internal(UU_EXIT_FATAL, format, alist);
138168404Spjd}
139168404Spjd
140168404Spjd/*PRINTFLIKE1*/
141168404Spjdvoid
142168404Spjduu_die(const char *format, ...)
143168404Spjd{
144168404Spjd	va_list alist;
145168404Spjd	va_start(alist, format);
146168404Spjd	uu_die_internal(UU_EXIT_FATAL, format, alist);
147168404Spjd	va_end(alist);
148168404Spjd}
149168404Spjd
150168404Spjdvoid
151168404Spjduu_vxdie(int status, const char *format, va_list alist)
152168404Spjd{
153168404Spjd	uu_die_internal(status, format, alist);
154168404Spjd}
155168404Spjd
156168404Spjd/*PRINTFLIKE2*/
157168404Spjdvoid
158168404Spjduu_xdie(int status, const char *format, ...)
159168404Spjd{
160168404Spjd	va_list alist;
161168404Spjd	va_start(alist, format);
162168404Spjd	uu_die_internal(status, format, alist);
163168404Spjd	va_end(alist);
164168404Spjd}
165168404Spjd
166168404Spjdconst char *
167168404Spjduu_setpname(char *arg0)
168168404Spjd{
169168404Spjd	/*
170168404Spjd	 * Having a NULL argv[0], while uncommon, is possible.  It
171168404Spjd	 * makes more sense to handle this event in uu_setpname rather
172168404Spjd	 * than in each of its consumers.
173168404Spjd	 */
174168404Spjd	if (arg0 == NULL) {
175168404Spjd		pname = "unknown_command";
176168404Spjd		return (pname);
177168404Spjd	}
178168404Spjd
179168404Spjd	/*
180168404Spjd	 * Guard against '/' at end of command invocation.
181168404Spjd	 */
182168404Spjd	for (;;) {
183168404Spjd		char *p = strrchr(arg0, '/');
184168404Spjd		if (p == NULL) {
185168404Spjd			pname = arg0;
186168404Spjd			break;
187168404Spjd		} else {
188168404Spjd			if (*(p + 1) == '\0') {
189168404Spjd				*p = '\0';
190168404Spjd				continue;
191168404Spjd			}
192168404Spjd
193168404Spjd			pname = p + 1;
194168404Spjd			break;
195168404Spjd		}
196168404Spjd	}
197168404Spjd
198168404Spjd	return (pname);
199168404Spjd}
200168404Spjd
201168404Spjdconst char *
202168404Spjduu_getpname(void)
203168404Spjd{
204168404Spjd	return (pname);
205168404Spjd}
206