Revert rpmrc excision for now.
[platform/upstream/rpm.git] / rpmio / rpmlog.c
1 /** \ingroup rpmio
2  * \file rpmio/rpmlog.c
3  */
4
5 #include "system.h"
6
7 #include <stdarg.h>
8
9 #include "rpmlog.h"
10
11 /*@access rpmlogRec @*/
12
13 static int nrecs = 0;
14 static rpmlogRec recs = NULL;
15
16 int rpmlogGetNrecs(void)
17 {
18     return nrecs;
19 }
20
21 const char * rpmlogMessage(void)
22 {
23     if (nrecs > 0)
24         return recs[nrecs-1].message;
25     return _("(no error)");
26 }
27
28 void rpmlogPrint(FILE *f)
29 {
30     int i;
31
32     if (f == NULL)
33         f = stderr;
34
35     for (i = 0; i < nrecs; i++) {
36         rpmlogRec rec = recs + i;
37         if (rec->message && *rec->message)
38             fprintf(f, "    %s\n", rec->message);
39     }
40 }
41
42 void rpmlogClose (void)
43 {
44     int i;
45
46     for (i = 0; i < nrecs; i++) {
47         rpmlogRec rec = recs + i;
48         if (rec->message) {
49             free((void *)rec->message);
50             rec->message = NULL;
51         }
52     }
53     free(recs);
54     recs = NULL;
55     nrecs = 0;
56 }
57
58 void rpmlogOpen (const char *ident, int option, int facility)
59 {
60 }
61
62 static int rpmlogMask = RPMLOG_UPTO( RPMLOG_NOTICE );
63 static int rpmlogFacility = RPMLOG_USER;
64
65 int rpmlogSetMask (int mask)
66 {
67     int omask = rpmlogMask;
68     if (mask)
69         rpmlogMask = mask;
70     return omask;
71 }
72
73 static rpmlogCallback _rpmlogCallback = NULL;
74
75 rpmlogCallback rpmlogSetCallback(rpmlogCallback cb)
76 {
77     rpmlogCallback ocb = _rpmlogCallback;
78     _rpmlogCallback = cb;
79     return ocb;
80 }
81
82 static char *rpmlogMsgPrefix[] = {
83     N_("fatal error: "),/*!< RPMLOG_EMERG */
84     N_("fatal error: "),/*!< RPMLOG_ALERT */
85     N_("fatal error: "),/*!< RPMLOG_CRIT */
86     N_("error: "),      /*!< RPMLOG_ERR */
87     N_("warning: "),    /*!< RPMLOG_WARNING */
88     "",                 /*!< RPMLOG_NOTICE */
89     "",                 /*!< RPMLOG_INFO */
90     "D: ",              /*!< RPMLOG_DEBUG */
91 };
92
93 static void vrpmlog (int code, const char *fmt, va_list ap)
94 {
95     int pri = RPMLOG_PRI(code);
96     int mask = RPMLOG_MASK(pri);
97     int fac = RPMLOG_FAC(code);
98     char msgbuf[BUFSIZ], *msg;
99     FILE * msgout = stderr;
100     rpmlogRec rec;
101
102     if ((mask & rpmlogMask) == 0)
103         return;
104
105     vsnprintf(msgbuf, sizeof(msgbuf), fmt, ap);
106     msgbuf[sizeof(msgbuf) - 1] = '\0';
107     msg = msgbuf;
108
109     /* Save copy of all messages at warning (or below == "more important"). */
110     if (pri <= RPMLOG_WARNING) {
111
112         if (recs == NULL)
113             recs = xmalloc((nrecs+2) * sizeof(*recs));
114         else
115             recs = xrealloc(recs, (nrecs+2) * sizeof(*recs));
116         recs[nrecs+1].code = 0;
117         recs[nrecs+1].message = NULL;
118         rec = recs + nrecs;
119         ++nrecs;
120
121         rec->code = code;
122         rec->message = xstrdup(msg);
123
124         if (_rpmlogCallback) {
125             _rpmlogCallback();
126             return;     /* XXX Preserve legacy rpmError behavior. */
127         }
128     }
129
130     /* rpmMessage behavior */
131
132     switch (pri) {
133     case RPMLOG_INFO:
134     case RPMLOG_NOTICE:
135         msgout = stdout;
136         break;
137
138     case RPMLOG_EMERG:
139     case RPMLOG_ALERT:
140     case RPMLOG_CRIT:
141     case RPMLOG_ERR: /* XXX Legacy rpmError behavior used stdout w/o prefix. */
142     case RPMLOG_WARNING:
143     case RPMLOG_DEBUG:
144         break;
145     }
146
147     /* Silly FORTRAN-like carriage control. */
148     if (*msg == '+')
149         msg++;
150     else if (rpmlogMsgPrefix[pri] && *rpmlogMsgPrefix[pri])
151         fputs(_(rpmlogMsgPrefix[pri]), msgout);
152
153     fputs(msg, msgout);
154     fflush(msgout);
155     if (pri <= RPMLOG_CRIT)
156         exit(EXIT_FAILURE);
157 }
158
159 void rpmlog (int code, const char *fmt, ...)
160 {
161     va_list ap;
162
163     va_start(ap, fmt);
164     vrpmlog(code, fmt, ap);
165     va_end(ap);
166 }