📄 nntpcli.c
字号:
/*
* Client routines for Network News Tranfer Protocol ala RFC977
*
*
*/
#include <stdio.h>
#include <sys/types.h>
#include <time.h>
#include <sys/timeb.h>
#include <ctype.h>
#include <string.h> /* for strchr() */
#ifdef __TURBOC__
#include <dir.h>
#endif
#include "global.h"
#include "timer.h"
#include "cmdparse.h"
#include "commands.h"
#include "socket.h"
#include "usock.h"
#include "netuser.h"
#include "proc.h"
#include "smtp.h"
#include "files.h"
#define NNTPMAXLEN 512
struct nntpservers {
struct timer nntpcli_t;
char *name;
char *groups;
int lowtime, hightime; /* for connect window */
struct nntpservers *next;
};
#define MAXGROUPDIRS 10
static struct grouploc {
char *prefix; /* e.g. comp, rec, net, talk, alt ... */
char *directory; /* directory where these groups should be */
} groupdirs[MAXGROUPDIRS] = { NULL, NULL };
struct nntpservers *Nntpservers = NULL;
static char *Nntpgroups = NULL;
static unsigned short nntptrace = 1;
static char *validchars = "abcdefghijklmnopqrstuvwxyz0123456789-_";
static void nntptick(void *tp);
static void nntp_job(int i1,void *tp,void *v1);
static int gettxt(FILE *network,FILE *fp);
static int getreply(FILE *network);
static int getarticle(FILE *network,char *msgid);
static int dogroups(int argc,char *argv[],void *p);
static int doadds(int argc,char *argv[],void *p);
static int dodrops(int argc,char *argv[],void *p);
static int dokicks(int argc,char *argv[],void *p);
static int dolists(int argc,char *argv[],void *p);
static int donntrace(int argc,char *argv[],void *p);
static int dondir(int argc,char *argv[],void *p);
/* Tracing levels:
0 - no tracing
1 - serious errors reported
2 - transient errors reported
3 - session progress reported
4 - actual received articles displayed
*/
static struct cmds Nntpcmds[] = {
"addserver", doadds, 0, 3,
"nntp addserver <nntpserver> <interval>",
"directory", dondir, 0, 0, NULL,
"dropserver", dodrops, 0, 2,
"nntp dropserver <nntpserver>",
"groups", dogroups, 0, 0, NULL,
"kick", dokicks, 0, 2,
"nntp kick <nntpserver>",
"listservers", dolists, 0, 0, NULL,
"trace", donntrace, 0, 0, NULL,
NULL,
};
int
donntp(argc,argv,p)
int argc;
char *argv[];
void *p;
{
return subcmd(Nntpcmds,argc,argv,p);
}
static int
doadds(argc,argv,p)
int argc;
char *argv[];
void *p;
{
struct nntpservers *np;
for(np = Nntpservers; np != NULL; np = np->next)
if(stricmp(np->name,argv[1]) == 0)
break;
if (np == NULL) {
np = (struct nntpservers *) callocw(1,sizeof(struct nntpservers));
np->name = strdup(argv[1]);
np->next = Nntpservers;
Nntpservers = np;
np->groups = NULL;
np->lowtime = np->hightime = -1;
np->nntpcli_t.func = nntptick; /* what to call on timeout */
np->nntpcli_t.arg = (void *)np;
}
if (argc > 3) {
int i;
if (np->groups == NULL) {
np->groups = mallocw(NNTPMAXLEN);
*np->groups = '\0';
}
for (i = 3; i < argc; ++i) {
if (isdigit(*argv[i])) {
int lh, ll, hh, hl;
sscanf(argv[i], "%d:%d-%d:%d", &lh, &ll, &hh, &hl);
np->lowtime = lh * 100 + ll;
np->hightime = hh * 100 + hl;
} else if ((strlen(np->groups)+strlen(argv[i])+2) >= NNTPMAXLEN)
printf("Group list too long! Group '%s' ignored!\n", argv[i]);
else { /* it's a group, and it fits... add it to list */
if (*np->groups != '\0')
strcat(np->groups, ",");
strcat(np->groups, argv[i]);
}
}
if (*np->groups == '\0') { /* No groups specified? */
free(np->groups);
np->groups = NULL;
}
}
/* set timer duration */
set_timer(&np->nntpcli_t,atol(argv[2])*1000L);
start_timer(&np->nntpcli_t); /* and fire it up */
return 0;
}
static int
dodrops(argc,argv,p)
int argc;
char *argv[];
void *p;
{
struct nntpservers *np, *npprev = NULL;
for(np = Nntpservers; np != NULL; npprev = np, np = np->next)
if(stricmp(np->name,argv[1]) == 0) {
stop_timer(&np->nntpcli_t);
free(np->name);
if (np->groups)
free(np->groups);
if(npprev != NULL)
npprev->next = np->next;
else
Nntpservers = np->next;
free(np);
return 0;
}
printf("No such server enabled.\n");
return 0;
}
static int
dolists(argc,argv,p)
int argc;
char *argv[];
void *p;
{
struct nntpservers *np;
for(np = Nntpservers; np != NULL; np = np->next) {
char tbuf[80];
if (np->lowtime != -1 && np->hightime != -1)
sprintf(tbuf, " -- %02d:%02d-%02d:%02d", np->lowtime/100, np->lowtime%100, np->hightime/100, np->hightime%100);
else
tbuf[0] = '\0';
printf("%-32s (%lu/%lu%s) %s\n", np->name,
read_timer(&np->nntpcli_t) /1000L,
dur_timer(&np->nntpcli_t) /1000L,
tbuf, np->groups ? np->groups : "");
}
return 0;
}
static int donntrace(argc, argv, p)
int argc;
char *argv[];
void *p;
{
return setshort(&nntptrace,"NNTP tracing",argc,argv);
}
static char *News_spool = NULL;
static int np_all = 0; /* non-zero if Newsdir is a malloc'ed space */
static int dondir(argc, argv, p)
int argc;
char *argv[];
void *p;
{
if (argc < 2) {
int i;
printf("spool: %s\n", News_spool ? News_spool : Mailspool);
printf("control: %s\n", Newsdir);
for (i = 0; i < MAXGROUPDIRS; ++i)
if (groupdirs[i].prefix)
printf("%-10.10s %s\n", groupdirs[i].prefix, groupdirs[i].directory);
} else {
char *p;
if ((p = strchr(argv[1], '=')) != NULL) { /* set a groupdir */
int i;
*p++ = '\0';
for (i = 0; i < MAXGROUPDIRS; ++i)
if (groupdirs[i].prefix)
if (!strnicmp(groupdirs[i].prefix, argv[1], strlen(argv[1]))) {
if (groupdirs[i].directory) {
free(groupdirs[i].directory);
groupdirs[i].directory = NULL;
}
if (*p == '\0') {
free(groupdirs[i].prefix);
groupdirs[i].prefix = NULL;
} else
groupdirs[i].directory = strdup(p);
return 0;
}
if (*p == '\0') /* trashing a group that's not there */
return 0;
for (i = 0; i < MAXGROUPDIRS; ++i){
if (groupdirs[i].prefix == NULL) {
groupdirs[i].prefix = strdup(argv[1]);
if (groupdirs[i].directory) {
free(groupdirs[i].directory);
groupdirs[i].directory = NULL;
}
groupdirs[i].directory = strdup(p);
return 0;
}
}
printf("Directory table full\n");
}
else { /* no '=', so just set default */
if (News_spool)
free(News_spool);
News_spool = strdup(argv[1]);
}
if (argc > 2) { /* they specified a newsdir as well */
if (np_all)
free(Newsdir);
Newsdir = strdup(argv[2]);
np_all = 1;
}
}
return 0;
}
static int
dokicks(argc,argv,p)
int argc;
char *argv[];
void *p;
{
struct nntpservers *np;
for(np = Nntpservers; np != NULL; np = np->next)
if(stricmp(np->name,argv[1]) == 0) {
/* If the timer is not running, the timeout function has
* already been called and we don't want to call it again.
*/
if(run_timer(&np->nntpcli_t)) {
stop_timer(&np->nntpcli_t);
nntptick((void *)np);
}
return 0;
}
printf("No such server enabled.\n");
return 0;
}
static int
dogroups(argc,argv,p)
int argc;
char *argv[];
void *p;
{
int i;
if(argc < 2) {
if(Nntpgroups == NULL || (Nntpgroups != NULL && strcmp(Nntpgroups,"*") == 0))
printf("All groups are currently enabled.\n");
else
printf("Currently enabled newsgroups:\n%s\n",Nntpgroups);
return 0;
}
if(Nntpgroups == NULL)
Nntpgroups = mallocw(NNTPMAXLEN);
*Nntpgroups = '\0';
for(i=1; i < argc; ++i) {
if(i > 1)
strcat(Nntpgroups,",");
strcat(Nntpgroups,argv[i]);
}
return 0;
}
/* This is the routine that gets called every so often to connect to
* NNTP servers.
*/
static void
nntptick(tp)
void *tp;
{
newproc("NNTP client", 3072, nntp_job, 0, tp, NULL,0);
}
static void
nntp_job(i1,tp,v1)
int i1;
void *tp, *v1;
{
FILE *fp, *tmpf;
int s = -1, i;
FILE *network;
/* long pos; */
struct tm *ltm;
time_t t;
int now;
struct nntpservers *np = (struct nntpservers *) tp;
struct sockaddr_in fsocket;
char tbuf[NNTPMAXLEN], buf[NNTPMAXLEN], *cp, *lastdate = NULL;
if (nntptrace >= 3)
printf("NNTP daemon entered, target = %s\n",np->name);
if(availmem() != 0){
if (nntptrace >= 2)
printf("NNTP daemon quit -- low memory\n");
/* Memory is tight, don't do anything */
start_timer(&np->nntpcli_t);
return;
}
time(&t); /* more portable than gettime() */
ltm = localtime(&t);
now = ltm->tm_hour * 100 + ltm->tm_min;
if (np->lowtime < np->hightime) { /* doesn't cross midnight */
if (now < np->lowtime || now >= np->hightime) {
if (nntptrace >= 3)
printf("NNTP window to '%s' not open\n", np->name);
start_timer(&np->nntpcli_t);
return;
}
} else {
if (now < np->lowtime && now >= np->hightime) {
if (nntptrace >= 3)
printf("NNTP window to '%s' not open\n", np->name);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -