• Main Page
  • Related Pages
  • Modules
  • Data Structures
  • Files
  • File List
  • Globals

rpmio/rpmlog.c

Go to the documentation of this file.
00001 
00005 #include "system.h"
00006 #include <stdarg.h>
00007 #define _RPMLOG_INTERNAL
00008 #include <rpmlog.h>
00009 #include "debug.h"
00010 
00011 /*@access rpmlogRec @*/
00012 
00013 /*@unchecked@*/
00014 static int nrecs = 0;
00015 /*@unchecked@*/
00016 static /*@only@*/ /*@null@*/ rpmlogRec recs = NULL;
00017 
00023 /*@unused@*/ static inline /*@null@*/ void *
00024 _free(/*@only@*/ /*@null@*/ /*@out@*/ const void * p) /*@modifies p@*/
00025 {
00026     if (p != NULL)      free((void *)p);
00027     return NULL;
00028 }
00029 
00030 int rpmlogGetNrecs(void)
00031 {
00032     return nrecs;
00033 }
00034 
00035 int rpmlogCode(void)
00036 {
00037     if (recs != NULL && nrecs > 0)
00038         return recs[nrecs-1].code;
00039     return -1;
00040 }
00041 
00042 const char * rpmlogMessage(void)
00043 {
00044     if (recs != NULL && nrecs > 0)
00045         return recs[nrecs-1].message;
00046     return _("(no error)");
00047 }
00048 
00049 const char * rpmlogRecMessage(rpmlogRec rec)
00050 {
00051     assert(rec != NULL);
00052     return (rec->message);
00053 }
00054 
00055 rpmlogLvl rpmlogRecPriority(rpmlogRec rec)
00056 {
00057     assert(rec != NULL);
00058     return (rec->pri);
00059 }
00060 
00061 /*@-modfilesys@*/
00062 void rpmlogPrint(FILE *f)
00063 {
00064     int i;
00065 
00066     if (f == NULL)
00067         f = stderr;
00068 
00069     if (recs)
00070     for (i = 0; i < nrecs; i++) {
00071         rpmlogRec rec = recs + i;
00072         if (rec->message && *rec->message)
00073             fprintf(f, "    %s", rec->message);
00074     }
00075 }
00076 /*@=modfilesys@*/
00077 
00078 void rpmlogClose (void)
00079         /*@globals recs, nrecs @*/
00080         /*@modifies recs, nrecs @*/
00081 {
00082     int i;
00083 
00084     if (recs)
00085     for (i = 0; i < nrecs; i++) {
00086         rpmlogRec rec = recs + i;
00087         rec->message = _free(rec->message);
00088     }
00089     recs = _free(recs);
00090     nrecs = 0;
00091 }
00092 
00093 void rpmlogOpen (/*@unused@*/ const char *ident,
00094                 /*@unused@*/ int option,
00095                 /*@unused@*/ int facility)
00096 {
00097 }
00098 
00099 /*@unchecked@*/
00100 static unsigned rpmlogMask = RPMLOG_UPTO( RPMLOG_NOTICE );
00101 
00102 #if 0
00103 /*@unchecked@*/
00104 static /*@unused@*/ unsigned rpmlogFacility = RPMLOG_USER;
00105 #endif
00106 
00107 int rpmlogSetMask (int mask)
00108         /*@globals rpmlogMask @*/
00109         /*@modifies rpmlogMask @*/
00110 {
00111     int omask = rpmlogMask;
00112     if (mask)
00113         rpmlogMask = mask;
00114     return omask;
00115 }
00116 
00117 /*@unchecked@*/ /*@null@*/
00118 static rpmlogCallback _rpmlogCallback;
00119 
00120 /*@unchecked@*/ /*@null@*/
00121 static rpmlogCallbackData _rpmlogCallbackData;
00122 
00123 rpmlogCallback rpmlogSetCallback(rpmlogCallback cb, rpmlogCallbackData data)
00124         /*@globals _rpmlogCallback, _rpmlogCallbackData @*/
00125         /*@modifies _rpmlogCallback, _rpmlogCallbackData @*/
00126 {
00127     rpmlogCallback ocb = _rpmlogCallback;
00128     _rpmlogCallback = cb;
00129     _rpmlogCallbackData = data;
00130     return ocb;
00131 }
00132 
00133 void rpmlogGetCallback(rpmlogCallback *cb, rpmlogCallbackData *data)
00134         /*@globals _rpmlogCallback, _rpmlogCallbackData @*/
00135 {
00136     *cb = _rpmlogCallback;
00137     *data = _rpmlogCallbackData;
00138     return;
00139 }
00140 
00141 /*@unchecked@*/ /*@null@*/
00142 static FILE * _stdlog = NULL;
00143 
00144 static int rpmlogDefault(rpmlogRec rec)
00145         /*@globals fileSystem @*/
00146         /*@modifies fileSystem @*/
00147 {
00148     FILE *msgout = (_stdlog ? _stdlog : stderr);
00149 
00150     switch (rec->pri) {
00151     case RPMLOG_INFO:
00152     case RPMLOG_NOTICE:
00153         msgout = (_stdlog ? _stdlog : stdout);
00154         break;
00155     case RPMLOG_EMERG:
00156     case RPMLOG_ALERT:
00157     case RPMLOG_CRIT:
00158     case RPMLOG_ERR:
00159     case RPMLOG_WARNING:
00160     case RPMLOG_DEBUG:
00161     default:
00162         break;
00163     }
00164 
00165     (void) fputs(rpmlogLevelPrefix(rec->pri), msgout);
00166 
00167     if (rec->message)
00168         (void) fputs(rec->message, msgout);
00169     (void) fflush(msgout);
00170 
00171     return (rec->pri <= RPMLOG_CRIT ? RPMLOG_EXIT : 0);
00172 }
00173 
00174 FILE * rpmlogSetFile(FILE * fp)
00175         /*@globals _stdlog @*/
00176         /*@modifies _stdlog @*/
00177 {
00178     FILE * ofp = _stdlog;
00179     _stdlog = fp;
00180     return ofp;
00181 }
00182 
00183 /*@-readonlytrans@*/    /* FIX: double indirection. */
00184 /*@observer@*/ /*@unchecked@*/
00185 static const char *rpmlogMsgPrefix[] = {
00186     N_("fatal error: "),
00187     N_("fatal error: "),
00188     N_("fatal error: "),
00189     N_("error: "),      
00190     N_("warning: "),    
00191     "",                 
00192     "",                 
00193     "D: ",              
00194 };
00195 /*@=readonlytrans@*/
00196 
00197 const char * rpmlogLevelPrefix(rpmlogLvl pri)
00198 {
00199     return rpmlogMsgPrefix[pri&0x7];
00200 }
00201 
00202 #if !defined(HAVE_VSNPRINTF)
00203 static inline int vsnprintf(char * buf, /*@unused@*/ int nb,
00204         const char * fmt, va_list ap)
00205 {
00206     return vsprintf(buf, fmt, ap);
00207 }
00208 #endif
00209 
00210 /*@-modfilesys@*/
00211 /*@-compmempass@*/ /* FIX: rpmlogMsgPrefix[] dependent, not unqualified */
00212 /*@-nullstate@*/ /* FIX: rpmlogMsgPrefix[] may be NULL */
00213 void vrpmlog (unsigned code, const char *fmt, va_list ap)
00214         /*@globals nrecs, recs, internalState @*/
00215         /*@modifies nrecs, recs, internalState @*/
00216 {
00217     unsigned pri = RPMLOG_PRI(code);
00218     unsigned mask = RPMLOG_MASK(pri);
00219 #if 0
00220     /*@unused@*/ unsigned fac = RPMLOG_FAC(code);
00221 #endif
00222     char *msgbuf, *msg;
00223     size_t msgnb = BUFSIZ;
00224     int nb;
00225     int cbrc = RPMLOG_DEFAULT;
00226     int needexit = 0;
00227     struct rpmlogRec_s rec;
00228 
00229     if ((mask & rpmlogMask) == 0)
00230         return;
00231 
00232     msgbuf = xmalloc(msgnb);
00233     *msgbuf = '\0';
00234 
00235     /* Allocate a sufficently large buffer for output. */
00236     while (1) {
00237         va_list apc;
00238         /*@-unrecog -usedef@*/ va_copy(apc, ap); /*@=unrecog =usedef@*/
00239         nb = vsnprintf(msgbuf, msgnb, fmt, apc);
00240         if (nb > -1 && (size_t)nb < msgnb)
00241             break;
00242         if (nb > -1)            /* glibc 2.1 (and later) */
00243             msgnb = nb+1;
00244         else                    /* glibc 2.0 */
00245             msgnb *= 2;
00246         msgbuf = xrealloc(msgbuf, msgnb);
00247 /*@-mods@*/
00248         va_end(apc);
00249 /*@=mods@*/
00250     }
00251     msgbuf[msgnb - 1] = '\0';
00252     msg = msgbuf;
00253 
00254     rec.code = code;
00255     rec.message = msg;
00256     rec.pri = pri;
00257 
00258     /* Save copy of all messages at warning (or below == "more important"). */
00259     if (pri <= RPMLOG_WARNING) {
00260         if (recs == NULL)
00261             recs = xmalloc((nrecs+2) * sizeof(*recs));
00262         else
00263             recs = xrealloc(recs, (nrecs+2) * sizeof(*recs));
00264         recs[nrecs].code = rec.code;
00265         recs[nrecs].pri = rec.pri;
00266         recs[nrecs].message = xstrdup(msgbuf);
00267         ++nrecs;
00268         recs[nrecs].code = 0;
00269         recs[nrecs].pri = 0;
00270         recs[nrecs].message = NULL;
00271     }
00272 
00273     if (_rpmlogCallback) {
00274         cbrc = _rpmlogCallback(&rec, _rpmlogCallbackData);
00275         needexit += cbrc & RPMLOG_EXIT;
00276     }
00277 
00278     if (cbrc & RPMLOG_DEFAULT) {
00279 /*@-usereleased@*/
00280         cbrc = rpmlogDefault(&rec);
00281 /*@=usereleased@*/
00282         needexit += cbrc & RPMLOG_EXIT;
00283     }
00284 
00285 /*@-usereleased@*/      /* msgbuf is NULL or needs free'ing */
00286     msgbuf = _free(msgbuf);
00287 /*@=usereleased@*/
00288     if (needexit)
00289         exit(EXIT_FAILURE);
00290 }
00291 /*@=compmempass =nullstate@*/
00292 /*@=modfilesys@*/
00293 
00294 void _rpmlog (int code, const char *fmt, ...)
00295 {
00296     va_list ap;
00297 
00298     va_start(ap, fmt);
00299     /*@-internalglobs@*/ /* FIX: shrug */
00300     vrpmlog(code, fmt, ap);
00301     /*@=internalglobs@*/
00302     va_end(ap);
00303 }

Generated on Fri Dec 3 2010 20:54:34 for rpm by  doxygen 1.7.2