| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080 |
- /*
- 3APA3A simpliest proxy server
- (c) 2002-2020 by Vladimir Dubrovin <3proxy@3proxy.ru>
- please read License Agreement
- */
- #include "proxy.h"
- pthread_mutex_t log_mutex;
- #ifdef _WIN32
- HANDLE log_sem;
- #else
- sem_t log_sem;
- #endif
- #define MAXLOG 1024
- #define EVENTSIZE (4096 - sizeof(void *))
- #define LOGBUFSIZE (EVENTSIZE - sizeof(struct logevent))
- #define MAX_SEM_COUNT 256
- typedef enum {
- REGISTER,
- UNREGISTER,
- LOG,
- FLUSH,
- FREEPARAM
- } EVENTTYPE;
- struct clientparam logparam;
- struct srvparam logsrv;
- struct LOGGER;
- void(*prelog)(struct clientparam * param) = NULL;
- struct logevent {
- struct logevent *next;
- struct LOGGER *log;
- EVENTTYPE event;
- int inbuf;
- struct clientparam *param;
- char * logstring;
- char buf[1];
- } *logtail=NULL, *loghead=NULL;
- static void delayflushlogs(void);
- static void delayunregisterlog (struct LOGGER * log);
- static void delayregisterlog (struct LOGGER * log);
- static void delaydolog(struct logevent *evt);
- static void delayfreeparam(struct clientparam *param);
- void logpush(struct logevent *evt);
- #ifdef WITHMAIN
- #define HAVERADIUS 0
- #define HAVESQL 0
- #else
- int raddobuf(struct clientparam * param, unsigned char * buf, int bufsize, const unsigned char *s);
- void logradius(const char * buf, int len, struct LOGGER *logger);
- #define HAVERADIUS 1
- #ifndef NOODBC
- #define HAVESQL 1
- static int sqlinit(struct LOGGER *logger);
- static int sqldobuf(struct clientparam * param, unsigned char * buf, int bufsize, const unsigned char *s);
- static void sqllog(const char * buf, int len, struct LOGGER *logger);
- static void sqlrotate(struct LOGGER *logger);
- static void sqlclose(struct LOGGER *logger);
- #else
- #define HAVESQL 0
- #endif
- #endif
- #ifdef _WIN32
- #define HAVESYSLOG 0
- #else
- #define HAVESYSLOG 1
- static int sysloginit(struct LOGGER *logger);
- static void logsyslog(const char * buf, int len, struct LOGGER *logger);
- static void syslogrotate(struct LOGGER *logger);
- static void syslogclose(struct LOGGER *logger);
- #endif
- static int stdloginit(struct LOGGER *logger);
- static int stddobuf(struct clientparam * param, unsigned char * buf, int bufsize, const unsigned char *s);
- static void stdlog(const char * buf, int len, struct LOGGER *logger);
- static void stdlogrotate(struct LOGGER *logger);
- static void stdlogclose(struct LOGGER *logger);
- static void stdlogflush(struct LOGGER *logger);
- struct LOGFUNC stdlogfuncs[] = {
- #if HAVESYSLOG > 0
- {stdlogfuncs+1, sysloginit, stddobuf, logsyslog, syslogrotate, NULL, syslogclose, "@"},
- #endif
- #if HAVERADIUS > 0
- {stdlogfuncs+1+HAVESYSLOG, NULL, raddobuf, logradius, NULL, NULL, NULL, "radius"},
- #endif
- #if HAVESQL > 0
- {stdlogfuncs+1+HAVESYSLOG+HAVERADIUS, sqlinit, sqldobuf, sqllog, sqlrotate, NULL, sqlclose, "&"},
- #endif
- {NULL, stdloginit, stddobuf, stdlog, stdlogrotate, stdlogflush, stdlogclose, ""}
- };
- struct LOGFUNC *logfuncs = stdlogfuncs;
- struct stdlogdata{
- FILE *fp;
- } errld;
- struct LOGGER errlogger = {NULL, NULL, "stderr", &errld, stdlogfuncs+1+HAVESYSLOG+HAVERADIUS+HAVESQL, 0, 0, 1};
- struct LOGGER *loggers = &errlogger;
- static void delayflushlogs(void){
- struct LOGGER *log;
- for(log = loggers; log; log=log->next){
- if(log->logfunc && log->logfunc->flush)log->logfunc->flush(log);
- }
- }
- void flushlogs(void){
- struct logevent * evt;
- evt = malloc(sizeof(struct logevent));
- evt->event = FLUSH;
- logpush(evt);
- }
- void delayregisterlog(struct LOGGER *log){
- struct LOGFUNC *funcs;
- if(log->logfunc) return;
- for(funcs = logfuncs; funcs; funcs=funcs->next){
- if(!strncmp(log->selector, funcs->prefix, strlen(funcs->prefix))){
- if(funcs->init && funcs->init(log)) break;
- log->logfunc = funcs;
- return;
- }
- }
- }
- struct LOGGER * registerlog(const char * logstring, int logtype){
- struct LOGGER *log;
- if(!logstring || !strcmp(logstring, "NUL") || !strcmp(logstring, "/dev/null")) return NULL;
- pthread_mutex_lock(&log_mutex);
- for(log = loggers; log; log=log->next){
- if(!strcmp(logstring, log->selector)){
- if(logtype >= 0) log->rotate = logtype;
- log->registered++;
- pthread_mutex_unlock(&log_mutex);
- return log;
- }
- }
- log = malloc(sizeof(struct LOGGER));
- if(!log) {
- pthread_mutex_unlock(&log_mutex);
- return NULL;
- }
- memset (log, 0, sizeof(struct LOGGER));
- log->selector = mystrdup(logstring);
- if(log->selector){
- struct logevent *evt;
- if(logtype)log->rotate = logtype;
- log->registered++;
- log->next = loggers;
- if (log->next)log->next->prev = log;
- loggers = log;
- pthread_mutex_unlock(&log_mutex);
- evt = malloc(sizeof(struct logevent));
- evt->event = REGISTER;
- evt->log = log;
- logpush(evt);
- return log;
- }
- pthread_mutex_unlock(&log_mutex);
- myfree(log);
- return NULL;
- }
- static void delayunregisterlog (struct LOGGER * log){
- if(log){
- pthread_mutex_lock(&log_mutex);
- log->registered--;
- if(!log->registered){
- if(log->prev)log->prev->next = log->next;
- else loggers = log->next;
- if(log->next)log->next->prev = log->prev;
- pthread_mutex_unlock(&log_mutex);
- if(log->logfunc){
- if(log->logfunc->flush) log->logfunc->flush(log);
- if(log->logfunc->close) log->logfunc->close(log);
- }
- myfree(log->selector);
- myfree(log);
- }
- else pthread_mutex_unlock(&log_mutex);
- }
- }
- void unregisterlog (struct LOGGER * log){
- struct logevent *evt;
- if(!log) return;
- evt = malloc(sizeof(struct logevent));
- evt->event = UNREGISTER;
- evt->log = log;
- logpush(evt);
- }
- #ifdef _WIN32
- DWORD WINAPI logthreadfunc(LPVOID p) {
- #else
- void * logthreadfunc (void *p) {
- #endif
- for(;;){
- struct logevent *evt;
- #ifdef _WIN32
- WaitForSingleObject(log_sem, INFINITE);
- #else
- sem_wait(&log_sem);
- #endif
- while(loghead){
- pthread_mutex_lock(&log_mutex);
- evt = loghead;
- loghead = evt->next;
- if(!loghead)logtail = NULL;
- pthread_mutex_unlock(&log_mutex);
- switch(evt->event){
- case REGISTER:
- delayregisterlog(evt->log);
- break;
- case UNREGISTER:
- delayunregisterlog(evt->log);
- break;
- case FLUSH:
- delayflushlogs();
- break;
- case LOG:
- delaydolog(evt);
- break;
- case FREEPARAM:
- delayfreeparam(evt->param);
- break;
- default:
- break;
- }
- myfree(evt);
- }
- }
- return 0;
- }
- void logpush(struct logevent *evt){
- pthread_mutex_lock(&log_mutex);
- if(logtail) logtail->next = evt;
- logtail = evt;
- evt->next = NULL;
- if(!loghead)loghead = evt;
-
- pthread_mutex_unlock(&log_mutex);
- #ifdef _WIN32
- ReleaseSemaphore(log_sem, 1, NULL);
- #else
- sem_post(&log_sem);
- #endif
- }
- void initlog(void){
- pthread_t thread;
- srvinit(&logsrv, &logparam);
- pthread_mutex_init(&log_mutex, NULL);
- errld.fp = stdout;
- #ifdef _WIN32
- {
- HANDLE h;
- if(!(log_sem = CreateSemaphore(NULL, 0, MAX_SEM_COUNT, NULL))) exit(11);
- #ifndef _WINCE
- h = (HANDLE)_beginthreadex((LPSECURITY_ATTRIBUTES )NULL, 65536, (void *)logthreadfunc, NULL, 0, &thread);
- #else
- h = (HANDLE)CreateThread((LPSECURITY_ATTRIBUTES )NULL, 65536, (void *)logthreadfunc, NULL, 0, &thread);
- #endif
- if (h) {
- CloseHandle(h);
- }
- else {
- exit(10);
- }
- }
- #else
- {
- pthread_attr_t pa;
- pthread_attr_init(&pa);
- pthread_attr_setstacksize(&pa,PTHREAD_STACK_MIN + 1024*256);
- pthread_attr_setdetachstate(&pa,PTHREAD_CREATE_DETACHED);
- if(sem_init(&log_sem, 0, 0)) exit(11);
- if(pthread_create(&thread, &pa, logthreadfunc, NULL)) exit(10);
- }
- #endif
- }
- static void delaydolog(struct logevent *evt){
- if(!evt->log->logfunc || !evt->log->logfunc->log) return;
- if(evt->inbuf){
- evt->log->logfunc->log(evt->buf, evt->inbuf, evt->log);
- }
- else if(evt->param && evt->log->logfunc->dobuf){
- char buf[LOGBUFSIZE];
- evt->log->logfunc->log(buf, evt->log->logfunc->dobuf(evt->param, buf, LOGBUFSIZE, evt->logstring), evt->log);
- }
- }
- void dolog(struct clientparam * param, const unsigned char *s){
- static int init = 0;
- if(!param || !param->srv){
- stdlog(s, strlen(s), &errlogger);
- return;
- }
- if(prelog)prelog(param);
- if(!param->nolog && param->srv->log) {
- struct logevent *evt;
- if(!param->srv->log->logfunc) {
- int slen =0, hlen=0, ulen=0;
-
- slen = s?strlen(s)+1 : 0;
- hlen = param->hostname? strlen(param->hostname)+1 : 0;
- ulen = param->username? strlen(param->username)+1 : 0;
- if(!(evt = malloc(sizeof(struct logevent) + slen + ulen + hlen))) return;
- evt->inbuf = 0;
- evt->param=param;
- evt->logstring = NULL;
- if(slen){
- memcpy(evt->buf,s, slen);
- evt->logstring = evt->buf;
- }
- if(hlen){
- memcpy(evt->buf+slen,param->hostname, hlen);
- param->hostname = evt->buf + slen;
- }
- if(ulen){
- memcpy(evt->buf+slen+hlen,param->username, ulen);
- param->username = evt->buf + slen + hlen;
- }
- evt->event = LOG;
- evt->log = param->srv->log;
- logpush(evt);
- }
- else if (param->srv->log->logfunc->log){
- if(!(evt = malloc(param->srv->log->logfunc->dobuf?EVENTSIZE:sizeof(struct logevent)))) return;
- evt->inbuf = 0;
- evt->param = NULL;
- evt->logstring = NULL;
-
- if(param->srv->log->logfunc->dobuf){
- evt->inbuf = param->srv->log->logfunc->dobuf(param, evt->buf, LOGBUFSIZE, s);
- }
- evt->event = LOG;
- evt->log = param->srv->log;
- logpush(evt);
- }
- }
- if(param->trafcountfunc)(*param->trafcountfunc)(param);
- clearstat(param);
- }
- static void delayfreeparam(struct clientparam * param) {
- if(param->res == 2) return;
- if(param->ctrlsocksrv != INVALID_SOCKET && param->ctrlsocksrv != param->remsock) {
- so._shutdown(param->ctrlsocksrv, SHUT_RDWR);
- so._closesocket(param->ctrlsocksrv);
- }
- if(param->ctrlsock != INVALID_SOCKET && param->ctrlsock != param->clisock) {
- so._shutdown(param->ctrlsock, SHUT_RDWR);
- so._closesocket(param->ctrlsock);
- }
- if(param->remsock != INVALID_SOCKET) {
- so._shutdown(param->remsock, SHUT_RDWR);
- so._closesocket(param->remsock);
- }
- if(param->clisock != INVALID_SOCKET) {
- so._shutdown(param->clisock, SHUT_RDWR);
- so._closesocket(param->clisock);
- }
- myfree(param->clibuf);
- myfree(param->srvbuf);
- if(param->datfilterssrv) myfree(param->datfilterssrv);
- #ifndef STDMAIN
- if(param->reqfilters) myfree(param->reqfilters);
- if(param->hdrfilterscli) myfree(param->hdrfilterscli);
- if(param->hdrfilterssrv) myfree(param->hdrfilterssrv);
- if(param->predatfilters) myfree(param->predatfilters);
- if(param->datfilterscli) myfree(param->datfilterscli);
- if(param->filters){
- if(param->nfilters)while(param->nfilters--){
- if(param->filters[param->nfilters].filter->filter_clear)
- (*param->filters[param->nfilters].filter->filter_clear)(param->filters[param->nfilters].data);
- }
- myfree(param->filters);
- }
- if(conf.connlimiter && (param->res != 95 || param->remsock != INVALID_SOCKET)) stopconnlims(param);
- #endif
- if(param->srv){
- pthread_mutex_lock(¶m->srv->counter_mutex);
- if(param->prev){
- param->prev->next = param->next;
- }
- else
- param->srv->child = param->next;
- if(param->next){
- param->next->prev = param->prev;
- }
- (param->srv->childcount)--;
- if(param->srv->service == S_ZOMBIE && !param->srv->child)srvpostfree(param->srv);
- pthread_mutex_unlock(¶m->srv->counter_mutex);
- }
- if(param->hostname) myfree(param->hostname);
- if(param->username) myfree(param->username);
- if(param->password) myfree(param->password);
- if(param->extusername) myfree(param->extusername);
- if(param->extpassword) myfree(param->extpassword);
- myfree(param);
- }
- void freeparam(struct clientparam * param) {
- struct logevent *evt;
- evt = malloc(sizeof(struct logevent));
- evt->event = FREEPARAM;
- evt->param = param;
- logpush(evt);
- }
- void clearstat(struct clientparam * param) {
- #ifdef _WIN32
- struct timeb tb;
- ftime(&tb);
- param->time_start = (time_t)tb.time;
- param->msec_start = (unsigned)tb.millitm;
- #else
- struct timeval tv;
- struct timezone tz;
- gettimeofday(&tv, &tz);
- param->time_start = (time_t)tv.tv_sec;
- param->msec_start = (tv.tv_usec / 1000);
- #endif
- param->statscli64 = param->statssrv64 = param->nreads = param->nwrites =
- param->nconnects = 0;
- }
- char months[12][4] = {
- "Jan", "Feb", "Mar", "Apr", "May", "Jun",
- "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
- };
- unsigned char * dologname (unsigned char *buf, int bufsize, unsigned char *name, const unsigned char *ext, ROTATION lt, time_t t) {
- struct tm *ts;
- ts = localtime(&t);
- if(strchr((char *)name, '%')){
- struct clientparam fakecli;
- memset(&fakecli, 0, sizeof(fakecli));
- dobuf2(&fakecli, buf, bufsize - strlen(ext), NULL, NULL, ts, (char *)name);
- }
- else switch(lt){
- case NONE:
- sprintf((char *)buf, "%s", name);
- break;
- case ANNUALLY:
- sprintf((char *)buf, "%s.%04d", name, ts->tm_year+1900);
- break;
- case MONTHLY:
- sprintf((char *)buf, "%s.%04d.%02d", name, ts->tm_year+1900, ts->tm_mon+1);
- break;
- case WEEKLY:
- t = t - (ts->tm_wday * (60*60*24));
- ts = localtime(&t);
- sprintf((char *)buf, "%s.%04d.%02d.%02d", name, ts->tm_year+1900, ts->tm_mon+1, ts->tm_mday);
- break;
- case DAILY:
- sprintf((char *)buf, "%s.%04d.%02d.%02d", name, ts->tm_year+1900, ts->tm_mon+1, ts->tm_mday);
- break;
- case HOURLY:
- sprintf((char *)buf, "%s.%04d.%02d.%02d-%02d", name, ts->tm_year+1900, ts->tm_mon+1, ts->tm_mday, ts->tm_hour);
- break;
- case MINUTELY:
- sprintf((char *)buf, "%s.%04d.%02d.%02d-%02d.%02d", name, ts->tm_year+1900, ts->tm_mon+1, ts->tm_mday, ts->tm_hour, ts->tm_min);
- break;
- default:
- break;
- }
- if(ext){
- strcat((char *)buf, ".");
- strcat((char *)buf, (char *)ext);
- }
- return buf;
- }
- int dobuf2(struct clientparam * param, unsigned char * buf, int bufsize, const unsigned char *s, const unsigned char * doublec, struct tm* tm, char * format){
- int i, j;
- int len;
- time_t sec;
- unsigned msec;
- long timezone;
- unsigned delay;
- #ifdef _WIN32
- struct timeb tb;
- ftime(&tb);
- sec = (time_t)tb.time;
- msec = (unsigned)tb.millitm;
- timezone = tm->tm_isdst*60 - tb.timezone;
- #else
- struct timeval tv;
- struct timezone tz;
- gettimeofday(&tv, &tz);
- sec = (time_t)tv.tv_sec;
- msec = tv.tv_usec / 1000;
- #ifdef _SOLARIS
- timezone = -altzone / 60;
- #else
- timezone = tm->tm_gmtoff / 60;
- #endif
- #endif
- delay = param->time_start?((unsigned) ((sec - param->time_start))*1000 + msec) - param->msec_start : 0;
- *buf = 0;
- for(i=0, j=0; format[j] && i < (bufsize-70); j++){
- if(format[j] == '%' && format[j+1]){
- j++;
- switch(format[j]){
- case '%':
- buf[i++] = '%';
- break;
- case 'y':
- sprintf((char *)buf+i, "%.2d", tm->tm_year%100);
- i+=2;
- break;
- case 'Y':
- sprintf((char *)buf+i, "%.4d", tm->tm_year+1900);
- i+=4;
- break;
- case 'm':
- sprintf((char *)buf+i, "%.2d", tm->tm_mon+1);
- i+=2;
- break;
- case 'o':
- sprintf((char *)buf+i, "%s", months[tm->tm_mon]);
- i+=3;
- break;
- case 'd':
- sprintf((char *)buf+i, "%.2d", tm->tm_mday);
- i+=2;
- break;
- case 'H':
- sprintf((char *)buf+i, "%.2d", tm->tm_hour);
- i+=2;
- break;
- case 'M':
- sprintf((char *)buf+i, "%.2d", tm->tm_min);
- i+=2;
- break;
- case 'S':
- sprintf((char *)buf+i, "%.2d", tm->tm_sec);
- i+=2;
- break;
- case 't':
- sprintf((char *)buf+i, "%.10u", (unsigned)sec);
- i+=10;
- break;
- case 'b':
- i+=sprintf((char *)buf+i, "%u", delay?(unsigned)(param->statscli64 * 1000./delay):0);
- break;
- case 'B':
- i+=sprintf((char *)buf+i, "%u", delay?(unsigned)(param->statssrv64 * 1000./delay):0);
- break;
- case 'D':
- i+=sprintf((char *)buf+i, "%u", delay);
- break;
- case '.':
- sprintf((char *)buf+i, "%.3u", msec);
- i+=3;
- break;
- case 'z':
- sprintf((char *)buf+i, "%+.2ld%.2u", timezone / 60, (unsigned)(timezone%60));
- i+=5;
- break;
- case 'U':
- if(param->username && *param->username){
- for(len = 0; i< (bufsize - 3) && param->username[len]; len++){
- buf[i] = param->username[len];
- if(param->srv->nonprintable && (buf[i] < 0x20 || strchr((char *)param->srv->nonprintable, buf[i]))) buf[i] = param->srv->replace;
- if(doublec && strchr((char *)doublec, buf[i])) {
- buf[i+1] = buf[i];
- i++;
- }
- i++;
- }
- }
- else {
- buf[i++] = '-';
- }
- break;
- case 'n':
- len = param->hostname? (int)strlen((char *)param->hostname) : 0;
- if (len > 0 && !strchr((char *)param->hostname, ':')) for(len = 0; param->hostname[len] && i < (bufsize-3); len++, i++){
- buf[i] = param->hostname[len];
- if(param->srv->nonprintable && (buf[i] < 0x20 || strchr((char *)param->srv->nonprintable, buf[i]))) buf[i] = param->srv->replace;
- if(doublec && strchr((char *)doublec, buf[i])) {
- buf[i+1] = buf[i];
- i++;
- }
- }
- else {
- buf[i++] = '[';
- i += myinet_ntop(*SAFAMILY(¶m->req), SAADDR(¶m->req), (char *)buf + i, 64);
- buf[i++] = ']';
- }
- break;
- case 'N':
- if(param->service < 15) {
- len = (conf.stringtable)? (int)strlen((char *)conf.stringtable[SERVICES + param->service]) : 0;
- if(len > 20) len = 20;
- memcpy(buf+i, (len)?conf.stringtable[SERVICES + param->service]:(unsigned char*)"-", (len)?len:1);
- i += (len)?len:1;
- }
- break;
- case 'E':
- sprintf((char *)buf+i, "%.05d", param->res);
- i += 5;
- break;
- case 'T':
- if(s){
- for(len = 0; i < (bufsize-3) && s[len]; len++){
- buf[i] = s[len];
- if(param->srv->nonprintable && (buf[i] < 0x20 || strchr((char *)param->srv->nonprintable, buf[i]))) buf[i] = param->srv->replace;
- if(doublec && strchr((char *)doublec, buf[i])) {
- buf[i+1] = buf[i];
- i++;
- }
- i++;
- }
- }
- break;
- case 'e':
- i += myinet_ntop(*SAFAMILY(¶m->sinsl), SAADDR(¶m->sinsl), (char *)buf + i, 64);
- break;
- case 'i':
- i += myinet_ntop(*SAFAMILY(¶m->sincl), SAADDR(¶m->sincl), (char *)buf + i, 64);
- break;
- case 'C':
- i += myinet_ntop(*SAFAMILY(¶m->sincr), SAADDR(¶m->sincr), (char *)buf + i, 64);
- break;
- case 'R':
- i += myinet_ntop(*SAFAMILY(¶m->sinsr), SAADDR(¶m->sinsr), (char *)buf + i, 64);
- break;
- case 'Q':
- i += myinet_ntop(*SAFAMILY(¶m->req), SAADDR(¶m->req), (char *)buf + i, 64);
- break;
- case 'p':
- sprintf((char *)buf+i, "%hu", ntohs(*SAPORT(¶m->srv->intsa)));
- i += (int)strlen((char *)buf+i);
- break;
- case 'c':
- sprintf((char *)buf+i, "%hu", ntohs(*SAPORT(¶m->sincr)));
- i += (int)strlen((char *)buf+i);
- break;
- case 'r':
- sprintf((char *)buf+i, "%hu", ntohs(*SAPORT(¶m->sinsr)));
- i += (int)strlen((char *)buf+i);
- break;
- case 'q':
- sprintf((char *)buf+i, "%hu", ntohs(*SAPORT(¶m->req)));
- i += (int)strlen((char *)buf+i);
- break;
- case 'L':
- sprintf((char *)buf+i, "%"PRIu64, param->cycles);
- i += (int)strlen((char *)buf+i);
- break;
- case 'I':
- sprintf((char *)buf+i, "%"PRIu64, param->statssrv64);
- i += (int)strlen((char *)buf+i);
- break;
- case 'O':
- sprintf((char *)buf+i, "%"PRIu64, param->statscli64);
- i += (int)strlen((char *)buf+i);
- break;
- case 'h':
- sprintf((char *)buf+i, "%d", param->redirected);
- i += (int)strlen((char *)buf+i);
- break;
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9':
- {
- int k, pmin=0, pmax=0;
- for (k = j; isnumber(format[k]); k++);
- if(format[k] == '-' && isnumber(format[k+1])){
- pmin = atoi(format + j) - 1;
- k++;
- pmax = atoi(format + k) -1;
- for (; isnumber(format[k]); k++);
- j = k;
- }
- if(!s || format[k]!='T') break;
- for(k = 0, len = 0; s[len]; len++){
- if(isspace(s[len])){
- k++;
- while(isspace(s[len+1]))len++;
- if(k == pmin) continue;
- }
- if(k>=pmin && k<=pmax && i < (bufsize-3)) {
- buf[i] = s[len];
- if(param->srv->nonprintable && (buf[i] < 0x20 || strchr((char *)param->srv->nonprintable, buf[i]))) buf[i] = param->srv->replace;
- if(doublec && strchr((char *)doublec, buf[i])) {
- buf[i+1] = buf[i];
- i++;
- }
- i++;
- }
- }
- break;
- }
- default:
- buf[i++] = format[j];
- }
- }
- else buf[i++] = format[j];
- }
- buf[i] = 0;
- return i;
- }
- int dobuf(struct clientparam * param, unsigned char * buf, int bufsize, const unsigned char *s, const unsigned char * doublec){
- struct tm* tm;
- int i;
- char * format;
- time_t t;
- time(&t);
- if(!param) return 0;
- format = param->srv->logformat?(char *)param->srv->logformat : DEFLOGFORMAT;
- tm = (*format == 'G' || *format == 'g')?
- gmtime(&t) : localtime(&t);
- i = dobuf2(param, buf, bufsize, s, doublec, tm, format + 1);
- return i;
- }
- static int stdloginit(struct LOGGER *logger){
- char tmpbuf[1024];
- struct stdlogdata *lp;
- lp = myalloc(sizeof(struct stdlogdata));
- if(!lp) return 1;
- logger->data = lp;
- if(!*logger->selector || !strcmp(logger->selector, "stdout")){
- logger->rotate = NONE;
- lp->fp = stdout;
- }
- else if(!strcmp(logger->selector,"stderr")){
- logger->rotate = NONE;
- lp->fp = stderr;
- }
- else {
- lp->fp = fopen((char *)dologname (tmpbuf, sizeof(tmpbuf) - 1, logger->selector, NULL, logger->rotate, time(NULL)), "a");
- if(!lp->fp){
- myfree(lp);
- return(2);
- }
- }
- return 0;
- }
- static int stddobuf(struct clientparam * param, unsigned char * buf, int bufsize, const unsigned char *s){
- return dobuf(param, buf, bufsize, s, NULL);
- }
- static void stdlog(const char * buf, int len, struct LOGGER *logger) {
- FILE *log = ((struct stdlogdata *)logger->data)->fp;
- fprintf(log, "%s\n", buf);
- }
- static void stdlogrotate(struct LOGGER *logger){
- char tmpbuf[1024];
- struct stdlogdata *lp = (struct stdlogdata *)logger->data;
- if(lp->fp) lp->fp = freopen((char *)dologname (tmpbuf, sizeof(tmpbuf) -1, logger->selector, NULL, logger->rotate, conf.time), "a", lp->fp);
- else lp->fp = fopen((char *)dologname (tmpbuf, sizeof(tmpbuf) -1, logger->selector, NULL, logger->rotate, conf.time), "a");
- logger->rotated = conf.time;
- if(logger->rotate) {
- int t;
- t = 1;
- switch(logger->rotate){
- case ANNUALLY:
- t = t * 12;
- case MONTHLY:
- t = t * 4;
- case WEEKLY:
- t = t * 7;
- case DAILY:
- t = t * 24;
- case HOURLY:
- t = t * 60;
- case MINUTELY:
- t = t * 60;
- default:
- break;
- }
- /*
- FIXME: move archiver to thread
- */
- dologname (tmpbuf, sizeof(tmpbuf) -1, logger->selector, (conf.archiver)?conf.archiver[1]:NULL, logger->rotate, (logger->rotated - t * conf.rotate));
- remove ((char *) tmpbuf);
- if(conf.archiver) {
- int i;
- *tmpbuf = 0;
- for(i = 2; i < conf.archiverc && strlen((char *)tmpbuf) < 512; i++){
- strcat((char *)tmpbuf, " ");
- if(!strcmp((char *)conf.archiver[i], "%A")){
- strcat((char *)tmpbuf, "\"");
- dologname (tmpbuf + strlen((char *)tmpbuf), sizeof(tmpbuf) - (strlen((char *)tmpbuf) + 1), logger->selector, conf.archiver[1], logger->rotate, (logger->rotated - t));
- strcat((char *)tmpbuf, "\"");
- }
- else if(!strcmp((char *)conf.archiver[i], "%F")){
- strcat((char *)tmpbuf, "\"");
- dologname (tmpbuf+strlen((char *)tmpbuf), sizeof(tmpbuf) - (strlen((char *)tmpbuf) + 1), logger->selector, NULL, logger->rotate, (logger->rotated-t));
- strcat((char *)tmpbuf, "\"");
- }
- else
- strcat((char *)tmpbuf, (char *)conf.archiver[i]);
- }
- system((char *)tmpbuf+1);
- }
- }
- }
- static void stdlogflush(struct LOGGER *logger){
- fflush(((struct stdlogdata *)logger->data)->fp);
- }
- static void stdlogclose(struct LOGGER *logger){
- if(((struct stdlogdata *)logger->data)->fp != stdout && ((struct stdlogdata *)logger->data)->fp != stderr)
- fclose(((struct stdlogdata *)logger->data)->fp);
- myfree(logger->data);
- }
- #if HAVESYSLOG > 0
- static int sysloginit(struct LOGGER *logger){
- openlog(logger->selector, LOG_PID, LOG_DAEMON);
- return 0;
- }
- static void logsyslog(const char * buf, int len, struct LOGGER *logger) {
- syslog(LOG_INFO, "%s", buf);
- }
- static void syslogrotate(struct LOGGER *logger){
- closelog();
- openlog(logger->selector+1, LOG_PID, LOG_DAEMON);
- }
- static void syslogclose(struct LOGGER *logger){
- closelog();
- }
- #endif
- #if HAVESQL > 0
- struct sqldata {
- SQLHENV henv;
- SQLHSTMT hstmt;
- SQLHDBC hdbc;
- int attempt;
- time_t attempt_time;
- };
- static int sqlinit2(struct sqldata * sd, char * source){
- SQLRETURN retcode;
- char * datasource;
- char * username;
- char * password;
- char * string;
- int ret = 0;
- retcode = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &sd->henv);
- if (!sd->henv || (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO)){
- return 1;
- }
- retcode = SQLSetEnvAttr(sd->henv, SQL_ATTR_ODBC_VERSION, (void*)SQL_OV_ODBC3, 0);
- if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO) {
- ret = 2;
- goto CLOSEENV;
- }
- retcode = SQLAllocHandle(SQL_HANDLE_DBC, sd->henv, &sd->hdbc);
- if (!sd->hdbc || (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO)) {
- ret = 3;
- goto CLOSEENV;
- }
- SQLSetConnectAttr(sd->hdbc, SQL_LOGIN_TIMEOUT, (void*)15, 0);
- string = mystrdup(source);
- if(!string) goto CLOSEHDBC;
- datasource = strtok(string, ",");
- username = strtok(NULL, ",");
- password = strtok(NULL, ",");
-
- /* Connect to data source */
- retcode = SQLConnect(sd->hdbc, (SQLCHAR*) datasource, (SQLSMALLINT)strlen(datasource),
- (SQLCHAR*) username, (SQLSMALLINT)((username)?strlen(username):0),
- (SQLCHAR*) password, (SQLSMALLINT)((password)?strlen(password):0));
- myfree(string);
- if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO){
- ret = 4;
- goto CLOSEHDBC;
- }
- retcode = SQLAllocHandle(SQL_HANDLE_STMT, sd->hdbc, &sd->hstmt);
- if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO){
- sd->hstmt = 0;
- ret = 5;
- goto CLOSEHDBC;
- }
- return 0;
- CLOSEHDBC:
- SQLFreeHandle(SQL_HANDLE_DBC, sd->hdbc);
- sd->hdbc = 0;
- CLOSEENV:
- SQLFreeHandle(SQL_HANDLE_ENV, sd->henv);
- sd->henv = 0;
- return ret;
- }
- static int sqlinit(struct LOGGER *logger){
- struct sqldata *sd;
- int res;
-
- sd = (struct sqldata *)myalloc(sizeof(struct sqldata));
- memset(sd, 0, sizeof(struct sqldata));
- logger->data = sd;
- if((res = sqlinit2(sd, logger->selector))) {
- myfree(sd);
- return res;
- }
- return 0;
- }
- static int sqldobuf(struct clientparam * param, unsigned char * buf, int bufsize, const unsigned char *s){
- return dobuf(param, buf, bufsize, s, (unsigned char *)"\'");
- }
- static void sqllog(const char * buf, int len, struct LOGGER *logger){
- SQLRETURN ret;
- struct sqldata *sd = (struct sqldata *)logger->data;
- if(sd->attempt > 5){
- if (conf.time - sd->attempt_time < 180){
- return;
- }
- }
- if(sd->attempt){
- sd->attempt++;
- sqlrotate(logger);
- if(!sd->hstmt){
- sd->attempt_time=conf.time;
- return;
- }
- }
- ret = SQLExecDirect(sd->hstmt, (SQLCHAR *)buf, (SQLINTEGER)len);
- if(ret != SQL_SUCCESS && ret != SQL_SUCCESS_WITH_INFO){
- sqlrotate(logger);
- if(sd->hstmt) {
- ret = SQLExecDirect(sd->hstmt, (SQLCHAR *)buf, (SQLINTEGER)len);
- if(ret != SQL_SUCCESS && ret != SQL_SUCCESS_WITH_INFO){
- sd->attempt++;
- sd->attempt_time=conf.time;
- return;
- }
- }
- }
- sd->attempt=0;
- }
- static void sqlrotate(struct LOGGER *logger){
- struct sqldata * sd;
- sqlclose(logger);
- sd = (struct sqldata *)myalloc(sizeof(struct sqldata));
- memset(sd, 0, sizeof(struct sqldata));
- logger->data = sd;
- sqlinit2(sd, logger->selector+1);
- }
- static void sqlclose(struct LOGGER *logger){
- struct sqldata *sd = (struct sqldata *)logger->data;
- if(sd->hstmt) {
- SQLFreeHandle(SQL_HANDLE_STMT, sd->hstmt);
- sd->hstmt = NULL;
- }
- if(sd->hdbc){
- SQLDisconnect(sd->hdbc);
- SQLFreeHandle(SQL_HANDLE_DBC, sd->hdbc);
- sd->hdbc = NULL;
- }
- if(sd->henv) {
- SQLFreeHandle(SQL_HANDLE_ENV, sd->henv);
- sd->henv = NULL;
- }
- myfree(sd);
- }
- #endif
|