dmake: do not set MAKEFLAGS=k
[unleashed/tickless.git] / usr / src / cmd / logadm / err.c
blob5663232ec21e7c99a01c37bbf2943270e1b9c5f3
1 /*
2 * CDDL HEADER START
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
19 * CDDL HEADER END
22 * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
24 * logadm/err.c -- some basic error routines
28 #include <stdio.h>
29 #include <unistd.h>
30 #include <libintl.h>
31 #include <stdlib.h>
32 #include <stdarg.h>
33 #include <string.h>
34 #include <errno.h>
35 #include "err.h"
37 jmp_buf *Err_env_ptr;
38 static const char *Myname;
39 static int Exitcode;
40 static FILE *Errorfile;
43 * err_init -- initialize the error handling routine
46 void
47 err_init(const char *myname)
49 char *ptr;
51 if ((ptr = strrchr(myname, '/')) == NULL)
52 Myname = myname;
53 else
54 Myname = ptr + 1;
57 static const char *File;
58 static int Line;
61 * err_fileline -- record the filename/line number for err(EF_FILE, ...)
63 void
64 err_fileline(const char *file, int line)
66 File = file;
67 Line = line;
71 * err -- print an error message and return, exit or longjmp based on flags
73 * this routine calls gettext() to translate the fmt string.
75 /*PRINTFLIKE2*/
76 void
77 err(int flags, const char *fmt, ...)
79 va_list ap;
80 int safe_errno = errno;
81 char *errno_msg = NULL;
82 int as_is = 0;
83 int jump = 0;
84 int warning = 0;
85 int fileline = 0;
86 char *prefix = "Error: ";
87 const char *intlfmt;
89 va_start(ap, fmt);
90 intlfmt = gettext(fmt);
92 if (flags & EF_WARN) {
93 warning = 1;
94 prefix = "Warning: ";
96 if (flags & EF_FILE) {
97 fileline = 1;
98 Exitcode++;
100 if (flags & EF_SYS)
101 errno_msg = strerror(safe_errno);
102 if (flags & EF_JMP)
103 jump = 1;
104 if (flags & EF_RAW)
105 as_is = 1;
107 /* print a copy to stderr */
108 if (!as_is) {
109 if (Myname != NULL) {
110 (void) fprintf(stderr, "%s: ", Myname);
111 if (Errorfile)
112 (void) fprintf(Errorfile, "%s: ", Myname);
114 if (fileline && File) {
115 (void) fprintf(stderr, "%s line %d: ", File, Line);
116 if (Errorfile)
117 (void) fprintf(Errorfile,
118 "%s line %d: ", File, Line);
120 (void) fputs(gettext(prefix), stderr);
121 if (Errorfile)
122 (void) fputs(gettext(prefix), Errorfile);
124 (void) vfprintf(stderr, intlfmt, ap);
125 if (Errorfile)
126 (void) vfprintf(Errorfile, intlfmt, ap);
127 if (errno_msg != NULL) {
128 (void) fprintf(stderr, ": %s", errno_msg);
129 if (Errorfile)
130 (void) fprintf(Errorfile, ": %s", errno_msg);
132 if (!as_is) {
133 (void) fprintf(stderr, "\n");
134 if (Errorfile)
135 (void) fprintf(Errorfile, "\n");
137 (void) fflush(stderr);
138 if (Errorfile)
139 (void) fflush(Errorfile);
141 va_end(ap);
143 if (jump)
144 longjmp(*Err_env_ptr, 1);
146 if (!warning && !fileline) {
147 err_done(1);
148 /*NOTREACHED*/
153 * out -- print a message and return
155 * this routine calls gettext() to translate the fmt string.
157 /*PRINTFLIKE1*/
158 void
159 out(const char *fmt, ...)
161 va_list ap;
163 va_start(ap, fmt);
165 (void) vfprintf(stdout, gettext(fmt), ap);
167 va_end(ap);
170 #define CHUNKSIZE 8192 /* for copying stderr */
172 * err_fromfd -- copy data from fd to stderr
174 void
175 err_fromfd(int fd)
177 char buf[CHUNKSIZE];
178 int count;
180 while ((count = read(fd, buf, CHUNKSIZE)) > 0) {
181 (void) fwrite(buf, 1, count, stderr);
182 if (Errorfile)
183 (void) fwrite(buf, 1, count, Errorfile);
185 (void) fflush(stderr);
186 if (Errorfile)
187 (void) fflush(Errorfile);
191 * err_done -- exit the program
193 void
194 err_done(int exitcode)
196 /* send error mail if applicable */
197 err_mailto(NULL);
199 if (exitcode)
200 exit(exitcode);
201 else
202 exit(Exitcode);
203 /*NOTREACHED*/
206 #define MAXLINE 8192 /* for tmp file line buffer */
208 * err_mailto -- arrange for error output to be mailed to someone
210 void
211 err_mailto(const char *recipient)
213 static const char *lastrecipient;
214 static char mailcmd[] = "/bin/mailx -s 'logadm error output'";
215 char *cmd;
216 int len;
217 FILE *pfp;
218 char line[MAXLINE];
220 if (lastrecipient != NULL) {
221 if (recipient != NULL &&
222 strcmp(recipient, lastrecipient) == 0)
223 return; /* keep going, same recipient */
225 /* stop saving output for lastrecipient and send message */
226 if (ftell(Errorfile)) {
227 rewind(Errorfile);
228 len = strlen(lastrecipient) + strlen(mailcmd) + 2;
229 cmd = MALLOC(len);
230 (void) snprintf(cmd, len, "%s %s",
231 mailcmd, lastrecipient);
232 if ((pfp = popen(cmd, "w")) == NULL)
233 err(EF_SYS, "popen to mailx");
234 while (fgets(line, MAXLINE, Errorfile) != NULL)
235 (void) fputs(line, pfp);
236 (void) pclose(pfp);
238 (void) fclose(Errorfile);
239 Errorfile = NULL;
242 if (recipient != NULL) {
243 /* start saving error output for this recipient */
244 if ((Errorfile = tmpfile()) == NULL)
245 err(EF_SYS, "tmpfile");
247 lastrecipient = recipient;
251 * err_malloc -- a malloc() with checks
253 * this routine is typically called via the MALLOC() macro in err.h
255 void *
256 err_malloc(int nbytes, const char *fname, int line)
258 void *retval = malloc(nbytes);
260 if (retval == NULL)
261 err(0, "%s:%d: out of memory", fname, line);
263 return (retval);
267 * err_realloc -- a realloc() with checks
269 * this routine is typically called via the REALLOC() macro in err.h
271 void *
272 err_realloc(void *ptr, int nbytes, const char *fname, int line)
274 void *retval = realloc(ptr, nbytes);
276 if (retval == NULL)
277 err(0, "%s:%d: out of memory", fname, line);
279 return (retval);
283 * err_strdup -- a strdup() with checks
285 * this routine is typically called via the STRDUP() macro in err.h
287 char *
288 err_strdup(const char *ptr, const char *fname, int line)
290 char *retval = NULL;
292 if (ptr != NULL) {
293 retval = strdup(ptr);
294 if (retval == NULL)
295 err(0, "%s:%d: out of memory", fname, line);
296 } else
297 err(0, "%s:%d: could not strdup", fname, line);
300 return (retval);
305 * err_free -- a free() with checks
307 * this routine is typically called via the FREE() macro in err.h
309 /*ARGSUSED1*/
310 void
311 err_free(void *ptr, const char *fname, int line)
313 /* nothing to check in this version */
314 free(ptr);
318 * err_exitcode -- set an error exit code for when done(0) is called
320 void
321 err_exitcode(int exitcode)
323 Exitcode = exitcode;