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 #pragma ident "%Z%%M% %I% %E% SMI" 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 } 208