Commit 5ecf1f48 authored by rswindell's avatar rswindell
Browse files

Switched from std C time functions (gmtime, localtime, and ctime) to reentrant

variants (gmtime_r, localtime_r, and ctime_r) for thread-safe operation on Unix
parent d804c2b2
......@@ -44,7 +44,7 @@ bool sbbs_t::answer()
char tmp[MAX_PATH+1];
char tmp2[MAX_PATH+1];
int i,l,in;
struct tm * tm;
struct tm tm;
struct in_addr addr;
useron.number=0;
......@@ -52,15 +52,14 @@ bool sbbs_t::answer()
/* Caller ID is IP address */
addr.s_addr=client_addr;
strcpy(cid,inet_ntoa(addr));
tm=localtime(&now);
if(tm==NULL)
return(false);
memset(&tm,0,sizeof(tm));
localtime_r(&now,&tm);
sprintf(str,"%s %s %s %02d %u Node %3u"
,hhmmtostr(&cfg,tm,str2)
,wday[tm->tm_wday]
,mon[tm->tm_mon],tm->tm_mday,tm->tm_year+1900,cfg.node_num);
,hhmmtostr(&cfg,&tm,str2)
,wday[tm.tm_wday]
,mon[tm.tm_mon],tm.tm_mday,tm.tm_year+1900,cfg.node_num);
logline("@ ",str);
sprintf(str,"%s %s [%s]", connection, client_name, cid);
......
......@@ -92,7 +92,6 @@ char* sbbs_t::atcode(char* sp, char* str)
stats_t stats;
node_t node;
struct tm tm;
struct tm * tm_p;
str[0]=0;
......@@ -209,11 +208,7 @@ char* sbbs_t::atcode(char* sp, char* str)
if(!strcmp(sp,"TIME") || !strcmp(sp,"SYSTIME")) {
now=time(NULL);
tm_p=localtime(&now);
if(tm_p!=NULL)
tm=*tm_p;
else
memset(&tm,0,sizeof(tm));
memset(&tm,0,sizeof(tm));
sprintf(str,"%02d:%02d %s"
,tm.tm_hour==0 ? 12
: tm.tm_hour>12 ? tm.tm_hour-12
......@@ -426,11 +421,8 @@ char* sbbs_t::atcode(char* sp, char* str)
return(unixtodstr(&cfg,useron.laston,str));
if(!strcmp(sp,"LASTTIMEON")) {
tm_p=localtime(&useron.laston);
if(tm_p)
tm=*tm_p;
else
memset(&tm,0,sizeof(tm));
memset(&tm,0,sizeof(tm));
localtime_r(&useron.laston,&tm);
sprintf(str,"%02d:%02d %s"
,tm.tm_hour==0 ? 12
: tm.tm_hour>12 ? tm.tm_hour-12
......
......@@ -347,7 +347,7 @@ void sbbs_t::start_batch_download()
uint i,xfrprot;
ulong totalcdt,totalsize,totaltime;
time_t start,end,t;
struct tm * tm;
struct tm tm;
if(useron.rest&FLAG('D')) { /* Download restriction */
bputs(text[R_Download]);
......@@ -454,10 +454,8 @@ void sbbs_t::start_batch_download()
t=now;
if(cur_cps)
t+=(totalsize/(ulong)cur_cps);
tm=localtime(&t);
if(tm==NULL)
return;
thisnode.aux=(tm->tm_hour*60)+tm->tm_min;
localtime_r(&t,&tm);
thisnode.aux=(tm.tm_hour*60)+tm.tm_min;
thisnode.action=action;
putnodedat(cfg.node_num,&thisnode); /* calculate ETA */
start=time(NULL);
......
......@@ -1381,15 +1381,10 @@ void sbbs_t::guruchat(char *line, char *gurubuf, int gurunum)
int file;
uint c,i,j,k;
long len;
struct tm *tm_p;
struct tm tm;
now=time(NULL);
tm_p=localtime(&now);
if(tm_p)
tm=*tm_p;
else
memset(&tm,0,sizeof(tm));
localtime_r(&now,&tm);
for(i=0;i<100;i++) {
if((answer[i]=(char *)MALLOC(513))==NULL) {
......
......@@ -42,7 +42,7 @@ bool sbbs_t::ar_exp(uchar **ptrptr, user_t* user)
bool result,_not,_or,equal;
uint i,n,artype,age;
ulong l;
struct tm * tm;
struct tm tm;
result = true;
......@@ -203,9 +203,9 @@ bool sbbs_t::ar_exp(uchar **ptrptr, user_t* user)
break;
case AR_DAY:
now=time(NULL);
tm=localtime(&now);
if(tm==NULL || (equal && tm->tm_wday!=(int)n)
|| (!equal && tm->tm_wday<(int)n))
localtime_r(&now,&tm);
if((equal && tm.tm_wday!=(int)n)
|| (!equal && tm.tm_wday<(int)n))
result=_not;
else
result=!_not;
......@@ -382,8 +382,8 @@ bool sbbs_t::ar_exp(uchar **ptrptr, user_t* user)
break;
case AR_TIME:
now=time(NULL);
tm=localtime(&now);
if(tm==NULL || (tm->tm_hour*60)+tm->tm_min<(int)i)
localtime_r(&now,&tm);
if((tm.tm_hour*60)+tm.tm_min<(int)i)
result=_not;
else
result=!_not;
......
......@@ -267,7 +267,7 @@ void sbbs_t::ctrl_a(char x)
{
int i;
char tmp1[128],atr=curatr;
struct tm * tm;
struct tm tm;
if(x && (uchar)x<ESC) { /* Ctrl-A through Ctrl-Z for users with MF only */
if(!(useron.flags1&FLAG(x+64)))
......@@ -336,12 +336,11 @@ void sbbs_t::ctrl_a(char x)
break;
case 'T': /* Time */
now=time(NULL);
tm=localtime(&now);
if(tm!=NULL)
bprintf("%02d:%02d %s"
,tm->tm_hour==0 ? 12
: tm->tm_hour>12 ? tm->tm_hour-12
: tm->tm_hour, tm->tm_min, tm->tm_hour>11 ? "pm":"am");
localtime_r(&now,&tm);
bprintf("%02d:%02d %s"
,tm.tm_hour==0 ? 12
: tm.tm_hour>12 ? tm.tm_hour-12
: tm.tm_hour, tm.tm_min, tm.tm_hour>11 ? "pm":"am");
break;
case 'D': /* Date */
now=time(NULL);
......
......@@ -168,13 +168,11 @@ void sbbs_t::gettimeleft(void)
time_t eventtime=0;
time_t thisevent;
long tleft;
struct tm *tm, last_tm;
struct tm tm, last_tm;
now=time(NULL);
tm=localtime(&now);
if(tm==NULL)
return;
localtime_r(&now,&tm);
if(useron.exempt&FLAG('T')) { /* Time online exemption */
timeleft=cfg.level_timepercall[useron.level]*60;
if(timeleft<10) /* never get below 10 for exempt users */
......@@ -199,22 +197,16 @@ void sbbs_t::gettimeleft(void)
continue;
if(!(cfg.event[i]->misc&EVENT_FORCE)
|| (!(cfg.event[i]->misc&EVENT_EXCL) && cfg.event[i]->node!=cfg.node_num)
|| !(cfg.event[i]->days&(1<<tm->tm_wday)))
|| !(cfg.event[i]->days&(1<<tm.tm_wday)))
continue;
tm=localtime(&cfg.event[i]->last);
if(tm)
last_tm=*tm;
else
memset(&last_tm,0,sizeof(last_tm));
tm=localtime(&now);
if(tm==NULL)
return;
tm->tm_hour=cfg.event[i]->time/60; /* hasn't run yet today */
tm->tm_min=cfg.event[i]->time-(tm->tm_hour*60);
tm->tm_sec=0;
thisevent=mktime(tm);
if(tm->tm_mday==last_tm.tm_mday && tm->tm_mon==last_tm.tm_mon)
localtime_r(&cfg.event[i]->last,&last_tm);
localtime_r(&now,&tm);
tm.tm_hour=cfg.event[i]->time/60; /* hasn't run yet today */
tm.tm_min=cfg.event[i]->time-(tm.tm_hour*60);
tm.tm_sec=0;
thisevent=mktime(&tm);
if(tm.tm_mday==last_tm.tm_mday && tm.tm_mon==last_tm.tm_mon)
thisevent+=24L*60L*60L; /* already ran today, so add 24hrs */
if(!eventtime || thisevent<eventtime)
eventtime=thisevent;
......
......@@ -94,27 +94,26 @@ time_t DLLCALL dstrtounix(scfg_t* cfg, char *instr)
/****************************************************************************/
char* DLLCALL unixtodstr(scfg_t* cfg, time_t unix_time, char *str)
{
struct tm* tm;
struct tm tm;
if(!unix_time)
strcpy(str,"00/00/00");
else {
tm=localtime(&unix_time);
if(tm==NULL) {
if(localtime_r(&unix_time,&tm)==NULL) {
strcpy(str,"00/00/00");
return(str);
}
if(tm->tm_mon>11) { /* DOS leap year bug */
tm->tm_mon=0;
tm->tm_year++; }
if(tm->tm_mday>31)
tm->tm_mday=1;
if(tm.tm_mon>11) { /* DOS leap year bug */
tm.tm_mon=0;
tm.tm_year++; }
if(tm.tm_mday>31)
tm.tm_mday=1;
if(cfg->sys_misc&SM_EURODATE)
sprintf(str,"%02u/%02u/%02u",tm->tm_mday,tm->tm_mon+1
,TM_YEAR(tm->tm_year));
sprintf(str,"%02u/%02u/%02u",tm.tm_mday,tm.tm_mon+1
,TM_YEAR(tm.tm_year));
else
sprintf(str,"%02u/%02u/%02u",tm->tm_mon+1,tm->tm_mday
,TM_YEAR(tm->tm_year)); }
sprintf(str,"%02u/%02u/%02u",tm.tm_mon+1,tm.tm_mday
,TM_YEAR(tm.tm_year)); }
return(str);
}
......@@ -154,35 +153,34 @@ char* DLLCALL timestr(scfg_t* cfg, time_t *intime, char* str)
{
char* mer;
uchar hour;
struct tm* gm;
struct tm tm;
gm=localtime(intime);
if(gm==NULL) {
if(localtime_r(intime,&tm)==NULL) {
strcpy(str,"Invalid Time");
return(str);
}
if(cfg->sys_misc&SM_MILITARY) {
sprintf(str,"%s %s %02u %4u %02u:%02u:%02u"
,wday[gm->tm_wday],mon[gm->tm_mon],gm->tm_mday,1900+gm->tm_year
,gm->tm_hour,gm->tm_min,gm->tm_sec);
,wday[tm.tm_wday],mon[tm.tm_mon],tm.tm_mday,1900+tm.tm_year
,tm.tm_hour,tm.tm_min,tm.tm_sec);
return(str);
}
if(gm->tm_hour>=12) {
if(gm->tm_hour==12)
if(tm.tm_hour>=12) {
if(tm.tm_hour==12)
hour=12;
else
hour=gm->tm_hour-12;
hour=tm.tm_hour-12;
mer="pm";
} else {
if(gm->tm_hour==0)
if(tm.tm_hour==0)
hour=12;
else
hour=gm->tm_hour;
hour=tm.tm_hour;
mer="am";
}
sprintf(str,"%s %s %02u %4u %02u:%02u %s"
,wday[gm->tm_wday],mon[gm->tm_mon],gm->tm_mday,1900+gm->tm_year
,hour,gm->tm_min,mer);
,wday[tm.tm_wday],mon[tm.tm_mon],tm.tm_mday,1900+tm.tm_year
,hour,tm.tm_min,mer);
return(str);
}
......@@ -350,13 +348,9 @@ char* DLLCALL zonestr(short zone)
/****************************************************************************/
char* DLLCALL msgdate(when_t when, char* buf)
{
struct tm tm;
struct tm* tm_p;
struct tm tm;
tm_p=localtime((const time_t*)&when.time);
if(tm_p!=NULL)
tm=*tm_p;
else
if(localtime_r((const time_t*)&when.time,&tm)==NULL)
memset(&tm,0,sizeof(tm));
sprintf(buf,"%s, %d %s %d %02d:%02d:%02d %s"
,wday[tm.tm_wday]
......
......@@ -47,7 +47,7 @@ int sbbs_t::exec_function(csi_t *csi)
uint i,j,k;
long l;
node_t node;
struct tm * tm;
struct tm tm;
switch(*(csi->ip++)) {
......@@ -239,22 +239,20 @@ int sbbs_t::exec_function(csi_t *csi)
case CS_SYSTEM_LOG: /* System log */
if(!chksyspass())
return(0);
tm=localtime(&now);
if(tm==NULL)
if(localtime_r(&now,&tm)==NULL)
return(0);
sprintf(str,"%slogs/%2.2d%2.2d%2.2d.log", cfg.data_dir
,tm->tm_mon+1,tm->tm_mday,TM_YEAR(tm->tm_year));
,tm.tm_mon+1,tm.tm_mday,TM_YEAR(tm.tm_year));
printfile(str,0);
return(0);
case CS_SYSTEM_YLOG: /* Yesterday's log */
if(!chksyspass())
return(0);
now-=(ulong)60L*24L*60L;
tm=localtime(&now);
if(tm==NULL)
if(localtime_r(&now,&tm)==NULL)
return(0);
sprintf(str,"%slogs/%2.2d%2.2d%2.2d.log",cfg.data_dir
,tm->tm_mon+1,tm->tm_mday,TM_YEAR(tm->tm_year));
,tm.tm_mon+1,tm.tm_mday,TM_YEAR(tm.tm_year));
printfile(str,0);
return(0);
case CS_SYSTEM_STATS: /* System Statistics */
......
......@@ -47,7 +47,7 @@ int sbbs_t::exec_misc(csi_t* csi, char *path)
void *vp;
va_list arglist[64];
struct dirent *de;
struct tm *tm_p;
struct tm tm;
switch(*(csi->ip++)) {
case CS_VAR_INSTRUCTION:
......@@ -518,10 +518,11 @@ int sbbs_t::exec_misc(csi_t* csi, char *path)
lp=getintvar(csi,*(long *)csi->ip);
csi->ip+=4;
if(pp && lp) {
tm_p=localtime((time_t *)lp);
if(tm_p) {
strftime(buf,128,str,tm_p);
*pp=copystrvar(csi,*pp,buf); } }
if(localtime_r((time_t *)lp,&tm)!=NULL) {
strftime(buf,128,str,&tm);
*pp=copystrvar(csi,*pp,buf);
}
}
return(0);
case TIME_STR:
pp=getstrvar(csi,*(long *)csi->ip);
......
......@@ -105,7 +105,7 @@ bool sbbs_t::netmail(char *into, char *title, long mode)
long length,l;
faddr_t addr;
fmsghdr_t hdr;
struct tm * tm;
struct tm tm;
if(useron.etoday>=cfg.level_emailperday[useron.level] && !SYSOP) {
bputs(text[TooManyEmailsToday]);
......@@ -170,11 +170,10 @@ bool sbbs_t::netmail(char *into, char *title, long mode)
}
now=time(NULL);
tm=localtime(&now);
if(tm!=NULL)
if(localtime_r(&now,&tm)!=NULL)
sprintf(hdr.time,"%02u %3.3s %02u %02u:%02u:%02u"
,tm->tm_mday,mon[tm->tm_mon],TM_YEAR(tm->tm_year)
,tm->tm_hour,tm->tm_min,tm->tm_sec);
,tm.tm_mday,mon[tm.tm_mon],TM_YEAR(tm.tm_year)
,tm.tm_hour,tm.tm_min,tm.tm_sec);
hdr.destzone =addr.zone;
hdr.destnet =addr.net;
......
......@@ -2244,7 +2244,6 @@ static void ctrl_thread(void* arg)
node_t node;
client_t client;
struct tm tm;
struct tm * tm_p;
struct tm cur_tm;
#ifdef JAVASCRIPT
jsval js_val;
......@@ -2873,22 +2872,16 @@ static void ctrl_thread(void* arg)
sockprintf(sock, "150 Directory of %s%s", local_dir, p);
now=time(NULL);
tm_p=localtime(&now);
if(tm_p==NULL)
if(localtime_r(&now,&cur_tm)==NULL)
memset(&cur_tm,0,sizeof(cur_tm));
else
cur_tm=*tm_p;
glob(path,0,NULL,&g);
for(i=0;i<(int)g.gl_pathc;i++) {
if(detail) {
f.size=flength(g.gl_pathv[i]);
t=fdate(g.gl_pathv[i]);
tm_p=localtime(&t);
if(tm_p==NULL)
if(localtime_r(&t,&tm)==NULL)
memset(&tm,0,sizeof(tm));
else
tm=*tm_p;
fprintf(fp,"%crw-r--r-- 1 %-8s local %9ld %s %2d "
,isdir(g.gl_pathv[i]) ? 'd':'-'
,scfg.sys_id
......@@ -3072,11 +3065,8 @@ static void ctrl_thread(void* arg)
}
if(!strnicmp(cmd,"MDTM ",5)) {
t=fdate(fname);
tm_p=gmtime(&t); /* specifically use GMT/UTC representation */
if(tm_p==NULL)
if(gmtime_r(&t,&tm)==NULL) /* specifically use GMT/UTC representation */
memset(&tm,0,sizeof(tm));
else
tm=*tm_p;
sockprintf(sock,"213 %u%02u%02u%02u%02u%02u"
,1900+tm.tm_year,tm.tm_mon+1,tm.tm_mday
,tm.tm_hour,tm.tm_min,tm.tm_sec);
......@@ -3166,11 +3156,8 @@ static void ctrl_thread(void* arg)
detail=FALSE;
sockprintf(sock,"150 Opening ASCII mode data connection for /bin/ls.");
now=time(NULL);
tm_p=localtime(&now);
if(tm_p==NULL)
if(localtime_r(&now,&cur_tm)==NULL)
memset(&cur_tm,0,sizeof(cur_tm));
else
cur_tm=*tm_p;
/* ASCII Index File */
if(startup->options&FTP_OPT_INDEX_FILE && startup->index_file_name[0]
......@@ -3216,11 +3203,8 @@ static void ctrl_thread(void* arg)
t=time(NULL);
l=10240;
};
tm_p=localtime(&t);
if(tm_p==NULL)
if(localtime_r(&t,&tm)==NULL)
memset(&tm,0,sizeof(tm));
else
tm=*tm_p;
fprintf(fp,"-r--r--r-- 1 %-*s %-8s %9ld %s %2d %02d:%02d %s.qwk\r\n"
,NAME_LEN
,scfg.sys_id
......@@ -3291,11 +3275,8 @@ static void ctrl_thread(void* arg)
}
else {
t=fdate(np);
tm_p=localtime(&t);
if(tm_p==NULL)
if(localtime_r(&t,&tm)==NULL)
memset(&tm,0,sizeof(tm));
else
tm=*tm_p;
fprintf(fp,"-r--r--r-- 1 %-*s %-8s %9ld %s %2d %02d:%02d %s\r\n"
,NAME_LEN
,scfg.sys_id
......@@ -3370,11 +3351,8 @@ static void ctrl_thread(void* arg)
f.size=flength(g.gl_pathv[i]);
getfiledat(&scfg,&f);
t=fdate(g.gl_pathv[i]);
tm_p=localtime(&t);
if(tm_p==NULL)
if(localtime_r(&t,&tm)==NULL)
memset(&tm,0,sizeof(tm));
else
tm=*tm_p;
if(filedat) {
if(f.misc&FM_ANON)
SAFECOPY(str,ANONYMOUS);
......@@ -3837,11 +3815,8 @@ static void ctrl_thread(void* arg)
sockprintf(sock,"213 %lu",flength(fname));
else if(getdate && success) {
t=fdate(fname);
tm_p=gmtime(&t); /* specifically use GMT/UTC representation */
if(tm_p==NULL)
if(gmtime_r(&t,&tm)==NULL) /* specifically use GMT/UTC representation */
memset(&tm,0,sizeof(tm));
else
tm=*tm_p;
sockprintf(sock,"213 %u%02u%02u%02u%02u%02u"
,1900+tm.tm_year,tm.tm_mon+1,tm.tm_mday
,tm.tm_hour,tm.tm_min,tm.tm_sec);
......@@ -4327,6 +4302,7 @@ void DLLCALL ftp_server(void* arg)
char path[MAX_PATH+1];
char error[256];
char compiler[32];
char str[256];
SOCKADDR_IN server_addr;
SOCKADDR_IN client_addr;
socklen_t client_addr_len;
......@@ -4408,7 +4384,7 @@ void DLLCALL ftp_server(void* arg)
t=time(NULL);
lprintf("Initializing on %.24s with options: %lx"
,ctime(&t),startup->options);
,ctime_r(&t,str,sizeof(str)),startup->options);
/* Initial configuration and load from CNF files */
SAFECOPY(scfg.ctrl_dir, startup->ctrl_dir);
......
......@@ -692,7 +692,7 @@ js_strftime(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
char str[128];
char* fmt;
time_t t=time(NULL);
struct tm* tm_p;
struct tm tm;
if(!JSVAL_IS_STRING(argv[0])) {
JS_ReportError(cx,nostringarg);
......@@ -704,9 +704,9 @@ js_strftime(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
JS_ValueToInt32(cx,argv[1],(int32*)&t);
strcpy(str,"-Invalid time-");
tm_p=localtime(&t);
if(tm_p)
strftime(str,sizeof(str),fmt,tm_p);
if(localtime_r(&t,&tm)==NULL)
memset(&tm,0,sizeof(tm));
strftime(str,sizeof(str),fmt,&tm);
*rval = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, str));
return(JS_TRUE);
......
......@@ -858,7 +858,7 @@ int sbbs_t::listfileinfo(uint dirnum, char *filespec, long mode)
long usrcdt;
time_t start,end,t;
file_t f;
struct tm * tm;
struct tm tm;
sprintf(str,"%sxfer.ixt",cfg.data_dir);
if(mode==FI_USERXFER) {
......@@ -1281,10 +1281,8 @@ int sbbs_t::listfileinfo(uint dirnum, char *filespec, long mode)
getnodedat(cfg.node_num,&thisnode,1);
action=NODE_DLNG;
t=now+f.timetodl;
tm=localtime(&t);
if(tm==NULL)
break;
thisnode.aux=(tm->tm_hour*60)+tm->tm_min;
localtime_r(&t,&tm);
thisnode.aux=(tm.tm_hour*60)+tm.tm_min;
putnodedat(cfg.node_num,&thisnode); /* calculate ETA */
start=time(NULL);
error=protocol(cmdstr(cfg.prot[i]->dlcmd,path,nulstr,NULL),false);
......
......@@ -138,20 +138,19 @@ bool sbbs_t::syslog(char* code, char *entry)
char str[128];
char tmp[64];
int file;
struct tm * tm;
struct tm tm;
now=time(NULL);
tm=localtime(&now);
if(tm==NULL)
if(localtime_r(&now,&tm)==NULL)
return(false);
sprintf(fname,"%slogs/%2.2d%2.2d%2.2d.log",cfg.data_dir,tm->tm_mon+1,tm->tm_mday
,TM_YEAR(tm->tm_year));
sprintf(fname,"%slogs/%2.2d%2.2d%2.2d.log",cfg.data_dir,tm.tm_mon+1,tm.tm_mday
,TM_YEAR(tm.tm_year));
if((file=nopen(fname,O_WRONLY|O_APPEND|O_CREAT))==-1) {
lprintf("!ERRROR %d opening/creating %s",errno,fname);
return(false);
}
sprintf(str,"%-2.2s %s %s\r\n\r\n",code, hhmmtostr(&cfg,tm,tmp), entry);
sprintf(str,"%-2.2s %s %s\r\n\r\n",code, hhmmtostr(&cfg,&tm,tmp), entry);
write(file,str,strlen(str));
close(file);
......