⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 log.c

📁 这是一个LINUX环境的 VDR 插件源代码,可支持Irdeto, Seca, Viaccess, Nagra, Conax & Cryptoworks等CA系统的读卡、共享等操作。
💻 C
字号:
/* * Softcam plugin to VDR (C++) * * This code is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This code is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * Or, point your browser to http://www.gnu.org/copyleft/gpl.html */#include <stdlib.h>#include <stdio.h>#include <stdarg.h>#include <unistd.h>#include <time.h>#include <vdr/tools.h>#include <vdr/thread.h>#include "log.h"#include "misc.h"#define LMOD_SUP 32#define LMOD_CFG_VALID  0x80000000struct LogHeader {  int c;  char stamp[32];  char tag[64];  };struct LogConfig logcfg = {  1,0,0,  "/var/log/vdr-sc"  };static const struct LogModule lm_general = {  (LMOD_ENABLE|L_GEN_ALL)&LOPT_MASK,  (LMOD_ENABLE|L_GEN_ALL)&LOPT_MASK,  "general", { "error","warn","info","debug","misc" }  };static const struct LogModule *mods[LMOD_SUP] = { &lm_general };static int config[LMOD_SUP] = { LMOD_ENABLE|L_GEN_ALL|LMOD_CFG_VALID };static int cmask[LMOD_SUP]  = { LMOD_ENABLE|L_GEN_ALL };static cMutex logfileMutex;static FILE *logfile=0;static bool logfileShutup=false, logfileReopen=false;static unsigned int lastCrc=0;static int lastC=0, lastCount=0;static cTimeMs lastTime;static cMutex lastMutex;// -- cLogging -----------------------------------------------------------------bool cLogging::AddModule(int m, const struct LogModule *lm){  if(m<LMOD_SUP) {    if(mods[m]) Printf(L_GEN_DEBUG,"duplicate logging module id %d (%s & %s)",m,mods[m]->Name,lm->Name);    mods[m]=lm;    if(config[m]&LMOD_CFG_VALID) UpgradeOptions(m);    else SetModuleDefault(LCLASS(m,0));//printf("module %-16s added. mod=%x supp=%x def=%x cfg=%x\n",lm->Name,m,lm->OptSupported,lm->OptDefault,config[m]);    }  else Printf(L_GEN_DEBUG,"failed to add logging module %d (%s)",m,lm->Name);  return true;}const struct LogModule *cLogging::GetModule(int c){  int m=LMOD(c);  return m<LMOD_SUP ? mods[m] : 0;}bool cLogging::GetHeader(int c, struct LogHeader *lh){  const struct LogModule *lm=GetModule(c);  if(lm) {    time_t tt=time(0);    struct tm tm_r;    strftime(lh->stamp,sizeof(lh->stamp),"%b %e %T",localtime_r(&tt,&tm_r));    int i, o=LOPT(c)&~LMOD_ENABLE;    for(i=0; i<LOPT_NUM; i++,o>>=1) if(o&1) break;    snprintf(lh->tag,sizeof(lh->tag),"%s.%s",lm->Name,(i>=1 && i<LOPT_NUM && lm->OptName[i-1])?lm->OptName[i-1]:"unknown");    lh->c=c;    return true;    }  return false;  }void cLogging::LogLine(const struct LogHeader *lh, const char *txt, bool doCrc){  if(doCrc) {    unsigned int crc=crc32_le(0,(const unsigned char *)txt,strlen(txt)+1);    lastMutex.Lock();    if(lastCrc==crc && lastC==lh->c && ++lastCount<4000000 && lastTime.Elapsed()<=30*1000) {      lastMutex.Unlock();      return;      }    else {      unsigned int saveCrc=lastCrc;      int saveCount=lastCount, saveC=lastC;      lastTime.Set();      lastCrc=crc; lastC=lh->c; lastCount=0;      lastMutex.Unlock();      if(saveCount>1) {        struct LogHeader lh2;        if(GetHeader(saveC,&lh2)) {          char buff[128];          snprintf(buff,sizeof(buff),"last message repeated %d times",saveCount);          LogLine(&lh2,buff,false);          }        if(saveCrc==crc && saveC==lh->c) return;        }      }    }  if(logcfg.logCon)    printf("%s [%s] %s\n",lh->stamp,lh->tag,txt);  if(logcfg.logFile) {    if((!logfile && !logfileShutup) || logfileReopen) {      logfileMutex.Lock();      if(logfileReopen) {        logfileReopen=false;        if(logfile) {          PRINTF(L_GEN_DEBUG,"logfile closed, reopen as '%s'",logcfg.logFilename);          fclose(logfile);          logfile=0;          }        }      if(!logfile) {        logfile=fopen(logcfg.logFilename,"a");        if(logfile) {          setlinebuf(logfile);          PRINTF(L_GEN_DEBUG,"logfile '%s' opened",logcfg.logFilename);          }        else {          logfileShutup=true;          PRINTF(L_GEN_ERROR,"failed to open logfile '%s': %s",logcfg.logFilename,strerror(errno));          }        }      logfileMutex.Unlock();      }    if(logfile)      fprintf(logfile,"%s [%s] %s\n",lh->stamp,lh->tag,txt);    }  if(logcfg.logSys || LMOD(lh->c)==L_GEN) {    int pri=-1;    switch(lh->c) {      case L_GEN_ERROR:      case L_GEN_WARN:  if(SysLogLevel>0) pri=LOG_ERR; break;      case L_GEN_INFO:  if(SysLogLevel>1) pri=LOG_INFO; break;      case L_GEN_DEBUG: if(SysLogLevel>2) pri=LOG_DEBUG; break;      case L_GEN_MISC:  if(logcfg.logSys) pri=LOG_DEBUG; break;      default:          pri=LOG_DEBUG; break;      }    if(pri>=0)      syslog(pri,"[%d] [%s] %s",cThread::ThreadId(),lh->tag,txt);    }}bool cLogging::Enabled(int c){  int m=LMOD(c);  int o=LOPT(c)|LMOD_CFG_VALID|LMOD_ENABLE;  return m<LMOD_SUP && (config[m] & o)==o;}void cLogging::Printf(int c, const char *format, ...){  if(Enabled(c)) {    struct LogHeader lh;    if(GetHeader(c,&lh)) {      char buff[1024];      va_list ap;      va_start(ap,format);      vsnprintf(buff,sizeof(buff),format,ap);      va_end(ap);      LogLine(&lh,buff);      }    }}void cLogging::Puts(int c, const char *txt){  if(txt && Enabled(c)) {    struct LogHeader lh;    if(GetHeader(c,&lh)) {      LogLine(&lh,txt);      }    }}void cLogging::PutLB(int c, cLineBuff *lb){  if(lb->Length()>0) {    Puts(c,lb->Line());    lb->Flush();    }}void cLogging::Dump(int c, const void *data, int n, const char *format, ...){  if(Enabled(c)) {    struct LogHeader lh;    if(GetHeader(c,&lh)) {      char buff[1024];      va_list ap;      va_start(ap,format);      vsnprintf(buff,sizeof(buff),format,ap);      va_end(ap);      LogLine(&lh,buff);      const unsigned char *d=(const unsigned char *)data;      for(int i=0; i<n;) {        int q=sprintf(buff,"%04x:",i);        for(int l=0 ; l<16 && i<n ; l++) q+=sprintf(&buff[q]," %02x",d[i++]);        LogLine(&lh,buff);        }      }    }}void cLogging::LineDump(int c, const void *data, int n, const char *format, ...){  if(Enabled(c)) {    struct LogHeader lh;    if(GetHeader(c,&lh)) {      char buff[4096];      va_list ap;      va_start(ap,format);      unsigned int q=vsnprintf(buff,sizeof(buff),format,ap);      va_end(ap);      const unsigned char *d=(const unsigned char *)data;      for(int i=0; i<n; i++) {        if(q>=sizeof(buff)-8) {          q+=snprintf(&buff[q],sizeof(buff)-q,"....");          break;          }        q+=snprintf(&buff[q],sizeof(buff)-q," %02x",d[i]);        }      LogLine(&lh,buff);      }    }}void cLogging::SetModuleDefault(int c){  const struct LogModule *lm=GetModule(c);  if(lm) {    int m=LMOD(c);    config[m]=(lm->OptDefault&LOPT_MASK)|LMOD_CFG_VALID;    cmask[m] = lm->OptSupported&LOPT_MASK;    }}void cLogging::SetModuleOptions(int c){  const struct LogModule *lm=GetModule(c);  if(lm) config[LMOD(c)]=(LOPT(c)&(lm->OptSupported&LOPT_MASK))|LMOD_CFG_VALID;}int cLogging::GetModuleOptions(int c){  const struct LogModule *lm=GetModule(c);  return lm ? LOPT(config[LMOD(c)]) : -1;}void cLogging::SetModuleOption(int c, bool on){  const struct LogModule *lm=GetModule(c);  if(lm) {    int m=LMOD(c);    int o=LOPT(c)&(lm->OptSupported&LOPT_MASK);    if(o) {      if(on) config[m]|=o; else config[m]&=(~o);      config[m]|=LMOD_CFG_VALID;      }    }}void cLogging::UpgradeOptions(int m){  const struct LogModule *lm=mods[m];  if(lm) {    config[m]&=(lm->OptSupported&LOPT_MASK);    config[m]|=(lm->OptDefault&LOPT_MASK)&(~cmask[m]);    cmask[m]  =lm->OptSupported&LOPT_MASK;    config[m]|=LMOD_CFG_VALID;    }}const char *cLogging::GetModuleName(int c){  const struct LogModule *lm=GetModule(c);  return lm ? lm->Name : 0;}const char *cLogging::GetOptionName(int c){  const struct LogModule *lm=GetModule(c);  if(lm) {    int o=LOPT(c)&~LMOD_ENABLE;    if(lm->OptSupported & o) {      int i;      for(i=0; i<LOPT_NUM; i++,o>>=1) if(o&1) break;      return (i>=1 && i<LOPT_NUM && lm->OptName[i-1]) ? lm->OptName[i-1] : 0;      }    }  return 0;}bool cLogging::GetConfig(cLineBuff *lb){  lb->Flush();  bool cont=false;  for(int m=1; m<LMOD_SUP; m++)    if(config[m]&LMOD_CFG_VALID) {      lb->Printf("%s%d:%x:%x",cont?",":"",m,config[m]&~LMOD_CFG_VALID,cmask[m]);      cont=true;      }  return cont;}void cLogging::ParseConfig(const char *txt){  int n=0, l, m, o, d;  while(sscanf(&txt[n],"%d:%x:%x%n",&m,&o,&d,&l)==3) {    if(m>=1 && m<LMOD_SUP) {      config[m]=(o&LOPT_MASK)|LMOD_CFG_VALID;      cmask[m] =(d&LOPT_MASK);      UpgradeOptions(m);      }    n+=l;    if(txt[n]!=',') break;    n++;    }}void cLogging::ReopenLogfile(void){  logfileMutex.Lock();  logfileReopen=true;  logfileMutex.Unlock();}int cLogging::GetClassByName(const char *name){  const char *s=index(name,'.');  if(s) {    unsigned int l=s-name;    for(int m=1; m<LMOD_SUP; m++) {      const struct LogModule *lm=mods[m];      if(lm && strlen(lm->Name)==l && !strncasecmp(name,lm->Name,l)) {        s++;        if(!strcasecmp(s,"enable"))           return LCLASS(m,1);        for(int o=1; o<LOPT_NUM; o++)          if((lm->OptSupported&(1<<o)) && lm->OptName[o-1] && !strcasecmp(s,lm->OptName[o-1]))            return LCLASS(m,1<<o);        break;        }      }    }  return -1;  }// -- cLogLineBuff -------------------------------------------------------------cLogLineBuff::cLogLineBuff(int C):cLineBuff(256){  c=C;}cLogLineBuff::~cLogLineBuff(){  Flush();}void cLogLineBuff::Flush(void){  cLogging::PutLB(c,this);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -