Newer
Older
/* Synchronet node information writing 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"
/****************************************************************************/

rswindell
committed
/* Write the data from the structure 'node' into node.dab */
/* getnodedat(num,&node,1); must have been called before calling this func */
/* NOTE: ------^ the indicates the node record has been locked */
/****************************************************************************/
bool sbbs_t::putnodedat(uint number, node_t* node)
char path[MAX_PATH+1];
int wr=0;
int wrerr=0;
int attempts;
if(number < 1 || number>cfg.sys_nodes) {
errormsg(WHERE,ERR_CHK,"node number",number);
if(number==cfg.node_num) {
if((node->status==NODE_INUSE || node->status==NODE_QUIET)
&& node->action<NODE_LAST_ACTION
&& text[NodeActionMainMenu+node->action][0]) {
node->misc |= NODE_EXT;
putnodeext(number, expand_atcodes(text[NodeActionMainMenu+node->action], tmp, sizeof tmp));
snprintf(path, sizeof path, "%snode.dab",cfg.ctrl_dir);
pthread_mutex_lock(&nodefile_mutex);
if(nodefile==-1) {
if((nodefile=nopen(path,O_CREAT|O_RDWR|O_DENYNONE))==-1) {
pthread_mutex_unlock(&nodefile_mutex);
errormsg(WHERE,ERR_OPEN,path,O_CREAT|O_RDWR|O_DENYNONE);
return false;
}
}
for(attempts=0;attempts<10;attempts++) {
if(seeknodedat(nodefile, number)) {
wr=write(nodefile,node,sizeof(node_t));
if(wr==sizeof(node_t))
break;
wrerr=errno; /* save write error */
}
FILE_RETRY_DELAY(attempts + 1);
unlocknodedat(number);
if(mqtt->connected) {
int result = mqtt_putnodedat(mqtt, number, node);
if(result != MQTT_SUCCESS)
lprintf(LOG_WARNING, "ERROR %d (%d) publishing node status", result, errno);
if(wr!=sizeof(node_t)) {
errno=wrerr;
errormsg(WHERE,ERR_WRITE,"nodefile",number);
return false;
return utime(path,NULL) == 0; /* Update mod time for NFS/smbfs compatibility */
}
bool sbbs_t::unlocknodedat(uint number)
{
if(number < 1 || number > cfg.sys_nodes) {
errormsg(WHERE, ERR_CHK, "node number", number);
return false;
}
int result = unlock(nodefile, (number - 1) * sizeof(node_t), sizeof(node_t));
if(cfg.node_misc & NM_CLOSENODEDAB) {
close(nodefile);
nodefile = -1;
}
pthread_mutex_unlock(&nodefile_mutex);
return result == 0;
bool sbbs_t::putnodeext(uint number, char *ext)
char str[MAX_PATH+1];
int wr;
if(number < 1 || number>cfg.sys_nodes) {
errormsg(WHERE,ERR_CHK,"node number",number);
return false;
number--; /* make zero based */
if((node_ext=opennodeext(&cfg))==-1) {
errormsg(WHERE,ERR_OPEN,"node.exb",O_CREAT|O_RDWR|O_DENYNONE);
return false;
}
for(count=0;count<LOOP_NODEDAB;count++) {
lseek(node_ext,(long)number*128L,SEEK_SET);
if(lock(node_ext,(long)number*128L,128)==-1)
continue;
wr=write(node_ext,ext,128);
unlock(node_ext,(long)number*128L,128);
if(wr==128)
FILE_RETRY_DELAY(count + 1);
close(node_ext);
node_ext=-1;
if(count>(LOOP_NODEDAB/2) && count!=LOOP_NODEDAB) {
snprintf(str, sizeof str, "NODE.EXB (node %d) COLLISION - Count: %d"
logline(LOG_NOTICE,"!!",str);
}
if(count==LOOP_NODEDAB) {
errormsg(WHERE,ERR_WRITE,"NODE.EXB",number+1);
return false;
}
return true;
bool sbbs_t::putnode_downloading(off_t size)
{
action = NODE_DLNG;
/* calculate ETA */
time_t t = now;
if(size < cur_cps)
++t;
else if(cur_cps > 0)
t += size / cur_cps;
struct tm tm;
if(localtime_r(&t, &tm) != NULL)
thisnode.aux = (tm.tm_hour * 60) + tm.tm_min;
if(!getnodedat(cfg.node_num, &thisnode, /* lock-it: */true))
return false;
thisnode.action = action;
return putnodedat(cfg.node_num, &thisnode);