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
00023
00024 static int nrecs = 0;
00025 static rpmlogRec recs = NULL;
00026
00032 static inline void *
00033 _free( const void * 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 ( const char *ident, int option,
00088 int facility)
00089 {
00090 }
00091
00092 static int rpmlogMask = RPMLOG_UPTO( RPMLOG_NOTICE );
00093 static 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 rpmlogCallback _rpmlogCallback = NULL;
00104
00105 rpmlogCallback rpmlogSetCallback(rpmlogCallback cb)
00106 {
00107 rpmlogCallback ocb = _rpmlogCallback;
00108 _rpmlogCallback = cb;
00109 return ocb;
00110 }
00111
00112
00113 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
00124
00125 #if !defined(HAVE_VSNPRINTF)
00126 static inline int vsnprintf(char * buf, int nb,
00127 const char * fmt, va_list ap)
00128 {
00129 return vsprintf(buf, fmt, ap);
00130 }
00131 #endif
00132
00133 static void vrpmlog (unsigned code, const char *fmt, va_list ap)
00134
00135 {
00136 int pri = RPMLOG_PRI(code);
00137 int mask = RPMLOG_MASK(pri);
00138 int fac = RPMLOG_FAC(code);
00139 char *msgbuf, *msg;
00140 int msgnb = BUFSIZ, nb;
00141 FILE * msgout = stderr;
00142
00143 if ((mask & rpmlogMask) == 0)
00144 return;
00145
00146 msgbuf = xmalloc(msgnb);
00147 *msgbuf = '\0';
00148
00149
00150 while (1) {
00151 va_list apc;
00152 va_copy(apc, ap);
00153 nb = vsnprintf(msgbuf, msgnb, fmt, apc);
00154 if (nb > -1 && nb < msgnb)
00155 break;
00156 if (nb > -1)
00157 msgnb = nb+1;
00158 else
00159 msgnb *= 2;
00160 msgbuf = xrealloc(msgbuf, msgnb);
00161 }
00162 msgbuf[msgnb - 1] = '\0';
00163 msg = msgbuf;
00164
00165
00166 if (pri <= RPMLOG_WARNING) {
00167
00168 if (recs == NULL)
00169 recs = xmalloc((nrecs+2) * sizeof(*recs));
00170 else
00171 recs = xrealloc(recs, (nrecs+2) * sizeof(*recs));
00172 recs[nrecs].code = code;
00173 recs[nrecs].message = msg = xrealloc(msgbuf, strlen(msgbuf)+1);
00174 msgbuf = NULL;
00175 recs[nrecs+1].code = 0;
00176 recs[nrecs+1].message = NULL;
00177 ++nrecs;
00178
00179 if (_rpmlogCallback) {
00180 _rpmlogCallback();
00181 return;
00182 }
00183 }
00184
00185
00186
00187 switch (pri) {
00188 case RPMLOG_INFO:
00189 case RPMLOG_NOTICE:
00190 msgout = stdout;
00191 break;
00192
00193 case RPMLOG_EMERG:
00194 case RPMLOG_ALERT:
00195 case RPMLOG_CRIT:
00196 case RPMLOG_ERR:
00197 case RPMLOG_WARNING:
00198 case RPMLOG_DEBUG:
00199 break;
00200 }
00201
00202 if (rpmlogMsgPrefix[pri] && *rpmlogMsgPrefix[pri])
00203 (void) fputs(_(rpmlogMsgPrefix[pri]), msgout);
00204
00205 (void) fputs(msg, msgout);
00206 (void) fflush(msgout);
00207 msgbuf = _free(msgbuf);
00208 if (pri <= RPMLOG_CRIT)
00209 exit(EXIT_FAILURE);
00210 }
00211
00212 void rpmlog (int code, const char *fmt, ...)
00213 {
00214 va_list ap;
00215
00216 va_start(ap, fmt);
00217 vrpmlog(code, fmt, ap);
00218 va_end(ap);
00219 }
00220
00221 int rpmErrorCode(void)
00222 {
00223 return rpmlogCode();
00224 }
00225
00226 const char * rpmErrorString(void)
00227 {
00228 return rpmlogMessage();
00229 }
00230
00231 rpmlogCallback rpmErrorSetCallback(rpmlogCallback cb)
00232 {
00233 return rpmlogSetCallback(cb);
00234 }