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 27 #include "libuutil_common.h" 28 29 #include <libintl.h> 30 #include <limits.h> 31 #include <string.h> 32 #include <stdlib.h> 33 #include <stdarg.h> 34 #include <stdio.h> 35 #include <errno.h> 36 #include <wchar.h> 37 #include <unistd.h> 38 39 static const char PNAME_FMT[] = "%s: "; 40 static const char ERRNO_FMT[] = ": %s\n"; 41 42 static const char *pname; 43 44 static void 45 uu_die_internal(int status, const char *format, va_list alist) __NORETURN; 46 47 int uu_exit_ok_value = EXIT_SUCCESS; 48 int uu_exit_fatal_value = EXIT_FAILURE; 49 int uu_exit_usage_value = 2; 50 51 int * 52 uu_exit_ok(void) 53 { 54 return (&uu_exit_ok_value); 55 } 56 57 int * 58 uu_exit_fatal(void) 59 { 60 return (&uu_exit_fatal_value); 61 } 62 63 int * 64 uu_exit_usage(void) 65 { 66 return (&uu_exit_usage_value); 67 } 68 69 void 70 uu_alt_exit(int profile) 71 { 72 switch (profile) { 73 case UU_PROFILE_DEFAULT: 74 uu_exit_ok_value = EXIT_SUCCESS; 75 uu_exit_fatal_value = EXIT_FAILURE; 76 uu_exit_usage_value = 2; 77 break; 78 case UU_PROFILE_LAUNCHER: 79 uu_exit_ok_value = EXIT_SUCCESS; 80 uu_exit_fatal_value = 124; 81 uu_exit_usage_value = 125; 82 break; 83 } 84 } 85 86 static void 87 uu_warn_internal(int err, const char *format, va_list alist) 88 { 89 if (pname != NULL) 90 (void) fprintf(stderr, PNAME_FMT, pname); 91 92 (void) vfprintf(stderr, format, alist); 93 94 if (strrchr(format, '\n') == NULL) 95 (void) fprintf(stderr, ERRNO_FMT, strerror(err)); 96 } 97 98 void 99 uu_vwarn(const char *format, va_list alist) 100 { 101 uu_warn_internal(errno, format, alist); 102 } 103 104 /*PRINTFLIKE1*/ 105 void 106 uu_warn(const char *format, ...) 107 { 108 va_list alist; 109 va_start(alist, format); 110 uu_warn_internal(errno, format, alist); 111 va_end(alist); 112 } 113 114 static void 115 uu_die_internal(int status, const char *format, va_list alist) 116 { 117 uu_warn_internal(errno, format, alist); 118 #ifdef DEBUG 119 { 120 char *cp; 121 122 if (!issetugid()) { 123 cp = getenv("UU_DIE_ABORTS"); 124 if (cp != NULL && *cp != '\0') 125 abort(); 126 } 127 } 128 #endif 129 exit(status); 130 } 131 132 void 133 uu_vdie(const char *format, va_list alist) 134 { 135 uu_die_internal(UU_EXIT_FATAL, format, alist); 136 } 137 138 /*PRINTFLIKE1*/ 139 void 140 uu_die(const char *format, ...) 141 { 142 va_list alist; 143 va_start(alist, format); 144 uu_die_internal(UU_EXIT_FATAL, format, alist); 145 va_end(alist); 146 } 147 148 void 149 uu_vxdie(int status, const char *format, va_list alist) 150 { 151 uu_die_internal(status, format, alist); 152 } 153 154 /*PRINTFLIKE2*/ 155 void 156 uu_xdie(int status, const char *format, ...) 157 { 158 va_list alist; 159 va_start(alist, format); 160 uu_die_internal(status, format, alist); 161 va_end(alist); 162 } 163 164 const char * 165 uu_setpname(char *arg0) 166 { 167 /* 168 * Having a NULL argv[0], while uncommon, is possible. It 169 * makes more sense to handle this event in uu_setpname rather 170 * than in each of its consumers. 171 */ 172 if (arg0 == NULL) { 173 pname = getexecname(); 174 if (pname == NULL) 175 pname = "unknown_command"; 176 return (pname); 177 } 178 179 /* 180 * Guard against '/' at end of command invocation. 181 */ 182 for (;;) { 183 char *p = strrchr(arg0, '/'); 184 if (p == NULL) { 185 pname = arg0; 186 break; 187 } else { 188 if (*(p + 1) == '\0') { 189 *p = '\0'; 190 continue; 191 } 192 193 pname = p + 1; 194 break; 195 } 196 } 197 198 return (pname); 199 } 200 201 const char * 202 uu_getpname(void) 203 { 204 return (pname); 205 } 206