Exemplo n.º 1
0
// returns the filename for a save file given it's number
const char *GetProfileName(int num)
{
	if (num == 0)
		return "profile.dat";
	else
		return stprintf("profile%d.dat", num+1);
}
Exemplo n.º 2
0
/** @brief handles close syscall at the entrance and the exit
    Close a file descriptor */
void syscall_close(reg_s * reg, process_descriptor_t * proc)
{
  if (proc_entering(proc)) {
    proc_inside(proc);
  } else {
    if (reg->ret == 0){
      proc_outside(proc);
      int fd = reg->arg[0];
      process_close_call(proc, fd);
      if(strace_option) {
	stprintf(proc,"close(%d)",fd);
	stprintf_tabto(proc);
	stprintf(proc,"= %lu",reg->ret);
	stprintf_eol(proc);
      }
    }
    
    if (strace_option)
      print_close_syscall(reg, proc);
  }
}
Exemplo n.º 3
0
void
ReaderTask(int fd, const char *id)
{
    time_t dtime = 0;
    time_t ltime = 0;
    time_t itime = 0;
    time_t ftime = 0;
    time_t atime = 0;
    int counter = 0;
    int forceallcheck = 0;
    int check_disconn_counter = 0;

    TFd = fd;

    /*
     * [re]open RTStatus
     */
    RTStatusOpen(RTStatus, ThisReaderFork * DOpts.ReaderThreads + 1, DOpts.ReaderThreads);

    /*
     * Since we setuid(), we won't core.  This is for debugging
     */
    if (CoreDebugOpt || (DOpts.ReaderCrashHandler != NULL &&
			strcasecmp(DOpts.ReaderCrashHandler, "none") != 0)) {
	signal(SIGSEGV, sigSegVReader);
	signal(SIGBUS, sigSegVReader);
	signal(SIGFPE, sigSegVReader);
	signal(SIGILL, sigSegVReader);
    }

    signal(SIGHUP, sigHup);
    signal(SIGUSR1, sigUsr1);

    /*
     * Setup thread for passed pipe
     */
    ResetThreads();
    AddThread("reader", fd, -1, THREAD_READER, -1, 0);

    FD_SET(fd, &RFds);

    /*
     * Open KPDB database for active file
     */

    if ((KDBActive = KPDBOpen(PatDbExpand(ReaderDActivePat), O_RDWR)) == NULL) {
	logit(LOG_CRIT, "Unable to open %s", PatDbExpand(ReaderDActivePat));
	sleep(60);
	exit(1);
    }

    LoadExpireCtl(1);

    /*
     * Only startup connections to backend spools for reader threads
     */
    if (!FeedOnlyServer)
	CheckServerConfig(time(NULL), 1);

    /*
     * Selection core
     */

    while (!TerminatePending || NReadServAct || NumReaders) {
	/*
	 *  select core
	 */
	struct timeval tv;
	fd_set rfds = RFds;
	fd_set wfds = WFds;
	fd_set read_only_to_find_eof_fds;
	int i, sel_r;

	if (TerminatePending) {
	    if (TerminateTime == 0)
		TerminateTime = time(NULL) + 2;
	    if (TerminateTime < time(NULL) || !NumReaders)
		CanTerminate = 1;
	}

	/*
	 *  Get next scheduled timeout, no more then 2 seconds
	 *  (x 10 counter counts = 20 seconds max for {d,i,f}time 
	 *  check)
	 *
	 * If we are terminating, then speed up the select to clear
	 * out the connections.
	 *
	 */

	if (TerminatePending)
	    NextTimeout(&tv, 50);
	else
	    NextTimeout(&tv, 2 * 1000);

	stprintf("%s readers=%02d spoolsrv=%d/%d postsrv=%d/%d",
	    id,
	    NumReaders,
	    NReadServAct, NReadServers, 
	    NWriteServAct, NWriteServers
	);

	/* Check for disconnected clients every 50 times through the loop */
	FD_ZERO(&read_only_to_find_eof_fds);
	if (++check_disconn_counter == 50) {
	    for (i = 0; i < MaxFds; ++i) {
		if (FD_ISSET(i, &wfds) && (!(FD_ISSET(i, &rfds)))) {
		    FD_SET(i, &rfds);
		    FD_SET(i, &read_only_to_find_eof_fds);
		}
	    }
	    check_disconn_counter = 0;
	}

#if USE_AIO
	AIOUnblockSignal();
#endif
	sel_r = select(MaxFds, &rfds, &wfds, NULL, &tv);
#if USE_AIO
	AIOBlockSignal();
#endif

	gettimeofday(&CurTime, NULL);

	if(sel_r < 0 && errno != EINTR)
	    logit(LOG_CRIT,
		  "select error: %s (rfds=0x%x, wfds=0x%x)",
		  strerror(errno),
		  rfds,
		  wfds);

	/*
	 * select is critical, don't make unnecessary system calls.  Only
	 * test the time every 10 selects (20 seconds worst case), and
	 * only check for a new server configuration file every 60 seconds 
	 * after the initial load.  This may rearrange THREAD_SPOOL and
	 * THREAD_POST threads.
	 *
	 * We do not startup spool/post servers for feed-only forks
	 *
	 * However, flush overview cache even for feed-only forks.
	 */

	if (FeedOnlyServer <= 0) {
	    if (++counter == 10) {
		time_t t = CurTime.tv_sec;
		if (ltime) {
		    dtime += t - ltime;
		    itime += t - ltime;
		    ftime += t - ltime;
		    atime += t - ltime;
		}

		/*
		 * Check for server config change once a minute
		 */
		if (dtime < -5 || dtime >= 5) {
		    if (!TerminatePending)
			CheckServerConfig(t, ServersTerminated);
		    dtime = 0;
		}

		/*
		 * Flush overview every 30 seconds to allow dexpireover to work
		 */
		if (ftime < -5 || ftime >= 30) {
		    FlushOverCache();
		    LoadExpireCtl(0);
		    ftime = 0;
		}

		/*
		 * Poll all active descriptors once every 5 minutes.  This
		 * will work around a linux embrionic close bug that
		 * doesn't wakeup select(), and is used to idle-timeout
		 * connections. XXX
		 */
		if (itime < -5 || itime >= 300) {
		    rfds = RFds;
		    itime = 0;
		}

		/*
		 * Force a check all of FD's every 30 seconds to handle
		 * idle and session timeouts
		 */
		if (atime < -5 || atime >= 30) {
		    forceallcheck = 1;
		    atime = 0;
		}
		ltime = t;
		counter = 0;
	    }
	} else {
	    /*
	     * For a feed-only server, we only flush the overview FD
	     * cache every 5 minutes, and with a greater granularity.
	     * It should cycle much faster than that normally, and this
	     * is to prevent idle feed-only forks from keeping locks.
	     *
	     */

	    if (++counter == 10) {
		time_t t = CurTime.tv_sec;
		if (ltime) {
		    ftime += t - ltime;
		}

		if (ftime < -5 || ftime >= 300) {
		    FlushOverCache();
		    ftime = 0;
		}
		ltime = t;
		counter = 0;
	    }
	}

	for (i = 0; i < MaxFds; ++i) {
	    if (FD_ISSET(i, &rfds) && FD_ISSET(i, &read_only_to_find_eof_fds)) {
		char junk_byte;
		int ret_val;
		/*
		 * This FD is not marked for reading, but select() claims
		 * it has something to say. We don't actually want to read
		 * from it, but we do want to close it if the associated
		 * connection is dead.
		 */
		FD_CLR(i, &rfds);

		/* Use recv() with MSG_PEEK to see if it's closed.
		 * We shouldn't block because we're O_NONBLOCK.
		 */
		ret_val = recv(i, &junk_byte, 1, MSG_PEEK);

		/* If ret_val is zero, this means the socket is closed.
		 * Blast it. Otherwise, ignore it.
		 */
		if(ret_val == 0) {
		    ForkDesc *desc;
		    if((desc = FindThread(i, -1)) != NULL) {
			Connection *conn = desc->d_Data;

			if(conn) {
			    NNTerminate(conn);
			    DeleteConnection(conn);
			}
			DelThread(desc);
		    }
		}
	    }
	}

	for (i = 0; i < MaxFds; ++i) {
	    if (forceallcheck || TerminatePending ||
		FD_ISSET(i, &rfds) || FD_ISSET(i, &wfds)) {
		ForkDesc *desc;

		if ((desc = FindThread(i, -1)) != NULL) {
		    Connection *conn = desc->d_Data;

		    if (conn) {
			/*
			 * handle output I/O (optimization)
			 */

			MBFlush(conn, &conn->co_TMBuf);
			conn->co_FCounter = 0;
		    } 

		    /*
		     * Function dispatch
		     */

		    switch(desc->d_Type) {
		    case THREAD_READER:
			if (FD_ISSET(i, &rfds) || FD_ISSET(i, &wfds))
			    HandleReaderMsg(desc);
			break;
		    case THREAD_NNTP:		/* client	  */
			conn->co_Func(conn);
			if (conn->co_Auth.dr_ResultFlags & DR_REQUIRE_DNS) {
			    /* Go back to parent for DNS check */
			    conn->co_Auth.dr_Code = 0;
			    conn->co_TMBuf.mh_WEof = 1;
			}
			break;
		    case THREAD_SPOOL:		/* spool server	  */
		    case THREAD_POST:		/* posting server */
			conn->co_Func(conn);
			LogServerInfo(conn, TFd);
			break;
		    default:
			/* panic */
			break;
		    }

		    /*
		     * do not call MBFlush after the function because the
		     * function may be waiting for write data to drain and
		     * we don't want to cause write data to drain here and
		     * then not get a select wakeup later.
		     *
		     * check for connection termination
		     */

		    if (conn) {
			int idleTimeout = 0;
			if (conn->co_Auth.dr_ReaderDef) {
			    if (conn->co_Auth.dr_ReaderDef->rd_IdleTimeout &&
				    conn->co_LastActiveTime +
				    conn->co_Auth.dr_ReaderDef->rd_IdleTimeout <=
				    CurTime.tv_sec) {
				logit(LOG_INFO, "timeout idle %s",
				    conn->co_Auth.dr_Host);
				MBLogPrintf(conn,
				    &conn->co_TMBuf,
				    "400 %s: Idle timeout.\r\n",
				    conn->co_Auth.dr_VServerDef->vs_HostName
				);
				idleTimeout = 1;
				NNTerminate(conn);
			    }
			    if (conn->co_Auth.dr_ReaderDef->rd_SessionTimeout &&
				    conn->co_SessionStartTime +
				    conn->co_Auth.dr_ReaderDef->rd_SessionTimeout <=
				    CurTime.tv_sec) {
				logit(LOG_INFO, "timeout session %s",
				    conn->co_Auth.dr_Host);
				MBLogPrintf(conn,
				    &conn->co_TMBuf,
				    "400 %s: Session timeout.\r\n",
				    conn->co_Auth.dr_VServerDef->vs_HostName
				);
				idleTimeout = 1;
				NNTerminate(conn);
			    }
			}
			if ((!conn->co_Auth.dr_Code &&
				desc->d_Type == THREAD_NNTP) ||
			    idleTimeout ||
			    (conn->co_RMBuf.mh_REof && 
			    conn->co_TMBuf.mh_WEof &&
			    conn->co_TMBuf.mh_MBuf == NULL) ||
			    (TerminatePending &&
					!(conn->co_Flags & COF_MAYNOTCLOSE))
			) {
			    DeleteConnection(conn);
			    DelThread(desc);
			}
		    }
		}
	    }
	}
	forceallcheck = 0;
	(void)ScanTimers(1, 0);
	if (CanTerminate)
	    break;
    }
    RTStatusClose();
    KPDBClose(KDBActive);
    exit(0);
}
Exemplo n.º 4
0
void stprintf_tabto(process_descriptor_t * proc) {
    if (proc->curcol < acolumn)
            stprintf(proc, "%s", acolumn_spaces + proc->curcol);

}
Exemplo n.º 5
0
	/********************************************************************
	* [函数名]: insertCurrentTime
	* [描述]: 日志当前时间 (eg: YYYY-MM-DD hh:mm:ss)
	*         y: year    M: month    d: day
	*         h: hour    m: minute   s: second
	* [修改记录]:
	*   2015-05-20,littledj: create
	*   2015-05-20,littledj: 增加自定义格式
	********************************************************************/
	void GLogger::insertCurrentTime(tstring format)
	{
		if (format.empty())
			format = TEXT("** yyyy-MM-dd hh:mm:ss **\n");

		time_t tt = time(0);
		struct tm *lt = localtime(&tt);

		tchar* ct = new tchar[format.length() + 4];		
		tchar tmp[5];
		tcscpy(ct, format.c_str());
		for (size_t i = 0; i < format.size(); i++)
		{
			if (tcsncmp(ct + i, TEXT("yyyy"), 4 ) == 0)
			{
				stprintf(tmp, TEXT("%04d"), lt->tm_year + 1900);
				tcsncpy(ct + i, tmp, 4);
				i += 3;
				continue;
			}
			if (tcsncmp(ct + i, TEXT("MM"), 2) == 0)
			{
				stprintf(tmp, TEXT("%02d"), lt->tm_mon + 1);
				tcsncpy(ct + i, tmp, 2);
				i++;
				continue;
			}
			if (tcsncmp(ct + i, TEXT("dd"), 2) == 0)
			{
				stprintf(tmp, TEXT("%02d"), lt->tm_mday);
				tcsncpy(ct + i, tmp, 2);
				i++;
				continue;
			}
			if (tcsncmp(ct + i, TEXT("hh"), 2) == 0 || tcsncmp(ct + i, TEXT("HH"), 2) == 0)
			{
				stprintf(tmp, TEXT("%02d"), lt->tm_hour);
				tcsncpy(ct + i, tmp, 2);
				i++;
				continue;
			}
			if (tcsncmp(ct + i, TEXT("mm"), 2) == 0)
			{
				stprintf(tmp, TEXT("%02d"), lt->tm_min);
				tcsncpy(ct + i, tmp, 2);
				i++;
				continue;
			}
			if (tcsncmp(ct + i, TEXT("ss"), 2) == 0)
			{
				stprintf(tmp, TEXT("%02d"), lt->tm_sec);
				tcsncpy(ct + i, tmp, 2);
				i++;
				continue;
			}
		}

		tstring msg = formatMsg(PRINT_TYPE::RAW, TEXT("%s"), ct);
		delete[] ct;

		if (m_enableColor)
			output(msg, m_defaultColor);
		else
			output(msg);

		// 保存当前消息
		saveToMessagePool(PRINT_TYPE::RAW, msg);
	}