diff options
author | piaip <piaip@63ad8ddf-47c3-0310-b6dd-a9e9d9715204> | 2008-03-20 19:33:49 +0800 |
---|---|---|
committer | piaip <piaip@63ad8ddf-47c3-0310-b6dd-a9e9d9715204> | 2008-03-20 19:33:49 +0800 |
commit | 6c7b18b32d87c2a835f7e5c48faac4a8ad44668b (patch) | |
tree | e88e1b2b1007f4ddcd348a4a1bf1d13c515c4564 /daemon/innbbsd/innbbsd.c | |
parent | f59699c22c130373cda3cc4cb6fab5bae510bd5a (diff) | |
download | pttbbs-piaip.newlayout.tar pttbbs-piaip.newlayout.tar.gz pttbbs-piaip.newlayout.tar.bz2 pttbbs-piaip.newlayout.tar.lz pttbbs-piaip.newlayout.tar.xz pttbbs-piaip.newlayout.tar.zst pttbbs-piaip.newlayout.zip |
- (internal/exp) first draft of new layoutpiaip.newlayout
git-svn-id: http://opensvn.csie.org/pttbbs/branches/piaip.newlayout@4013 63ad8ddf-47c3-0310-b6dd-a9e9d9715204
Diffstat (limited to 'daemon/innbbsd/innbbsd.c')
-rw-r--r-- | daemon/innbbsd/innbbsd.c | 794 |
1 files changed, 794 insertions, 0 deletions
diff --git a/daemon/innbbsd/innbbsd.c b/daemon/innbbsd/innbbsd.c new file mode 100644 index 00000000..f71ab30c --- /dev/null +++ b/daemon/innbbsd/innbbsd.c @@ -0,0 +1,794 @@ +#include "innbbsconf.h" +#include "daemon.h" +#include "innbbsd.h" +#include <dirent.h> +#include "bbslib.h" +#include "inntobbs.h" +#include "nntp.h" +#include "externs.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} +}; + +void +installinnbbsd(void) +{ + installdaemon(cmds, 100, NULL); +} + +#ifdef OLDLIBINBBSINND +void +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; +} + +int +islocalconnect(client) + ClientType *client; +{ + if (strcmp(client->username, "localuser") != 0 || + strcmp(client->hostname, "localhost") != 0) + return 0; + return 1; +} + +static int shutdownflag = 0; +void +INNBBSDhalt() +{ + shutdownflag = 1; +} + +int +INNBBSDshutdown(void) +{ + return shutdownflag; +} + +static int +CMDshutdown(client) + ClientType *client; +{ + argv_t *argv = &client->Argv; + 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; + 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; + 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; + 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; + 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; + 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; + 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; + 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; + 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; + 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; + 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; + 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; + 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; + str_decode_M3(HEADER[SUBJECT_H]); + str_decode_M3(HEADER[FROM_H]); + str_decode_M3(HEADER[DATE_H]); + str_decode_M3(HEADER[MID_H]); + str_decode_M3(HEADER[NEWSGROUPS_H]); + 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 if (strstr(SUBJECT, "@@") && strstr(BODY, "NCM") && strstr(BODY, "PGP")) { + rel = receive_nocem(); + } 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); */ +} |