Newer
Older
/* Synchronet log file routines */
/****************************************************************************
* @format.tab-size 4 (Plain Text/Source Code File Header) *
* @format.use-tabs true (see http://www.synchro.net/ptsc_hdr.html) *
* *
* Copyright Rob Swindell - http://www.synchro.net/copyright.html *
* *
* This program is free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License *
* as published by the Free Software Foundation; either version 2 *
* of the License, or (at your option) any later version. *
* See the GNU General Public License for more details: gpl.txt or *
* http://www.fsf.org/copyleft/gpl.html *
* *
* For Synchronet coding style and modification guidelines, see *
* http://www.synchro.net/source.html *
* *
* Note: If this box doesn't appear square, then you need to fix your tabs. *
****************************************************************************/
#include "sbbs.h"
#include "git_branch.h"
#include "git_hash.h"
extern "C" BOOL hacklog(scfg_t* cfg, const char* prot, const char* user, const char* text, const char* host, union xp_sockaddr* addr)
char tstr[64];
char fname[MAX_PATH+1];
time32_t now=time32(NULL);
if((fp = fnopen(NULL, fname, O_WRONLY|O_CREAT|O_APPEND)) == NULL)
return false;
fprintf(fp,"SUSPECTED %s HACK ATTEMPT for user '%s' on %.24s%sUsing port %u at %s [%s]%s"
,prot
,user
,timestr(cfg,now,tstr)
if(text != NULL)
fprintf(fp, "Details: %s%s", text, log_line_ending);
fputs(log_line_ending, fp);
fclose(fp);
BOOL sbbs_t::hacklog(const char* prot, const char* text)
{
return ::hacklog(&cfg, prot, useron.alias, text, client_name, &client_addr);
}
extern "C" BOOL spamlog(scfg_t* cfg, char* prot, char* action
,char* reason, char* host, char* ip_addr
,char* to, char* from)
char to_user[256];
char tstr[64];
char fname[MAX_PATH+1];
time32_t now=time32(NULL);
if((fp = fnopen(NULL, fname, O_WRONLY|O_CREAT|O_APPEND)) == NULL)
return false;
if(from==NULL)
from=host;
fprintf(fp, "SUSPECTED %s SPAM %s on %.24s%sHost: %s [%s]%sFrom: %.128s %s%s"
,timestr(cfg,now,tstr)
,host
,ip_addr
if(reason != NULL)
fprintf(fp, "Reason: %s%s", reason, log_line_ending);
fputs(log_line_ending, fp);
fclose(fp);
return true;
extern "C" int errorlog(scfg_t* cfg, int level, const char* host, const char* text)
{
FILE* fp;
char buf[128];
char path[MAX_PATH+1];
time_t now = time(NULL);
SAFEPRINTF(path, "%serror.log", cfg->logs_dir);
if((fp = fnopen(NULL,path,O_WRONLY|O_CREAT|O_APPEND))==NULL)
return -1;
fprintf(fp,"%.24s %s/%s %s%s%s%s%s"
,ctime_r(&now, buf)
,GIT_BRANCH
,GIT_HASH
,host==NULL ? "":host
,log_line_ending
,text
,log_line_ending
,log_line_ending
);
fclose(fp);
if(cfg->node_erruser && level <= cfg->node_errlevel) {
char subject[128];
SAFEPRINTF2(subject, "%s %sERROR occurred", host == NULL ? "" : host, level <= LOG_CRIT ? "CRITICAL " : "");
notify(cfg, cfg->node_erruser, subject, text);
}
return 0;
}
void sbbs_t::logentry(const char *code, const char *entry)
{
char str[512];
now=time(NULL);
SAFEPRINTF4(str, "Node %2d %s%s %s", cfg.node_num, timestr(now), log_line_ending, entry);
logline(code,str);
}
/****************************************************************************/
/* Writes 'str' verbatim into node.log */
/****************************************************************************/
void sbbs_t::log(const char *str)
{
if(logfile_fp==NULL || online==ON_LOCAL) return;
if(logcol>=78 || (78-logcol)<strlen(str)) {
fputs(" ",logfile_fp);
fputs(str,logfile_fp);
if(*lastchar(str)==LF) {
fflush(logfile_fp);
}
else
logcol+=strlen(str);
}
/****************************************************************************/
/* Writes 'str' on it's own line in node.log (using LOG_INFO level) */
/****************************************************************************/
void sbbs_t::logline(const char *code, const char *str)
{
logline(LOG_INFO, code, str);
}
/****************************************************************************/
/* Writes 'str' on it's own line in node.log */
/****************************************************************************/
void sbbs_t::logline(int level, const char *code, const char *str)
if(strchr(str,'\n')==NULL) // Keep the console log pretty
lputs(level, str);
if(logfile_fp==NULL || (online==ON_LOCAL && strcmp(code,"!!"))) return;
if(logcol!=1)
fputs(log_line_ending, logfile_fp);
fprintf(logfile_fp,"%-2.2s %s%s", code, str, log_line_ending);
}
/****************************************************************************/
/* Writes a comma then 'ch' to log, tracking column. */
/****************************************************************************/
void sbbs_t::logch(char ch, bool comma)
{
if(logfile_fp==NULL || (online==ON_LOCAL)) return;
if((uchar)ch<' ') /* Don't log control chars */
return;
if(logcol==1) {
logcol=4;
fprintf(logfile_fp," ");
}
else if(logcol>=78) {
logcol=4;
}
if(comma && logcol!=4) {
fprintf(logfile_fp,",");
logcol++;
}
if(ch&0x80) {
ch&=0x7f;
return;
fprintf(logfile_fp,"/");
}
fprintf(logfile_fp,"%c",ch);
logcol++;
}
/****************************************************************************/
/* Error handling routine. Prints to local and remote screens the error */
/* information, function, action, object and access and then attempts to */
/* write the error information into the file ERROR.LOG and NODE.LOG */
/****************************************************************************/
void sbbs_t::errormsg(int line, const char* function, const char *src, const char* action, const char *object
,long access, const char *extinfo)
char str[2048];
char errno_str[128];
char errno_info[256] = "";
/* prevent recursion */
if(errormsg_inside)
return;
errormsg_inside=true;
if(strcmp(action, ERR_CHK) != 0)
safe_snprintf(errno_info, sizeof(errno_info), "%d (%s) "
#ifdef _WIN32
"(WinError %u) "
#endif
,errno, safe_strerror(errno, errno_str, sizeof(errno_str))
#ifdef _WIN32
,GetLastError()
#endif
);
safe_snprintf(str,sizeof(str),"ERROR %s"
"in %s line %u (%s) %s \"%s\" access=%ld %s%s"
,src, line, function, action, object, access
,extinfo==NULL ? "":"info="
,extinfo==NULL ? "":extinfo);
lprintf(LOG_ERR, "!%s", str);
if(online == ON_REMOTE) {
int savatr=curatr;
attr(cfg.color[clr_err]);
bprintf("\7\r\n!ERROR %s %s\r\n", action, object); /* tell user about error */
bputs("\r\nThe sysop has been notified.\r\n");
pause();
attr(savatr);
safe_snprintf(str,sizeof(str),"ERROR %s %s", action, object);
if(cfg.node_num>0) {
getnodedat(cfg.node_num,&thisnode,1);
if(thisnode.errors<UCHAR_MAX)
thisnode.errors++;
criterrs=thisnode.errors;
putnodedat(cfg.node_num,&thisnode);
}
now=time(NULL);
if(logfile_fp!=NULL) {
if(logcol!=1)
fputs(log_line_ending, logfile_fp);
fprintf(logfile_fp,"!! %s%s", str, log_line_ending);
logcol=1;
fflush(logfile_fp);
errormsg_inside=false;
}