Răsfoiți Sursa

Merge remote-tracking branch 'refs/remotes/origin/devel-logthread' into devel

z3APA3A 5 ani în urmă
părinte
comite
0f560a4725

+ 1 - 1
Makefile.msvc

@@ -8,7 +8,7 @@
 
 BUILDDIR = ../bin/
 CC = cl
-CFLAGS = /nologo /MT /W3 /Ox /GS /EHs- /GA /GF /D "MSVC" /D "WITH_STD_MALLOC" /D "WITH_WSAPOLL" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "_WIN32" /D "PRINTF_INT64_MODIFIER=\"I64\"" /Fp"proxy.pch" /FD /c $(VERSION) $(BUILDDATE)
+CFLAGS = /nologo /MT /W3 /Ox /GS /EHs- /GA /GF /D "MSVC" /D "WITH_STD_MALLOC" /D "WITH_WSAPOLL" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "_WIN32" /Fp"proxy.pch" /FD /c $(VERSION) $(BUILDDATE)
 COUT = /Fo
 LN = link
 LDFLAGS =  /nologo /subsystem:console /incremental:no /machine:I386

+ 1 - 1
Makefile.msvc64

@@ -8,7 +8,7 @@
 
 BUILDDIR = ../bin64/
 CC = cl
-CFLAGS = /nologo /MT /W3 /Ox /EHs- /GS /GA /GF /D "MSVC" /D "WITH_STD_MALLOC" /D "WITH_WSAPOLL" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "_WIN32" /D "PRINTF_INT64_MODIFIER=\"I64\"" /Fp"proxy.pch" /FD /c $(VERSION) $(BUILDDATE)
+CFLAGS = /nologo /MT /W3 /Ox /EHs- /GS /GA /GF /D "MSVC" /D "WITH_STD_MALLOC" /D "WITH_WSAPOLL" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "_WIN32" /Fp"proxy.pch" /FD /c $(VERSION) $(BUILDDATE)
 COUT = /Fo
 LN = link
 LDFLAGS = /nologo /subsystem:console /incremental:no /machine:x64

+ 1 - 1
Makefile.msvcARM64

@@ -8,7 +8,7 @@
 
 BUILDDIR = ../bin64/
 CC = cl
-CFLAGS = /nologo /MT /W3 /Ox /EHs- /GS /GA /GF /D "MSVC" /D "WITH_STD_MALLOC" /D "WITH_WSAPOLL" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "_WIN32" /D "PRINTF_INT64_MODIFIER=\"I64\"" /Fp"proxy.pch" /FD /c $(VERSION) $(BUILDDATE)
+CFLAGS = /nologo /MT /W3 /Ox /EHs- /GS /GA /GF /D "MSVC" /D "WITH_STD_MALLOC" /D "WITH_WSAPOLL" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "_WIN32" /Fp"proxy.pch" /FD /c $(VERSION) $(BUILDDATE)
 COUT = /Fo
 LN = link
 LDFLAGS = /nologo /subsystem:console /incremental:no /machine:arm64

+ 1 - 1
Makefile.msvcCE

@@ -8,7 +8,7 @@
 
 BUILDDIR = ../bin/
 CC = cl
-CFLAGS = /DARM /D "NOODBC" /nologo /MT /W3 /Wp64 /Ox /GS /EHs- /GA /GF /D "MSVC" /D "_WINCE" /D "WITH_STD_MALLOC" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "_WIN32" /D "PRINTF_INT64_MODIFIER=\"I64\"" /Fp"proxy.pch" /FD /c
+CFLAGS = /DARM /D "NOODBC" /nologo /MT /W3 /Wp64 /Ox /GS /EHs- /GA /GF /D "MSVC" /D "_WINCE" /D "WITH_STD_MALLOC" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "_WIN32" /Fp"proxy.pch" /FD /c
 COUT = /Fo
 LN = link
 LDFLAGS = /nologo /subsystem:console /incremental:no

+ 1 - 1
Makefile.watcom

@@ -8,7 +8,7 @@
 
 BUILDDIR = ../bin/
 CC = cl
-CFLAGS = /nologo /Ox /MT /D "NOIPV6" /D "NODEBUG" /D "NOODBC" /D "NORADIUS" /D"WATCOM" /D "MSVC" /D "WITH_STD_MALLOC" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "_WIN32" /D "PRINTF_INT64_MODIFIER=\"I64\"" /c $(VERSION) $(BUILDDATE)
+CFLAGS = /nologo /Ox /MT /D "NOIPV6" /D "NODEBUG" /D "NOODBC" /D "NORADIUS" /D"WATCOM" /D "MSVC" /D "WITH_STD_MALLOC" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "_WIN32" /c $(VERSION) $(BUILDDATE)
 COUT = /Fo
 LN = link
 LDFLAGS = /nologo /subsystem:console /incremental:no 

+ 5 - 67
src/3proxy.c

@@ -63,11 +63,6 @@ void __stdcall CommandHandler( DWORD dwCommand )
 	conf.paused++;
 	Sleep(2000);
         SetStatus( SERVICE_STOPPED, 0, 0 );
-#ifndef NOODBC
-	pthread_mutex_lock(&log_mutex);
-	close_sql();
-	pthread_mutex_unlock(&log_mutex);
-#endif
         break;
     case SERVICE_CONTROL_PAUSE:
         SetStatus( SERVICE_PAUSE_PENDING, 0, 1 );
