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

📄 innd.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 2 页
字号:
/*  $Revision: 1.39 $****  Variable definitions, miscellany, and main().*/#define DEFINE_DATA#include "innd.h"#include <signal.h>#include <sys/ioctl.h>#include <sys/uio.h>#if	NOFILE_LIMIT > 0#include <sys/resource.h>#endif	/* NOFILE_LIMIT > 0 */#if	defined(DO_FAST_RESOLV)#include <arpa/nameser.h>#include <resolv.h>#endif	/* defined(DO_FAST_RESOLV) */#if	defined(HAVE_SETBUFFER)#define SETBUFFER(F, buff, size)	setbuffer((F), (buff), (size))STATIC int	LogBufferSize = 4096;#else#define SETBUFFER(F, buff, size)	setbuf((F), (buff))STATIC int	LogBufferSize = BUFSIZ;#endif	/* defined(HAVE_SETBUFFER) */BOOL		AmRoot = TRUE;BOOL		BufferedLogs = TRUE;BOOL		NNRPTracing = FALSE;BOOL		Tracing = FALSE;char		LogName[] = "ME";char		SPOOL[] = _PATH_SPOOL;int		ErrorCount = IO_ERROR_COUNT;int		MaxIncoming = DEFAULT_CONNECTIONS;int		SPOOLlen = STRLEN(SPOOL);long		LargestArticle = MAX_ART_SIZE;OPERATINGMODE	Mode = OMrunning;time_t		Cutoff = DEFAULT_CUTOFF * 24 * 60 * 60;#if	defined(__CENTERLINE__)BOOL		Debug = TRUE;#elseBOOL		Debug = FALSE;#endif	/* defined(__CENTERLINE__) */#if	defined(lint) || defined(__CENTERLINE__)int		KeepLintQuiet = 0;#endif	/* defined(lint) || defined(__CENTERLINE__) */STATIC char	*ErrlogBuffer;STATIC char	*LogBuffer;STATIC char	ERRLOG[] = _PATH_ERRLOG;STATIC char	INNDDIR[] = _PATH_INNDDIR;STATIC char	LOG[] = _PATH_LOGFILE;STATIC char	PID[] = _PATH_SERVERPID;STATIC UID_T	NewsUID;STATIC GID_T	NewsGID;/***  Sprintf a long into a buffer with enough leading zero's so that it**  takes up width characters.  Don't add trailing NUL.  Return TRUE**  if it fit.  Used for updating high-water marks in the active file**  in-place.*/BOOLFormatLong(p, value, width)    register char	*p;    register long	value;    register int	width;{    for (p += width - 1; width-- > 0; ) {	*p-- = (int)(value % 10) + '0';	value /= 10;    }    return value == 0;}/***  Glue a string, a char, and a string together.  Useful for making**  filenames.*/voidFileGlue(p, n1, c, n2)    register char	*p;    register char	*n1;    char		c;    register char	*n2;{    p += strlen(strcpy(p, n1));    *p++ = c;    (void)strcpy(p, n2);}/***  Turn any \r or \n in text into spaces.  Used to splice back multi-line**  headers into a single line.*/STATIC char *Join(text)    register char	*text;{    register char	*p;    for (p = text; *p; p++)	if (*p == '\n' || *p == '\r')	    *p = ' ';    return text;}/***  Return a short name that won't overrun our bufer or syslog's buffer.**  q should either be p, or point into p where the "interesting" part is.*/char *MaxLength(p, q)    char		*p;    char		*q;{    static char		buff[80];    register int	i;    /* Already short enough? */    i = strlen(p);    if (i < sizeof buff - 1)	return Join(p);    /* Simple case of just want the begining? */    if (q - p < sizeof buff - 4) {	(void)strncpy(buff, p, sizeof buff - 4);	(void)strcpy(&buff[sizeof buff - 4], "...");    }    /* Is getting last 10 characters good enough? */    else if ((p + i) - q < 10) {	(void)strncpy(buff, p, sizeof buff - 14);	(void)strcpy(&buff[sizeof buff - 14], "...");	(void)strcpy(&buff[sizeof buff - 11], &p[i - 10]);    }    else {	/* Not in last 10 bytes, so use double elipses. */	(void)strncpy(buff, p, sizeof buff - 17);	(void)strcpy(&buff[sizeof buff - 17], "...");	(void)strncpy(&buff[sizeof buff - 14], &q[-5], 10);	(void)strcpy(&buff[sizeof buff - 4], "...");    }    return Join(buff);}/***  Split text into comma-separated fields.  Return an allocated**  NULL-terminated array of the fields within the modified argument that**  the caller is expected to save or free.  We don't use strchr() since**  the text is expected to be either relatively short or "comma-dense."*/char **CommaSplit(text)    char		*text;{    register int	i;    register char	*p;    register char	**av;    char		**save;    /* How much space do we need? */    for (i = 2, p = text; *p; p++)	if (*p == ',')	    i++;    for (av = save = NEW(char*, i), *av++ = p = text; *p; )	if (*p == ',') {	    *p++ = '\0';	    *av++ = p;	}	else	    p++;    *av = NULL;    return save;}/***  Do we need a shell for the command?  If not, av is filled in with**  the individual words of the command and the command is modified to**  have NUL's inserted.*/BOOLNeedShell(p, av, end)    register char	*p;    register char	**av;    register char	**end;{    static char		Metachars[] = ";<>|*?[]{}()#$&=`'\"\\~\n";    register char	*q;    /* We don't use execvp(); works for users, fails out of /etc/rc. */    if (*p != '/')	return TRUE;    for (q = p; *q; q++)	if (strchr(Metachars, *q) != NULL)	    return TRUE;    for (end--; av < end; ) {	/* Mark this word, check for shell meta-characters. */	for (*av++ = p; *p && !ISWHITE(*p); p++)	    continue;	/* If end of list, we're done. */	if (*p == '\0') {	    *av = NULL;	    return FALSE;	}	/* Skip whitespace, find next word. */	for (*p++ = '\0'; ISWHITE(*p); p++)	    continue;	if (*p == '\0') {	    *av = NULL;	    return FALSE;	}    }    /* Didn't fit. */    return TRUE;}/***  Spawn a process, with I/O redirected as needed.  Return the PID or -1**  (and a syslog'd message) on error.*/intSpawn(fd0, fd1, fd2, av)    int		fd0;    int		fd1;    int		fd2;    char	*av[];{    static char	NOCLOSE[] = "%s cant close %d in %s %m";    static char	NODUP2[] = "%s cant dup2 %d to %d in %s %m";    int		i;    /* Fork; on error, give up.  If not using the patched dbz, make     * this call fork! */    i = FORK();    if (i == -1) {	syslog(L_ERROR, "%s cant fork %s %m", LogName, av[0]);	return -1;    }    /* If parent, do nothing. */    if (i > 0)	return i;    /* Child -- do any I/O redirection. */    if (fd0 != 0) {	if (dup2(fd0, 0) < 0) {	    syslog(L_FATAL, NODUP2, LogName, fd0, 0, av[0]);	    _exit(1);	}	if (fd0 != fd1 && fd0 != fd2 && close(fd0) < 0)	    syslog(L_ERROR, NOCLOSE, LogName, fd0, av[0]);    }    if (fd1 != 1) {	if (dup2(fd1, 1) < 0) {	    syslog(L_FATAL, NODUP2, LogName, fd1, 1, av[0]);	    _exit(1);	}	if (fd1 != fd2 && close(fd1) < 0)	    syslog(L_ERROR, NOCLOSE, LogName, fd1, av[0]);    }    if (fd2 != 2) {	if (dup2(fd2, 2) < 0) {	    syslog(L_FATAL, NODUP2, LogName, fd2, 2, av[0]);	    _exit(1);	}	if (close(fd2) < 0)	    syslog(L_ERROR, NOCLOSE, LogName, fd2, av[0]);    }    CloseOnExec(0, FALSE);    CloseOnExec(1, FALSE);    CloseOnExec(2, FALSE);    /* Try to set our permissions. */#if	defined(DO_INND_NICE_KIDS)    (void)nice(INND_NICE_VALUE);#endif	/* defined(DO_INND_NICE_KIDS) */    if (setgid(NewsGID) == -1)	syslog(L_ERROR, "%s cant setgid in %s %m", LogName, av[0]);    if (setuid(NewsUID) == -1)	syslog(L_ERROR, "%s cant setuid in %s %m", LogName, av[0]);    /* Close the DBZ database without doing any writing. */    /* Not needed with the patched DBZ; can't be used with vfork.     * (void)dbzcancel();     * (void)dbmclose();     */    /* Start the desired process (finally!). */    (void)execv(av[0], av);    syslog(L_FATAL, "%s cant exec in %s %m", LogName, av[0]);    _exit(1);    /* NOTREACHED */}/***  Stat our control directory and see who should own things.*/STATIC BOOLGetNewsOwnerships(){    struct stat	Sb;    /* Make sure item exists and is of the right type. */    if (stat(INNDDIR, &Sb) < 0)	return FALSE;    if (!S_ISDIR(Sb.st_mode))	return FALSE;    NewsUID = Sb.st_uid;    NewsGID = Sb.st_gid;    return TRUE;}/***  Change the onwership of a file.*/voidxchown(p)    char	*p;{    if (chown(p, NewsUID, NewsGID) < 0)	syslog(L_ERROR, "%s cant chown %s %m", LogName, p);}/***  Try to make one directory.  Return FALSE on error.*/STATIC BOOLMakeDir(Name)    char		*Name;{    struct stat		Sb;    if (mkdir(Name, GROUPDIR_MODE) >= 0) {	if (AmRoot)	    xchown(Name);	return TRUE;    }    /* See if it failed because it already exists. */    return stat(Name, &Sb) >= 0 && S_ISDIR(Sb.st_mode);}/***  Given a directory, comp/foo/bar, create that directory and all**  intermediate directories needed.  Return 0 if ok, else -1.*/BOOLMakeSpoolDirectory(Name)    register char	*Name;{    register char	*p;    BOOL		made;    /* Optimize common case -- parent almost always exists. */    if (MakeDir(Name))	return TRUE;    /* Try to make each of comp and comp/foo in turn. */    for (p = Name; *p; p++)	if (*p == '/') {	    *p = '\0';	    made = MakeDir(Name);	    *p = '/';	    if (!made)		return FALSE;	}    return MakeDir(Name);}/***  Flush one log file, with pessimistic size of working filename buffer.*/voidReopenLog(F)    FILE	*F;{    char	buff[sizeof LOG + sizeof ERRLOG + 4 + 1];    char	*Name;    char	*Buffer;    int		mask;        if (Debug)	return;    if (F == Log) {	Name = LOG;	Buffer = LogBuffer;    }    else {	Name = ERRLOG;	Buffer = ErrlogBuffer;    }    FileGlue(buff, Name, '.', "old");    if (rename(Name, buff) < 0)	syslog(L_ERROR, "%s cant rename %s to %s %m", LogName, Name, buff);    mask = umask(033);    if (freopen(Name, "a", F) != F) {	syslog(L_FATAL, "%s cant freopen %s %m", LogName, Name);	exit(1);    }    (void)umask(mask);    if (AmRoot)	xchown(Name);    if (BufferedLogs)	SETBUFFER(F, Buffer, LogBufferSize);}/***  Function called when memory allocation fails.*/STATIC intAllocationFailure(what, i)    char		*what;    unsigned int	i;{    /* Print i as %d so huge values are real obvious. */    syslog(L_FATAL, "%s cant %s %d bytes %m", LogName, what, i);    exit(1);    /* NOTREACHED */}/*

⌨️ 快捷键说明

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