PageRenderTime 19ms CodeModel.GetById 1ms app.highlight 14ms RepoModel.GetById 1ms app.codeStats 0ms

/src/common/err.c

https://code.google.com/
C | 205 lines | 124 code | 25 blank | 56 comment | 47 complexity | ee9da4484c01ce5ef1a02c5fa6cc1e2a MD5 | raw file
  1/*****************************************************************************\
  2 *  $Id$
  3 *****************************************************************************
  4 *  Copyright (C) 2001-2006 The Regents of the University of California.
  5 *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
  6 *  Written by Jim Garlick <garlick@llnl.gov>.
  7 *  UCRL-CODE-2003-005.
  8 *  
  9 *  This file is part of Pdsh, a parallel remote shell program.
 10 *  For details, see <http://www.llnl.gov/linux/pdsh/>.
 11 *  
 12 *  Pdsh is free software; you can redistribute it and/or modify it under
 13 *  the terms of the GNU General Public License as published by the Free
 14 *  Software Foundation; either version 2 of the License, or (at your option)
 15 *  any later version.
 16 *  
 17 *  Pdsh is distributed in the hope that it will be useful, but WITHOUT ANY
 18 *  WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 19 *  FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
 20 *  details.
 21 *  
 22 *  You should have received a copy of the GNU General Public License along
 23 *  with Pdsh; if not, write to the Free Software Foundation, Inc.,
 24 *  59 Temple Place, Suite 330, Boston, MA  02111-1307  USA.
 25\*****************************************************************************/
 26
 27/*
 28 * Error printing routines with variable arguments.
 29 */
 30
 31#if     HAVE_CONFIG_H
 32#include "config.h"
 33#endif
 34
 35#include <stdarg.h>
 36#include <netdb.h>
 37#include <string.h>
 38#include <assert.h>
 39#if	HAVE_UNISTD_H
 40#include <unistd.h>             /* gethostname */
 41#endif
 42#include <ctype.h>
 43#include <stdlib.h>             /* exit */
 44
 45#include "xstring.h"
 46#include "xmalloc.h"
 47#include "macros.h" 
 48
 49static char *prog = NULL;
 50static char *host = NULL;
 51
 52/*
 53 * Optionally leave domain on hostnames with _verr's %S
 54 */
 55static bool keep_host_domain = false;
 56
 57/*
 58 * Call this before calling err() or errx().  Sets hostname and program name 
 59 * for %H, %p, and %P.
 60 *   str (IN)	program name
 61 */
 62void err_init(char *str)
 63{
 64    char thishost[MAXHOSTNAMELEN];
 65    char *p;
 66
 67    gethostname(thishost, MAXHOSTNAMELEN);
 68    if ((p = strchr(thishost, '.')) != NULL)
 69        *p = '\0';
 70    host = Strdup(thishost);
 71    prog = Strdup(str);
 72}
 73
 74void err_no_strip_domain ()
 75{
 76    keep_host_domain = true;
 77}
 78
 79/*
 80 * Free heap storage allocated by err_init()
 81 */
 82void err_cleanup(void)
 83{
 84    Free((void **) &prog);
 85    Free((void **) &host);
 86}
 87
 88/* 
 89 * _verr() is like vfprintf, but handles (only) the following formats:
 90 * following formats:
 91 * %s	string
 92 * %S   string, but treat as hostname and truncate after dot
 93 * %c	character
 94 * %m	string (sys_errlist[errno])
 95 * %d   int	
 96 * %z   equivalent to %.3d 
 97 * %p   program name with @host attached
 98 * %P   program name
 99 * %H   hostname for this host
100 */
101static void _verr(FILE * stream, char *format, va_list ap)
102{
103    char *buf = NULL;
104    char *q;
105    int percent = 0;
106    char tmpstr[LINEBUFSIZE];
107
108    /* Note: snprintf silently truncates if argument exceeds size of tmpstr */
109
110    assert(prog != NULL && host != NULL);
111    while (format && *format) { /* iterate thru chars */
112        if (percent == 1) {
113            percent = 0;
114            if (*format == 's') {       /* %s - string */
115                xstrcat(&buf, va_arg(ap, char *));
116            } else if (*format == 'S') {        /* %S - string, trunc */
117                snprintf(tmpstr, sizeof(tmpstr), "%s", va_arg(ap, char *));
118                if (  !isdigit(*tmpstr) 
119                   && !keep_host_domain 
120                   && (q = strchr(tmpstr, '.')))
121                    *q = '\0';
122                xstrcat(&buf, tmpstr);
123            } else if (*format == 'z') {        /* %z - same as %.3d */
124                snprintf(tmpstr, sizeof(tmpstr), "%.3d", va_arg(ap, int));
125                xstrcat(&buf, tmpstr);
126            } else if (*format == 'c') {        /* %c - character */
127                xstrcatchar(&buf, va_arg(ap, int));
128            } else if (*format == 'd') {        /* %d - integer */
129                snprintf(tmpstr, sizeof(tmpstr), "%d", va_arg(ap, int));
130                xstrcat(&buf, tmpstr);
131            } else if (*format == 'm') {        /* %m - error code */
132                xstrerrorcat(&buf);
133            } else if (*format == 'P') {        /* %P - prog name */
134                assert(prog != NULL);
135                xstrcat(&buf, prog);
136            } else if (*format == 'H') {        /* %H - this host */
137                assert(host != NULL);
138                xstrcat(&buf, host);
139            } else if (*format == 'p') {        /* %p - prog@host */
140                assert(prog != NULL);
141                assert(host != NULL);
142                snprintf(tmpstr, sizeof(tmpstr), "%s@%s", prog, host);
143                xstrcat(&buf, tmpstr);
144            } else              /* pass thru */
145                xstrcatchar(&buf, *format);
146        } else if (*format == '%')
147            percent = 1;        /* remember % */
148        else
149            xstrcatchar(&buf, *format); /* pass thru */
150        format++;
151    }
152
153    fputs(buf, stream);         /* print it */
154    Free((void **) &buf);       /* clean up */
155}
156
157void err(char *format, ...)
158{
159    va_list ap;
160
161    va_start(ap, format);
162    _verr(stderr, format, ap);
163    va_end(ap);
164}
165
166void errx(char *format, ...)
167{
168    va_list ap;
169
170    va_start(ap, format);
171    _verr(stderr, format, ap);
172    va_end(ap);
173    exit(1);
174}
175
176void out(char *format, ...)
177{
178    va_list ap;
179
180    va_start(ap, format);
181    _verr(stdout, format, ap);
182    va_end(ap);
183}
184
185void errf(FILE *stream, char *format, va_list ap)
186{
187    if (!stream)
188        return;
189
190    _verr(stream, format, ap);
191}
192
193void lsd_fatal_error(char *file, int line, char *mesg)
194{
195    errx ("%p: %s:%d: %s\n", file, line, mesg);
196}
197
198void lsd_nomem_error(char *file, int line, char *mesg)
199{
200    errx ("%p: %s:%d: %s: Out of memory\n", file, line, mesg);
201}
202
203/*
204 * vi:tabstop=4 shiftwidth=4 expandtab
205 */