Main Page   Modules   Data Structures   File List   Data Fields   Globals   Related Pages  

rpmio/rpmlog.c

Go to the documentation of this file.
00001 
00005 #include "system.h"
00006 #include <stdarg.h>
00007 #include "rpmlog.h"
00008 #include "debug.h"
00009 
00010 #ifndef va_copy
00011 # ifdef __va_copy
00012 #  define va_copy(DEST,SRC) __va_copy((DEST),(SRC))
00013 # else
00014 #  ifdef HAVE_VA_LIST_AS_ARRAY
00015 #   define va_copy(DEST,SRC) (*(DEST) = *(SRC))
00016 #  else
00017 #   define va_copy(DEST,SRC) ((DEST) = (SRC))
00018 #  endif
00019 # endif
00020 #endif
00021 
00022 /*@access rpmlogRec @*/
00023 
00024 static int nrecs = 0;
00025 static /*@only@*/ /*@null@*/ rpmlogRec recs = NULL;
00026 
00032 /*@unused@*/ static inline /*@null@*/ void *
00033 _free(/*@only@*/ /*@null@*/ const void * p) /*@modifies p@*/
00034 {
00035     if (p != NULL)      free((void *)p);
00036     return NULL;
00037 }
00038 
00039 int rpmlogGetNrecs(void)
00040 {
00041     return nrecs;
00042 }
00043 
00044 int rpmlogCode(void)
00045 {
00046     if (recs != NULL && nrecs > 0)
00047         return recs[nrecs-1].code;
00048     return -1;
00049 }
00050 
00051 
00052 const char * rpmlogMessage(void)
00053 {
00054     if (recs != NULL && nrecs > 0)
00055         return recs[nrecs-1].message;
00056     return _("(no error)");
00057 }
00058 
00059 void rpmlogPrint(FILE *f)
00060 {
00061     int i;
00062 
00063     if (f == NULL)
00064         f = stderr;
00065 
00066     if (recs)
00067     for (i = 0; i < nrecs; i++) {
00068         rpmlogRec rec = recs + i;
00069         if (rec->message && *rec->message)
00070             fprintf(f, "    %s", rec->message);
00071     }
00072 }
00073 
00074 void rpmlogClose (void)
00075 {
00076     int i;
00077 
00078     if (recs)
00079     for (i = 0; i < nrecs; i++) {
00080         rpmlogRec rec = recs + i;
00081         rec->message = _free(rec->message);
00082     }
00083     recs = _free(recs);
00084     nrecs = 0;
00085 }
00086 
00087 void rpmlogOpen (/*@unused@*/ const char *ident, /*@unused@*/ int option,
00088                 /*@unused@*/ int facility)
00089 {
00090 }
00091 
00092 static int rpmlogMask = RPMLOG_UPTO( RPMLOG_NOTICE );
00093 static /*@unused@*/ int rpmlogFacility = RPMLOG_USER;
00094 
00095 int rpmlogSetMask (int mask)
00096 {
00097     int omask = rpmlogMask;
00098     if (mask)
00099         rpmlogMask = mask;
00100     return omask;
00101 }
00102 
00103 static /*@null@*/ rpmlogCallback _rpmlogCallback = NULL;
00104 
00105 rpmlogCallback rpmlogSetCallback(rpmlogCallback cb)
00106 {
00107     rpmlogCallback ocb = _rpmlogCallback;
00108     _rpmlogCallback = cb;
00109     return ocb;
00110 }
00111 
00112 /*@-readonlytrans@*/    /* FIX: double indeirection. */
00113 /*@observer@*/ static char *rpmlogMsgPrefix[] = {
00114     N_("fatal error: "),
00115     N_("fatal error: "),
00116     N_("fatal error: "),
00117     N_("error: "),      
00118     N_("warning: "),    
00119     "",                 
00120     "",                 
00121     "D: ",              
00122 };
00123 /*@=readonlytrans@*/
00124 
00125 #if !defined(HAVE_VSNPRINTF)
00126 static inline int vsnprintf(char * buf, /*@unused@*/ int nb,
00127         const char * fmt, va_list ap)
00128 {
00129     return vsprintf(buf, fmt, ap);
00130 }
00131 #endif
00132 
00133 void rpmlog (int code, const char *fmt, ...)
00134         /*@modifies internalState @*/
00135 {
00136     va_list ap;
00137     int pri = RPMLOG_PRI(code);
00138     int mask = RPMLOG_MASK(pri);
00139     /*@unused@*/ int fac = RPMLOG_FAC(code);
00140     char *msgbuf, *msg;
00141     int msgnb = BUFSIZ, nb;
00142     FILE * msgout = stderr;
00143 
00144     if ((mask & rpmlogMask) == 0)
00145         return;
00146 
00147     msgbuf = xmalloc(msgnb);
00148     *msgbuf = '\0';
00149 
00150     /* Allocate a sufficently large buffer for output. */
00151     while (1) {
00152         /*@-sysunrecog -usedef@*/ va_start(ap, fmt); /*@=sysunrecog =usedef@*/
00153         /*@-unrecog@*/ nb = vsnprintf(msgbuf, msgnb, fmt, ap); /*@=unrecog@*/
00154         va_end(ap);
00155         if (nb > -1 && nb < msgnb)
00156             break;
00157         if (nb > -1)            /* glibc 2.1 */
00158             msgnb = nb+1;
00159         else                    /* glibc 2.0 */
00160             msgnb *= 2;
00161         msgbuf = xrealloc(msgbuf, msgnb);
00162     }
00163     msgbuf[msgnb - 1] = '\0';
00164     msg = msgbuf;
00165 
00166     /* Save copy of all messages at warning (or below == "more important"). */
00167     if (pri <= RPMLOG_WARNING) {
00168 
00169         if (recs == NULL)
00170             recs = xmalloc((nrecs+2) * sizeof(*recs));
00171         else
00172             recs = xrealloc(recs, (nrecs+2) * sizeof(*recs));
00173         recs[nrecs].code = code;
00174         recs[nrecs].message = msg = xrealloc(msgbuf, strlen(msgbuf)+1);
00175         msgbuf = NULL;          /* XXX don't free at exit. */
00176         recs[nrecs+1].code = 0;
00177         recs[nrecs+1].message = NULL;
00178         ++nrecs;
00179 
00180         if (_rpmlogCallback) {
00181             _rpmlogCallback();
00182             return;     /* XXX Preserve legacy rpmError behavior. */
00183         }
00184     }
00185 
00186     /* rpmMessage behavior */
00187 
00188     switch (pri) {
00189     case RPMLOG_INFO:
00190     case RPMLOG_NOTICE:
00191         msgout = stdout;
00192         break;
00193 
00194     case RPMLOG_EMERG:
00195     case RPMLOG_ALERT:
00196     case RPMLOG_CRIT:
00197     case RPMLOG_ERR: /* XXX Legacy rpmError behavior used stdout w/o prefix. */
00198     case RPMLOG_WARNING:
00199     case RPMLOG_DEBUG:
00200         break;
00201     }
00202 
00203     if (rpmlogMsgPrefix[pri] && *rpmlogMsgPrefix[pri])
00204         (void) fputs(_(rpmlogMsgPrefix[pri]), msgout);
00205 
00206     (void) fputs(msg, msgout);
00207     (void) fflush(msgout);
00208     msgbuf = _free(msgbuf);
00209     if (pri <= RPMLOG_CRIT)
00210         exit(EXIT_FAILURE);
00211 }
00212 
00213 /*
00214 void rpmlog (int code, const char *fmt, ...)
00215 {
00216     va_list ap;
00217 
00218     va_start(ap, fmt);
00219     vrpmlog(code, fmt, ap);
00220     va_end(ap);
00221 }
00222 */
00223 
00224 int rpmErrorCode(void)
00225 {
00226     return rpmlogCode();
00227 }
00228 
00229 const char * rpmErrorString(void)
00230 {
00231     return rpmlogMessage();
00232 }
00233 
00234 rpmlogCallback rpmErrorSetCallback(rpmlogCallback cb)
00235 {
00236     return rpmlogSetCallback(cb);
00237 }

Generated at Wed Mar 27 03:56:53 2002 for rpm by doxygen1.2.8.1 written by Dimitri van Heesch, © 1997-2001