@@ -116,13 +111,7 @@ void mysigpause (int sig){
 
 void mysigterm (int sig){
 	conf.paused++;
-	usleep(999*SLEEPTIME);
-	usleep(999*SLEEPTIME);
-#ifndef NOODBC
-	pthread_mutex_lock(&log_mutex);
-	close_sql();
-	pthread_mutex_unlock(&log_mutex);
-#endif
+	usleep(2000*SLEEPTIME);
 	conf.timetoexit = 1;
 }
 
@@ -200,11 +189,11 @@ void dumpcounters(struct trafcount *tlin, int counterd){
 	if(cheader.updated && conf.countertype && timechanged(cheader.updated, conf.time, conf.countertype)){
 		FILE * cfp;
 				
-		cfp = fopen((char *)dologname(tmpbuf, (unsigned char *)conf.counterfile, NULL, conf.countertype, cheader.updated), "w");
+		cfp = fopen((char *)dologname(tmpbuf, sizeof(tmpbuf), (unsigned char *)conf.counterfile, NULL, conf.countertype, cheader.updated), "w");
 		if(cfp){
 			for(tl = tlin; cfp && tl; tl = tl->next){
 				if(tl->type >= conf.countertype)
-					fprintf(cfp, "%05d %020"PRINTF_INT64_MODIFIER"u%s%s\n", tl->number, tl->traf64, tl->comment?" #" : "", tl->comment? tl->comment : "");
+					fprintf(cfp, "%05d %020" PRIu64 "%s%s\n", tl->number, tl->traf64, tl->comment?" #" : "", tl->comment? tl->comment : "");
 			}
 			fclose(cfp);
 		}
@@ -235,12 +224,12 @@ void dumpcounters(struct trafcount *tlin, int counterd){
 void cyclestep(void){
  struct tm *tm;
  time_t minutecounter;
- unsigned char tmpbuf[8192];
 
  minutecounter = time(0);
  for(;;){
 	usleep(SLEEPTIME*999);
 	
+	flushlogs();
 	conf.time = time(0);
 	if(conf.needreload) {
 		doschedule();
@@ -248,7 +237,6 @@ void cyclestep(void){
 		conf.needreload = 0;
 	}
 	doschedule();
-	if(conf.stdlog)fflush(conf.stdlog);
 	if(timechanged(minutecounter, conf.time, MINUTELY)) {
 		struct filemon *fm;
 		struct stat sb;
@@ -269,55 +257,6 @@ void cyclestep(void){
 		tm->tm_hour = tm->tm_min = tm->tm_sec = 0;
 		basetime = mktime(tm);
 	}
-	if(conf.logname) {
-		if(timechanged(conf.logtime, conf.time, conf.logtype)) {
-			if(conf.stdlog) conf.stdlog = freopen((char *)dologname (tmpbuf, conf.logname, NULL, conf.logtype, conf.time), "a", conf.stdlog);
-			else conf.stdlog = fopen((char *)dologname (tmpbuf, conf.logname, NULL, conf.logtype, conf.time), "a");
-			conf.logtime = conf.time;
-			if(conf.logtype != NONE && conf.rotate) {
-				int t;
-				t = 1;
-				switch(conf.logtype){
-					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;
-				}
-				dologname (tmpbuf, conf.logname, (conf.archiver)?conf.archiver[1]:NULL, conf.logtype, (conf.logtime - 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), conf.logname, conf.archiver[1], conf.logtype, (conf.logtime - t));
-							strcat((char *)tmpbuf, "\"");
-						}
-						else if(!strcmp((char *)conf.archiver[i], "%F")){
-							strcat((char *)tmpbuf, "\"");
-							dologname (tmpbuf+strlen((char *)tmpbuf), conf.logname, NULL, conf.logtype, (conf.logtime-t));
-							strcat((char *)tmpbuf, "\"");
-						}
-						else
-							strcat((char *)tmpbuf, (char *)conf.archiver[i]);
-					}
-					system((char *)tmpbuf+1);
-				}
-			}
-		}
-	}
 	if(conf.counterd >= 0 && conf.trafcounter) {
 		if(timechanged(cheader.updated, conf.time, MINUTELY)){
 			dumpcounters(conf.trafcounter, conf.counterd);
@@ -512,11 +451,10 @@ int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int
   pthread_mutex_init(&hash_mutex, NULL);
   pthread_mutex_init(&tc_mutex, NULL);
   pthread_mutex_init(&pwl_mutex, NULL);
-  pthread_mutex_init(&log_mutex, NULL);
 #ifndef NORADIUS
   pthread_mutex_init(&rad_mutex, NULL);
 #endif
-
+  initlog();
   freeconf(&conf);
   res = readconfig(fp);
   conf.version++;

+ 23 - 21
src/Makefile.inc

@@ -26,50 +26,52 @@ ftp$(OBJSUFFICS): ftp.c proxy.h structures.h
 sockgetchar$(OBJSUFFICS): sockgetchar.c proxy.h structures.h
 	$(CC) $(CFLAGS) sockgetchar.c
 
-proxy$(OBJSUFFICS): proxy.c proxy.h structures.h proxymain.c
+proxy$(OBJSUFFICS): proxy.c proxy.h structures.h proxymain.c log.c
 	$(CC) $(CFLAGS) $(DEFINEOPTION)WITHMAIN $(DEFINEOPTION)NOPORTMAP $(DEFINEOPTION)ANONYMOUS proxy.c
 
-pop3p$(OBJSUFFICS): pop3p.c proxy.h structures.h proxymain.c
+pop3p$(OBJSUFFICS): pop3p.c proxy.h structures.h proxymain.c log.c
 	$(CC) $(CFLAGS) $(DEFINEOPTION)WITHMAIN $(DEFINEOPTION)NOPORTMAP pop3p.c
 
-smtpp$(OBJSUFFICS): smtpp.c proxy.h structures.h proxymain.c
+smtpp$(OBJSUFFICS): smtpp.c proxy.h structures.h proxymain.c log.c
 	$(CC) $(CFLAGS) $(DEFINEOPTION)WITHMAIN $(DEFINEOPTION)NOPORTMAP smtpp.c
 
-ftppr$(OBJSUFFICS): ftppr.c proxy.h structures.h proxymain.c
+ftppr$(OBJSUFFICS): ftppr.c proxy.h structures.h proxymain.c log.c
 	$(CC) $(CFLAGS) $(DEFINEOPTION)WITHMAIN $(DEFINEOPTION)NOPORTMAP ftppr.c
 
-tcppm$(OBJSUFFICS): tcppm.c proxy.h structures.h proxymain.c
+tcppm$(OBJSUFFICS): tcppm.c proxy.h structures.h proxymain.c log.c
 	$(CC) $(CFLAGS) $(DEFINEOPTION)WITHMAIN $(DEFINEOPTION)PORTMAP tcppm.c
 
-socks$(OBJSUFFICS): socks.c proxy.h structures.h proxymain.c
+socks$(OBJSUFFICS): socks.c proxy.h structures.h proxymain.c log.c
 	$(CC) $(CFLAGS) $(DEFINEOPTION)WITHMAIN $(DEFINEOPTION)NOPORTMAP socks.c
 
-udppm$(OBJSUFFICS): udppm.c proxy.h structures.h proxymain.c
+udppm$(OBJSUFFICS): udppm.c proxy.h structures.h proxymain.c log.c
 	$(CC) $(CFLAGS) $(DEFINEOPTION)WITHMAIN $(DEFINEOPTION)PORTMAP udppm.c
 
+
+
 3proxy$(OBJSUFFICS): 3proxy.c proxy.h structures.h
 	$(CC) $(CFLAGS) 3proxy.c
 
-$(BUILDDIR)proxy$(EXESUFFICS): sockmap$(OBJSUFFICS) proxy$(OBJSUFFICS) sockgetchar$(OBJSUFFICS) common$(OBJSUFFICS) log$(OBJSUFFICS) base64$(OBJSUFFICS) ftp$(OBJSUFFICS) $(COMPATLIBS)
-	$(LN) $(LNOUT)$(BUILDDIR)proxy$(EXESUFFICS) $(LDFLAGS) sockmap$(OBJSUFFICS) proxy$(OBJSUFFICS) sockgetchar$(OBJSUFFICS) log$(OBJSUFFICS) common$(OBJSUFFICS) base64$(OBJSUFFICS) ftp$(OBJSUFFICS) $(COMPATLIBS) $(LIBS)
+$(BUILDDIR)proxy$(EXESUFFICS): sockmap$(OBJSUFFICS) proxy$(OBJSUFFICS) sockgetchar$(OBJSUFFICS) common$(OBJSUFFICS) base64$(OBJSUFFICS) ftp$(OBJSUFFICS) $(COMPATLIBS)
+	$(LN) $(LNOUT)$(BUILDDIR)proxy$(EXESUFFICS) $(LDFLAGS) sockmap$(OBJSUFFICS) proxy$(OBJSUFFICS) sockgetchar$(OBJSUFFICS) common$(OBJSUFFICS) base64$(OBJSUFFICS) ftp$(OBJSUFFICS) $(COMPATLIBS) $(LIBS)
 
-$(BUILDDIR)pop3p$(EXESUFFICS): sockmap$(OBJSUFFICS) pop3p$(OBJSUFFICS) sockgetchar$(OBJSUFFICS) common$(OBJSUFFICS) log$(OBJSUFFICS) $(COMPATLIBS)
-	$(LN) $(LNOUT)$(BUILDDIR)pop3p$(EXESUFFICS) $(LDFLAGS) sockmap$(OBJSUFFICS) pop3p$(OBJSUFFICS) sockgetchar$(OBJSUFFICS) log$(OBJSUFFICS) common$(OBJSUFFICS) $(COMPATLIBS) $(LIBS)
+$(BUILDDIR)pop3p$(EXESUFFICS): sockmap$(OBJSUFFICS) pop3p$(OBJSUFFICS) sockgetchar$(OBJSUFFICS) common$(OBJSUFFICS) $(COMPATLIBS)
+	$(LN) $(LNOUT)$(BUILDDIR)pop3p$(EXESUFFICS) $(LDFLAGS) sockmap$(OBJSUFFICS) pop3p$(OBJSUFFICS) sockgetchar$(OBJSUFFICS) common$(OBJSUFFICS) $(COMPATLIBS) $(LIBS)
 
-$(BUILDDIR)smtpp$(EXESUFFICS): sockmap$(OBJSUFFICS) smtpp$(OBJSUFFICS) sockgetchar$(OBJSUFFICS) common$(OBJSUFFICS) log$(OBJSUFFICS) base64$(OBJSUFFICS) $(COMPATLIBS)
-	$(LN) $(LNOUT)$(BUILDDIR)smtpp$(EXESUFFICS) $(LDFLAGS) sockmap$(OBJSUFFICS) smtpp$(OBJSUFFICS) sockgetchar$(OBJSUFFICS) base64$(OBJSUFFICS) log$(OBJSUFFICS) common$(OBJSUFFICS) $(COMPATLIBS) $(LIBS)
+$(BUILDDIR)smtpp$(EXESUFFICS): sockmap$(OBJSUFFICS) smtpp$(OBJSUFFICS) sockgetchar$(OBJSUFFICS) common$(OBJSUFFICS) base64$(OBJSUFFICS) $(COMPATLIBS)
+	$(LN) $(LNOUT)$(BUILDDIR)smtpp$(EXESUFFICS) $(LDFLAGS) sockmap$(OBJSUFFICS) smtpp$(OBJSUFFICS) sockgetchar$(OBJSUFFICS) base64$(OBJSUFFICS) common$(OBJSUFFICS) $(COMPATLIBS) $(LIBS)
 
-$(BUILDDIR)ftppr$(EXESUFFICS): sockmap$(OBJSUFFICS) ftppr$(OBJSUFFICS) ftp$(OBJSUFFICS) sockgetchar$(OBJSUFFICS) common$(OBJSUFFICS) log$(OBJSUFFICS) $(COMPATLIBS)
-	$(LN) $(LNOUT)$(BUILDDIR)ftppr$(EXESUFFICS) $(LDFLAGS) sockmap$(OBJSUFFICS) ftppr$(OBJSUFFICS) sockgetchar$(OBJSUFFICS) common$(OBJSUFFICS) log$(OBJSUFFICS) ftp$(OBJSUFFICS) $(COMPATLIBS) $(LIBS)
+$(BUILDDIR)ftppr$(EXESUFFICS): sockmap$(OBJSUFFICS) ftppr$(OBJSUFFICS) ftp$(OBJSUFFICS) sockgetchar$(OBJSUFFICS) common$(OBJSUFFICS) $(COMPATLIBS)
+	$(LN) $(LNOUT)$(BUILDDIR)ftppr$(EXESUFFICS) $(LDFLAGS) sockmap$(OBJSUFFICS) ftppr$(OBJSUFFICS) sockgetchar$(OBJSUFFICS) common$(OBJSUFFICS) ftp$(OBJSUFFICS) $(COMPATLIBS) $(LIBS)
 
-$(BUILDDIR)socks$(EXESUFFICS): sockmap$(OBJSUFFICS) socks$(OBJSUFFICS) sockgetchar$(OBJSUFFICS) common$(OBJSUFFICS) log$(OBJSUFFICS)
-	$(LN) $(LNOUT)$(BUILDDIR)socks$(EXESUFFICS) $(LDFLAGS) sockmap$(OBJSUFFICS) socks$(OBJSUFFICS) sockgetchar$(OBJSUFFICS) log$(OBJSUFFICS) common$(OBJSUFFICS) $(LIBS)
+$(BUILDDIR)socks$(EXESUFFICS): sockmap$(OBJSUFFICS) socks$(OBJSUFFICS) sockgetchar$(OBJSUFFICS) common$(OBJSUFFICS)
+	$(LN) $(LNOUT)$(BUILDDIR)socks$(EXESUFFICS) $(LDFLAGS) sockmap$(OBJSUFFICS) socks$(OBJSUFFICS) sockgetchar$(OBJSUFFICS) common$(OBJSUFFICS) $(LIBS)
 
-$(BUILDDIR)tcppm$(EXESUFFICS): sockmap$(OBJSUFFICS) sockgetchar$(OBJSUFFICS) tcppm$(OBJSUFFICS) common$(OBJSUFFICS) log$(OBJSUFFICS)
-	$(LN) $(LNOUT)$(BUILDDIR)tcppm$(EXESUFFICS) $(LDFLAGS) sockmap$(OBJSUFFICS) sockgetchar$(OBJSUFFICS) tcppm$(OBJSUFFICS) log$(OBJSUFFICS) common$(OBJSUFFICS) $(LIBS)
+$(BUILDDIR)tcppm$(EXESUFFICS): sockmap$(OBJSUFFICS) sockgetchar$(OBJSUFFICS) tcppm$(OBJSUFFICS) common$(OBJSUFFICS)
+	$(LN) $(LNOUT)$(BUILDDIR)tcppm$(EXESUFFICS) $(LDFLAGS) sockmap$(OBJSUFFICS) sockgetchar$(OBJSUFFICS) tcppm$(OBJSUFFICS) common$(OBJSUFFICS) $(LIBS)
 
-$(BUILDDIR)udppm$(EXESUFFICS): sockmap$(OBJSUFFICS) sockgetchar$(OBJSUFFICS) udppm$(OBJSUFFICS) common$(OBJSUFFICS) log$(OBJSUFFICS)
-	$(LN) $(LNOUT)$(BUILDDIR)udppm$(EXESUFFICS) $(LDFLAGS) sockmap$(OBJSUFFICS) sockgetchar$(OBJSUFFICS) udppm$(OBJSUFFICS) log$(OBJSUFFICS) common$(OBJSUFFICS) $(LIBS)
+$(BUILDDIR)udppm$(EXESUFFICS): sockmap$(OBJSUFFICS) sockgetchar$(OBJSUFFICS) udppm$(OBJSUFFICS) common$(OBJSUFFICS)
+	$(LN) $(LNOUT)$(BUILDDIR)udppm$(EXESUFFICS) $(LDFLAGS) sockmap$(OBJSUFFICS) sockgetchar$(OBJSUFFICS) udppm$(OBJSUFFICS) common$(OBJSUFFICS) $(LIBS)
 
 mainfunc$(OBJSUFFICS): proxy.h structures.h proxymain.c
 	$(CC) $(COUT)mainfunc$(OBJSUFFICS) $(CFLAGS) $(DEFINEOPTION)MODULEMAINFUNC=mainfunc proxymain.c

+ 0 - 152
src/auth.c

@@ -1370,155 +1370,3 @@ unsigned long fakeresolver (int af, unsigned char *name, unsigned char * value){
  }
  return 1;
 }
-
-#ifndef NOODBC
-
-SQLHENV  henv = NULL;
-SQLHSTMT hstmt = NULL;
-SQLHDBC hdbc = NULL;
-char * sqlstring = NULL;
-
-
-void close_sql(){
-	if(hstmt) {
-		SQLFreeHandle(SQL_HANDLE_STMT, hstmt);
-		hstmt = NULL;
-	}
-	if(hdbc){
-		SQLDisconnect(hdbc);
-		SQLFreeHandle(SQL_HANDLE_DBC, hdbc);
-		hdbc = NULL;
-	}
-	if(henv) {
-		SQLFreeHandle(SQL_HANDLE_ENV, henv);
-		henv = NULL;
-	}
-}
-
-int attempt = 0;
-time_t attempt_time = 0;
-
-int init_sql(char * s){
-	SQLRETURN  retcode;
-	char * datasource;
-	char * username;
-	char * password;
-	char * string;
-
-	if(!s) return 0;
-	if(!sqlstring || strcmp(sqlstring, s)){
-		string = sqlstring;
-		sqlstring=mystrdup(s);
-		if(string)myfree(string);
-	}
-
-	if(hstmt || hdbc || henv) close_sql();
-	attempt++;
-	attempt_time = time(0);
-	if(!henv){
-		retcode = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &henv);
-		if (!henv || (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO)){
-			henv = NULL;
-			return 0;
-		}
-		retcode = SQLSetEnvAttr(henv, SQL_ATTR_ODBC_VERSION, (void*)SQL_OV_ODBC3, 0); 
-
-		if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO) {
-			return 0;
-		}
-	}
-	if(!hdbc){
-		retcode = SQLAllocHandle(SQL_HANDLE_DBC, henv, &hdbc); 
-		if (!hdbc || (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO)) {
-			hdbc = NULL;
-			SQLFreeHandle(SQL_HANDLE_ENV, henv);
-			henv = NULL;
-			return 0;
-		}
-	       	SQLSetConnectAttr(hdbc, SQL_LOGIN_TIMEOUT, (void*)15, 0);
-	}
-	string = mystrdup(sqlstring);
-	if(!string) return 0;
-	datasource = strtok(string, ",");
-	username = strtok(NULL, ",");
-	password = strtok(NULL, ",");
-	
-
-         /* Connect to data source */
-        retcode = SQLConnect(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){
-		SQLFreeHandle(SQL_HANDLE_DBC, hdbc);
-		hdbc = NULL;
-		SQLFreeHandle(SQL_HANDLE_ENV, henv);
-		henv = NULL;
-		return 0;
-	}
-        retcode = SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmt); 
-        if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO){
-		close_sql();
-		return 0;
-	}
-	return 1;
-}
-
-void sqlerr (char *buf){
-	if(conf.stdlog){
-		fprintf(conf.stdlog, "%s\n", buf);
-		fflush(conf.stdlog);
-	}
-	pthread_mutex_unlock(&log_mutex);
-}
-
-unsigned char statbuf[8192];
-
-void logsql(struct clientparam * param, const unsigned char *s) {
-	SQLRETURN ret;
-	int len;
-
-
-	if(param->nolog) return;
-	pthread_mutex_lock(&log_mutex);
-	len = dobuf(param, statbuf, s, (unsigned char *)"\'");
-
-	if(attempt > 5){
-		time_t t;
-
-		t = time(0);
-		if (t - attempt_time < 180){
-			sqlerr((char *)statbuf);
-			return;
-		}
-	}
-	if(!hstmt){
-		if(!init_sql(sqlstring)) {
-			sqlerr((char *)statbuf);
-			return;
-		}
-	}
-	if(hstmt){
-		ret = SQLExecDirect(hstmt, (SQLCHAR *)statbuf, (SQLINTEGER)len);
-		if(ret != SQL_SUCCESS && ret != SQL_SUCCESS_WITH_INFO){
-			close_sql();
-			if(!init_sql(sqlstring)){
-				sqlerr((char *)statbuf);
-				return;
-			}
-			if(hstmt) {
-				ret = SQLExecDirect(hstmt, (SQLCHAR *)statbuf, (SQLINTEGER)len);
-				if(ret != SQL_SUCCESS && ret != SQL_SUCCESS_WITH_INFO){
-					sqlerr((char *)statbuf);
-					return;
-				}
-				attempt = 0;
-			}
-		}
-		attempt = 0;
-	}
-	pthread_mutex_unlock(&log_mutex);
-}
-
-#endif

+ 54 - 28
src/authradius.c

@@ -293,14 +293,14 @@ typedef struct radius_packet_t {
   uint8_t       id;
   uint16_t      length;
   uint8_t       vector[AUTH_VECTOR_LEN];
-  uint8_t       data[4096];
+  uint8_t       data[2048];
 } radius_packet_t;
           
 #define RETURN(xxx) { res = xxx; goto CLEANRET; }
 
-int radsend(struct clientparam * param, int auth, int stop){
+#define packet (*((radius_packet_t *)inbuf))
 
-	int loop;
+int radbuf(struct clientparam * param, unsigned char * inbuf, int auth, int stop){
 	int id;
 	int res = 4;
 	SOCKET sockfd = -1;
@@ -308,29 +308,16 @@ int radsend(struct clientparam * param, int auth, int stop){
 	int total_length;
 	int len;
 	int op;
-#ifdef NOIPV6
-	struct  sockaddr_in     saremote;
-#else
-	struct  sockaddr_in6     saremote;
-#endif
-	struct pollfd fds[1];
 	char vector[AUTH_VECTOR_LEN];
-	radius_packet_t packet, rpacket;
-	SASIZETYPE salen;
-	int data_len;
-	uint8_t	*vendor_len;
 	int count=0;
-	uint8_t *attr;
 	long vendor=0;
-	int vendorlen=0;
 	char buf[64];
 
-
 	if(!radiussecret || !nradservers) {
-		return 4;
+		return 0;
 	}
 
-	memset(&packet, 0, sizeof(packet));
+	memset(&packet, 0, sizeof(radius_packet_t));
 
 
 	pthread_mutex_lock(&rad_mutex);
@@ -526,6 +513,39 @@ int radsend(struct clientparam * param, int auth, int stop){
 		md5_calc(packet.vector, (u_char *)&packet, total_length + len);
 	}
 	memcpy(vector, packet.vector, AUTH_VECTOR_LEN);
+	return total_length;
+
+}
+
+
+int radsend(const unsigned char *inbuf, int total_length, int auth, 
+#ifdef NOIPV6
+	struct  sockaddr_in*     sinsl
+#else
+	struct  sockaddr_in6*     sinsl
+#endif
+){
+
+	int loop;
+	int res = 4;
+	SOCKET sockfd = -1;
+	int len;
+#ifdef NOIPV6
+	struct  sockaddr_in     saremote;
+#else
+	struct  sockaddr_in6     saremote;
+#endif
+	struct pollfd fds[1];
+	radius_packet_t rpacket;
+	SASIZETYPE salen;
+	int data_len;
+	uint8_t	*vendor_len;
+	int count=0;
+	uint8_t *attr;
+	long vendor=0;
+	int vendorlen=0;
+
+
 	
 	for (loop = 0; loop < nradservers && loop < MAXRADIUS; loop++) {
 		SOCKET remsock;
@@ -554,7 +574,7 @@ int radsend(struct clientparam * param, int auth, int stop){
 		}
 		else remsock = radiuslist[loop].logsock;
 */
-		so._bind(param->remsock,(struct sockaddr *)&radiuslist[loop].localaddr,SASIZE(&radiuslist[loop].localaddr));
+		so._bind(remsock,(struct sockaddr *)&radiuslist[loop].localaddr,SASIZE(&radiuslist[loop].localaddr));
 		len = so._sendto(remsock, (char *)&packet, total_length, 0,
 		      (struct sockaddr *)&saremote, sizeof(saremote));
 		if(len != ntohs(packet.length)){
@@ -621,13 +641,13 @@ int radsend(struct clientparam * param, int auth, int stop){
 			}
 	
 			if (!vendor && attr[0] == PW_FRAMED_IP_ADDRESS && attr[1] == 6) {
-				*SAFAMILY(&param->sinsl) = AF_INET;
-				memcpy(SAADDR(&param->sinsl), attr+2, 4);
+				*SAFAMILY(sinsl) = AF_INET;
+				memcpy(SAADDR(sinsl), attr+2, 4);
 			}
 
 			else if (!vendor && attr[0] == PW_FRAMED_IPV6_ADDRESS && attr[1] == 18) {
-				*SAFAMILY(&param->sinsl) = AF_INET6;
-				memcpy(SAADDR(&param->sinsl), attr+2, 16);
+				*SAFAMILY(sinsl) = AF_INET6;
+				memcpy(SAADDR(sinsl), attr+2, 16);
 			}
 			else if (!vendor && attr[0] == PW_REPLY_MESSAGE && attr[1] >= 3 && isdigit(attr[2])) {
 				res = 0;
@@ -657,14 +677,20 @@ CLEANRET:
 }
 
 int radauth(struct clientparam * param){
+	radius_packet_t ppacket;
+	int len;
 	/*radsend(param, 0, 0);*/
-	return radsend(param, 1, 0);
+	len = radbuf(param, (unsigned char *)&ppacket, 1, 0);
+	return len?radsend((unsigned char *)&ppacket, len, 1, &param->sinsl):4;
+}
+
+
+int raddobuf(struct clientparam * param, unsigned char * buf, const unsigned char *s){
+	return radbuf(param, buf, 0, 1);
 }
 
-void logradius(struct clientparam * param, const unsigned char *s) {
-	radsend(param, 0, 1);
-	if(param->trafcountfunc)(*param->trafcountfunc)(param);
-	clearstat(param);
+void logradius(const unsigned char *buf, int len, struct LOGGER *logger){
+	if(len)radsend(buf, len, 0, NULL);
 }
 
 

+ 37 - 34
src/common.c

@@ -93,42 +93,46 @@ char *rotations[] = {
 
 
 struct extparam conf = {
-	{1, 5, 30, 60, 180, 1800, 15, 60, 15, 5, 0, 0},
-	NULL,
-	NULL,
-	NULL, NULL,
-	NULL,
-	NULL,
-	NULL,
-	0,
-	0, -1, 0, 0, 0, 0, 
-	0, 500, 0, 0, 0, 0,
-	6, 600,
-	1048576,
-	NULL, NULL,
-	NONE, NONE,
-	NULL,
+	{1, 5, 30, 60, 180, 1800, 15, 60, 15, 5, 0, 0}, /* int timeouts[12]; */
+	NULL, /*struct ace * acl; */
+	NULL, /* char * conffile; */
+	NULL, NULL, /* struct bandlim * bandlimiter,  *bandlimiterout; */
+	NULL, /* struct connlim * connlimiter; */
+	NULL, /* struct trafcount * trafcounter; */
+	NULL, /* struct srvparam *services; */
+	0, /* int stacksize, */ 
+	0, -1, 0, 0, 0, 0, /* threadinit, counterd, haveerror, rotate, paused, archiverc, */
+	0, 500, 0, 0, 0, 0, /* demon, maxchild, needreload, timetoexit, version, noforce; */
+	6, 600, /* int authcachetype, authcachetime; */
+	1048576, /* int filtermaxsize; */
+	NULL, /* **archiver; */
+	NONE, NONE, /* 	ROTATION logtype, countertype; */
+	NULL, /* 	char * counterfile; */
 #ifndef NOIPV6
-	{AF_INET},{AF_INET6},{AF_INET}, 
+	{AF_INET},{AF_INET6},{AF_INET}, /*	struct sockaddr_in6 intsa;
+						struct sockaddr_in6 extsa6;
+						struct sockaddr_in6 extsa; */
+
 #else
-	{AF_INET},{AF_INET}, 
+	{AF_INET},{AF_INET}, /*	struct sockaddr_in intsa;
+				struct sockaddr_in extsa; */
+
 #endif
-	NULL,
-	NULL,
-	doconnect,
-	lognone,
-	NULL,
-	NULL,
-	NULL, NULL,
-	NULL,
-	NULL,
-	NULL,
-	NULL,
-	NULL,
-	NULL,
-	(time_t)0, (time_t)0,
-	0,0,
-	'@',
+	NULL, /* struct passwords *pwl; */
+	NULL, /* struct auth * authenticate; */
+	doconnect, /* AUTHFUNC authfunc; */
+	NULL, /* BANDLIMFUNC bandlimfunc; */
+	NULL, /* TRAFCOUNTFUNC trafcountfunc; */
+	NULL, /* void (*prelog)(struct clientparam * param); */
+	NULL, NULL, /* unsigned char *logtarget, *logformat; */
+	NULL, /* struct filemon * fmon; */
+	NULL, /* struct filter * filters; */
+	NULL, /* struct auth *authfuncs; */
+	NULL, /* char* demanddialprog; */
+	NULL, /* unsigned char **stringtable; */
+	(time_t)0, /* time_t time; */
+	0,0, /* 	unsigned logdumpsrv, logdumpcli; */
+	'@', /* 	char delimchar; */
 };
 
 int numservers=0;
@@ -519,7 +523,6 @@ unsigned long getip(unsigned char *name){
 	}
 	if((tmpresolv=resolvfunc)){
 		if((*tmpresolv)(AF_INET, name, (unsigned char *)&retval)) return retval;
-		if(conf.demanddialprog) system(conf.demanddialprog);
 		return (*tmpresolv)(AF_INET, name, (unsigned char *)&retval)?retval:0;
 	}
 #if !defined(_WIN32) && !defined(GETHOSTBYNAME_R)

+ 38 - 156
src/conf.c

@@ -101,49 +101,6 @@ int getrotate(char c){
 }
 
 
-unsigned char * dologname (unsigned char *buf, 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, 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 start_proxy_thread(struct child * chp){
   pthread_t thread;
@@ -281,65 +238,12 @@ static int h_external(int argc, unsigned char ** argv){
 
 
 static int h_log(int argc, unsigned char ** argv){ 
-	unsigned char tmpbuf[8192];
-	int notchanged = 0;
-
-
-	havelog = 1;
-	if(argc > 1 && conf.logtarget && !strcmp((char *)conf.logtarget, (char *)argv[1])) {
-		notchanged = 1;
-	}
-	if(!notchanged && conf.logtarget){
-		myfree(conf.logtarget);
-		conf.logtarget = NULL;
-	}
-	if(argc > 1) {
-		if(!strcmp((char *) argv[1], "/dev/null")) {
-			conf.logfunc = lognone;
-			return 0;
-		}
-		if(!notchanged) conf.logtarget = (unsigned char *)mystrdup((char *)argv[1]);
-		if(*argv[1]=='@'){
-#ifndef _WIN32
-			conf.logfunc = logsyslog;
-			if(notchanged) return 0;
-			openlog((char *)conf.logtarget+1, LOG_PID, LOG_DAEMON);
-#endif
-		}
-#ifndef NOODBC
-		else if(*argv[1]=='&'){
-			if(notchanged) return 0;
-			conf.logfunc = logsql;
-			pthread_mutex_lock(&log_mutex);
-			close_sql();
-			init_sql((char *)argv[1]+1);
-			pthread_mutex_unlock(&log_mutex);
-		}
-#endif
-#ifndef NORADIUS
-		else if(!strcmp(argv[1],"radius")){
-			conf.logfunc = logradius;
-		}
-#endif
-		else {
-			if(argc > 2) {
-				conf.logtype = getrotate(*argv[2]);
-			}
-			conf.logfunc = logstdout;
-			if(notchanged) return 0;
-			conf.logtime = time(0);
-			if(conf.logname)myfree(conf.logname);
-			conf.logname = (unsigned char *)mystrdup((char *)argv[1]);
-			if(conf.stdlog) conf.stdlog = freopen((char *)dologname (tmpbuf, conf.logname, NULL, conf.logtype, conf.logtime), "a", conf.stdlog);
-			else conf.stdlog = fopen((char *)dologname (tmpbuf, conf.logname, NULL, conf.logtype, conf.logtime), "a");
-			if(!conf.stdlog){
-				perror((char *)tmpbuf);
-				return 1;
-			}
-
-		}
+	myfree(conf.logtarget);
+	if(argc < 2) conf.logtarget = (unsigned char *)mystrdup("");
+	else conf.logtarget = (unsigned char *)mystrdup((char *)argv[1]);
+	if(argc > 2) {
+		conf.logtype = getrotate(*argv[2]);
 	}
-	else conf.logfunc = logstdout;
 	return 0;
 }
 
@@ -648,12 +552,6 @@ static int h_nsrecord(int argc, unsigned char **argv){
 	return 0;
 }
 
-static int h_dialer(int argc, unsigned char **argv){
-	if(conf.demanddialprog) myfree(conf.demanddialprog);
-	conf.demanddialprog = mystrdup((char *)argv[1]);
-	return 0;
-}
-
 static int h_system(int argc, unsigned char **argv){
   int res;
 
@@ -1535,36 +1433,35 @@ struct commands commandhandlers[]={
 	{commandhandlers+28, "nscache", h_nscache, 2, 2},
 	{commandhandlers+29, "nscache6", h_nscache6, 2, 2},
 	{commandhandlers+30, "nsrecord", h_nsrecord, 3, 3},
-	{commandhandlers+31, "dialer", h_dialer, 2, 2},
-	{commandhandlers+32, "system", h_system, 2, 2},
-	{commandhandlers+33, "pidfile", h_pidfile, 2, 2},
-	{commandhandlers+34, "monitor", h_monitor, 2, 2},
-	{commandhandlers+35, "parent", h_parent, 5, 0},
-	{commandhandlers+36, "allow", h_ace, 1, 0},
-	{commandhandlers+37, "deny", h_ace, 1, 0},
-	{commandhandlers+38, "redirect", h_ace, 3, 0},
-	{commandhandlers+39, "bandlimin", h_ace, 2, 0},
-	{commandhandlers+40, "bandlimout", h_ace, 2, 0},
-	{commandhandlers+41, "nobandlimin", h_ace, 1, 0},
-	{commandhandlers+42, "nobandlimout", h_ace, 1, 0},
-	{commandhandlers+43, "countin", h_ace, 4, 0},
-	{commandhandlers+44, "nocountin", h_ace, 1, 0},
-	{commandhandlers+45, "countout", h_ace, 4, 0},
-	{commandhandlers+46, "nocountout", h_ace, 1, 0},
-	{commandhandlers+47, "connlim", h_ace, 4, 0},
-	{commandhandlers+48, "noconnlim", h_ace, 1, 0},
-	{commandhandlers+49, "plugin", h_plugin, 3, 0},
-	{commandhandlers+50, "logdump", h_logdump, 2, 3},
-	{commandhandlers+51, "filtermaxsize", h_filtermaxsize, 2, 2},
-	{commandhandlers+52, "nolog", h_nolog, 1, 1},
-	{commandhandlers+53, "weight", h_nolog, 2, 2},
-	{commandhandlers+54, "authcache", h_authcache, 2, 3},
-	{commandhandlers+55, "smtpp", h_proxy, 1, 0},
-	{commandhandlers+56, "delimchar",h_delimchar, 2, 2},
-	{commandhandlers+57, "authnserver", h_authnserver, 2, 2},
-	{commandhandlers+58, "stacksize", h_stacksize, 2, 2},
-	{commandhandlers+59, "force", h_force, 1, 1},
-	{commandhandlers+60, "noforce", h_noforce, 1, 1},
+	{commandhandlers+31, "system", h_system, 2, 2},
+	{commandhandlers+32, "pidfile", h_pidfile, 2, 2},
+	{commandhandlers+33, "monitor", h_monitor, 2, 2},
+	{commandhandlers+34, "parent", h_parent, 5, 0},
+	{commandhandlers+35, "allow", h_ace, 1, 0},
+	{commandhandlers+36, "deny", h_ace, 1, 0},
+	{commandhandlers+37, "redirect", h_ace, 3, 0},
+	{commandhandlers+38, "bandlimin", h_ace, 2, 0},
+	{commandhandlers+39, "bandlimout", h_ace, 2, 0},
+	{commandhandlers+40, "nobandlimin", h_ace, 1, 0},
+	{commandhandlers+41, "nobandlimout", h_ace, 1, 0},
+	{commandhandlers+42, "countin", h_ace, 4, 0},
+	{commandhandlers+43, "nocountin", h_ace, 1, 0},
+	{commandhandlers+44, "countout", h_ace, 4, 0},
+	{commandhandlers+45, "nocountout", h_ace, 1, 0},
+	{commandhandlers+46, "connlim", h_ace, 4, 0},
+	{commandhandlers+47, "noconnlim", h_ace, 1, 0},
+	{commandhandlers+48, "plugin", h_plugin, 3, 0},
+	{commandhandlers+49, "logdump", h_logdump, 2, 3},
+	{commandhandlers+50, "filtermaxsize", h_filtermaxsize, 2, 2},
+	{commandhandlers+51, "nolog", h_nolog, 1, 1},
+	{commandhandlers+52, "weight", h_nolog, 2, 2},
+	{commandhandlers+53, "authcache", h_authcache, 2, 3},
+	{commandhandlers+54, "smtpp", h_proxy, 1, 0},
+	{commandhandlers+55, "delimchar",h_delimchar, 2, 2},
+	{commandhandlers+56, "authnserver", h_authnserver, 2, 2},
+	{commandhandlers+57, "stacksize", h_stacksize, 2, 2},
+	{commandhandlers+58, "force", h_force, 1, 1},
+	{commandhandlers+59, "noforce", h_noforce, 1, 1},
 #ifndef NORADIUS
 	{commandhandlers+61, "radius", h_radius, 3, 0},
 #endif
@@ -1745,7 +1642,7 @@ void freeconf(struct extparam *confp){
  struct ace *acl;
  struct filemon *fm;
  int counterd, archiverc;
- unsigned char *logname, *logtarget;
+ unsigned char *logtarget;
  unsigned char **archiver;
  unsigned char * logformat;
 
@@ -1781,18 +1678,13 @@ void freeconf(struct extparam *confp){
  pthread_mutex_unlock(&pwl_mutex);
 
 
-/*
  logtarget = confp->logtarget;
  confp->logtarget = NULL;
- logname = confp->logname;
- confp->logname = NULL;
-*/
- confp->logfunc = lognone;
  logformat = confp->logformat;
  confp->logformat = NULL;
  confp->rotate = 0;
  confp->logtype = NONE;
- confp->logtime = confp->time = 0;
+ confp->time = 0;
 
  archiverc = confp->archiverc;
  confp->archiverc = 0;
@@ -1840,22 +1732,12 @@ void freeconf(struct extparam *confp){
  for(; fm; fm = (struct filemon *)itfree(fm, fm->next)){
 	if(fm->path) myfree(fm->path);
  }
-/*
- if(logtarget) {
-	myfree(logtarget);
- }
- if(logname) {
-	myfree(logname);
- }
-*/
- if(logformat) {
-	myfree(logformat);
- }
+ myfree(logtarget);
+ myfree(logformat);
  if(archiver) {
 	for(i = 0; i < archiverc; i++) myfree(archiver[i]);
 	myfree(archiver);
  }
- havelog = 0;
 }
 
 int reload (void){

+ 12 - 29
src/datatypes.c

@@ -9,7 +9,7 @@
 
 static void pr_unsigned64(struct node *node, CBFUNC cbf, void*cb){
 	char buf[32];
-	if(node->value)(*cbf)(cb, buf, sprintf(buf, "%"PRINTF_INT64_MODIFIER"u", *(uint64_t *)node->value));
+	if(node->value)(*cbf)(cb, buf, sprintf(buf, "%"PRIu64, *(uint64_t *)node->value));
 }
 
 static void pr_integer(struct node *node, CBFUNC cbf, void*cb){
@@ -523,19 +523,8 @@ static void * ef_server_childcount(struct node * node){
 }
 
 static void * ef_server_log(struct node * node){
-	if(((struct srvparam *)node->value) -> logfunc == lognone)	return "none";
-#ifndef NORADIUS
-	else if(((struct srvparam *)node->value) -> logfunc == logradius)	return "radius";
-#endif
-	else if(((struct srvparam *)node->value) -> logfunc == logstdout)
-		return (((struct srvparam *)node->value) -> logtarget)?"file":"stdout";
-#ifndef _WIN32
-	else if(((struct srvparam *)node->value) -> logfunc == logsyslog)	return "syslog";
-#endif
-#ifndef NOODBC
-	else if(((struct srvparam *)node->value) -> logfunc == logsql)	return "odbc";
-#endif
-	return NULL;
+	if(((struct srvparam *)node->value) -> log == NULL)	return "none";
+	return ((struct srvparam *)node->value) -> log -> selector;
 }
 
 static void * ef_server_logformat(struct node * node){
@@ -551,11 +540,6 @@ static void * ef_server_replacement(struct node * node){
 	return NULL;
 }
 
-static void * ef_server_logtarget(struct node * node){
-	return ((struct srvparam *)node->value) -> logtarget;
-}
-
-
 static void * ef_server_target(struct node * node){
 	return ((struct srvparam *)node->value) -> target;
 }
@@ -763,18 +747,17 @@ static struct property prop_server[] = {
 	{prop_server + 7, "singlepacket", ef_server_singlepacket, TYPE_INTEGER, "is single packet redirection"},
 	{prop_server + 8, "usentlm", ef_server_usentlm, TYPE_INTEGER, "allow NTLM authentication"},
 	{prop_server + 9, "log", ef_server_log, TYPE_STRING, "type of logging"},
-	{prop_server + 10, "logtarget", ef_server_logtarget, TYPE_STRING, "log target options"},
-	{prop_server + 11, "logformat", ef_server_logformat, TYPE_STRING, "logging format string"},
-	{prop_server + 12, "nonprintable", ef_server_nonprintable, TYPE_STRING, "non printable characters"},
-	{prop_server + 13, "replacement", ef_server_replacement, TYPE_CHAR, "replacement character"},
-	{prop_server + 14, "childcount", ef_server_childcount, TYPE_INTEGER, "number of servers connected"},
-	{prop_server + 15, "intsa", ef_server_intsa, TYPE_SA, "ip address of internal interface"},
-	{prop_server + 16, "extsa", ef_server_extsa, TYPE_SA, "ip address of external interface"},
+	{prop_server + 10, "logformat", ef_server_logformat, TYPE_STRING, "logging format string"},
+	{prop_server + 11, "nonprintable", ef_server_nonprintable, TYPE_STRING, "non printable characters"},
+	{prop_server + 12, "replacement", ef_server_replacement, TYPE_CHAR, "replacement character"},
+	{prop_server + 13, "childcount", ef_server_childcount, TYPE_INTEGER, "number of servers connected"},
+	{prop_server + 14, "intsa", ef_server_intsa, TYPE_SA, "ip address of internal interface"},
+	{prop_server + 15, "extsa", ef_server_extsa, TYPE_SA, "ip address of external interface"},
 #ifndef NOIPV6
-	{prop_server + 17, "extsa6", ef_server_extsa6, TYPE_SA, "ipv6 address of external interface"},
-	{prop_server + 18, "child", ef_server_child, TYPE_CLIENT, "connected clients"},
-#else
+	{prop_server + 16, "extsa6", ef_server_extsa6, TYPE_SA, "ipv6 address of external interface"},
 	{prop_server + 17, "child", ef_server_child, TYPE_CLIENT, "connected clients"},
+#else
+	{prop_server + 16, "child", ef_server_child, TYPE_CLIENT, "connected clients"},
 #endif
 	{NULL, "next", ef_server_next, TYPE_SERVER, "next"}
 };

+ 1 - 0
src/ftppr.c

@@ -333,4 +333,5 @@ struct proxydef childdef = {
 	" -hdefault_host[:port] - use this host and port as default if no host specified\n"
 };
 #include "proxymain.c"
+#include "log.c"
 #endif

+ 768 - 41
src/log.c

@@ -6,32 +6,466 @@
 
 */
 
-
-
-
 #include "proxy.h"
 pthread_mutex_t log_mutex;
-int havelog = 0;
+#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;
+
+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);
+#ifndef WITHMAIN
+		if(log->rotate && log->logfunc && log->logfunc->rotate && timechanged(log->rotated, conf.time, log->rotate)){
+			log->logfunc->rotate(log);
+			log->rotated = conf.time;
+		}
+#endif
+	}
+}
+
+
+
+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;
+			log->rotated = conf.time;
+			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->logfunc(param, s);
-	else {
-		if(!init){
-			srvinit(&logsrv, &logparam);
-			init = 1;
+	if(!param || !param->srv){
+		stdlog(s, strlen(s), &errlogger);
+		return;
+	}
+	if(conf.prelog)conf.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);
 		}
-		logstdout(&logparam, s);
+		myfree(param->filters);
 	}
+	if(conf.connlimiter && (param->res != 95 || param->remsock != INVALID_SOCKET)) stopconnlims(param);
+#endif
+	if(param->srv){
+		pthread_mutex_lock(&param->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(&param->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) {
 
@@ -60,8 +494,48 @@ char months[12][4] = {
 	"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;
 
-int dobuf2(struct clientparam * param, unsigned char * buf, const unsigned char *s, const unsigned char * doublec, struct tm* tm, char * format){
+	ts = localtime(&t);
+	if(strchr((char *)name, '%')){
+		dobuf2(&logparam, buf, bufsize - (ext?strlen(ext):0), 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;
@@ -96,7 +570,7 @@ int dobuf2(struct clientparam * param, unsigned char * buf, const unsigned char
 
 	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 < 4040; j++){
+	for(i=0, j=0; format[j] && i < (bufsize-70); j++){
 		if(format[j] == '%' && format[j+1]){
 			j++;
 			switch(format[j]){
@@ -158,7 +632,7 @@ int dobuf2(struct clientparam * param, unsigned char * buf, const unsigned char
 				 break;
 				case 'U':
 				 if(param->username && *param->username){
-					for(len = 0; i< 4000 && param->username[len]; len++){
+					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])) {
@@ -174,7 +648,7 @@ int dobuf2(struct clientparam * param, unsigned char * buf, const unsigned char
 				 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 < 256; len++, i++){
+					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])) {
@@ -203,7 +677,7 @@ int dobuf2(struct clientparam * param, unsigned char * buf, const unsigned char
 				 break;
 				case 'T':
 				 if(s){
-					for(len = 0; i<4000 && s[len]; len++){
+					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])) {
@@ -246,15 +720,15 @@ int dobuf2(struct clientparam * param, unsigned char * buf, const unsigned char
 				 i += (int)strlen((char *)buf+i);
 				 break;
 				case 'L':
-				 sprintf((char *)buf+i, "%"PRINTF_INT64_MODIFIER"u", param->cycles);
+				 sprintf((char *)buf+i, "%"PRIu64, param->cycles);
 				 i += (int)strlen((char *)buf+i);
 				 break;
 				case 'I':
-				 sprintf((char *)buf+i, "%"PRINTF_INT64_MODIFIER"u", param->statssrv64);
+				 sprintf((char *)buf+i, "%"PRIu64, param->statssrv64);
 				 i += (int)strlen((char *)buf+i);
 				 break;
 				case 'O':
-				 sprintf((char *)buf+i, "%"PRINTF_INT64_MODIFIER"u", param->statscli64);
+				 sprintf((char *)buf+i, "%"PRIu64, param->statscli64);
 				 i += (int)strlen((char *)buf+i);
 				 break;
 				case 'h':
@@ -281,13 +755,13 @@ int dobuf2(struct clientparam * param, unsigned char * buf, const unsigned char
 							j = k;
 						}
 						if(!s || format[k]!='T') break;
-						for(k = 0, len = 0; s[len] && i < 4000; len++){
+						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) {
+							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])) {
@@ -310,7 +784,7 @@ int dobuf2(struct clientparam * param, unsigned char * buf, const unsigned char
 	return i;
 }
 
-int dobuf(struct clientparam * param, unsigned char * buf, const unsigned char *s, const unsigned char * doublec){
+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;
@@ -318,37 +792,290 @@ int dobuf(struct clientparam * param, unsigned char * buf, const unsigned char *
 
 	time(&t);
 	if(!param) return 0;
-	if(param->trafcountfunc)(*param->trafcountfunc)(param);
 	format = param->srv->logformat?(char *)param->srv->logformat : DEFLOGFORMAT;
 	tm = (*format == 'G' || *format == 'g')?
 		gmtime(&t) : localtime(&t);
-	i = dobuf2(param, buf, s, doublec, tm, format + 1);
-	clearstat(param);
+	i = dobuf2(param, buf, bufsize, s, doublec, tm, format + 1);
 	return i;
 }
 
-void lognone(struct clientparam * param, const unsigned char *s) {
-	if(param->trafcountfunc)(*param->trafcountfunc)(param);
-	clearstat(param);
+
+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);
+	}
+ }
 }
 
-void logstdout(struct clientparam * param, const unsigned char *s) {
-	FILE *log;
-	unsigned char tmpbuf[8192];
+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);
+}
 
-	dobuf(param, tmpbuf, s, NULL);
-	log = param->srv->stdlog?param->srv->stdlog:conf.stdlog?conf.stdlog:stdout;
-	if(!param->nolog)if(fprintf(log, "%s\n", tmpbuf) < 0) {
-		perror("printf()");
-	};
-	if(log != conf.stdlog)fflush(log);
+static void syslogrotate(struct LOGGER *logger){
+	closelog();
+	openlog(logger->selector+1, LOG_PID, LOG_DAEMON);
 }
-#ifndef _WIN32
-void logsyslog(struct clientparam * param, const unsigned char *s) {
 
-	unsigned char tmpbuf[8192];
-	dobuf(param, tmpbuf, s, NULL);
-	if(!param->nolog)syslog(LOG_INFO, "%s", tmpbuf);
+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

+ 2 - 0
src/plugins.c

@@ -75,6 +75,8 @@ struct symbol symbols[] = {
 	{symbols+48, "make_ace", (void *) make_ace},
 	{symbols+49, "freeacl", (void *) freeacl},
 	{symbols+50, "checkpreACL", (void *) checkpreACL},
+	{symbols+51, "dolog", (void *) dolog},
+	{symbols+52, "logfuncs", (void *) &logfuncs},
 	{NULL, "", NULL}
 };
 

+ 10 - 4
src/plugins/LdapPlugin/ldapauth.c

@@ -22,6 +22,9 @@ static struct commands ldap_trafgroup_handler;
 static struct commands ldap_attrsgroup_handler;
 static struct commands ldap_dircount_handler;
 
+static void (*dolog)(struct clientparam * param, const unsigned char *s);
+
+
 static char   *attrs[] = { NULL, NULL};
 static char   *ldap_group_attr;
 static char   *ldap_access;
@@ -109,7 +112,7 @@ static int ldapfunc(struct clientparam *param)
   ld = ldap_init( ldap_serv, 389 );
   if ( ld == NULL ) 
    {
-    param->srv->logfunc(param,"Error ldap_init: No init lib ldap");
+    dolog(param,"Error ldap_init: No init lib ldap");
     /*ldap_perror( ld, "Error ldap_init" ); */
     return 7; 
    }
@@ -133,7 +136,7 @@ static int ldapfunc(struct clientparam *param)
   
   if ( rc != LDAP_SUCCESS ) 
     {
-     param->srv->logfunc(param,"Error ldap_bind: No connect ldap catalog");
+     dolog(param,"Error ldap_bind: No connect ldap catalog");
      ldap_unbind_s(ld);	
      return 7;
     }
@@ -144,7 +147,7 @@ static int ldapfunc(struct clientparam *param)
 
   if ( ld == NULL ) 
    {
-    param->srv->logfunc(param,"Error ldap_init: No init lib ldap");
+    dolog(param,"Error ldap_init: No init lib ldap");
     /*ldap_perror( ld, "Error ldap_init" ); */
     return 7; 
    }
@@ -153,7 +156,7 @@ static int ldapfunc(struct clientparam *param)
  
    if ( rc != LDAP_SUCCESS ) 
     {
-     param->srv->logfunc(param, "Error ldap_bind: Not authorize in ldap\
+     dolog(param, "Error ldap_bind: Not authorize in ldap\
      catalog,  checked option \'ldapconnect\' ");
      ldap_unbind_s(ld);
      return 7;
@@ -472,6 +475,9 @@ PLUGINAPI int PLUGINCALL start(struct pluginlink * pluginlink,
     return (0);
    }
 
+
+   dolog=pluginlink->findbyname("dolog");
+
    already_loaded = 1;
     
     mypluginlink=pluginlink;

+ 10 - 7
src/plugins/SSLPlugin/ssl_plugin.c

@@ -28,6 +28,7 @@ extern "C" {
 #endif
 
 PROXYFUNC tcppmfunc, proxyfunc, smtppfunc, ftpprfunc;
+static void (*pdolog)(struct clientparam * param, const unsigned char *s);
 
 static struct pluginlink * pl;
 
@@ -238,25 +239,25 @@ int dossl(struct clientparam* param, SSL_CONN* ServerConnp, SSL_CONN* ClientConn
  ServerConn = ssl_handshake_to_server(param->remsock, (char *)param->hostname, &ServerCert, &errSSL);
  if ( ServerConn == NULL || ServerCert == NULL ) {
 	param->res = 8011;
-	param->srv->logfunc(param, (unsigned char *)"SSL handshake to server failed");
-	if(ServerConn == NULL) 	param->srv->logfunc(param, (unsigned char *)"ServerConn is NULL");
-	if(ServerCert == NULL) 	param->srv->logfunc(param, (unsigned char *)"ServerCert is NULL");
-	if(errSSL)param->srv->logfunc(param, (unsigned char *)errSSL);
+	pdolog(param, (unsigned char *)"SSL handshake to server failed");
+	if(ServerConn == NULL) 	pdolog(param, (unsigned char *)"ServerConn is NULL");
+	if(ServerCert == NULL) 	pdolog(param, (unsigned char *)"ServerCert is NULL");
+	if(errSSL)pdolog(param, (unsigned char *)errSSL);
 	return 1;
  }
  FakeCert = ssl_copy_cert(ServerCert);
  if ( FakeCert == NULL ) {
 	param->res = 8012;
 	_ssl_cert_free(ServerCert);
-	param->srv->logfunc(param, (unsigned char *)"Failed to create certificate copy");
+	pdolog(param, (unsigned char *)"Failed to create certificate copy");
 	ssl_conn_free(ServerConn);
 	return 2;
  }
  ClientConn = ssl_handshake_to_client(param->clisock, FakeCert, &errSSL);
  if ( ClientConn == NULL ) {
 	param->res = 8012;
-	param->srv->logfunc(param, (unsigned char *)"Handshake to client failed");
-	if(errSSL)param->srv->logfunc(param, (unsigned char *)errSSL);
+	pdolog(param, (unsigned char *)"Handshake to client failed");
+	if(errSSL)pdolog(param, (unsigned char *)errSSL);
 	_ssl_cert_free(ServerCert);
 	_ssl_cert_free(FakeCert);
 	ssl_conn_free(ServerConn);
@@ -382,6 +383,8 @@ PLUGINAPI int PLUGINCALL ssl_plugin (struct pluginlink * pluginlink,
 					 int argc, char** argv){
 
 	pl = pluginlink;
+        pdolog=pluginlink->findbyname("dolog");
+
 	if(!ssl_loaded){
 		ssl_loaded = 1;
 		pthread_mutex_init(&ssl_mutex, NULL);

+ 1 - 1
src/plugins/TrafficPlugin/Makefile.inc

@@ -4,4 +4,4 @@ TrafficPlugin$(OBJSUFFICS): TrafficPlugin.c
 	$(CC) $(DCFLAGS) $(CFLAGS) TrafficPlugin.c
 
 $(BUILDDIR)TrafficPlugin$(DLSUFFICS): TrafficPlugin$(OBJSUFFICS)
-	$(LN) $(LNOUT)../../$(BUILDDIR)TrafficPlugin$(DLSUFFICS) $(LDFLAGS) $(DLFLAGS) TrafficPlugin$(OBJSUFFICS)
+	$(LN) $(LNOUT)../../$(BUILDDIR)TrafficPlugin$(DLSUFFICS) $(LDFLAGS) $(DLFLAGS) TrafficPlugin$(OBJSUFFICS) $(LIBS)

+ 14 - 17
src/plugins/TrafficPlugin/TrafficPlugin.c

@@ -28,8 +28,8 @@ int DBGLEVEL = 0;
 int already_loaded = 0;
 typedef int (* handler)(int argc, unsigned char ** argv);
 
-struct extparam * conf;
-struct commands * commandhandlers;
+struct extparam * sconfp;
+struct commands * scommandhandlers;
 struct pluginlink * pl;
 
 typedef enum {
@@ -169,12 +169,9 @@ int h_trafcorrect(int argc, unsigned char ** argv) {
 	return 1;
 }
 
-static unsigned short myhtons(unsigned short port) {
-  return (port << 8) | (port >> 8);
-}
+void(*origprelog)(struct clientparam * param) = NULL;
 
-LOGFUNC origlogfunc;
-void mylogfunc(struct clientparam * param, const unsigned char * pz) {
+void mylogfunc(struct clientparam * param) {
 	PROXYSERVICE g_s = S_NOSERVICE;
 	int port;
 	int rule = 0;
@@ -189,7 +186,7 @@ void mylogfunc(struct clientparam * param, const unsigned char * pz) {
 		port = starttrafcorrect->port;
 		g_s = starttrafcorrect->p_service;
 		if (starttrafcorrect->p_service == S_NOSERVICE) g_s = param->service;
-		if (starttrafcorrect->port <= 0)  port = myhtons(*SAPORT(&param->sinsr));
+		if (starttrafcorrect->port <= 0)  port = htons(*SAPORT(&param->sinsr));
 		
 #ifndef NOPSTDINT
 		statssrv_before = param->statssrv64;
@@ -199,7 +196,7 @@ void mylogfunc(struct clientparam * param, const unsigned char * pz) {
 		statscli_before = param->statscli;
 #endif
 		rule++;
-		if (((g_s == param->service) && (port == myhtons(*SAPORT(&param->sinsr)))) || 
+		if (((g_s == param->service) && (port == htons(*SAPORT(&param->sinsr)))) || 
 			( ((starttrafcorrect->type == UDP) && 
 				((param->operation == UDPASSOC)||
 				 (param->operation == DNSRESOLVE)||
@@ -240,9 +237,9 @@ void mylogfunc(struct clientparam * param, const unsigned char * pz) {
 				}
 				if (DBGLEVEL == 1) {
 #ifndef NOPSTDINT
-					fprintf(stdout, "Port=%hd; Before: srv=%"PRINTF_INT64_MODIFIER"d, cli=%"PRINTF_INT64_MODIFIER"d; After:  srv=%"PRINTF_INT64_MODIFIER"d, cli=%"PRINTF_INT64_MODIFIER"d; nreads=%ld; nwrites=%ld; Rule=%d\n",myhtons(*SAPORT(&param->sinsr)), statssrv_before, statscli_before, param->statssrv64, param->statscli64,param->nreads,param->nwrites,rule);
+					fprintf(stdout, "Port=%hd; Before: srv=%"PRIu64", cli=%"PRIu64"; After:  srv=%"PRIu64", cli=%"PRIu64"; nreads=%ld; nwrites=%ld; Rule=%d\n",htons(*SAPORT(&param->sinsr)), statssrv_before, statscli_before, param->statssrv64, param->statscli64,param->nreads,param->nwrites,rule);
 #else
-					fprintf(stdout, "Port=%hd; Before: srv=%lu, cli=%lu; After:  srv=%lu, cli=%lu; nreads=%ld; nwrites=%ld; Rule=%d\n",myhtons(param->sins.sin_port), statssrv_before, statscli_before, param->statssrv, param->statscli,param->nreads,param->nwrites,rule);
+					fprintf(stdout, "Port=%hd; Before: srv=%lu, cli=%lu; After:  srv=%lu, cli=%lu; nreads=%ld; nwrites=%ld; Rule=%d\n",htons(*SAPORT(&param->sins)), statssrv_before, statscli_before, param->statssrv, param->statscli,param->nreads,param->nwrites,rule);
 #endif
 				}
 				ok = 1;
@@ -252,7 +249,7 @@ void mylogfunc(struct clientparam * param, const unsigned char * pz) {
 	if ((!ok) && (DBGLEVEL == 1)) {
 		fprintf(stdout, "No rules specifed: service=%d, port=%d, operation=%d", param->service, *SAPORT(&param->sinsr),param->operation);
 	}
-	origlogfunc(param, pz);
+	if(origprelog)origprelog(param);
 }
 
 #ifdef _WIN32
@@ -277,8 +274,8 @@ BOOL WINAPI DllMain( HINSTANCE hModule,
 PLUGINAPI int PLUGINCALL start(struct pluginlink * pluginlink, int argc, char** argv) {
 
 	struct commands * starthandler;
-	conf = pluginlink->conf;
-	commandhandlers = pluginlink->commandhandlers;
+	sconfp = pluginlink->conf;
+	scommandhandlers = pluginlink->commandhandlers;
 	pl = pluginlink;
 
 	if (argc>1) {
@@ -295,7 +292,7 @@ PLUGINAPI int PLUGINCALL start(struct pluginlink * pluginlink, int argc, char**
 	}
 	already_loaded = 1;
 	/* äîáàâëÿåì êîìàíäó "trafcorrect" */
-	starthandler = commandhandlers;
+	starthandler = scommandhandlers;
 	for ( ; starthandler->next; starthandler = starthandler->next);
 	trafcorrect_handler.next = NULL;
 	trafcorrect_handler.minargs = 1;
@@ -305,8 +302,8 @@ PLUGINAPI int PLUGINCALL start(struct pluginlink * pluginlink, int argc, char**
 	starthandler->next = &trafcorrect_handler;
 	
 	/* ïîäìåíÿåì conf->logfunc, ñ öåëüþ êîíòðîëèðîâàòü òðàôôèê */
-	origlogfunc = conf->logfunc;
-	conf->logfunc = mylogfunc;
+	origprelog = sconfp->prelog;
+	sconfp->prelog = mylogfunc;
 	return 0;
 }
 

+ 0 - 1
src/plugins/TransparentPlugin/transparent_plugin.c

@@ -54,7 +54,6 @@ static FILTER_ACTION transparent_filter_client(void *fo, struct clientparam * pa
 	}
 #else
 #error No SO_ORIGINAL_DST defined
-       	param->srv->logfunc(param, (unsigned char *)"transparent_plugin: No SO_ORIGINAL_DST defined");
 	return REJECT;
 #endif
 #else

+ 1 - 0
src/pop3p.c

@@ -69,4 +69,5 @@ struct proxydef childdef = {
 
 };
 #include "proxymain.c"
+#include "log.c"
 #endif

+ 7 - 6
src/proxy.c

@@ -392,7 +392,7 @@ for(;;){
 				while( (i = sockgetlinebuf(param, CLIENT, buf, BUFSIZE - 1, '\n', conf.timeouts[STRING_S])) > 2){
 					if(i> 15 && (!strncasecmp((char *)(buf), "content-length", 14))){
 						buf[i]=0;
-						sscanf((char *)buf + 15, "%"PRINTF_INT64_MODIFIER"u", &contentlength64);
+						sscanf((char *)buf + 15, "%"PRIu64, &contentlength64);
 					}
 				}
 				while( contentlength64 > 0 && (i = sockgetlinebuf(param, CLIENT, buf, (BUFSIZE < contentlength64)? BUFSIZE - 1:(int)contentlength64, '\n', conf.timeouts[STRING_S])) > 0){
@@ -502,7 +502,7 @@ for(;;){
 		if(!sb)continue;
 		++sb;
 		while(isspace(*sb))sb++;
-		sscanf((char *)sb, "%"PRINTF_INT64_MODIFIER"u",&contentlength64);
+		sscanf((char *)sb, "%"PRIu64,&contentlength64);
 		if(param->maxtrafout64 && (param->maxtrafout64 < param->statscli64 || contentlength64 > param->maxtrafout64 - param->statscli64)){
 			RETURN(10);
 		}
@@ -549,7 +549,7 @@ for(;;){
 	contentlength64 = param->cliinbuf;
 	param->ndatfilterscli = 0;
   }
-  sprintf((char*)buf+strlen((char *)buf), "Content-Length: %"PRINTF_INT64_MODIFIER"u\r\n", contentlength64);
+  sprintf((char*)buf+strlen((char *)buf), "Content-Length: %"PRIu64"\r\n", contentlength64);
  }
 
 #endif
@@ -923,7 +923,7 @@ for(;;){
 		if(!sb)continue;
 		++sb;
 		while(isspace(*sb))sb++;
-		sscanf((char *)sb, "%"PRINTF_INT64_MODIFIER"u", &contentlength64);
+		sscanf((char *)sb, "%"PRIu64, &contentlength64);
 		hascontent = 1;
 		if(param->unsafefilter && param->ndatfilterssrv > 0) {
 			hascontent = 2;
@@ -996,7 +996,7 @@ for(;;){
 	}
 	if(action != PASS) RETURN(517);
 	contentlength64 = param->srvinbuf;
-	sprintf((char*)buf+strlen((char *)buf), "Content-Length: %"PRINTF_INT64_MODIFIER"u\r\n", contentlength64);
+	sprintf((char*)buf+strlen((char *)buf), "Content-Length: %"PRIu64"\r\n", contentlength64);
 	hascontent = 1;
   }
  }
@@ -1043,7 +1043,7 @@ for(;;){
 			}
 			smallbuf[i] = 0;
 			contentlength64 = 0;
-			sscanf((char *)smallbuf, "%"PRINTF_INT64_MODIFIER"x", &contentlength64);
+			sscanf((char *)smallbuf, "%"SCNx64, &contentlength64);
 			if(contentlength64 == 0) {
 				param->chunked = 2;
 			}
@@ -1141,4 +1141,5 @@ struct proxydef childdef = {
 	"-a1 - anonymous proxy with random client IP spoofing\r\n"
 };
 #include "proxymain.c"
+#include "log.c"
 #endif

+ 7 - 16
src/proxy.h

@@ -54,6 +54,7 @@
 #include <sys/time.h>
 #include <unistd.h>
 #include <pthread.h>
+#include <semaphore.h>
 #include <syslog.h>
 #include <errno.h>
 #endif
@@ -166,21 +167,10 @@ int sockgetlinebuf(struct clientparam * param, DIRECTION which, unsigned char *
 
 
 
-
+void initlog(void);
 void dolog(struct clientparam * param, const unsigned char *s);
-int dobuf(struct clientparam * param, unsigned char * buf, const unsigned char *s, const unsigned char * doublec);
-int dobuf2(struct clientparam * param, unsigned char * buf, const unsigned char *s, const unsigned char * doublec, struct tm* tm, char * format);
-extern FILE * stdlog;
-void logstdout(struct clientparam * param, const unsigned char *s);
-void logsyslog(struct clientparam * param, const unsigned char *s);
-void lognone(struct clientparam * param, const unsigned char *s);
-void logradius(struct clientparam * param, const unsigned char *s);
-
-#ifndef NOSQL
-void logsql(struct clientparam * param, const unsigned char *s);
-int init_sql(char * s);
-void close_sql();
-#endif
+int dobuf(struct clientparam * param, unsigned char * buf, int bufsize, const unsigned char *s, const unsigned char * doublec);
+int dobuf2(struct clientparam * param, unsigned char * buf, int bufsize, const unsigned char *s, const unsigned char * doublec, struct tm* tm, char * format);
 int doconnect(struct clientparam * param);
 int alwaysauth(struct clientparam * param);
 int ipauth(struct clientparam * param);
@@ -202,11 +192,12 @@ unsigned long myresolver(int, unsigned char *, unsigned char *);
 unsigned long fakeresolver (int, unsigned char *, unsigned char*);
 int inithashtable(struct hashtable *hashtable, unsigned nhashsize);
 void freeparam(struct clientparam * param);
+void srvpostfree(struct srvparam * srv);
 void clearstat(struct clientparam * param);
 void dumpcounters(struct trafcount *tl, int counterd);
-
 int startconnlims (struct clientparam *param);
 void stopconnlims (struct clientparam *param);
+int timechanged (time_t oldtime, time_t newtime, ROTATION lt);
 
 
 
@@ -274,7 +265,7 @@ FILTER_ACTION handledatfltsrv(struct clientparam *param, unsigned char ** buf_p,
 void srvinit(struct srvparam * srv, struct clientparam *param);
 void srvinit2(struct srvparam * srv, struct clientparam *param);
 void srvfree(struct srvparam * srv);
-unsigned char * dologname (unsigned char *buf, unsigned char *name, const unsigned char *ext, ROTATION lt, time_t t);
+unsigned char * dologname (unsigned char *buf, int bufsize, unsigned char *name, const unsigned char *ext, ROTATION lt, time_t t);
 int readconfig(FILE * fp);
 int connectwithpoll(SOCKET sock, struct sockaddr *sa, SASIZETYPE size, int to);
 

+ 129 - 197
src/proxymain.c

@@ -8,6 +8,8 @@
 
 #include "proxy.h"
 
+void srvpostfree(struct srvparam * srv);
+
 #define param ((struct clientparam *) p)
 #ifdef _WIN32
 DWORD WINAPI threadfunc(LPVOID p) {
@@ -179,7 +181,7 @@ int MODULEMAINFUNC (int argc, char** argv){
  SASIZETYPE size;
  pthread_t thread;
  struct clientparam defparam;
- struct srvparam srv;
+ struct srvparam *srv;
  struct clientparam * newparam;
  int error = 0;
  unsigned sleeptime;
@@ -271,20 +273,21 @@ int MODULEMAINFUNC (int argc, char** argv){
 
 #endif
 
- srvinit(&srv, &defparam);
- srv.pf = childdef.pf;
+ srv = malloc(sizeof(struct srvparam));
+ srvinit(srv, &defparam);
+ srv->pf = childdef.pf;
  isudp = childdef.isudp;
- srv.service = defparam.service = childdef.service;
+ srv->service = defparam.service = childdef.service;
  
 #ifndef STDMAIN
- copyacl(conf.acl, &srv);
- srv.authfuncs = copyauth(conf.authfuncs);
+ copyacl(conf.acl, srv);
+ srv->authfuncs = copyauth(conf.authfuncs);
  if(!conf.services){
-	conf.services = &srv;
+	conf.services = srv;
  }
  else {
-	srv.next = conf.services;
-	conf.services = conf.services->prev = &srv;
+	srv->next = conf.services;
+	conf.services = conf.services->prev = srv;
  }
 #ifndef _WIN32
  {
@@ -294,8 +297,8 @@ int MODULEMAINFUNC (int argc, char** argv){
  }
 #endif
 #else
- srv.needuser = 0;
- pthread_mutex_init(&log_mutex, NULL);
+ srv->needuser = 0;
+ initlog();
 #endif
 
  for (i=1; i<argc; i++) {
@@ -307,37 +310,16 @@ int MODULEMAINFUNC (int argc, char** argv){
 			break;
 #ifdef SO_BINDTODEVICE
 		 case 'D':
-			if(argv[i][2] == 'i') srv.ibindtodevice = mystrdup(argv[i] + 3);
-			else srv.obindtodevice = mystrdup(argv[i] + 3);
+			if(argv[i][2] == 'i') srv->ibindtodevice = mystrdup(argv[i] + 3);
+			else srv->obindtodevice = mystrdup(argv[i] + 3);
 			break;
 #endif
 		 case 'l':
-			srv.logfunc = logstdout;
-			if(srv.logtarget) myfree(srv.logtarget);
-			srv.logtarget = (unsigned char *)mystrdup(argv[i] + 2);
-			if(argv[i][2]) {
-				if(argv[i][2]=='@'){
-
-#ifdef STDMAIN
-#ifndef _WIN32
-					openlog(argv[i]+3, LOG_PID, LOG_DAEMON);
-					srv.logfunc = logsyslog;
-#endif
-#endif
-
-				}
-				else {
-					fp = fopen(argv[i] + 2, "a");
-					if (fp) {
-						srv.stdlog = fp;
-						fseek(fp, 0L, SEEK_END);
-					}
-				}
-
-			}
+			myfree(srv->logtarget);
+			srv->logtarget = (unsigned char *)mystrdup(argv[i] + 2);
 			break;
 		 case 'i':
-			getip46(46, (unsigned char *)argv[i]+2, (struct sockaddr *)&srv.intsa);
+			getip46(46, (unsigned char *)argv[i]+2, (struct sockaddr *)&srv->intsa);
 			break;
 		 case 'e':
 			{
@@ -346,29 +328,29 @@ int MODULEMAINFUNC (int argc, char** argv){
 				memset(&sa6, 0, sizeof(sa6));
 				error = !getip46(46, (unsigned char *)argv[i]+2, (struct sockaddr *)&sa6);
 				if(!error) {
-					if (*SAFAMILY(&sa6)==AF_INET) srv.extsa = sa6;
-					else srv.extsa6 = sa6;
+					if (*SAFAMILY(&sa6)==AF_INET) srv->extsa = sa6;
+					else srv->extsa6 = sa6;
 				} 
 #else
-				error = !getip46(46, (unsigned char *)argv[i]+2, (struct sockaddr *)&srv.extsa);
+				error = !getip46(46, (unsigned char *)argv[i]+2, (struct sockaddr *)&srv->extsa);
 #endif
 			}
 			break;
 		 case 'N':
-			getip46(46, (unsigned char *)argv[i]+2, (struct sockaddr *)&srv.extNat);
+			getip46(46, (unsigned char *)argv[i]+2, (struct sockaddr *)&srv->extNat);
 			break;
 		 case 'p':
-			*SAPORT(&srv.intsa) = htons(atoi(argv[i]+2));
+			*SAPORT(&srv->intsa) = htons(atoi(argv[i]+2));
 			break;
 		 case '4':
 		 case '6':
-			srv.family = atoi(argv[i]+1);
+			srv->family = atoi(argv[i]+1);
 			break;
 		 case 'b':
-			srv.bufsize = atoi(argv[i]+2);
+			srv->bufsize = atoi(argv[i]+2);
 			break;
 		 case 'n':
-			srv.usentlm = atoi(argv[i]+2);
+			srv->usentlm = atoi(argv[i]+2);
 			break;
 #ifdef STDMAIN
 #ifndef _WIN32
@@ -382,11 +364,11 @@ int MODULEMAINFUNC (int argc, char** argv){
 #endif
 #endif
 		 case 'f':
-			if(srv.logformat)myfree(srv.logformat);
-			srv.logformat = (unsigned char *)mystrdup(argv[i] + 2);
+			if(srv->logformat)myfree(srv->logformat);
+			srv->logformat = (unsigned char *)mystrdup(argv[i] + 2);
 			break;
 		 case 't':
-			srv.silent = 1;
+			srv->silent = 1;
 			break;
 		 case 'h':
 			hostname = argv[i] + 2;
@@ -400,44 +382,44 @@ int MODULEMAINFUNC (int argc, char** argv){
 			iscbl = 1;
 			break;
 		 case 'u':
-			srv.needuser = 0;
-			if(*(argv[i] + 2)) srv.needuser = atoi(argv[i] + 2);
+			srv->needuser = 0;
+			if(*(argv[i] + 2)) srv->needuser = atoi(argv[i] + 2);
 			break;
 		 case 'T':
-			srv.transparent = 1;
+			srv->transparent = 1;
 			break;
 		 case 'S':
-			srv.stacksize = atoi(argv[i]+2);
+			srv->stacksize = atoi(argv[i]+2);
 			break;
 		case 'a':
-			srv.anonymous = 1 + atoi(argv[i]+2);
+			srv->anonymous = 1 + atoi(argv[i]+2);
 			break;
 		case 's':
 #ifdef WITHSPLICE
-			if(isudp || srv.service == S_ADMIN)
+			if(isudp || srv->service == S_ADMIN)
 #endif
-				srv.singlepacket = 1 + atoi(argv[i]+2);
+				srv->singlepacket = 1 + atoi(argv[i]+2);
 #ifdef WITHSPLICE
 			else
-				if(*(argv[i]+2)) srv.usesplice = atoi(argv[i]+2);
+				if(*(argv[i]+2)) srv->usesplice = atoi(argv[i]+2);
 #endif
 			break;
 		 case 'o':
 			switch(argv[i][2]){
 			 case 's':
-				srv.srvsockopts = getopts(argv[i]+3);
+				srv->srvsockopts = getopts(argv[i]+3);
 				break;
 			 case 'c':
-				srv.clisockopts = getopts(argv[i]+3);
+				srv->clisockopts = getopts(argv[i]+3);
 				break;
 			 case 'l':
-				srv.lissockopts = getopts(argv[i]+3);
+				srv->lissockopts = getopts(argv[i]+3);
 				break;
 			 case 'r':
-				srv.cbcsockopts = getopts(argv[i]+3);
+				srv->cbcsockopts = getopts(argv[i]+3);
 				break;
 			 case 'R':
-				srv.cbcsockopts = getopts(argv[i]+3);
+				srv->cbcsockopts = getopts(argv[i]+3);
 				break;
 			 default:
 				error = 1;
@@ -488,7 +470,7 @@ int MODULEMAINFUNC (int argc, char** argv){
  else {
 #endif
 #ifndef NOPORTMAP
-	if (error || argc != i+3 || *argv[i]=='-'|| (*SAPORT(&srv.intsa) = htons((unsigned short)atoi(argv[i])))==0 || (srv.targetport = htons((unsigned short)atoi(argv[i+2])))==0) {
+	if (error || argc != i+3 || *argv[i]=='-'|| (*SAPORT(&srv->intsa) = htons((unsigned short)atoi(argv[i])))==0 || (srv->targetport = htons((unsigned short)atoi(argv[i+2])))==0) {
 #ifndef STDMAIN
 		haveerror = 1;
 		conf.threadinit = 0;
@@ -514,7 +496,7 @@ int MODULEMAINFUNC (int argc, char** argv){
 		);
 		return (1);
 	}
-	srv.target = (unsigned char *)mystrdup(argv[i+1]);
+	srv->target = (unsigned char *)mystrdup(argv[i+1]);
 #endif
 #ifndef STDMAIN
  }
@@ -533,7 +515,7 @@ int MODULEMAINFUNC (int argc, char** argv){
 		return 2;
 	};
 	*newparam = defparam;
-	return((*srv.pf)((void *)newparam)? 1:0);
+	return((*srv->pf)((void *)newparam)? 1:0);
 	
  }
 #endif
@@ -542,19 +524,19 @@ int MODULEMAINFUNC (int argc, char** argv){
 #endif
 
  
- srvinit2(&srv, &defparam);
- if(!*SAFAMILY(&srv.intsa)) *SAFAMILY(&srv.intsa) = AF_INET;
- if(!*SAPORT(&srv.intsa)) *SAPORT(&srv.intsa) = htons(childdef.port);
- *SAFAMILY(&srv.extsa) = AF_INET;
+ srvinit2(srv, &defparam);
+ if(!*SAFAMILY(&srv->intsa)) *SAFAMILY(&srv->intsa) = AF_INET;
+ if(!*SAPORT(&srv->intsa)) *SAPORT(&srv->intsa) = htons(childdef.port);
+ *SAFAMILY(&srv->extsa) = AF_INET;
 #ifndef NOIPV6
- *SAFAMILY(&srv.extsa6) = AF_INET6;
+ *SAFAMILY(&srv->extsa6) = AF_INET6;
 #endif
  if(hostname)parsehostname(hostname, &defparam, childdef.port);
 
 
 #ifndef STDMAIN
 
- copyfilter(conf.filters, &srv);
+ copyfilter(conf.filters, srv);
  conf.threadinit = 0;
 
 
@@ -563,27 +545,27 @@ int MODULEMAINFUNC (int argc, char** argv){
 
 
  if (!iscbc) {
-	if(srv.srvsock == INVALID_SOCKET){
+	if(srv->srvsock == INVALID_SOCKET){
 
 		if(!isudp){
 			lg.l_onoff = 1;
 			lg.l_linger = conf.timeouts[STRING_L];
-			sock=so._socket(SASOCK(&srv.intsa), SOCK_STREAM, IPPROTO_TCP);
+			sock=so._socket(SASOCK(&srv->intsa), SOCK_STREAM, IPPROTO_TCP);
 		}
 		else {
-			sock=so._socket(SASOCK(&srv.intsa), SOCK_DGRAM, IPPROTO_UDP);
+			sock=so._socket(SASOCK(&srv->intsa), SOCK_DGRAM, IPPROTO_UDP);
 		}
 		if( sock == INVALID_SOCKET) {
 			perror("socket()");
 			return -2;
 		}
-		setopts(sock, srv.lissockopts);
+		setopts(sock, srv->lissockopts);
 #ifdef _WIN32
 		ioctlsocket(sock, FIONBIO, &ul);
 #else
 		fcntl(sock,F_SETFL,O_NONBLOCK | fcntl(sock,F_GETFL));
 #endif
-		srv.srvsock = sock;
+		srv->srvsock = sock;
 		opt = 1;
 		if(so._setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *)&opt, sizeof(int)))perror("setsockopt()");
 #ifdef SO_REUSEPORT
@@ -591,13 +573,13 @@ int MODULEMAINFUNC (int argc, char** argv){
 		so._setsockopt(sock, SOL_SOCKET, SO_REUSEPORT, (char *)&opt, sizeof(int));
 #endif
 #ifdef SO_BINDTODEVICE
-		if(srv.ibindtodevice) so._setsockopt(sock, SOL_SOCKET, SO_BINDTODEVICE, srv.ibindtodevice, strlen(srv.ibindtodevice) + 1);
+		if(srv->ibindtodevice) so._setsockopt(sock, SOL_SOCKET, SO_BINDTODEVICE, srv->ibindtodevice, strlen(srv->ibindtodevice) + 1);
 #endif
 	}
-	size = sizeof(srv.intsa);
-	for(sleeptime = SLEEPTIME * 100; so._bind(sock, (struct sockaddr*)&srv.intsa, SASIZE(&srv.intsa))==-1; usleep(sleeptime)) {
+	size = sizeof(srv->intsa);
+	for(sleeptime = SLEEPTIME * 100; so._bind(sock, (struct sockaddr*)&srv->intsa, SASIZE(&srv->intsa))==-1; usleep(sleeptime)) {
 		sprintf((char *)buf, "bind(): %s", strerror(errno));
-		if(!srv.silent)dolog(&defparam, buf);	
+		if(!srv->silent)dolog(&defparam, buf);	
 		sleeptime = (sleeptime<<1);	
 		if(!sleeptime) {
 			so._closesocket(sock);
@@ -605,69 +587,69 @@ int MODULEMAINFUNC (int argc, char** argv){
 		}
 	}
  	if(!isudp){
- 		if(so._listen (sock, 1 + (srv.maxchild>>4))==-1) {
+ 		if(so._listen (sock, 1 + (srv->maxchild>>4))==-1) {
 			sprintf((char *)buf, "listen(): %s", strerror(errno));
-			if(!srv.silent)dolog(&defparam, buf);
+			if(!srv->silent)dolog(&defparam, buf);
 			return -4;
 		}
 	}
 	else 
 		defparam.clisock = sock;
 
-	if(!srv.silent && !iscbc){
+	if(!srv->silent && !iscbc){
 		sprintf((char *)buf, "Accepting connections [%u/%u]", (unsigned)getpid(), (unsigned)pthread_self());
 		dolog(&defparam, buf);
 	}
  }
  if(iscbl){
-	parsehost(srv.family, cbl_string, (struct sockaddr *)&cbsa);
-	if((srv.cbsock=so._socket(SASOCK(&cbsa), SOCK_STREAM, IPPROTO_TCP))==INVALID_SOCKET) {
+	parsehost(srv->family, cbl_string, (struct sockaddr *)&cbsa);
+	if((srv->cbsock=so._socket(SASOCK(&cbsa), SOCK_STREAM, IPPROTO_TCP))==INVALID_SOCKET) {
 		dolog(&defparam, (unsigned char *)"Failed to allocate connect back socket");
 		return -6;
 	}
 	opt = 1;
-	so._setsockopt(srv.cbsock, SOL_SOCKET, SO_REUSEADDR, (char *)&opt, sizeof(int));
+	so._setsockopt(srv->cbsock, SOL_SOCKET, SO_REUSEADDR, (char *)&opt, sizeof(int));
 #ifdef SO_REUSEPORT
 	opt = 1;
-	so._setsockopt(srv.cbsock, SOL_SOCKET, SO_REUSEPORT, (char *)&opt, sizeof(int));
+	so._setsockopt(srv->cbsock, SOL_SOCKET, SO_REUSEPORT, (char *)&opt, sizeof(int));
 #endif
 
-	setopts(srv.cbsock, srv.cbssockopts);
+	setopts(srv->cbsock, srv->cbssockopts);
 
-	if(so._bind(srv.cbsock, (struct sockaddr*)&cbsa, SASIZE(&cbsa))==-1) {
+	if(so._bind(srv->cbsock, (struct sockaddr*)&cbsa, SASIZE(&cbsa))==-1) {
 		dolog(&defparam, (unsigned char *)"Failed to bind connect back socket");
 		return -7;
 	}
-	if(so._listen(srv.cbsock, 1 + (srv.maxchild>>4))==-1) {
+	if(so._listen(srv->cbsock, 1 + (srv->maxchild>>4))==-1) {
 		dolog(&defparam, (unsigned char *)"Failed to listen connect back socket");
 		return -8;
 	}
  }
 
- srv.fds.fd = sock;
- srv.fds.events = POLLIN;
+ srv->fds.fd = sock;
+ srv->fds.events = POLLIN;
  
 #ifndef _WIN32
  pthread_attr_init(&pa);
- pthread_attr_setstacksize(&pa,PTHREAD_STACK_MIN + (32768 + srv.stacksize));
+ pthread_attr_setstacksize(&pa,PTHREAD_STACK_MIN + (32768 + srv->stacksize));
  pthread_attr_setdetachstate(&pa,PTHREAD_CREATE_DETACHED);
 #endif
 
  for (;;) {
 	for(;;){
-		while((conf.paused == srv.paused && srv.childcount >= srv.maxchild)){
+		while((conf.paused == srv->paused && srv->childcount >= srv->maxchild)){
 			nlog++;			
-			if(!srv.silent && nlog > 5000) {
-				sprintf((char *)buf, "Warning: too many connected clients (%d/%d)", srv.childcount, srv.maxchild);
+			if(!srv->silent && nlog > 5000) {
+				sprintf((char *)buf, "Warning: too many connected clients (%d/%d)", srv->childcount, srv->maxchild);
 				dolog(&defparam, buf);
 				nlog = 0;
 			}
 			usleep(SLEEPTIME);
 		}
 		if (iscbc) break;
-		if (conf.paused != srv.paused) break;
-		if (srv.fds.events & POLLIN) {
-			error = so._poll(&srv.fds, 1, 1000);
+		if (conf.paused != srv->paused) break;
+		if (srv->fds.events & POLLIN) {
+			error = so._poll(&srv->fds, 1, 1000);
 		}
 		else {
 			usleep(SLEEPTIME);
@@ -677,20 +659,20 @@ int MODULEMAINFUNC (int argc, char** argv){
 		if (error == 0) continue;
 		if (errno != EAGAIN &&	errno != EINTR) {
 			sprintf((char *)buf, "poll(): %s/%d", strerror(errno), errno);
-			if(!srv.silent)dolog(&defparam, buf);
+			if(!srv->silent)dolog(&defparam, buf);
 			break;
 		}
 	}
-	if((conf.paused != srv.paused) || (error < 0)) break;
+	if((conf.paused != srv->paused) || (error < 0)) break;
 	error = 0;
 	if(!isudp){
 		size = sizeof(defparam.sincr);
 		if(iscbc){
 			new_sock=so._socket(SASOCK(&defparam.sincr), SOCK_STREAM, IPPROTO_TCP);
 			if(new_sock != INVALID_SOCKET){
-				setopts(new_sock, srv.cbcsockopts);
+				setopts(new_sock, srv->cbcsockopts);
 
-				parsehost(srv.family, cbc_string, (struct sockaddr *)&defparam.sincr);
+				parsehost(srv->family, cbc_string, (struct sockaddr *)&defparam.sincr);
 				if(connectwithpoll(new_sock,(struct sockaddr *)&defparam.sincr,SASIZE(&defparam.sincr),CONNBACK_TO)) {
 					so._closesocket(new_sock);
 					new_sock = INVALID_SOCKET;
@@ -748,7 +730,7 @@ int MODULEMAINFUNC (int argc, char** argv){
 				}
 #endif
 				nlog++;			
-				if(!srv.silent && (error || nlog > 5000)) {
+				if(!srv->silent && (error || nlog > 5000)) {
 					sprintf((char *)buf, "accept(): %s", strerror(errno));
 					dolog(&defparam, buf);
 					nlog = 0;
@@ -756,11 +738,11 @@ int MODULEMAINFUNC (int argc, char** argv){
 				continue;
 			}
 		}
-		setopts(new_sock, srv.clisockopts);
+		setopts(new_sock, srv->clisockopts);
 		size = sizeof(defparam.sincl);
 		if(so._getsockname(new_sock, (struct sockaddr *)&defparam.sincl, &size)){
 			sprintf((char *)buf, "getsockname(): %s", strerror(errno));
-			if(!srv.silent)dolog(&defparam, buf);
+			if(!srv->silent)dolog(&defparam, buf);
 			continue;
 		}
 #ifdef _WIN32
@@ -772,7 +754,7 @@ int MODULEMAINFUNC (int argc, char** argv){
 		so._setsockopt(new_sock, SOL_SOCKET, SO_OOBINLINE, (char *)&opt, sizeof(int));
 	}
 	else {
-		srv.fds.events = 0;
+		srv->fds.events = 0;
 	}
 	
 #ifndef STDMAIN
@@ -784,7 +766,7 @@ int MODULEMAINFUNC (int argc, char** argv){
 	if(! (newparam = myalloc (sizeof(defparam)))){
 		if(!isudp) so._closesocket(new_sock);
 		defparam.res = 21;
-		if(!srv.silent)dolog(&defparam, (unsigned char *)"Memory Allocation Failed");
+		if(!srv->silent)dolog(&defparam, (unsigned char *)"Memory Allocation Failed");
 		usleep(SLEEPTIME);
 		continue;
 	};
@@ -794,68 +776,64 @@ int MODULEMAINFUNC (int argc, char** argv){
 
 	if(!isudp) newparam->clisock = new_sock;
 #ifndef STDMAIN
-	if(makefilters(&srv, newparam) > CONTINUE){
+	if(makefilters(srv, newparam) > CONTINUE){
 		freeparam(newparam);		
 		continue;
 	}
 #endif
 	newparam->prev = newparam->next = NULL;
 	error = 0;
-	pthread_mutex_lock(&srv.counter_mutex);
-	if(!srv.child){
-		srv.child = newparam;
+	pthread_mutex_lock(&srv->counter_mutex);
+	if(!srv->child){
+		srv->child = newparam;
 	}
 	else {
-		newparam->next = srv.child;
-		srv.child = srv.child->prev = newparam;
+		newparam->next = srv->child;
+		srv->child = srv->child->prev = newparam;
 	}
 #ifdef _WIN32
 #ifndef _WINCE
-	h = (HANDLE)_beginthreadex((LPSECURITY_ATTRIBUTES )NULL, (unsigned)(16384 + srv.stacksize), (void *)threadfunc, (void *) newparam, 0, &thread);
+	h = (HANDLE)_beginthreadex((LPSECURITY_ATTRIBUTES )NULL, (unsigned)(16384 + srv->stacksize), (void *)threadfunc, (void *) newparam, 0, &thread);
 #else
-	h = (HANDLE)CreateThread((LPSECURITY_ATTRIBUTES )NULL, (unsigned)(16384 + srv.stacksize), (void *)threadfunc, (void *) newparam, 0, &thread);
+	h = (HANDLE)CreateThread((LPSECURITY_ATTRIBUTES )NULL, (unsigned)(16384 + srv->stacksize), (void *)threadfunc, (void *) newparam, 0, &thread);
 #endif
-	srv.childcount++;
+	srv->childcount++;
 	if (h) {
 		newparam->threadid = (unsigned)thread;
 		CloseHandle(h);
 	}
 	else {
 		sprintf((char *)buf, "_beginthreadex(): %s", _strerror(NULL));
-		if(!srv.silent)dolog(&defparam, buf);
+		if(!srv->silent)dolog(&defparam, buf);
 		error = 1;
 	}
 #else
 
 	error = pthread_create(&thread, &pa, threadfunc, (void *)newparam);
-	srv.childcount++;
+	srv->childcount++;
 	if(error){
 		sprintf((char *)buf, "pthread_create(): %s", strerror(error));
-		if(!srv.silent)dolog(&defparam, buf);
+		if(!srv->silent)dolog(&defparam, buf);
 	}
 	else {
 		newparam->threadid = (unsigned)thread;
 	}
 #endif
-	pthread_mutex_unlock(&srv.counter_mutex);
+	pthread_mutex_unlock(&srv->counter_mutex);
 	if(error) freeparam(newparam);
 
 	memset(&defparam.sincl, 0, sizeof(defparam.sincl));
 	memset(&defparam.sincr, 0, sizeof(defparam.sincr));
-	if(isudp) while(!srv.fds.events)usleep(SLEEPTIME);
+	if(isudp) while(!srv->fds.events)usleep(SLEEPTIME);
  }
 
- if(!srv.silent) srv.logfunc(&defparam, (unsigned char *)"Exiting thread");
+ if(!srv->silent) dolog(&defparam, (unsigned char *)"Exiting thread");
 
- srvfree(&srv);
+ srvfree(srv);
+ pthread_mutex_lock(&srv->counter_mutex);
+ if(!srv->child)srvpostfree(srv);
+ pthread_mutex_unlock(&srv->counter_mutex);
 
-#ifndef STDMAIN
- pthread_mutex_lock(&config_mutex);
- if(srv.next)srv.next->prev = srv.prev;
- if(srv.prev)srv.prev->next = srv.next;
- else conf.services = srv.next;
- pthread_mutex_unlock(&config_mutex);
-#endif
 
 #ifndef _WIN32
  pthread_attr_destroy(&pa);
@@ -874,18 +852,16 @@ void srvinit(struct srvparam * srv, struct clientparam *param){
  memset(srv, 0, sizeof(struct srvparam));
  srv->version = conf.version + 1;
  srv->paused = conf.paused;
- srv->logfunc = havelog?conf.logfunc:lognone;
  srv->noforce = conf.noforce;
  srv->logformat = conf.logformat? (unsigned char *)mystrdup((char *)conf.logformat) : NULL;
+ srv->logtarget = conf.logtarget? (unsigned char *)mystrdup((char *)conf.logtarget) : NULL;
  srv->authfunc = conf.authfunc;
  srv->usentlm = 0;
  srv->maxchild = conf.maxchild;
  srv->stacksize = conf.stacksize;
  srv->time_start = time(NULL);
- if(havelog && conf.logtarget){
-	 srv->logtarget = (unsigned char *)mystrdup((char *)conf.logtarget);
- }
  srv->srvsock = INVALID_SOCKET;
+ srv->logtype = conf.logtype;
  srv->logdumpsrv = conf.logdumpsrv;
  srv->logdumpcli = conf.logdumpcli;
  srv->cbsock = INVALID_SOCKET; 
@@ -921,6 +897,10 @@ void srvinit2(struct srvparam * srv, struct clientparam *param){
 		myfree(logformat);
 	}
  }
+ if(srv->logtarget){
+	srv->log = registerlog(srv->logtarget, srv->logtype);
+ }
+
  memset(&param->sinsl, 0, sizeof(param->sinsl));
  memset(&param->sinsr, 0, sizeof(param->sinsr));
  memset(&param->req, 0, sizeof(param->req));
@@ -935,14 +915,15 @@ void srvinit2(struct srvparam * srv, struct clientparam *param){
 	param->sinsr = srv->extsa;
 }
 
-void srvfree(struct srvparam * srv){
- if(srv->srvsock != INVALID_SOCKET) so._closesocket(srv->srvsock);
- srv->srvsock = INVALID_SOCKET;
- if(srv->cbsock != INVALID_SOCKET) so._closesocket(srv->cbsock);
- srv->cbsock = INVALID_SOCKET;
- srv->service = S_ZOMBIE;
- while(srv->child) usleep(SLEEPTIME * 100);
+
+void srvpostfree(struct srvparam * srv){
+ unregisterlog(srv->log);
 #ifndef STDMAIN
+ pthread_mutex_lock(&config_mutex);
+ if(srv->next)srv->next->prev = srv->prev;
+ if(srv->prev)srv->prev->next = srv->next;
+ else conf.services = srv->next;
+ pthread_mutex_unlock(&config_mutex);
  if(srv->filter){
 	while(srv->nfilters){
 		srv->nfilters--;
@@ -966,64 +947,15 @@ void srvfree(struct srvparam * srv){
  if(srv->ibindtodevice) myfree(srv->ibindtodevice);
  if(srv->obindtodevice) myfree(srv->obindtodevice);
 #endif
+ myfree(srv);
 }
 
-
-void freeparam(struct clientparam * param) {
-	if(param->res == 2) return;
-	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->clibuf) myfree(param->clibuf);
-	if(param->srvbuf) myfree(param->srvbuf);
-	if(param->srv){
-		pthread_mutex_lock(&param->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)--;
-		pthread_mutex_unlock(&param->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);
-	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);
+void srvfree(struct srvparam * srv){
+ if(srv->srvsock != INVALID_SOCKET) so._closesocket(srv->srvsock);
+ srv->srvsock = INVALID_SOCKET;
+ if(srv->cbsock != INVALID_SOCKET) so._closesocket(srv->cbsock);
+ srv->cbsock = INVALID_SOCKET;
+ srv->service = S_ZOMBIE;
 }
 
 

+ 1 - 0
src/smtpp.c

@@ -313,4 +313,5 @@ struct proxydef childdef = {
 
 };
 #include "proxymain.c"
+#include "log.c"
 #endif

+ 1 - 0
src/socks.c

@@ -464,4 +464,5 @@ struct proxydef childdef = {
 	"-N(EXTERNAL_IP) External NAT address to report to client for BIND\n"
 };
 #include "proxymain.c"
+#include "log.c"
 #endif

+ 46 - 14
src/structures.h

@@ -15,9 +15,7 @@
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <stdint.h>
-#ifndef PRINTF_INT64_MODIFIER
-#define PRINTF_INT64_MODIFIER "ll"
-#endif
+#include <inttypes.h>
 #ifdef  __cplusplus
 extern "C" {
 #endif
@@ -60,6 +58,15 @@ int mutex_unlock(int *val);
 #ifdef MSVC
 #pragma warning (disable : 4996)
 #endif
+#ifndef PRIu64
+#define PRIu64 "I64u"
+#endif
+#ifndef PRIi64
+#define PRIi64 "I64i"
+#endif
+#ifndef SCNx64
+#define SCNx64 "I64x"
+#endif
 #endif
 #define MAXBANDLIMS 10
 
@@ -188,8 +195,8 @@ struct node;
 struct symbol;
 struct pluginlink;
 struct srvparam;
-
-typedef void (*LOGFUNC)(struct clientparam * param, const unsigned char *);
+struct LOGFUNC;
+struct LOGGER;
 typedef int (*AUTHFUNC)(struct clientparam * param);
 typedef void * (*REDIRECTFUNC)(struct clientparam * param);
 typedef unsigned long (*RESOLVFUNC)(int af, unsigned char *name, unsigned char *value);
@@ -365,6 +372,31 @@ struct trafcount {
 	time_t updated;
 };
 
+struct LOGFUNC {
+	struct LOGFUNC* next;	
+	int (*init)(struct LOGGER *logger);
+	int (*dobuf)(struct clientparam * param, unsigned char * buf, int bufsize, const unsigned char *s);
+	void (*log)(const char * buf, int len, struct LOGGER *logger);
+	void (*rotate)(struct LOGGER *logger);
+	void (*flush)(struct LOGGER *logger);
+	void (*close)(struct LOGGER *logger);
+	char* prefix;
+};
+extern struct LOGFUNC *logfuncs;
+extern void(*prelog)(struct clientparam * param);
+struct LOGGER {
+	struct LOGGER *next;
+	struct LOGGER *prev;
+	char * selector;
+	void * data;
+	struct LOGFUNC *logfunc;
+	int rotate;
+	time_t rotated;
+	int registered;
+};
+struct LOGGER * registerlog(const char * logstring, int logtype);
+void unregisterlog (struct LOGGER * log);
+void flushlogs(void);
 struct nserver {
 #ifndef NOIPV6
 	struct sockaddr_in6 addr;
@@ -419,7 +451,6 @@ struct srvparam {
 	struct srvparam *prev;
 	struct clientparam *child;
 	PROXYSERVICE service;
-	LOGFUNC logfunc;
 	AUTHFUNC authfunc;
 	PROXYFUNC pf;
 	SOCKET srvsock, cbsock;
@@ -436,6 +467,7 @@ struct srvparam {
 	int stacksize;
 	int noforce;
 	int anonymous;
+	int logtype;
 	int clisockopts, srvsockopts, lissockopts, cbcsockopts, cbssockopts;
 #ifdef WITHSPLICE
 	int usesplice;
@@ -465,9 +497,10 @@ struct srvparam {
 	struct ace *preacl, *acl;
 	struct auth *authfuncs;
 	struct filter *filter;
-	unsigned char * logformat;
 	unsigned char * logtarget;
+	unsigned char * logformat;
 	unsigned char * nonprintable;
+	struct LOGGER *log;
 	unsigned short targetport;
 	unsigned char replace;
 	time_t time_start;
@@ -577,7 +610,7 @@ struct extparam {
 		demon, maxchild, needreload, timetoexit, version, noforce;
 	int authcachetype, authcachetime;
 	int filtermaxsize;
-	unsigned char *logname, **archiver;
+	unsigned char **archiver;
 	ROTATION logtype, countertype;
 	char * counterfile;
 #ifndef NOIPV6
@@ -591,17 +624,16 @@ struct extparam {
 	struct passwords *pwl;
 	struct auth * authenticate;
 	AUTHFUNC authfunc;
-	LOGFUNC logfunc;
 	BANDLIMFUNC bandlimfunc;
 	TRAFCOUNTFUNC trafcountfunc;
+	void (*prelog)(struct clientparam * param);
 	unsigned char *logtarget, *logformat;
 	struct filemon * fmon;
 	struct filter * filters;
 	struct auth *authfuncs;
-	FILE *stdlog;
 	char* demanddialprog;
 	unsigned char **stringtable;
-	time_t logtime, time;
+	time_t time;
 	unsigned logdumpsrv, logdumpcli;
 	char delimchar;
 };
@@ -738,8 +770,8 @@ struct pluginlink {
 	int (*sockgetcharsrv)(struct clientparam * param, int timeosec, int timeousec);
 	int (*sockgetlinebuf)(struct clientparam * param, DIRECTION which, unsigned char * buf, int bufsize, int delim, int to);
 	int (*myinet_ntop)(int af, void *src, char *dst, socklen_t size);
-	int (*dobuf)(struct clientparam * param, unsigned char * buf, const unsigned char *s, const unsigned char * doublec);
-	int (*dobuf2)(struct clientparam * param, unsigned char * buf, const unsigned char *s, const unsigned char * doublec, struct tm* tm, char * format);
+	int (*dobuf)(struct clientparam * param, unsigned char * buf, int bufsize, const unsigned char *s, const unsigned char * doublec);
+	int (*dobuf2)(struct clientparam * param, unsigned char * buf, int bufsize, const unsigned char *s, const unsigned char * doublec, struct tm* tm, char * format);
 	int (*scanaddr)(const unsigned char *s, unsigned long * ip, unsigned long * mask);
 	unsigned long (*getip46)(int family, unsigned char *name,  struct sockaddr *sa);
 	int (*sockmap)(struct clientparam * param, int timeo, int usesplice);
@@ -772,7 +804,7 @@ struct pluginlink {
 	int (*parseusername)(char *username, struct clientparam *param, int extpasswd);
 	int (*parseconnusername)(char *username, struct clientparam *param, int extpasswd, unsigned short port);
 	struct sockfuncs *so;
-	unsigned char * (*dologname) (unsigned char *buf, unsigned char *name, const unsigned char *ext, ROTATION lt, time_t t);
+	unsigned char * (*dologname) (unsigned char *buf, int bufsize, unsigned char *name, const unsigned char *ext, ROTATION lt, time_t t);
 };
 
 struct counter_header {

+ 1 - 0
src/tcppm.c

@@ -37,4 +37,5 @@ struct proxydef childdef = {
 	""
 };
 #include "proxymain.c"
+#include "log.c"
 #endif

+ 1 - 0
src/udppm.c

@@ -116,4 +116,5 @@ struct proxydef childdef = {
 	" -s single packet UDP service for request/reply (DNS-like) services\n"
 };
 #include "proxymain.c"
+#include "log.c"
 #endif

+ 2 - 2
src/webadmin.c

@@ -474,9 +474,9 @@ void * adminchild(struct clientparam* param) {
 			 }
 			 else {
 			  inbuf += sprintf(buf+inbuf,	
-					"</td><td>%"PRINTF_INT64_MODIFIER"u</td>"
+					"</td><td>%"PRIu64"</td>"
 					"<td>MB%s</td>"
-					"<td>%"PRINTF_INT64_MODIFIER"u.%"PRINTF_INT64_MODIFIER"u</td>"
+					"<td>%"PRIu64".%"PRIu64"</td>"
 					"<td>%s</td>",
 				 cp->traflim64 / (1024 * 1024),
 				 rotations[cp->type],