Esempio n. 1
0
void log_list_thread(void)
{
	char buf[LOG_BUF_SIZE];
	int last_count=ll_count(log_list), count, grow_count=0, write_count;
	do {
		LL_ITER it = ll_iter_create(log_list);
		struct s_log *log;
		write_count = 0;
		while ((log=ll_iter_next_remove(&it))) {
			int8_t do_flush = ll_count(log_list) == 0; //flush on writing last element

			cs_strncpy(buf, log->txt, LOG_BUF_SIZE);
			if (log->direct_log)
				cs_write_log(buf, do_flush);
			else
				write_to_log(buf, log, do_flush);
			free(log->txt);
			free(log);

			//If list is faster growing than we could write to file, drop list:
			write_count++;
			if (write_count%10000 == 0) { //check every 10000 writes:
				count = ll_count(log_list);
				if (count > last_count) {
					grow_count++;
					if (grow_count > 5) { //5 times still growing
						cs_write_log("------------->logging temporary disabled (30s) - too much data!\n", 1);
						cfg.disablelog = 1;
						ll_iter_reset(&it);
						while ((log=ll_iter_next_remove(&it))) { //clear log
							free(log->txt);
							free(log);
						}
						cs_sleepms(30*1000);
						cfg.disablelog = 0;

						grow_count = 0;
						last_count = 0;
						break;
					}
				}
				else
					grow_count = 0;
				last_count = count;
			}
		}
		cs_sleepms(250);
	} while(1);
}
Esempio n. 2
0
void log_list_thread(void)
{
	char buf[LOG_BUF_SIZE];
	log_running = 1;
	set_thread_name(__func__);
	do
	{
		log_list_queued = 0;
		LL_ITER it = ll_iter_create(log_list);
		struct s_log *log;
		while((log = ll_iter_next_remove(&it)))
		{
			int8_t do_flush = ll_count(log_list) == 0; //flush on writing last element

			cs_strncpy(buf, log->txt, LOG_BUF_SIZE);
			if(log->direct_log)
				{ cs_write_log(buf, do_flush); }
			else
				{ write_to_log(buf, log, do_flush); }
			NULLFREE(log->txt);
			NULLFREE(log);
		}
		if(!log_list_queued)  // The list is empty, sleep until new data comes in and we are woken up
			sleepms_on_cond(&log_thread_sleep_cond_mutex, &log_thread_sleep_cond, 60 * 1000);
	}
	while(log_running);
	ll_destroy(log_list);
	log_list = NULL;
}
Esempio n. 3
0
static void cs_write_log_int(char *txt)
{
	if(exit_oscam == 1) {
		cs_write_log(txt, 1);
	} else {
		struct s_log * log = cs_malloc(&log, sizeof(struct s_log), 0);
		log->txt = strnew(txt);
		log->header_len = 0;
		log->direct_log = 1;
		ll_append(log_list, log);
	}
}
Esempio n. 4
0
static void log_list_add(struct s_log *log)
{
	int32_t count = ll_count(log_list);
	log_list_queued++;
	if(count < MAX_LOG_LIST_BACKLOG)
	{
		ll_append(log_list, log);
	}
	else     // We have too much backlog
	{
		NULLFREE(log->txt);
		NULLFREE(log);
		cs_write_log("-------------> Too much data in log_list, dropping log message.\n", 1);
	}
	pthread_cond_signal(&log_thread_sleep_cond);
}
Esempio n. 5
0
static void cs_write_log_int(char *txt)
{
	if(exit_oscam == 1) {
		cs_write_log(txt, 1);
	} else {
		char *newtxt = cs_strdup(txt);
		if (!newtxt)
			return;
		struct s_log *log;
		if (!cs_malloc(&log, sizeof(struct s_log))) {
			free(newtxt);
			return;
		}
		log->txt = newtxt;
		log->header_len = 0;
		log->direct_log = 1;
		ll_append(log_list, log);
	}
}
Esempio n. 6
0
static void log_list_add(struct s_log *log)
{
	if(logStarted == 0)
		{ return; }
	
	int32_t count = ll_count(log_list);
	log_list_queued++;
	if(count < MAX_LOG_LIST_BACKLOG)
	{
		ll_append(log_list, log);
	}
	else     // We have too much backlog
	{
		NULLFREE(log->txt);
		NULLFREE(log);
		cs_write_log("-------------> Too much data in log_list, dropping log message.\n", 1, 0, 0);
	}
	SAFE_COND_SIGNAL_NOLOG(&log_thread_sleep_cond);
}
Esempio n. 7
0
void log_list_thread()
{
	char buf[LOG_BUF_SIZE];

	while (1) {
		LL_ITER it = ll_iter_create(log_list);
		struct s_log *log;
		while ((log=ll_iter_next_remove(&it))) {
			int8_t do_flush = ll_count(log_list) == 0; //flush on writing last element

			cs_strncpy(buf, log->txt, LOG_BUF_SIZE);
			if (log->direct_log)
				cs_write_log(buf, do_flush);
			else
				write_to_log(buf, log, do_flush);
			free(log->txt);
			free(log);
		}
		cs_sleepms(50);
	}
}
Esempio n. 8
0
static void cs_write_log_int(char *txt)
{
	if(exit_oscam == 1)
	{
		cs_write_log(txt, 1, 0, 0);
	}
	else
	{
		char *newtxt = cs_strdup(txt);
		if(!newtxt)
			{ return; }
		struct s_log *log;
		if(!cs_malloc(&log, sizeof(struct s_log)))
		{
			NULLFREE(newtxt);
			return;
		}
		log->txt = newtxt;
		log->header_len = 0;
		log->direct_log = 1;
		log_list_add(log);
	}
}
Esempio n. 9
0
static void write_to_log(char *txt, struct s_log *log, int8_t do_flush)
{
	char sbuf[16];

#ifdef CS_ANTICASC
	if (!strncmp(txt + log->header_len, "acasc:", 6)) {
		strcat(txt, "\n");
		switch_log(cfg.ac_logfile, &fpa, ac_init_log);
		if (fpa) {
			fputs(txt + 8, fpa);
			if (do_flush) fflush(fpa);
		}
	} else
#endif
	{
		if (cfg.logtosyslog)
			syslog(LOG_INFO, "%s", txt+24);
		strcat(txt, "\n");
	}
	cs_write_log(txt + 8, do_flush);

#if defined(WEBIF) || defined(MODULE_MONITOR)
	if (loghist && exit_oscam != 1) {
		char *usrtxt = log->cl_text;
		char *target_ptr = NULL;
		int32_t target_len = strlen(usrtxt) + (strlen(txt) - 8) + 1;

		cs_writelock(&loghistory_lock);
		char *lastpos = loghist + (cfg.loghistorysize) - 1;
		if(loghist + target_len + 1 >= lastpos){
			strncpy(txt + 39, "Log entry too long!", strlen(txt) - 39);	// we can assume that the min loghistorysize is always 1024 so we don't need to check if this new string fits into it!
			target_len = strlen(usrtxt) + (strlen(txt) - 8) + 1;
		}
		if (!loghistptr)
			loghistptr = loghist;

		if (loghistptr + target_len + 1 > lastpos) {
			*loghistptr='\0';
			loghistptr=loghist + target_len + 1;
			*loghistptr='\0';
			target_ptr=loghist;
		} else {
			target_ptr = loghistptr;
			loghistptr=loghistptr + target_len + 1;
			*loghistptr='\0';
		}
		cs_writeunlock(&loghistory_lock);

		snprintf(target_ptr, target_len + 1, "%s\t%s", usrtxt, txt + 8);
	}
#endif

	struct s_client *cl;
	for (cl=first_client; cl ; cl=cl->next) {
		if ((cl->typ == 'm') && (cl->monlvl>0) && cl->log) //this variable is only initialized for cl->typ = 'm'
		{
			if (cl->monlvl<2) {
				if (log->cl_typ != 'c' && log->cl_typ != 'm')
					continue;
				if (log->cl_usr && cl->account && strcmp(log->cl_usr, cl->account->usr))
					continue;
			}
			snprintf(sbuf, sizeof(sbuf), "%03d", cl->logcounter);
			cl->logcounter = (cl->logcounter+1) % 1000;
			memcpy(txt + 4, sbuf, 3);
#ifdef MODULE_MONITOR
			monitor_send_idx(cl, txt);
#endif
		}
	}
}
Esempio n. 10
0
static void write_to_log(char *txt, struct s_log *log, int8_t do_flush)
{
	if(logStarted == 0)
		{ return; }
	
	(void)log; // Prevent warning when WEBIF, MODULE_MONITOR and CS_ANTICASC are disabled

	// anticascading messages go to their own log
	if (!anticasc_logging(txt + log->header_date_offset))
	{
		if(cfg.logtosyslog)
		{
			syslog(LOG_INFO, "%s", txt + log->header_info_offset);
		}
			
		if (cfg.sysloghost != NULL && syslog_socket != -1)
		{	
			char tmp[128+LOG_BUF_SIZE];			
			static char hostname[64];
			static uint8_t have_hostname = 0;
			time_t walltime;
			struct tm lt;
			char timebuf[32];
						
			if(!have_hostname)
			{
				if(gethostname(hostname, 64) != 0)
				{
					cs_strncpy(hostname, "unknown", 64);
				}
				
				have_hostname = 1;
			}
										
			walltime = cs_time();
			localtime_r(&walltime, &lt);

			if(strftime(timebuf, 32, "%b %d %H:%M:%S", &lt) == 0)
			{
				cs_strncpy(timebuf, "unknown", 32);
			}			
			
			snprintf(tmp, sizeof(tmp), "%s %s oscam[%u]: %s", timebuf, hostname, getpid(), txt + log->header_info_offset);
			sendto(syslog_socket, tmp, strlen(tmp), 0, (struct sockaddr*) &syslog_addr, sizeof(syslog_addr));
		}
	}
	
	strcat(txt, "\n");
	cs_write_log(txt, do_flush, log->header_date_offset, log->header_time_offset);

#if defined(WEBIF) || defined(MODULE_MONITOR)
	if(loghist && !exit_oscam && cfg.loghistorysize)
	{
		char *usrtxt = log->cl_text;
		char *target_ptr = NULL;
		int32_t target_len = strlen(usrtxt) + strlen(txt+log->header_date_offset) + 1;

		cs_writelock_nolog(__func__, &loghistory_lock);
		char *lastpos = loghist + (cfg.loghistorysize) - 1;
		if(loghist + target_len + 1 >= lastpos)
		{
			// we can assume that the min loghistorysize is always 1024 so we don't need to check if this new string fits into it!
			strncpy(txt + log->header_len, "Log entry too long!", strlen(txt) - log->header_len);
			target_len = strlen(usrtxt) + strlen(txt+log->header_date_offset) + 1;
		}
		if(!loghistptr)
			{ loghistptr = loghist;	}

		if(loghistptr + target_len + 1 > lastpos)
		{
			*loghistptr = '\0';
			loghistptr = loghist + target_len + 1;
			*loghistptr = '\0';
			target_ptr = loghist;
		}
		else
		{
			target_ptr = loghistptr;
			loghistptr = loghistptr + target_len + 1;
			*loghistptr = '\0';
		}
		++counter;
		
		snprintf(target_ptr, target_len + 1, "%s\t%s", usrtxt, txt + log->header_date_offset);
		ull2b_buf(counter, (uchar *)(loghistid + ((target_ptr-loghist)/3)));
		
		cs_writeunlock_nolog(__func__, &loghistory_lock);
	}
#endif

#if defined(MODULE_MONITOR)
	char sbuf[16];
	struct s_client *cl;
	for(cl = first_client; cl ; cl = cl->next)
	{
		if((cl->typ == 'm') && (cl->monlvl > 0) && cl->log)  //this variable is only initialized for cl->typ = 'm'
		{
			if(cl->monlvl < 2)
			{
				if(log->cl_typ != 'c' && log->cl_typ != 'm')
					{ continue; }
				if(log->cl_usr && cl->account && strcmp(log->cl_usr, cl->account->usr))
					{ continue; }
			}
			
			if(log->header_len > 0)
			{
				snprintf(sbuf, sizeof(sbuf), "%03d", cl->logcounter);
				cl->logcounter = (cl->logcounter + 1) % 1000;
				memcpy(txt + log->header_logcount_offset, sbuf, 3);
				monitor_send_idx(cl, txt);
			}
			else
			{
				char tmp_log[8+LOG_BUF_SIZE];
				snprintf(tmp_log, sizeof(tmp_log), "[LOG%03d]%s", cl->logcounter, txt);
				cl->logcounter = (cl->logcounter + 1) % 1000;
				monitor_send_idx(cl, tmp_log);
			}
		}
	}
#endif
}