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 static void vrpmlog (unsigned code, const char *fmt, va_list ap)
00134         /*@modifies internalState @*/
00135 {
00136     int pri = RPMLOG_PRI(code);
00137     int mask = RPMLOG_MASK(pri);
00138     /*@unused@*/ int fac = RPMLOG_FAC(code);
00139     char *msgbuf, *msg;
00140     int msgnb = BUFSIZ, nb;
00141     FILE * msgout = stderr;
00142 
00143     if ((mask & rpmlogMask) == 0)
00144         return;
00145 
00146     msgbuf = xmalloc(msgnb);
00147     *msgbuf = '\0';
00148 
00149     /* Allocate a sufficently large buffer for output. */
00150     while (1) {
00151         va_list apc;
00152         /*@-sysunrecog -usedef@*/ va_copy(apc, ap); /*@=sysunrecog =usedef@*/
00153         /*@-unrecog@*/ nb = vsnprintf(msgbuf, msgnb, fmt, apc); /*@=unrecog@*/
00154         if (nb > -1 && nb < msgnb)
00155             break;
00156         if (nb > -1)            /* glibc 2.1 */
00157             msgnb = nb+1;
00158         else                    /* glibc 2.0 */
00159             msgnb *= 2;
00160         msgbuf = xrealloc(msgbuf, msgnb);
00161     }
00162     msgbuf[msgnb - 1] = '\0';
00163     msg = msgbuf;
00164 
00165     /* Save copy of all messages at warning (or below == "more important"). */
00166     if (pri <= RPMLOG_WARNING) {
00167 
00168         if (recs == NULL)
00169             recs = xmalloc((nrecs+2) * sizeof(*recs));
00170         else
00171             recs = xrealloc(recs, (nrecs+2) * sizeof(*recs));
00172         recs[nrecs].code = code;
00173         recs[nrecs].message = msg = xrealloc(msgbuf, strlen(msgbuf)+1);
00174         msgbuf = NULL;          /* XXX don't free at exit. */
00175         recs[nrecs+1].code = 0;
00176         recs[nrecs+1].message = NULL;
00177         ++nrecs;
00178 
00179         if (_rpmlogCallback) {
00180             _rpmlogCallback();
00181             return;     /* XXX Preserve legacy rpmError behavior. */
00182         }
00183     }
00184 
00185     /* rpmMessage behavior */
00186 
00187     switch (pri) {
00188     case RPMLOG_INFO:
00189     case RPMLOG_NOTICE:
00190         msgout = stdout;
00191         break;
00192 
00193     case RPMLOG_EMERG:
00194     case RPMLOG_ALERT:
00195     case RPMLOG_CRIT:
00196     case RPMLOG_ERR: /* XXX Legacy rpmError behavior used stdout w/o prefix. */
00197     case RPMLOG_WARNING:
00198     case RPMLOG_DEBUG:
00199         break;
00200     }
00201 
00202     if (rpmlogMsgPrefix[pri] && *rpmlogMsgPrefix[pri])
00203         (void) fputs(_(rpmlogMsgPrefix[pri]), msgout);
00204 
00205     (void) fputs(msg, msgout);
00206     (void) fflush(msgout);
00207     msgbuf = _free(msgbuf);
00208     if (pri <= RPMLOG_CRIT)
00209         exit(EXIT_FAILURE);
00210 }
00211 
00212 void rpmlog (int code, const char *fmt, ...)
00213 {
00214     va_list ap;
00215 
00216     va_start(ap, fmt);
00217     vrpmlog(code, fmt, ap);
00218     va_end(ap);
00219 }
00220 
00221 int rpmErrorCode(void)
00222 {
00223     return rpmlogCode();
00224 }
00225 
00226 const char * rpmErrorString(void)
00227 {
00228     return rpmlogMessage();
00229 }
00230 
00231 rpmlogCallback rpmErrorSetCallback(rpmlogCallback cb)
00232 {
00233     return rpmlogSetCallback(cb);
00234 }

Generated at Thu Sep 6 11:32:32 2001 for rpm by doxygen1.2.8.1 written by Dimitri van Heesch, © 1997-2001