⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cc.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 3 页
字号:
/*  $Revision: 1.41 $****  Routines for the control channel.  Create a Unix-domain datagram socket**  that processes on the local server send messages to.  The control**  channel is used only by ctlinnd to tell the server to perform**  special functions.  We use datagrams so that we don't need to do an**  accept() and tie up another descriptor.  Recvfrom seems to be broken on**  several systems, so the client passes in the socket name.****  This module completely rips away all pretense of software layering.*/#include "innd.h"#include "inndcomm.h"#if	defined(DO_HAVE_UNIX_DOMAIN)#include <sys/un.h>#endif	/* defined(DO_HAVE_UNIX_DOMAIN) *//***  An entry in the dispatch table.  The name, and implementing function,**  of every command we support.*/typedef struct _CCDISPATCH {    char	Name;    int		argc;    STRING	(*Function)();} CCDISPATCH;STATIC STRING	CCaddhist();STATIC STRING	CCallow();STATIC STRING	CCbegin();STATIC STRING	CCchgroup();STATIC STRING	CCdrop();STATIC STRING	CCflush();STATIC STRING	CCflushlogs();STATIC STRING	CCgo();STATIC STRING	CChangup();STATIC STRING	CCreserve();STATIC STRING	CCmode();STATIC STRING	CCname();STATIC STRING	CCnewgroup();STATIC STRING	CCparam();STATIC STRING	CCpause();STATIC STRING	CCreaders();STATIC STRING	CCrefile();STATIC STRING	CCreject();STATIC STRING	CCreload();STATIC STRING	CCrenumber();STATIC STRING	CCrmgroup();STATIC STRING	CCsend();STATIC STRING	CCshutdown();STATIC STRING	CCsignal();STATIC STRING	CCthrottle();STATIC STRING	CCtrace();STATIC STRING	CCxabort();STATIC STRING	CCxexec();STATIC char		CCpath[] = _PATH_NEWSCONTROL;STATIC char		**CCargv;STATIC char		CCnosite[] = "1 No such site";STATIC char		CCwrongtype[] = "1 Wrong site type";STATIC char		CCnogroup[] = "1 No such group";STATIC char		CCnochannel[] = "1 No such channel";STATIC char		CCnoreason[] = "1 Empty reason";STATIC char		CCnotrunning[] = "1 Must be running";STATIC BUFFER		CCreply;STATIC CHANNEL		*CCchan;STATIC int		CCwriter;STATIC CCDISPATCH	CCcommands[] = {    {	SC_ADDHIST,	5, CCaddhist	},    {	SC_ALLOW,	1, CCallow	},    {	SC_BEGIN,	1, CCbegin	},    {	SC_CANCEL,	1, CCcancel	},    {	SC_CHANGEGROUP,	2, CCchgroup	},    {	SC_CHECKFILE,	0, CCcheckfile	},    {	SC_DROP,	1, CCdrop	},    {	SC_FLUSH,	1, CCflush	},    {	SC_FLUSHLOGS,	0, CCflushlogs	},    {	SC_GO,		1, CCgo		},    {	SC_HANGUP,	1, CChangup	},    {	SC_MODE,	0, CCmode	},    {	SC_NAME,	1, CCname	},    {	SC_NEWGROUP,	3, CCnewgroup	},    {	SC_PARAM,	2, CCparam	},    {	SC_PAUSE,	1, CCpause	},    {	SC_READERS,	2, CCreaders	},    {	SC_REFILE,	2, CCrefile	},    {	SC_REJECT,	1, CCreject	},    {	SC_RENUMBER,	1, CCrenumber	},    {	SC_RELOAD,	2, CCreload	},    {	SC_RESERVE,	1, CCreserve	},    {	SC_RMGROUP,	1, CCrmgroup	},    {	SC_SEND,	2, CCsend	},    {	SC_SHUTDOWN,	1, CCshutdown	},    {	SC_SIGNAL,	2, CCsignal	},    {	SC_THROTTLE,	1, CCthrottle	},    {	SC_TRACE,	2, CCtrace	},    {	SC_XABORT,	1, CCxabort	},    {	SC_XEXEC,	1, CCxexec	}};voidCCcopyargv(av)    char		*av[];{    register char	**v;    register int	i;    /* Get the vector size. */    for (i = 0; av[i]; i++)	continue;    /* Get the vector, copy each element. */    for (v = CCargv = NEW(char*, i + 1); *av; av++)	*v++ = COPY(*av);    *v = NULL;}/***  Add <> around Message-ID if needed.*/STATIC STRINGCCgetid(p, store)    char		*p;    char		**store;{    static char		NULLMESGID[] = "1 Empty Message-ID";    static BUFFER	Save;    int			i;    if (*p == '\0')	return NULLMESGID;    if (*p == '<') {	if (p[1] == '\0' || p[1] == '>')	    return NULLMESGID;	*store = p;	return NULL;    }    /* Make sure the Message-ID buffer has room. */    i = 1 + strlen(p) + 1 + 1;    if (Save.Data == NULL) {	Save.Size = i;	Save.Data = NEW(char, Save.Size);    }    else if (Save.Size < i) {	Save.Size = i;	RENEW(Save.Data, char, Save.Size);    }    *store = Save.Data;    (void)sprintf(*store, "<%s>", p);    return NULL;}/***  Abort and dump core.*/STATIC STRINGCCxabort(av)    char		*av[];{    syslog(L_FATAL, "%s abort %s", LogName, av[0]);    abort();    syslog(L_FATAL, "%s cant abort %m", LogName);    CleanupAndExit(1, av[0]);    /* NOTREACHED */}/***  Do the work needed to add a history entry.*/STATIC STRINGCCaddhist(av)    char		*av[];{    static char		DIGITS[] = "0123456789";    ARTDATA		Data;    STRING		p;    BOOL		ok;    /* Check the fields. */    if ((p = CCgetid(av[0], &Data.MessageID)) != NULL)	return p;    if (HIShavearticle(Data.MessageID))	return "1 Duplicate";    if (strspn(av[1], DIGITS) != strlen(av[1]))	return "1 Bad arrival date";    Data.Arrived = atol(av[1]);    if (strspn(av[2], DIGITS) != strlen(av[2]))	return "1 Bad expiration date";    Data.Expires = atol(av[2]);    if (strspn(av[3], DIGITS) != strlen(av[3]))	return "1 Bad posted date";    Data.Posted = atol(av[3]);    if (Mode == OMrunning)	ok = HISwrite(&Data, av[4]);    else {	/* Possible race condition, but documented in ctlinnd manpage. */	HISsetup();	ok = HISwrite(&Data, av[4]);	HISclose();    }    return ok ? NULL : "1 Write failed";}/***  Do the work to allow foreign connectiosn.*/STATIC STRINGCCallow(av)    char	*av[];{    char	*p;    if (RejectReason == NULL)	return "1 Already allowed";    p = av[0];    if (*p && !EQ(p, RejectReason))	return "1 Wrong reason";    DISPOSE(RejectReason);    RejectReason = NULL;    return NULL;}/***  Do the work needed to start feeding a (new) site.*/STATIC STRINGCCbegin(av)    char		*av[];{    SITE		*sp;    register int	i;    register int	length;    register STRING	p;    register char	**strings;    register NEWSGROUP	*ngp;    STRING		error;    char		*subbed;    /* If site already exists, drop it. */    if (SITEfind(av[0]) != NULL && (p = CCdrop(av)) != NULL)	return p;    /* Find the named site. */    length = strlen(av[0]);    for (strings = SITEreadfile(TRUE), i = 0; (p = strings[i]) != NULL; i++)	if ((p[length] == NF_FIELD_SEP || p[length] == NF_SUBFIELD_SEP)	 && caseEQn(p, av[0], length)) {	    p = COPY(p);	    break;	}    if (p == NULL)	return CCnosite;    if (p[0] == 'M' && p[1] == 'E' && p[2] == NF_FIELD_SEP)	sp = &ME;    else {	/* Get space for the new site entry, and space for it in all	 * the groups. */	for (i = nSites, sp = Sites; --i >= 0; sp++)	    if (sp->Name == NULL)		break;	if (i < 0) {	    nSites++;	    RENEW(Sites, SITE, nSites);	    sp = &Sites[nSites - 1];	    for (i = nGroups, ngp = Groups; --i >= 0; ngp++)		RENEW(ngp->Sites, int, nSites);	}	SITElinkall();    }    /* Parse. */    subbed = NEW(char, nGroups);    error = SITEparseone(p, sp, subbed);    DISPOSE(subbed);    if (error != NULL) {	DISPOSE(p);	syslog(L_ERROR, "%s bad_newsfeeds %s", av[0], error);	return "1 Parse error";    }    if (sp != &ME && (!SITEsetup(sp) || !SITEfunnelpatch()))	return "1 Startup error";    SITEforward(sp, "begin");    return NULL;}/***  Common code to change a group's flags.*/STATIC STRINGCCdochange(ngp, Rest)    register NEWSGROUP	*ngp;    char		*Rest;{    int			length;    char		*p;    if (ngp->Rest[0] == Rest[0]) {	length = strlen(Rest);	if (ngp->Rest[length] == '\n' && EQn(ngp->Rest, Rest, length))	    return "0 Group status unchanged";    }    if (Mode != OMrunning)	return CCnotrunning;    p = COPY(ngp->Name);    if (!ICDchangegroup(ngp, Rest)) {	syslog(L_NOTICE, "%s cant change_group %s to %s", LogName, p, Rest);	DISPOSE(p);	return "1 Change failed (probably can't write active?)";    }    syslog(L_NOTICE, "%s change_group %s to %s", LogName, p, Rest);    DISPOSE(p);    return NULL;}/***  Change the mode of a newsgroup.*/STATIC STRINGCCchgroup(av)    char	*av[];{    NEWSGROUP	*ngp;    char	*Rest;    if ((ngp = NGfind(av[0])) == NULL)	return CCnogroup;    Rest = av[1];    if (Rest[0] != NF_FLAG_ALIAS) {	Rest[1] = '\0';	if (CTYPE(isupper, Rest[0]))	    Rest[0] = tolower(Rest[0]);    }    return CCdochange(ngp, Rest);}/***  Cancel a message.*/STRINGCCcancel(av)    char	*av[];{    ARTDATA	Data;    STRING	p;    Data.Posted = Now.time;    Data.Expires = 0;    Data.Feedsite = "?";    if ((p = CCgetid(av[0], &Data.MessageID)) != NULL)	return p;    if (Mode == OMrunning)	ARTcancel(&Data, Data.MessageID, TRUE);    else {	/* Possible race condition, but documented in ctlinnd manpage. */	HISsetup();	ARTcancel(&Data, Data.MessageID, TRUE);	HISclose();    }#if	defined(DO_LOG_CANCEL_COMMANDS)    syslog(L_NOTICE, "%s cancelled %s", LogName, Data.MessageID);#endif	/* defined(DO_LOG_CANCEL_COMMANDS) */    return NULL;}/***  Syntax-check the newsfeeds file.*//* ARGSUSED */STRINGCCcheckfile(av)    char		*av[];{    register char	**strings;    register char	*p;    register int	i;    register int	errors;    STRING		error;    SITE		fake;    /* Parse all site entries. */    strings = SITEreadfile(FALSE);    fake.Buffer.Size = 0;    fake.Buffer.Data = NULL;    for (errors = 0, i = 0; (p = strings[i]) != NULL; i++) {	if ((error = SITEparseone(p, &fake, (char *)NULL)) != NULL) {	    syslog(L_ERROR, "%s bad_newsfeeds %s", MaxLength(p, p), error);	    errors++;	}	SITEfree(&fake);    }    DISPOSE(strings);    if (errors == 0)	return NULL;    (void)sprintf(CCreply.Data, "1 Found %d errors -- see syslog", errors);    return CCreply.Data;}/***  Drop a site.*/STATIC STRINGCCdrop(av)    char		*av[];{    SITE		*sp;    register NEWSGROUP	*ngp;    register int	*ip;    register int	idx;    register int	i;    register int	j;    if ((sp = SITEfind(av[0])) == NULL)	return CCnosite;    SITEdrop(sp);    /* Loop over all groups, and if the site is in a group, clobber it. */    for (idx = sp - Sites, i = nGroups, ngp = Groups; --i >= 0; ngp++)	for (j = ngp->nSites, ip = ngp->Sites; --j >= 0; ip++)	    if (*ip == idx)		*ip = NOSITE;	return NULL;}/***  Flush all sites or one site.*/STATIC STRINGCCflush(av)    char		*av[];{    register SITE	*sp;    register int	i;    register char	*p;    p = av[0];    if (*p == '\0') {	ICDwrite();	for (sp = Sites, i = nSites; --i >= 0; sp++)	    SITEflush(sp, TRUE);	syslog(L_NOTICE, "%s flush_all", LogName);    }    else  {	if ((sp = SITEfind(p)) == NULL)	    return CCnosite;	syslog(L_NOTICE, "%s flush", sp->Name);	SITEflush(sp, TRUE);    }    return NULL;}/***  Flush the log files.*//* ARGSUSED0 */STATIC STRINGCCflushlogs(av)    char	*av[];{    if (Debug)	return "1 In debug mode";    ICDwrite();    ReopenLog(Log);    ReopenLog(Errlog);    return NULL;}/***  Leave paused or throttled mode.*/STATIC STRINGCCgo(av)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -