Log.c (3539B)
1 /* 2 * SIGI - Swisscom Internet GTK Interface 3 * 4 * @author: Dominik Schmidt <domischmidt@swissonline.ch> 5 * @license: CC-BY-SA-3.0 6 * @version: 2.0.0 7 */ 8 #include <EGong/Util/Log.h> 9 #include <EGong/Util/Misc.h> 10 11 #include <errno.h> 12 #include <unistd.h> 13 #include <stdlib.h> 14 #include <string.h> 15 #include <stdarg.h> 16 #ifdef _WIN32 17 #include <stdio.h> 18 #include <windows.h> 19 #include <winnt.h> 20 #endif 21 22 struct log_level log_levels[LOG_LEVEL_COUNT]={ 23 [LOG_LEVEL_DEBUG]={.name="DEBUG", .color="\e[2;37;40m"}, 24 [LOG_LEVEL_INFO]={.name="INFO", .color="\e[0;37;40m"}, 25 [LOG_LEVEL_WARNING]={.name="WARNING", .color="\e[1;33;40m"}, 26 [LOG_LEVEL_ERROR]={.name="ERROR", .color="\e[1;31;40m"}, 27 [LOG_LEVEL_FATAL]={.name="FATAL", .color="\e[1;33;41m"} 28 }; 29 30 void log_write_stdio(const char *msg, unsigned int length, unsigned int type, unsigned int level){ 31 int fd=STDOUT_FILENO; 32 if(level>=LOG_LEVEL_WARNING){ 33 fd=STDERR_FILENO; 34 } 35 if(EGong_global_configuration.log.color){ 36 STDNWRITE(log_levels[level].color,sizeof(((struct log_level *)NULL)->color)); 37 } 38 write(fd,msg,length); 39 if(EGong_global_configuration.log.color){ 40 STDWRITE("\e[0m"); 41 } 42 } 43 void do_log_call_composite(const struct log_source src, unsigned int type, unsigned int level, unsigned int destmask, ...){ 44 va_list ap; 45 va_start(ap, destmask); 46 char *arg=NULL; 47 char *buf=NULL; 48 char *bufptr=buf; 49 unsigned int length=0, totallength=0, alloc=0; 50 while(1){ 51 arg=va_arg(ap, char *); 52 if(arg==NULL){ 53 break; 54 } 55 length=strlen(arg); 56 if(length+totallength>100*alloc){ 57 buf=realloc(buf,((unsigned int)((length+totallength)/100)+1)*100); 58 bufptr=buf+totallength; 59 } 60 STRNCAT(bufptr,arg,length); 61 totallength+=length; 62 } 63 va_end (ap); 64 do_log_call(src, buf, totallength, type, level, destmask); 65 } 66 void do_log_call(const struct log_source src, const char *msg, unsigned int msglength, unsigned int type, unsigned int level, unsigned int destmask){ 67 if(EGong_global_configuration.log.level>level){ 68 return; 69 } 70 int error=errno; 71 char msgdest[msglength+src.file.l+src.line.l+src.func.l+50]; 72 const char *msgptr=msgdest; 73 char *msgbuf=msgdest; 74 unsigned int length=0; 75 if(type!=LOG_TYPE_RAW){ 76 STRCAT(msgbuf,"[") 77 STRNCAT(msgbuf, log_levels[level].name, strlen(log_levels[level].name)); 78 STRCAT(msgbuf,"] "); 79 80 STRNCAT(msgbuf,src.file.v, src.file.l-1); 81 STRCAT(msgbuf,":"); 82 STRNCAT(msgbuf, src.line.v, src.line.l-1); 83 STRCAT(msgbuf,", "); 84 STRNCAT(msgbuf, src.func.v, src.func.l-1); 85 STRCAT(msgbuf,": "); 86 87 STRNCAT(msgbuf, msg, msglength); 88 #ifdef _WIN32 89 if(type==LOG_TYPE_SIGNAL||type==LOG_TYPE_SOCKET){ 90 STRCAT(msgbuf,"("); 91 DWORD error; 92 if(type==LOG_TYPE_SIGNAL){ 93 error=GetLastError(); 94 } 95 else{ 96 error = WSAGetLastError(); 97 } 98 LPTSTR lpMsgBuf = (LPTSTR)"Unknown error"; 99 size_t ret=FormatMessage( 100 FORMAT_MESSAGE_ALLOCATE_BUFFER | 101 FORMAT_MESSAGE_FROM_SYSTEM | 102 FORMAT_MESSAGE_IGNORE_INSERTS, 103 NULL, error, 104 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), 105 (LPTSTR)&lpMsgBuf, 0, NULL); 106 if(ret){ 107 lpMsgBuf[ret-2]='\0'; 108 STRNCAT(msgbuf, lpMsgBuf,ret); 109 LocalFree(lpMsgBuf); 110 } 111 else{ 112 STRCAT(msgbuf,"Unknown"); 113 } 114 STRCAT(msgbuf,")"); 115 } 116 #else 117 if(type==LOG_TYPE_SIGNAL){ 118 char *err=strerror(error); 119 STRCAT(msgbuf,"("); 120 STRNCAT(msgbuf, err,strlen(err)); 121 STRCAT(msgbuf,")"); 122 } 123 #endif 124 STRCAT(msgbuf,"\n\0"); 125 length=(unsigned int)(msgbuf-msgptr); 126 } 127 else{ 128 msgptr=msg; 129 length=msglength; 130 } 131 if((destmask&LOG_DEST_STDIO)>0){ 132 log_write_stdio(msgptr,length, type, level); 133 } 134 }