/* Copyright 2000, 2001, 2002 Laurent Wacrenier This file is part of libhome libhome is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. libhome is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with libhome; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" static char const rcsid[] UNUSED = "$Id: error.c,v 1.20 2005/06/23 13:02:58 lwa Exp $"; #define passwd system_passwd /* select may be somewhere here ... */ #include #if HAVE_SYS_SELECT_H #include #endif #include #if HAVE_SYS_TIME_H #include #endif #include #include #include #include #include #include #undef passwd #include "hparam.h" static int h_retry=0; extern struct param home_param; #if !HAVE_VSYSLOG /* fake function for HPUX */ static void vsyslog(int priority, const char *message, va_list args) { char buf[10000]; /* big buffer */ int len; len = vsnprintf(buf, sizeof(buf) -1, message, args); buf[sizeof(buf) -1] = 0; syslog(priority, "%s", buf); } #endif static void printerr (char *h_errstr) { if (home_param.errmsg) { char *errmsg=home_param.errmsg; while(*errmsg) { switch(*errmsg) { case '\\': if (errmsg[1]=='n') putc('\n', stdout); else if (errmsg[1]=='r') putc('\r', stdout); else if (errmsg[1]=='0') exit(0); errmsg++; break; case '%': if (errmsg[1]=='s') fputs(h_errstr, stdout); else if (errmsg[1]=='%') putc(*errmsg, stdout); errmsg++; break; default: putc(*errmsg, stdout); break; } errmsg++; } exit(0); } } void home_debug(char *fmt, ...) { va_list ap; va_start(ap, fmt); if (home_param.log_stderr) { vfprintf(stderr, fmt, ap); fputc('\n', stderr); } else { vsyslog(LOG_DEBUG, fmt, ap); } va_end(ap); } int home_error(char *fmt, ...) { va_list ap; va_start(ap, fmt); if (home_param.log_stderr) { vfprintf(stderr, fmt, ap); fputc('\n', stderr); } else { vsyslog(LOG_INFO, fmt, ap); } va_end(ap); return 0; } int home_retry(char *fmt, ...) { extern int errno; char h_errstr[1024]; va_list ap; h_retry=1; va_start(ap, fmt); vsnprintf(h_errstr, sizeof(h_errstr), fmt, ap); va_end(ap); h_errstr[sizeof(h_errstr)-1]=0; if (home_param.log_stderr) { fprintf(stderr, "%s\n", h_errstr); } else { syslog(LOG_INFO, "%s", h_errstr); } printerr(h_errstr); return 0; } void *home_query(home_query_t query, char *who) { void *res = NULL; int old_h_retry = h_retry; int n = home_param.retries; int delay = home_param.retry_delay; do { h_retry = 0; res = query(who); if (res || h_retry == 0) { h_retry = old_h_retry; return res; } if (delay>0) { struct timeval t; t.tv_sec = delay; t.tv_usec = 0; select(0, NULL, NULL, NULL, &t); } } while(n-->0); return res; } struct passwd *home_getpwnam_return(struct passwd *p) { if (h_retry) { h_retry=0; errno=ENOMEM; return NULL; } else { errno=0; return p; } } int home_has_transcient_condition(void) { return h_retry; } void home_clear_transcient_condition(void) { h_retry = 0; } void *hmalloc_error(char *context, char *var) { if (var) { home_retry("%s: malloc error for %.20s...", context, var); } else { home_retry("%s: malloc error", context); } return NULL; }