rpm 5.2.1

- 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 }