Newer
Older
rswindell
committed
/* Synchronet QWKnet node list or route.dat file generator */
/****************************************************************************
* @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 "load_cfg.h"
#include "str_util.h"
#include "date_str.h"
#include "smblib.h"
unsigned _stklen=10000;
smb_t smb;
scfg_t cfg;
void stripctrla(char *str)
for(i=j=0;str[i] && j<sizeof(out)-1;i++) {
if(str[i]==CTRL_A && str[i+1]!=0)
i++;
else
out[j++]=str[i];
}
out[j]=0;
strcpy(str,out);
{
char tmp[256];
int i,j,k;
j=strlen(str);
for(i=k=0;i<j;i++) /* remove CRs */
if(str[i]==CR && str[i+1]==LF)
continue;
else
tmp[k++]=str[i];
tmp[k]=0;
return(fputs(tmp,stdout));
}
/****************************************************************************/
/* Performs printf() through local assembly routines */
/* Called from everywhere */
/****************************************************************************/
int lprintf(const char *fmat, ...)
{
va_list argptr;
char sbuf[256];
int chcount;
va_start(argptr,fmat);
chcount=vsnprintf(sbuf,sizeof(sbuf),fmat,argptr);
sbuf[sizeof(sbuf)-1]=0;
va_end(argptr);
lputs(sbuf);
return(chcount);
for(i=0;i<msg->hdr.total_dfields;i++) {
if(msg->dfield[i].type!=TEXT_TAIL)
fseek(smb.sdt_fp,msg->hdr.offset+msg->dfield[i].offset
if(fread(&xlat,2,1,smb.sdt_fp) != 1)
xlat = XLAT_NONE;
if(xlat!=XLAT_NONE) /* no translations supported */
continue;
if((buf=realloc_or_free(buf,l+msg->dfield[i].length+1))==NULL)
return(buf);
l+=fread(buf+l,1,length,smb.sdt_fp);
buf[l]=0;
}
return(buf);
void gettag(smbmsg_t* msg, char *tag)
tag[0]=0;
buf=loadmsgtail(msg);
if(buf==NULL)
return;
truncsp(buf);
stripctrla(buf);
p=strrchr(buf,LF);
if(!p) p=buf;
else p++;
if(!strnicmp(p," Synchronet ",16))
p+=16;
if(!strnicmp(p," * Synchronet * ",16))
p+=16;
while(*p && *p<=' ') p++;
strcpy(tag,p);
}
#define FEED (1<<0)
#define LOCAL (1<<1)
#define APPEND (1<<2)
#define TAGS (1<<3)
#define ROUTE (1<<1)
#define NODES (1<<2)
#define USERS (1<<3)
char *usage="\nusage: qwknodes [-opts] cmds"
rswindell
committed
"\n cmds: r = create route.dat"
"\n u = create users.dat"
"\n"
"\n opts: f = format addresses for nodes that feed from this system"
"\n a = append existing output files"
"\n t = include tag lines in nodes.dat"
"\n l = include local users in users.dat"
char str[256],tmp[128],tag[256],addr[256],*p;
int i,j,mode=0,cmd=0,o_mode,max_age=0;
ushort smm,sbl;
uint32_t *crc=NULL,curcrc,total_crcs=0,l;
FILE *route=NULL,*users=NULL,*nodes=NULL;
const char* revision = "1.26";
fprintf(stdout,"\nSynchronet QWKnet Node/Route/User List Generator v%s-%s\n"
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
,revision, PLATFORM_DESC);
for(i=1;i<argc;i++)
for(j=0;argv[i][j];j++)
switch(toupper(argv[i][j])) {
case '/':
case '-':
while(argv[i][++j])
switch(toupper(argv[i][j])) {
case 'F':
mode|=FEED;
break;
case 'L':
mode|=LOCAL;
break;
case 'A':
mode|=APPEND;
break;
case 'T':
mode|=TAGS;
break;
case 'M':
j++;
max_age=atoi(argv[i]+j);
while(isdigit(argv[i][j+1])) j++;
break;
default:
case 'R':
cmd|=ROUTE;
break;
case 'U':
cmd|=USERS;
break;
case 'N':
cmd|=NODES;
break;
default:
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
return(1);
}
if(mode&APPEND)
o_mode=O_WRONLY|O_CREAT|O_APPEND;
else
o_mode=O_WRONLY|O_CREAT|O_TRUNC;
if(cmd&NODES)
if((nodes=fnopen(&i,"nodes.dat",o_mode))==NULL) {
printf("\7\nError opening nodes.dat\n");
return(1);
}
if(cmd&USERS)
if((users=fnopen(&i,"users.dat",o_mode))==NULL) {
printf("\7\nError opening users.dat\n");
return(1);
}
if(cmd&ROUTE)
if((route=fnopen(&i,"route.dat",o_mode))==NULL) {
printf("\7\nError opening route.dat\n");
return(1);
}
cfg.size=sizeof(cfg);
SAFECOPY(cfg.ctrl_dir, get_ctrl_dir(/* warn: */TRUE));
if(!load_cfg(&cfg, /* text: */NULL, /* prep: */TRUE, /* node: */FALSE, str, sizeof(str))) {
printf("\7\n%s\n",str);
}
now=time(NULL);
smm=crc16("smm",0);
sbl=crc16("sbl",0);
fprintf(stdout,"\n\n");
for(i=0;i<cfg.total_subs;i++) {
if(!(cfg.sub[i]->misc&SUB_QNET))
continue;
fprintf(stdout,"%-*s %s\n"
,LEN_GSNAME,cfg.grp[cfg.sub[i]->grp]->sname,cfg.sub[i]->lname);
SAFEPRINTF2(smb.file,"%s%s",cfg.sub[i]->data_dir,cfg.sub[i]->code);
smb.retry_time=30;
smb.subnum=i;
if((j=smb_open(&smb))!=0) {
fprintf(stderr, "smb_open returned %d\n",j);
continue;
}
if((j=smb_locksmbhdr(&smb))!=0) {
fprintf(stderr, "smb_locksmbhdr returned %d\n",j);
smb_close(&smb);
continue;
}
if((j=smb_getstatus(&smb))!=0) {
fprintf(stderr, "smb_getstatus returned %d\n",j);
smb_close(&smb);
continue;
}
smb_unlocksmbhdr(&smb);
msg.idx_offset=smb.status.total_msgs;
if(!msg.idx_offset) {
smb_close(&smb);
printf("Empty.\n");
continue;
}
while(!kbhit() && !ferror(smb.sid_fp) && msg.idx_offset) {
msg.idx_offset--;
fseek(smb.sid_fp,msg.idx_offset*sizeof(idxrec_t),SEEK_SET);
if(!fread(&msg.idx,1,sizeof(idxrec_t),smb.sid_fp))
break;
fprintf(stdout,"%-5u\r",msg.idx_offset+1);
if(msg.idx.to==smm || msg.idx.to==sbl)
continue;
if(max_age && now-msg.idx.time>((time_t)max_age*24UL*60UL*60UL))
continue;
if((j=smb_lockmsghdr(&smb,&msg))!=0) {
fprintf(stderr, "smb_lockmsghdr returned %d\n",j);
break;
}
if((j=smb_getmsghdr(&smb,&msg))!=0) {
fprintf(stderr, "smb_getmsghdr returned %d\n",j);
break;
}
smb_unlockmsghdr(&smb,&msg);
if((mode&LOCAL && msg.from_net.type==NET_NONE)
|| (msg.from_net.type==NET_QWK && msg.from_net.addr!=NULL)) {
if(msg.from_net.type!=NET_QWK)
msg.from_net.addr="";
sprintf(str,"%s%s",(char *)msg.from_net.addr,(char *)msg.from);
curcrc=crc32(str,0);
}
else
curcrc=crc32(msg.from_net.addr,0);
for(l=0;l<total_crcs;l++)
if(curcrc==crc[l])
break;
if(l==total_crcs) {
total_crcs++;
if((crc=(uint32_t *)realloc_or_free(crc
,sizeof(uint32_t)*total_crcs))==NULL) {
printf("Error allocating %lu bytes\n"
break;
}
crc[l]=curcrc;
if(cmd&ROUTE && msg.from_net.type==NET_QWK) {
strcpy(addr,msg.from_net.addr);
if(mode&FEED) {
p=strrchr(addr,'/');
if(!p)
p=addr;
else
*(p++)=0;
safe_snprintf(str, sizeof(str), "%s %s:%s%c%s"
,unixtodstr(&cfg,msg.hdr.when_written.time,tmp)
,p,cfg.sys_id,p==addr ? 0 : '/'
,addr);
fprintf(route,"%s\r\n",str);
}
else {
p=strrchr(addr,'/');
if(p) {
*(p++)=0;
fprintf(route,"%s %s:%.*s\r\n"
,unixtodstr(&cfg,msg.hdr.when_written.time,str)
,p
,(uint)(p-addr)
,addr);
}
}
}
if(cmd&USERS) {
if(msg.from_net.type!=NET_QWK)
strcpy(str,cfg.sys_id);
else if(mode&FEED)
sprintf(str,"%s/%s",cfg.sys_id,(char *)msg.from_net.addr);
strcpy(str,msg.from_net.addr);
p=strrchr(str,'/');
if(p)
fprintf(users,"%-25.25s %-8.8s %s (%s)\r\n"
,msg.from,p+1
,unixtodstr(&cfg,msg.hdr.when_written.time,tmp)
,str);
else
fprintf(users,"%-25.25s %-8.8s %s\r\n"
,msg.from,str
,unixtodstr(&cfg,msg.hdr.when_written.time,tmp));
}
if(cmd&NODES && msg.from_net.type==NET_QWK) {
if(mode&TAGS)
sprintf(str,"%s/%s",cfg.sys_id,(char *)msg.from_net.addr);
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
else
strcpy(str,msg.from_net.addr);
p=strrchr(str,'/');
if(p) {
if(mode&TAGS)
fprintf(nodes,"%-8.8s %s\r\n"
,p+1
,tag);
else
fprintf(nodes,"%-8.8s %s (%s)\r\n"
,p+1
,unixtodstr(&cfg,msg.hdr.when_written.time,tmp)
,str);
}
else
fprintf(nodes,"%-8.8s %s\r\n"
,str
,mode&TAGS
? tag
: unixtodstr(&cfg,msg.hdr.when_written.time,tmp));
}
}
}
smb_freemsgmem(&msg);
}
smb_close(&smb);
if(kbhit()) {
getch();
fprintf(stdout,"Key pressed.\n");
fprintf(stdout,"Done.\n");