summaryrefslogtreecommitdiffstats
path: root/innbbsd/innbbsd.c
diff options
context:
space:
mode:
Diffstat (limited to 'innbbsd/innbbsd.c')
-rw-r--r--innbbsd/innbbsd.c775
1 files changed, 775 insertions, 0 deletions
diff --git a/innbbsd/innbbsd.c b/innbbsd/innbbsd.c
new file mode 100644
index 00000000..f35c1cfb
--- /dev/null
+++ b/innbbsd/innbbsd.c
@@ -0,0 +1,775 @@
+#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);*/
+}