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