Main Page   Modules   Compound List   File List   Compound Members   File Members   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 static void vrpmlog (unsigned code, const char *fmt, va_list ap)
00102 {
00103     int pri = RPMLOG_PRI(code);
00104     int mask = RPMLOG_MASK(pri);
00105     /*@unused@*/ int fac = RPMLOG_FAC(code);
00106     char *msgbuf, *msg;
00107     int msgnb = BUFSIZ, nb;
00108     FILE * msgout = stderr;
00109     rpmlogRec rec;
00110 
00111     if ((mask & rpmlogMask) == 0)
00112         return;
00113 
00114     msgbuf = xmalloc(msgnb);
00115     *msgbuf = '\0';
00116 
00117     /* Allocate a sufficently large buffer for output. */
00118     while (1) {
00119         /*@-unrecog@*/
00120         nb = vsnprintf(msgbuf, msgnb, fmt, ap);
00121         /*@=unrecog@*/
00122         if (nb > -1 && nb < msgnb)
00123             break;
00124         if (nb > -1)            /* glibc 2.1 */
00125             msgnb = nb+1;
00126         else                    /* glibc 2.0 */
00127             msgnb *= 2;
00128         msgbuf = xrealloc(msgbuf, msgnb);
00129     }
00130     msgbuf[msgnb - 1] = '\0';
00131     msg = msgbuf;
00132 
00133     /* Save copy of all messages at warning (or below == "more important"). */
00134     if (pri <= RPMLOG_WARNING) {
00135 
00136         if (recs == NULL)
00137             recs = xmalloc((nrecs+2) * sizeof(*recs));
00138         else
00139             recs = xrealloc(recs, (nrecs+2) * sizeof(*recs));
00140         recs[nrecs+1].code = 0;
00141         recs[nrecs+1].message = NULL;
00142         rec = recs + nrecs;
00143         ++nrecs;
00144 
00145         rec->code = code;
00146         rec->message = msgbuf;
00147         msgbuf = NULL;
00148 
00149         if (_rpmlogCallback) {
00150             _rpmlogCallback();
00151             if (msgbuf)
00152                 free(msgbuf);
00153             return;     /* XXX Preserve legacy rpmError behavior. */
00154         }
00155     }
00156 
00157     /* rpmMessage behavior */
00158 
00159     switch (pri) {
00160     case RPMLOG_INFO:
00161     case RPMLOG_NOTICE:
00162         msgout = stdout;
00163         break;
00164 
00165     case RPMLOG_EMERG:
00166     case RPMLOG_ALERT:
00167     case RPMLOG_CRIT:
00168     case RPMLOG_ERR: /* XXX Legacy rpmError behavior used stdout w/o prefix. */
00169     case RPMLOG_WARNING:
00170     case RPMLOG_DEBUG:
00171         break;
00172     }
00173 
00174     /* Silly FORTRAN-like carriage control. */
00175     if (*msg == '+')
00176         msg++;
00177     else if (rpmlogMsgPrefix[pri] && *rpmlogMsgPrefix[pri])
00178         fputs(_(rpmlogMsgPrefix[pri]), msgout);
00179 
00180     fputs(msg, msgout);
00181     fflush(msgout);
00182     if (msgbuf)
00183         free(msgbuf);
00184     if (pri <= RPMLOG_CRIT)
00185         exit(EXIT_FAILURE);
00186 }
00187 
00188 void rpmlog (int code, const char *fmt, ...)
00189 {
00190     va_list ap;
00191 
00192     va_start(ap, fmt);
00193     vrpmlog(code, fmt, ap);
00194     va_end(ap);
00195 }
00196 
00197 int rpmErrorCode(void)
00198 {
00199     return rpmlogCode();
00200 }
00201 
00202 const char * rpmErrorString(void)
00203 {
00204     return rpmlogMessage();
00205 }
00206 
00207 rpmlogCallback rpmErrorSetCallback(rpmlogCallback cb)
00208 {
00209     return rpmlogSetCallback(cb);
00210 }

Generated at Mon May 21 08:53:41 2001 for rpm by doxygen1.2.6 written by Dimitri van Heesch, © 1997-2001