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

Generated at Thu Apr 19 15:29:45 2001 for rpm by doxygen1.2.6-20010408 written by Dimitri van Heesch, © 1997-2001