Home | History | Annotate | Line # | Download | only in common
      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 = "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