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 void rpmlog (int code, const char *fmt, ...)
00134
00135 {
00136 va_list ap;
00137 int pri = RPMLOG_PRI(code);
00138 int mask = RPMLOG_MASK(pri);
00139 int fac = RPMLOG_FAC(code);
00140 char *msgbuf, *msg;
00141 int msgnb = BUFSIZ, nb;
00142 FILE * msgout = stderr;
00143
00144 if ((mask & rpmlogMask) == 0)
00145 return;
00146
00147 msgbuf = xmalloc(msgnb);
00148 *msgbuf = '\0';
00149
00150
00151 while (1) {
00152 va_start(ap, fmt);
00153 nb = vsnprintf(msgbuf, msgnb, fmt, ap);
00154 va_end(ap);
00155 if (nb > -1 && nb < msgnb)
00156 break;
00157 if (nb > -1)
00158 msgnb = nb+1;
00159 else
00160 msgnb *= 2;
00161 msgbuf = xrealloc(msgbuf, msgnb);
00162 }
00163 msgbuf[msgnb - 1] = '\0';
00164 msg = msgbuf;
00165
00166
00167 if (pri <= RPMLOG_WARNING) {
00168
00169 if (recs == NULL)
00170 recs = xmalloc((nrecs+2) * sizeof(*recs));
00171 else
00172 recs = xrealloc(recs, (nrecs+2) * sizeof(*recs));
00173 recs[nrecs].code = code;
00174 recs[nrecs].message = msg = xrealloc(msgbuf, strlen(msgbuf)+1);
00175 msgbuf = NULL;
00176 recs[nrecs+1].code = 0;
00177 recs[nrecs+1].message = NULL;
00178 ++nrecs;
00179
00180 if (_rpmlogCallback) {
00181 _rpmlogCallback();
00182 return;
00183 }
00184 }
00185
00186
00187
00188 switch (pri) {
00189 case RPMLOG_INFO:
00190 case RPMLOG_NOTICE:
00191 msgout = stdout;
00192 break;
00193
00194 case RPMLOG_EMERG:
00195 case RPMLOG_ALERT:
00196 case RPMLOG_CRIT:
00197 case RPMLOG_ERR:
00198 case RPMLOG_WARNING:
00199 case RPMLOG_DEBUG:
00200 break;
00201 }
00202
00203 if (rpmlogMsgPrefix[pri] && *rpmlogMsgPrefix[pri])
00204 (void) fputs(_(rpmlogMsgPrefix[pri]), msgout);
00205
00206 (void) fputs(msg, msgout);
00207 (void) fflush(msgout);
00208 msgbuf = _free(msgbuf);
00209 if (pri <= RPMLOG_CRIT)
00210 exit(EXIT_FAILURE);
00211 }
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224 int rpmErrorCode(void)
00225 {
00226 return rpmlogCode();
00227 }
00228
00229 const char * rpmErrorString(void)
00230 {
00231 return rpmlogMessage();
00232 }
00233
00234 rpmlogCallback rpmErrorSetCallback(rpmlogCallback cb)
00235 {
00236 return rpmlogSetCallback(cb);
00237 }