]>
Commit | Line | Data |
---|---|---|
34dc7c2f BB |
1 | /* |
2 | * CDDL HEADER START | |
3 | * | |
4 | * The contents of this file are subject to the terms of the | |
5 | * Common Development and Distribution License, Version 1.0 only | |
6 | * (the "License"). You may not use this file except in compliance | |
7 | * with the License. | |
8 | * | |
9 | * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE | |
10 | * or http://www.opensolaris.org/os/licensing. | |
11 | * See the License for the specific language governing permissions | |
12 | * and limitations under the License. | |
13 | * | |
14 | * When distributing Covered Code, include this CDDL HEADER in each | |
15 | * file and include the License file at usr/src/OPENSOLARIS.LICENSE. | |
16 | * If applicable, add the following below this CDDL HEADER, with the | |
17 | * fields enclosed by brackets "[]" replaced with your own identifying | |
18 | * information: Portions Copyright [yyyy] [name of copyright owner] | |
19 | * | |
20 | * CDDL HEADER END | |
21 | */ | |
22 | /* | |
23 | * Copyright 2005 Sun Microsystems, Inc. All rights reserved. | |
24 | * Use is subject to license terms. | |
25 | */ | |
26 | ||
e5dc681a | 27 | |
34dc7c2f BB |
28 | |
29 | #include "libuutil_common.h" | |
30 | ||
31 | #include <libintl.h> | |
32 | #include <limits.h> | |
33 | #include <string.h> | |
34 | #include <stdlib.h> | |
35 | #include <stdarg.h> | |
36 | #include <stdio.h> | |
37 | #include <errno.h> | |
38 | #include <wchar.h> | |
39 | #include <unistd.h> | |
40 | ||
41 | static const char PNAME_FMT[] = "%s: "; | |
42 | static const char ERRNO_FMT[] = ": %s\n"; | |
43 | ||
44 | static const char *pname; | |
45 | ||
46 | static void | |
47 | uu_die_internal(int status, const char *format, va_list alist) __NORETURN; | |
48 | ||
49 | int uu_exit_ok_value = EXIT_SUCCESS; | |
50 | int uu_exit_fatal_value = EXIT_FAILURE; | |
51 | int uu_exit_usage_value = 2; | |
52 | ||
53 | int * | |
54 | uu_exit_ok(void) | |
55 | { | |
56 | return (&uu_exit_ok_value); | |
57 | } | |
58 | ||
59 | int * | |
60 | uu_exit_fatal(void) | |
61 | { | |
62 | return (&uu_exit_fatal_value); | |
63 | } | |
64 | ||
65 | int * | |
66 | uu_exit_usage(void) | |
67 | { | |
68 | return (&uu_exit_usage_value); | |
69 | } | |
70 | ||
71 | void | |
72 | uu_alt_exit(int profile) | |
73 | { | |
74 | switch (profile) { | |
75 | case UU_PROFILE_DEFAULT: | |
76 | uu_exit_ok_value = EXIT_SUCCESS; | |
77 | uu_exit_fatal_value = EXIT_FAILURE; | |
78 | uu_exit_usage_value = 2; | |
79 | break; | |
80 | case UU_PROFILE_LAUNCHER: | |
81 | uu_exit_ok_value = EXIT_SUCCESS; | |
82 | uu_exit_fatal_value = 124; | |
83 | uu_exit_usage_value = 125; | |
84 | break; | |
85 | } | |
86 | } | |
87 | ||
88 | static void | |
89 | uu_warn_internal(int err, const char *format, va_list alist) | |
90 | { | |
91 | if (pname != NULL) | |
92 | (void) fprintf(stderr, PNAME_FMT, pname); | |
93 | ||
94 | (void) vfprintf(stderr, format, alist); | |
95 | ||
96 | if (strrchr(format, '\n') == NULL) | |
97 | (void) fprintf(stderr, ERRNO_FMT, strerror(err)); | |
98 | } | |
99 | ||
100 | void | |
101 | uu_vwarn(const char *format, va_list alist) | |
102 | { | |
103 | uu_warn_internal(errno, format, alist); | |
104 | } | |
105 | ||
106 | /*PRINTFLIKE1*/ | |
107 | void | |
108 | uu_warn(const char *format, ...) | |
109 | { | |
110 | va_list alist; | |
111 | va_start(alist, format); | |
112 | uu_warn_internal(errno, format, alist); | |
113 | va_end(alist); | |
114 | } | |
115 | ||
116 | static void | |
117 | uu_die_internal(int status, const char *format, va_list alist) | |
118 | { | |
119 | uu_warn_internal(errno, format, alist); | |
120 | #ifdef DEBUG | |
121 | { | |
122 | char *cp; | |
123 | ||
124 | if (!issetugid()) { | |
125 | cp = getenv("UU_DIE_ABORTS"); | |
126 | if (cp != NULL && *cp != '\0') | |
127 | abort(); | |
128 | } | |
129 | } | |
130 | #endif | |
131 | exit(status); | |
132 | } | |
133 | ||
134 | void | |
135 | uu_vdie(const char *format, va_list alist) | |
136 | { | |
137 | uu_die_internal(UU_EXIT_FATAL, format, alist); | |
138 | } | |
139 | ||
140 | /*PRINTFLIKE1*/ | |
141 | void | |
142 | uu_die(const char *format, ...) | |
143 | { | |
144 | va_list alist; | |
145 | va_start(alist, format); | |
146 | uu_die_internal(UU_EXIT_FATAL, format, alist); | |
147 | va_end(alist); | |
148 | } | |
149 | ||
150 | void | |
151 | uu_vxdie(int status, const char *format, va_list alist) | |
152 | { | |
153 | uu_die_internal(status, format, alist); | |
154 | } | |
155 | ||
156 | /*PRINTFLIKE2*/ | |
157 | void | |
158 | uu_xdie(int status, const char *format, ...) | |
159 | { | |
160 | va_list alist; | |
161 | va_start(alist, format); | |
162 | uu_die_internal(status, format, alist); | |
163 | va_end(alist); | |
164 | } | |
165 | ||
166 | const char * | |
167 | uu_setpname(char *arg0) | |
168 | { | |
169 | /* | |
170 | * Having a NULL argv[0], while uncommon, is possible. It | |
171 | * makes more sense to handle this event in uu_setpname rather | |
172 | * than in each of its consumers. | |
173 | */ | |
174 | if (arg0 == NULL) { | |
175 | pname = getexecname(); | |
176 | if (pname == NULL) | |
177 | pname = "unknown_command"; | |
178 | return (pname); | |
179 | } | |
180 | ||
181 | /* | |
182 | * Guard against '/' at end of command invocation. | |
183 | */ | |
184 | for (;;) { | |
185 | char *p = strrchr(arg0, '/'); | |
186 | if (p == NULL) { | |
187 | pname = arg0; | |
188 | break; | |
189 | } else { | |
190 | if (*(p + 1) == '\0') { | |
191 | *p = '\0'; | |
192 | continue; | |
193 | } | |
194 | ||
195 | pname = p + 1; | |
196 | break; | |
197 | } | |
198 | } | |
199 | ||
200 | return (pname); | |
201 | } | |
202 | ||
203 | const char * | |
204 | uu_getpname(void) | |
205 | { | |
206 | return (pname); | |
207 | } |