2 * Written by David Herrmann.
3 * Dedicated to the Public Domain.
17 /* /path/to/logfile.log or NULL. */
18 const char *iauth_logfile = NULL;
19 /* Current logfile or NULL. */
21 /* 1 if debug mode is enabled, otherwise 0. */
22 unsigned int iauth_debug = 0;
24 static void iauth_error(const char *msg, size_t len) {
25 fwrite(msg, 1, len, stderr);
26 fwrite("\n", 1, 1, stderr);
31 void iauth_ferror(const char *format, ...) {
34 va_start(arg, format);
35 iauth_verror(format, arg);
39 void iauth_verror(const char *format, va_list list) {
40 char buffer[IAUTH_LINE + 1];
43 memset(buffer, 0, IAUTH_LINE + 1);
44 len = vsnprintf(buffer, IAUTH_LINE, format, list);
45 if(!len) len = snprintf(buffer, IAUTH_LINE, "<no error message specified>");
46 iauth_error(buffer, len);
49 /* Checks whether we need to reopen the logfile.
50 * Aborts the application if the logfile cannot be
53 static void iauth_log_reopen() {
55 if(logfile) fclose(logfile);
56 logfile = fopen(iauth_logfile, "a");
57 if(!logfile) iauth_ferror("Logfile '%s' could not be opened in mode 'a'; errno = '%d'.", iauth_logfile, errno);
60 else if(!logfile) iauth_ferror("No logfile specified.");
63 static void iauth_log(unsigned int type, const char *msg, size_t len) {
66 char buffer[IAUTH_LINE + 1];
72 tstamp = localtime(&curtime);
73 memset(buffer, 0, IAUTH_LINE + 1);
74 len2 = snprintf(buffer, IAUTH_LINE + 1, "[%02d.%02d.%d %02d:%02d:%02d]", tstamp->tm_mday, tstamp->tm_mon + 1, tstamp->tm_year + 1900,
75 tstamp->tm_hour, tstamp->tm_min, tstamp->tm_sec);
76 len2 += snprintf(&buffer[len2], IAUTH_LINE + 1 - len2, " (%s): ", (type == IAUTH_FATAL)?"FATAL":(type == IAUTH_WARNING)?"WARNING":
77 (type == IAUTH_INFO)?"INFO":(type == IAUTH_DEBUG)?"DEBUG":"UNKNOWN");
79 if(fwrite(buffer, 1, len2, logfile) != len2) iauth_ferror("Write operation on logfile failed; errno = '%d'.", errno);
80 if(fwrite(msg, 1, len, logfile) != len) iauth_ferror("Write operation on logfile failed; errno = '%d'.", errno);
81 fwrite("\n", 1, 1, logfile);
85 void iauth_flog(unsigned int type, const char *format, ...) {
88 va_start(arg, format);
89 iauth_vlog(type, format, arg);
93 void iauth_vlog(unsigned int type, const char *format, va_list list) {
94 char buffer[IAUTH_LINE + 1];
97 memset(buffer, 0, IAUTH_LINE + 1);
98 len = vsnprintf(buffer, IAUTH_LINE, format, list);
99 if(!len) len = snprintf(buffer, IAUTH_LINE, "<no message specified>");
100 iauth_log(type, buffer, len);
103 void iauth_eflog(const char *format, ...) {
106 va_start(arg, format);
107 iauth_evlog(format, arg);
111 void iauth_evlog(const char *format, va_list list) {
112 char buffer[IAUTH_LINE + 1];
115 memset(buffer, 0, IAUTH_LINE + 1);
116 len = vsnprintf(buffer, IAUTH_LINE, format, list);
117 if(!len) len = snprintf(buffer, IAUTH_LINE, "<no message specified>");
118 iauth_log(IAUTH_FATAL, buffer, len);
119 iauth_error(buffer, len);
123 static char buffer[IAUTH_LINE + 1];
124 unsigned int i, ignore = 0;
128 if(!fgets(buffer, IAUTH_LINE, stdin)) {
129 if(feof(stdin)) return NULL;
130 iauth_eflog("Reading on stdin failed; errno = '%d'.", errno);
132 buffer[IAUTH_LINE] = 0;
134 for(i = 0; i < IAUTH_LINE; ++i) {
135 if(buffer[i] == '\n') {
140 if(i == 0) goto next_line;
141 if(buffer[i - 1] == '\r') {
142 if(i == 1) goto next_line;
147 iauth_flog(IAUTH_DEBUG, "IN -> %s", buffer);
153 /* Too long message. Discard it! */
154 iauth_flog(IAUTH_WARNING, "Message exceeded maximum length of '%d' bytes.", IAUTH_LINE);
159 void iauth_fsend(const char *format, ...) {
162 va_start(arg, format);
163 iauth_vsend(format, arg);
167 void iauth_vsend(const char *format, va_list list) {
168 char buffer[IAUTH_LINE + 1];
171 memset(buffer, 0, IAUTH_LINE + 1);
173 len2 = snprintf(buffer, IAUTH_LINE, "OUT <- ");
174 len = vsnprintf(&buffer[len2], IAUTH_LINE, format, list);
176 iauth_log(IAUTH_DEBUG, buffer, len + len2);
177 if(write(0, &buffer[len2], len) != len) iauth_eflog("IAuth write operation failed; errno = '%d'", errno);
181 len = vsnprintf(buffer, IAUTH_LINE, format, list);
183 if(write(0, buffer, len) != len) iauth_eflog("IAuth write operation failed; errno = '%d'", errno);