#include "innbbsconf.h"
#include "daemon.h"
#include "innbbsd.h"
#include <dirent.h>
#include "bbslib.h"
#include "inntobbs.h"
#include "nntp.h"
#ifdef GETRUSAGE
#include <sys/time.h>
#include <sys/resource.h>
#endif
#ifdef STDC
# ifndef ARG
# define ARG(x) (x)
# else
# define ARG(x) ()
# endif
#endif
/*< add <mid> <recno> ...
> 200 OK
< quit
500 BYE
> 300 DBZ Server ...
< query <mid>
> 250 <recno> ...
> 450 NOT FOUND!
*/
static int CMDhelp ARG((ClientType*));
static int CMDquit ARG((ClientType*));
static int CMDihave ARG((ClientType*));
static int CMDstat ARG((ClientType*));
static int CMDaddhist ARG((ClientType*));
static int CMDgrephist ARG((ClientType*));
static int CMDmidcheck ARG((ClientType*));
static int CMDshutdown ARG((ClientType*));
static int CMDmode ARG((ClientType*));
static int CMDreload ARG((ClientType*));
static int CMDhismaint ARG((ClientType*));
static int CMDverboselog ARG((ClientType*));
static int CMDlistnodelist ARG((ClientType*));
static int CMDlistnewsfeeds ARG((ClientType*));
#ifdef GETRUSAGE
static int CMDgetrusage ARG((ClientType*));
static int CMDmallocmap ARG((ClientType*));
#endif
static daemoncmd_t cmds[]=
/* cmd-name, cmd-usage, min-argc, max-argc, errorcode, normalcode, cmd-func */
{ {"help","help [cmd]",1,2,99,100,CMDhelp},
{"quit","quit",1,0,99,100,CMDquit},
#ifndef DBZSERVER
{"ihave","ihave mid",2,2,435,335,CMDihave},
#endif
{"stat","stat mid",2,2,223,430,CMDstat},
{"addhist","addhist <mid> <path>",3,3, NNTP_ADDHIST_BAD, NNTP_ADDHIST_OK,CMDaddhist},
{"grephist","grephist <mid>",2,2, NNTP_GREPHIST_BAD, NNTP_GREPHIST_OK, CMDgrephist},
{"midcheck","midcheck [on|off]",1,2, NNTP_MIDCHECK_BAD, NNTP_MIDCHECK_OK, CMDmidcheck},
{"shutdown","shutdown (local)",1,1, NNTP_SHUTDOWN_BAD, NNTP_SHUTDOWN_OK, CMDshutdown},
{"mode","mode (local)",1,1, NNTP_MODE_BAD, NNTP_MODE_OK, CMDmode},
{"listnodelist","listnodelist (local)",1,1, NNTP_MODE_BAD, NNTP_MODE_OK, CMDlistnodelist},
{"listnewsfeeds","listnewsfeeds (local)",1,1, NNTP_MODE_BAD, NNTP_MODE_OK, CMDlistnewsfeeds},
{"reload","reload (local)",1,1, NNTP_RELOAD_BAD, NNTP_RELOAD_OK, CMDreload},
{"hismaint","hismaint (local)",1,1, NNTP_RELOAD_BAD, NNTP_RELOAD_OK, CMDhismaint},
{"verboselog","verboselog [on|off](local)",1,2, NNTP_VERBOSELOG_BAD, NNTP_VERBOSELOG_OK, CMDverboselog},
#ifdef GETRUSAGE
{"getrusage","getrusage (local)",1,1, NNTP_MODE_BAD, NNTP_MODE_OK, CMDgetrusage},
#endif
#ifdef MALLOCMAP
{"mallocmap","mallocmap (local)",1,1, NNTP_MODE_BAD, NNTP_MODE_OK, CMDmallocmap},
#endif
{NULL,NULL,0,0,99,100,NULL}
};
installinnbbsd()
{
installdaemon(cmds,100,NULL);
}
#ifdef OLDLIBINBBSINND
testandmkdir(dir)
char *dir;
{
if (!isdir(dir)) {
char path[MAXPATHLEN+12];
sprintf(path,"mkdir -p %s",dir);
system(path);
}
}
static char splitbuf[2048];
static char joinbuf[1024];
#define MAXTOK 50
static char* Splitptr[MAXTOK];
char **split(line,pat)
char *line,*pat;
{
char *p;
int i;
for (i=0;i<MAXTOK;++i) Splitptr[i] = NULL;
strncpy(splitbuf,line,sizeof splitbuf - 1 );
/*printf("%d %d\n",strlen(line),strlen(splitbuf));*/
splitbuf[sizeof splitbuf - 1] = '\0';
for (i=0,p=splitbuf;*p && i< MAXTOK -1 ;){
for (Splitptr[i++]=p;*p && !strchr(pat,*p);p++);
if (*p=='\0') break;
for (*p++='\0'; *p && strchr(pat,*p);p++);
}
return Splitptr;
}
char **BNGsplit(line)
char *line;
{
char **ptr = split(line,",");
newsfeeds_t *nf1, *nf2;
char *n11, *n12, *n21, *n22;
int i,j;
for (i=0; ptr[i] != NULL; i++) {
nf1 = (newsfeeds_t*)search_group(ptr[i]);
for (j=i+1; ptr[j] != NULL; j++) {
if (strcmp(ptr[i],ptr[j])==0) {
*ptr[j] = '\0';
continue;
}
nf2 = (newsfeeds_t*)search_group(ptr[j]);
if (nf1 && nf2) {
if (strcmp(nf1->board,nf2->board)==0) {
*ptr[j] = '\0';
continue;
}
for (n11 = nf1->board, n12 = (char*)strchr(n11,',');
n11 && *n11 ; n12 = (char*) strchr(n11,',')) {
if (n12) *n12 = '\0';
for (n21 = nf2->board, n22 = (char*)strchr(n21,',');
n21 && *n21 ; n22 = (char*) strchr(n21,',')) {
if (n22) *n22 = '\0';
if (strcmp(n11,n21)==0) {
*n21 = '\t';
}
if (n22) {
*n22 = ',';
n21 = n22 + 1;
} else
break;
}
if (n12) {
*n12 = ',';
n11 = n12 +1;
} else
break;
}
}
}
}
return ptr;
}
char **ssplit(line,pat)
char *line,*pat;
{
char *p;
int i;
for (i=0;i<MAXTOK;++i) Splitptr[i] = NULL;
strncpy(splitbuf,line,1024);
for (i=0,p=splitbuf;*p && i< MAXTOK;){
for (Splitptr[i++]=p;*p && !strchr(pat,*p);p++);
if (*p=='\0') break;
*p=0;p++;
/* for (*p='\0'; strchr(pat,*p);p++);*/
}
return Splitptr;
}
char *join(lineptr,pat,num)
char **lineptr,*pat;
int num;
{
int i;
joinbuf[0] = '\0';
if (lineptr[0] != NULL)
strncpy(joinbuf,lineptr[0],1024);
else {
joinbuf[0]='\0';
return joinbuf;
}
for (i=1;i<num;i++) {
strcat(joinbuf,pat);
if (lineptr[i] != NULL)
strcat(joinbuf,lineptr[i]);
else
break;
}
return joinbuf;
}
#endif
static int CMDtnrpd(client)
ClientType *client;
{
argv_t *argv = &client->Argv;
fprintf(argv->out,"%d %s\n",argv->dc->usage);
return 0;
}
islocalconnect(client)
ClientType *client;
{
if (strcmp(client->username,"localuser") != 0 ||
strcmp(client->hostname,"localhost") != 0)
return 0;
return 1;
}
static shutdownflag = 0;
INNBBSDhalt()
{
shutdownflag = 1;
}
int INNBBSDshutdown()
{
return shutdownflag;
}
static int CMDshutdown(client)
ClientType *client;
{
argv_t *argv = &client->Argv;
buffer_t *in = &client->in;
daemoncmd_t *p = argv->dc;
if (!islocalconnect(client)) {
fprintf(argv->out,"%d shutdown access denied\r\n", p->errorcode);
fflush(argv->out);
verboselog("Shutdown Put: %d shutdown access denied\n", p->errorcode);
return 1;
}
shutdownflag = 1;
fprintf(argv->out,"%d shutdown starting\r\n", p->normalcode);
fflush(argv->out);
verboselog("Shutdown Put: %d shutdown starting\n", p->normalcode);
return 1;
}
static int CMDmode(client)
ClientType *client;
{
/*char cwdpath[MAXPATHLEN+1];*/
argv_t *argv = &client->Argv;
extern ClientType INNBBSD_STAT;
buffer_t *in = &client->in;
daemoncmd_t *p = argv->dc;
time_t uptime, now;
int i,j;
time_t lasthist;
ClientType *client1 = &INNBBSD_STAT;
if (!islocalconnect(client)) {
fprintf(argv->out,"%d mode access denied\r\n", p->errorcode);
fflush(argv->out);
verboselog("Mode Put: %d mode access denied\n", p->errorcode);
return 1;
}
fprintf(argv->out,"%d mode\r\n", p->normalcode);
fflush(argv->out);
verboselog("Mode Put: %d mode\n", p->normalcode);
uptime = innbbsdstartup();
time(&now);
fprintf(argv->out,"up since %salive %.2f days\r\n", ctime(&uptime), (double)(now - innbbsdstartup())/86400);
fprintf(argv->out,"BBSHOME %s\r\n", BBSHOME);
fprintf(argv->out,"MYBBSID %s\r\n", MYBBSID);
fprintf(argv->out,"ECHOMAIL %s\r\n", ECHOMAIL);
fprintf(argv->out,"INNDHOME %s\r\n", INNDHOME);
fprintf(argv->out,"HISTORY %s\r\n", HISTORY);
fprintf(argv->out,"LOGFILE %s\r\n", LOGFILE);
fprintf(argv->out,"INNBBSCONF %s\r\n", INNBBSCONF);
fprintf(argv->out,"BBSFEEDS %s\r\n", BBSFEEDS);
fprintf(argv->out,"Verbose log: %s\r\n", isverboselog() ?"ON":"OFF");
fprintf(argv->out,"History Expire Days %d\r\n", Expiredays);
fprintf(argv->out,"History Expire Time %d:%d\r\n", His_Maint_Hour, His_Maint_Min);
lasthist = gethisinfo();
if (lasthist > 0) {
time_t keep = lasthist, keep1;
time(&now);
fprintf(argv->out,"Oldest history entry created: %s",(char*)ctime(&keep));
keep = Expiredays * 86400 * 2 + lasthist;
keep1 = keep - now ;
fprintf(argv->out,"Next time to maintain history: (%.2f days later) %s",(double)keep1/86400, (char*)ctime(&keep));
}
fprintf(argv->out,"PID is %d\r\n", getpid());
fprintf(argv->out,"LOCAL ONLY %d\r\n", LOCALNODELIST);
fprintf(argv->out,"NONE NEWSFEEDS %d\r\n", NONENEWSFEEDS);
fprintf(argv->out,"Max connections %d\r\n", Maxclient);
#ifdef DEBUGCWD
getwd(cwdpath);
fprintf(argv->out,"Working directory %s\r\n", cwdpath);
#endif
if (Channel)
for (i=0, j=0; i< Maxclient; ++i) {
if (Channel[i].fd == -1) continue;
if (Channel+i == client) continue;
j++;
fprintf(argv->out," %d) in->used %d, in->left %d %s@%s\r\n",i,
Channel[i].in.used, Channel[i].in.left,
Channel[i].username,Channel[i].hostname);
}
fprintf(argv->out,"Total connections %d\r\n", j);
fprintf(argv->out,"Total rec: %d dup: %d fail: %d size: %d, stat rec: %d fail: %d\n", client1->ihavecount, client1->ihaveduplicate, client1->ihavefail, client1->ihavesize, client1->statcount, client1->statfail);
fprintf(argv->out,".\r\n");
fflush(argv->out);
return 1;
}
static int
CMDlistnodelist(client)
ClientType *client;
{
int nlcount;
argv_t *argv = &client->Argv;
buffer_t *in = &client->in;
daemoncmd_t *p = argv->dc;
if (!islocalconnect(client)) {
fprintf(argv->out,"%d listnodelist access denied\r\n", p->errorcode);
fflush(argv->out);
verboselog("Mallocmap Put: %d listnodelist access denied\n", p->errorcode);
return 1;
}
fprintf(argv->out,"%d listnodelist\r\n", p->normalcode);
for (nlcount =0; nlcount < NLCOUNT; nlcount++) {
nodelist_t *nl = NODELIST+nlcount;
fprintf(argv->out,"%2d %s /\\/\\ %s\r\n", nlcount+1, nl->node==NULL?"":nl->node, nl->exclusion==NULL?"":nl->exclusion);
fprintf(argv->out," %s:%s:%s\r\n",nl->host==NULL?"":nl->host, nl->protocol==NULL?"":nl->protocol, nl->comments == NULL ? "": nl->comments);
}
fprintf(argv->out,".\r\n");
fflush(argv->out);
verboselog("Listnodelist Put: %d listnodelist complete\n", p->normalcode);
return 1;
}
static int
CMDlistnewsfeeds(client)
ClientType *client;
{
argv_t *argv = &client->Argv;
buffer_t *in = &client->in;
daemoncmd_t *p = argv->dc;
int nfcount;
if (!islocalconnect(client)) {
fprintf(argv->out,"%d listnewsfeeds access denied\r\n", p->errorcode);
fflush(argv->out);
verboselog("Mallocmap Put: %d listnewsfeeds access denied\n", p->errorcode);
return 1;
}
fprintf(argv->out,"%d listnewsfeeds\r\n", p->normalcode);
for (nfcount =0; nfcount < NFCOUNT; nfcount++) {
newsfeeds_t *nf = NEWSFEEDS + nfcount;
fprintf(argv->out,"%3d %s<=>%s\r\n",nfcount+1, nf->newsgroups, nf->board);
fprintf(argv->out," %s\r\n",nf->path==NULL?"(Null)":nf->path);
}
fprintf(argv->out,".\r\n");
fflush(argv->out);
verboselog("Listnewsfeeds Put: %d listnewsfeeds complete\n", p->normalcode);
return 1;
}
#ifdef MALLOCMAP
static int CMDmallocmap(client)
ClientType *client;
{
argv_t *argv = &client->Argv;
buffer_t *in = &client->in;
daemoncmd_t *p = argv->dc;
struct rusage ru;
int savefd ;
if (!islocalconnect(client)) {
fprintf(argv->out,"%d mallocmap access denied\r\n", p->errorcode);
fflush(argv->out);
verboselog("Mallocmap Put: %d mallocmap access denied\n", p->errorcode);
return 1;
}
fprintf(argv->out,"%d mallocmap\r\n", p->normalcode);
savefd = dup(1);
dup2(client->fd, 1);
mallocmap();
dup2(savefd, 1);
close(savefd);
fprintf(argv->out,".\r\n");
fflush(argv->out);
verboselog("Mallocmap Put: %d mallocmap complete\n", p->normalcode);
return 1;
}
#endif
#ifdef GETRUSAGE
static int CMDgetrusage(client)
ClientType *client;
{
argv_t *argv = &client->Argv;
buffer_t *in = &client->in;
daemoncmd_t *p = argv->dc;
struct rusage ru;
if (!islocalconnect(client)) {
fprintf(argv->out,"%d getrusage access denied\r\n", p->errorcode);
fflush(argv->out);
verboselog("Getrusage Put: %d getrusage access denied\n", p->errorcode);
return 1;
}
fprintf(argv->out,"%d getrusage\r\n", p->normalcode);
if (getrusage(RUSAGE_SELF,&ru) == 0) {
fprintf(argv->out,"user time used: %.6f\r\n",(double)ru.ru_utime.tv_sec + (double)ru.ru_utime.tv_usec/1000000.0);
fprintf(argv->out,"system time used: %.6f\r\n",(double)ru.ru_stime.tv_sec + (double)ru.ru_stime.tv_usec/1000000.0);
fprintf(argv->out,"maximum resident set size: %lu\r\n",ru.ru_maxrss * getpagesize());
fprintf(argv->out,"integral resident set size: %lu\r\n",ru.ru_idrss * getpagesize());
fprintf(argv->out,"page faults not requiring physical I/O: %d\r\n",ru.ru_minflt);
fprintf(argv->out,"page faults requiring physical I/O: %d\r\n",ru.ru_majflt);
fprintf(argv->out,"swaps: %d\r\n",ru.ru_nswap);
fprintf(argv->out,"block input operations: %d\r\n",ru.ru_inblock);
fprintf(argv->out,"block output operations: %d\r\n",ru.ru_oublock);
fprintf(argv->out,"messages sent: %d\r\n",ru.ru_msgsnd);
fprintf(argv->out,"messages received: %d\r\n",ru.ru_msgrcv);
fprintf(argv->out,"signals received: %d\r\n",ru.ru_nsignals);
fprintf(argv->out,"voluntary context switches: %d\r\n",ru.ru_nvcsw);
fprintf(argv->out,"involuntary context switches: %d\r\n",ru.ru_nivcsw);
}
fprintf(argv->out,".\r\n");
fflush(argv->out);
verboselog("Getrusage Put: %d getrusage complete\n", p->normalcode);
return 1;
}
#endif
static int CMDhismaint(client)
ClientType *client;
{
argv_t *argv = &client->Argv;
buffer_t *in = &client->in;
daemoncmd_t *p = argv->dc;
if (!islocalconnect(client)) {
fprintf(argv->out,"%d hismaint access denied\r\n", p->errorcode);
fflush(argv->out);
verboselog("Hismaint Put: %d hismaint access denied\n", p->errorcode);
return 1;
}
verboselog("Hismaint Put: %d hismaint start\n", p->normalcode);
HISmaint();
fprintf(argv->out,"%d hismaint complete\r\n", p->normalcode);
fflush(argv->out);
verboselog("Hismaint Put: %d hismaint complete\n", p->normalcode);
return 1;
}
static int CMDreload(client)
ClientType *client;
{
argv_t *argv = &client->Argv;
buffer_t *in = &client->in;
daemoncmd_t *p = argv->dc;
if (!islocalconnect(client)) {
fprintf(argv->out,"%d reload access denied\r\n", p->errorcode);
fflush(argv->out);
verboselog("Reload Put: %d reload access denied\n", p->errorcode);
return 1;
}
initial_bbs("feed");
fprintf(argv->out,"%d reload complete\r\n", p->normalcode);
fflush(argv->out);
verboselog("Reload Put: %d reload complete\n", p->normalcode);
return 1;
}
static int CMDverboselog(client)
ClientType *client;
{
argv_t *argv = &client->Argv;
buffer_t *in = &client->in;
daemoncmd_t *p = argv->dc;
if (!islocalconnect(client)) {
fprintf(argv->out,"%d verboselog access denied\r\n", p->errorcode);
fflush(argv->out);
verboselog("Reload Put: %d verboselog access denied\n", p->errorcode);
return 1;
}
if (client->mode == 0) {
if (argv->argc > 1) {
if (strcasecmp(argv->argv[1],"off")==0) {
setverboseoff();
} else {
setverboseon();
}
}
}
fprintf(argv->out,"%d verboselog %s\r\n",p->normalcode,
isverboselog() ?"ON":"OFF");
fflush(argv->out);
verboselog("%d verboselog %s\r\n",p->normalcode,
isverboselog()?"ON":"OFF");
}
static int CMDmidcheck(client)
ClientType *client;
{
argv_t *argv = &client->Argv;
buffer_t *in = &client->in;
daemoncmd_t *p = argv->dc;
if (client->mode == 0) {
if (argv->argc > 1) {
if (strcasecmp(argv->argv[1],"off")==0) {
client->midcheck = 0;
} else {
client->midcheck = 1;
}
}
}
fprintf(argv->out,"%d mid check %s\r\n",p->normalcode,
client->midcheck == 1?"ON":"OFF");
fflush(argv->out);
verboselog("%d mid check %s\r\n",p->normalcode,
client->midcheck == 1?"ON":"OFF");
}
static int CMDgrephist(client)
ClientType *client;
{
argv_t *argv = &client->Argv;
buffer_t *in = &client->in;
daemoncmd_t *p = argv->dc;
if (client->mode == 0) {
if (argv->argc > 1) {
char *ptr;
ptr = (char*)DBfetch(argv->argv[1]);
if (ptr != NULL) {
fprintf(argv->out,"%d %s OK\r\n", p->normalcode, ptr);
fflush(argv->out);
verboselog("Addhist Put: %d %s OK\n", p->normalcode, ptr);
return 0;
} else {
fprintf(argv->out,"%d %s not found\r\n", p->errorcode,argv->argv[1]);
fflush(argv->out);
verboselog("Addhist Put: %d %s not found\n", p->errorcode, argv->argv[1]);
return 1;
}
}
}
fprintf(argv->out,"%d grephist error\r\n", p->errorcode);
fflush(argv->out);
verboselog("Addhist Put: %d grephist error\n", p->errorcode);
return 1;
}
static int CMDaddhist(client)
ClientType *client;
{
argv_t *argv = &client->Argv;
buffer_t *in = &client->in;
daemoncmd_t *p = argv->dc;
/*
if (strcmp(client->username,"localuser") != 0 ||
strcmp(client->hostname,"localhost") != 0) {
fprintf(argv->out,"%d add hist access denied\r\n", p->errorcode);
fflush(argv->out);
verboselog("Addhist Put: %d add hist access denied\n", p->errorcode);
return 1;
}
*/
if (client->mode == 0) {
if (argv->argc > 2) {
char *ptr;
ptr = (char*)DBfetch(argv->argv[1]);
if (ptr == NULL) {
if (storeDB(argv->argv[1], argv->argv[2]) < 0) {
fprintf(argv->out,"%d add hist store DB error\r\n", p->errorcode);
fflush(argv->out);
verboselog("Addhist Put: %d add hist store DB error\n", p->errorcode);
return 1;
} else {
fprintf(argv->out,"%d add hist OK\r\n", p->normalcode);
fflush(argv->out);
verboselog("Addhist Put: %d add hist OK\n", p->normalcode);
return 0;
}
} else {
fprintf(argv->out,"%d add hist duplicate error\r\n", p->errorcode);
fflush(argv->out);
verboselog("Addhist Put: %d add hist duplicate error\n", p->errorcode);
return 1;
}
}
}
fprintf(argv->out,"%d add hist error\r\n", p->errorcode);
fflush(argv->out);
verboselog("Addhist Put: %d add hist error\n", p->errorcode);
return 1;
}
static int CMDstat(client)
ClientType *client;
{
argv_t *argv = &client->Argv;
char *ptr, *frontptr;
buffer_t *in = &client->in;
daemoncmd_t *p;
if (client->mode == 0) {
client->statcount++;
if (argv->argc > 1) {
if (argv->argv[1][0] != '<') {
fprintf(argv->out,"430 No such article\r\n");
fflush(argv->out);
verboselog("Stat Put: 430 No such article\n");
client->statfail++;
return 0;
}
ptr = (char*)DBfetch(argv->argv[1]);
if (ptr != NULL) {
fprintf(argv->out,"223 0 status %s\r\n",argv->argv[1]);
fflush(argv->out);
client->mode = 0;
verboselog("Stat Put: 223 0 status %s\n",argv->argv[1]);
return 1;
} else {
fprintf(argv->out,"430 No such article\r\n");
fflush(argv->out);
verboselog("Stat Put: 430 No such article\n");
client->mode = 0;
client->statfail++;
}
}
}
}
#ifndef DBZSERVER
static int CMDihave(client)
ClientType *client;
{
argv_t *argv = &client->Argv;
char *ptr=NULL, *frontptr;
buffer_t *in = &client->in;
daemoncmd_t *p;
if (client->mode == 0) {
client->ihavecount++;
if (argv->argc > 1) {
if (argv->argv[1][0] != '<') {
fprintf(argv->out,"435 Bad Message-ID\r\n");
fflush(argv->out);
verboselog("Ihave Put: 435 Bad Message-ID\n");
client->ihavefail++;
return 0;
}
if (client->midcheck == 1)
ptr = (char*)DBfetch(argv->argv[1]);
if (ptr != NULL && client->midcheck == 1) {
fprintf(argv->out,"435 Duplicate\r\n");
fflush(argv->out);
client->mode = 0;
verboselog("Ihave Put: 435 Duplicate\n");
client->ihaveduplicate++;
client->ihavefail++;
return 1;
} else {
fprintf(argv->out,"335\r\n");
fflush(argv->out);
client->mode = 1;
verboselog("Ihave Put: 335\n");
}
}
} else {
client->mode = 0;
readlines(client);
if (HEADER[SUBJECT_H] && HEADER[FROM_H] && HEADER[DATE_H] &&
HEADER[MID_H] && HEADER[NEWSGROUPS_H] ) {
char *path1, *path2;
int rel ;
rel = 0;
path1 = (char*)mymalloc(strlen(HEADER[PATH_H]) + 3);
path2 = (char*)mymalloc(strlen(MYBBSID) + 3);
sprintf(path1, "!%s!",HEADER[PATH_H]);
sprintf(path2, "!%s!",MYBBSID);
if (HEADER[CONTROL_H]) {
bbslog( "Control: %s\n", HEADER[CONTROL_H] );
if (strncasecmp(HEADER[CONTROL_H],"cancel ",7)==0) {
rel = cancel_article_front(HEADER[CONTROL_H]+7);
} else {
rel = receive_control();
}
} else if ( (char*)strstr(path1, path2) != NULL) {
bbslog( ":Warn: Loop back article: %s!%s\n",MYBBSID,HEADER[PATH_H] );
} else {
rel = receive_article();
}
free(path1);
free(path2);
if (rel == -1) {
fprintf(argv->out,"400 server side failed\r\n");
fflush(argv->out);
verboselog("Ihave Put: 400\n");
clearfdset(client->fd);
fclose(client->Argv.in);
fclose(client->Argv.out);
close(client->fd);
client->fd = -1;
client->mode = 0;
client->ihavefail++;
return;
} else {
fprintf(argv->out,"235\r\n");
verboselog("Ihave Put: 235\n");
}
fflush(argv->out);
} else if (!HEADER[PATH_H]) {
fprintf(argv->out,"437 No Path in \"ihave %s\" header\r\n",HEADER[MID_H]);
fflush(argv->out);
verboselog("Put: 437 No Path in \"ihave %s\" header\n",HEADER[MID_H]);
client->ihavefail++;
} else {
fprintf(argv->out,"437 No colon-space in \"ihave %s\" header\r\n",HEADER[MID_H]);
fflush(argv->out);
verboselog("Ihave Put: 437 No colon-space in \"ihave %s\" header\n",HEADER[MID_H]);
client->ihavefail++;
}
#ifdef DEBUG
printf("subject is %s\n",HEADER[SUBJECT_H]);
printf("from is %s\n",HEADER[FROM_H]);
printf("Date is %s\n",HEADER[DATE_H]);
printf("Newsgroups is %s\n",HEADER[NEWSGROUPS_H]);
printf("mid is %s\n",HEADER[MID_H]);
printf("path is %s\n",HEADER[PATH_H]);
#endif
}
fflush(argv->out);
return 0;
}
#endif
static int CMDhelp(client)
ClientType *client;
{
argv_t *argv = &client->Argv;
daemoncmd_t *p;
if (argv->argc>=1) {
fprintf(argv->out,"%d Available Commands\r\n",argv->dc->normalcode);
for (p=cmds;p->name !=NULL;p++) {
fprintf(argv->out," %s\r\n",p->usage);
}
fprintf(argv->out,"Report problems to %s\r\n",ADMINUSER);
}
fputs(".\r\n",argv->out);
fflush(argv->out);
client->mode = 0;
return 0;
}
static int CMDquit(client)
ClientType *client;
{
argv_t *argv = &client->Argv;
fprintf(argv->out,"205 quit\r\n");
fflush(argv->out);
verboselog("Quit Put: 205 quit\n");
clearfdset(client->fd);
fclose(client->Argv.in);
fclose(client->Argv.out);
close(client->fd);
client->fd = -1;
client->mode = 0;
channeldestroy(client);
/*exit(0);*/
}