Remove files no longer part of the sendmail 8.12.2 distribution.

This commit is contained in:
gshapiro 2002-02-17 22:51:21 +00:00
parent 8449595fe9
commit 1a7e50d796
14 changed files with 0 additions and 2580 deletions

View File

@ -1,27 +0,0 @@
divert(-1)
#
# Copyright (c) 1998, 1999 Sendmail, Inc. and its suppliers.
# All rights reserved.
# Copyright (c) 1983 Eric P. Allman. All rights reserved.
# Copyright (c) 1988, 1993
# The Regents of the University of California. All rights reserved.
#
# By using this file, you agree to the terms and conditions set
# forth in the LICENSE file which can be found at the top level of
# the sendmail distribution.
#
#
#
# This is a generic configuration file for SunOS 5.x (a.k.a. Solaris 2.x)
# It has support for local and SMTP mail only. If you want to
# customize it, copy it to a name appropriate for your environment
# and do the modifications there.
#
divert(0)dnl
VERSIONID(`$Id: generic-solaris2.mc,v 8.11 1999/02/07 07:26:03 gshapiro Exp $')
OSTYPE(solaris2)dnl
DOMAIN(generic)dnl
MAILER(local)dnl
MAILER(smtp)dnl

View File

@ -1,18 +0,0 @@
divert(-1)
#
# Copyright (c) 1998 Sendmail, Inc. All rights reserved.
#
# By using this file, you agree to the terms and conditions set
# forth in the LICENSE file which can be found at the top level of
# the sendmail distribution.
#
#
divert(0)
VERSIONID(`$Id: rbl.m4,v 8.17 1999/04/04 00:51:12 ca Exp $')
divert(-1)
define(`_RBL_', ifelse(defn(`_ARG_'), `', `rbl.maps.vix.com', `_ARG_'))dnl
ifelse(defn(`_ARG_'), `', `', `
errprint(`Warning: FEATURE(`rbl') is deprecated, use FEATURE(`dnsbl') instead
')')dnl

View File

@ -1,21 +0,0 @@
divert(-1)
#
# Copyright (c) 1998, 1999 Sendmail, Inc. and its suppliers.
# All rights reserved.
# Copyright (c) 1995 Eric P. Allman. All rights reserved.
# Copyright (c) 1988, 1993
# The Regents of the University of California. All rights reserved.
#
# By using this file, you agree to the terms and conditions set
# forth in the LICENSE file which can be found at the top level of
# the sendmail distribution.
#
#
divert(0)
VERSIONID(`$Id: aix2.m4,v 8.12 1999/04/12 17:34:36 ca Exp $')
define(`LOCAL_MAILER_PATH', /bin/bellmail)dnl
define(`LOCAL_MAILER_ARGS', mail $u)dnl
_DEFIFNOT(`LOCAL_MAILER_FLAGS', `mn9')dnl
define(`confEBINDIR', `/usr/lib')dnl
define(`confTIME_ZONE', `USE_TZ')dnl

View File

@ -1,21 +0,0 @@
divert(-1)
#
# Copyright (c) 1998, 1999 Sendmail, Inc. and its suppliers.
# All rights reserved.
# Copyright (c) 1983 Eric P. Allman. All rights reserved.
# Copyright (c) 1988, 1993
# The Regents of the University of California. All rights reserved.
#
# By using this file, you agree to the terms and conditions set
# forth in the LICENSE file which can be found at the top level of
# the sendmail distribution.
#
#
divert(0)
VERSIONID(`$Id: a-ux.m4,v 8.1 2001/04/12 22:29:58 gshapiro Exp $')
ifdef(`QUEUE_DIR',, `define(`QUEUE_DIR', /usr/spool/mqueue)')dnl
ifdef(`UUCP_MAILER_PATH',, `define(`UUCP_MAILER_PATH', /usr/bin/uux)')dnl
_DEFIFNOT(`LOCAL_MAILER_FLAGS', `mn9')dnl
ifdef(`LOCAL_MAILER_ARGS',, `define(`LOCAL_MAILER_ARGS', `mail -d -r $f $u')')dnl
define(`confEBINDIR', `/usr/lib')dnl

View File

@ -1,103 +0,0 @@
/*
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* By using this file, you agree to the terms and conditions set
* forth in the LICENSE file which can be found at the top level of
* the sendmail distribution.
*
* $Id: cdefs.h,v 8.5 1999/06/02 22:32:17 gshapiro Exp $
* @(#)cdefs.h 8.8 (Berkeley) 1/9/95
*/
#ifndef _CDEFS_H_
# define _CDEFS_H_
# if defined(__cplusplus)
# define __BEGIN_DECLS extern "C" {
# define __END_DECLS };
# else /* defined(__cplusplus) */
# define __BEGIN_DECLS
# define __END_DECLS
# endif /* defined(__cplusplus) */
/*
* The __CONCAT macro is used to concatenate parts of symbol names, e.g.
* with "#define OLD(foo) __CONCAT(old,foo)", OLD(foo) produces oldfoo.
* The __CONCAT macro is a bit tricky -- make sure you don't put spaces
* in between its arguments. __CONCAT can also concatenate double-quoted
* strings produced by the __STRING macro, but this only works with ANSI C.
*/
# if defined(__STDC__) || defined(__cplusplus)
# define __P(protos) protos /* full-blown ANSI C */
# ifndef __CONCAT
# define __CONCAT(x,y) x ## y
# endif /* ! __CONCAT */
# define __STRING(x) #x
# ifndef __const
# define __const const /* define reserved names to standard */
# endif /* ! __const */
# define __signed signed
# define __volatile volatile
# if defined(__cplusplus)
# define __inline inline /* convert to C++ keyword */
# else /* defined(__cplusplus) */
# ifndef __GNUC__
# define __inline /* delete GCC keyword */
# endif /* ! __GNUC__ */
# endif /* defined(__cplusplus) */
# else /* defined(__STDC__) || defined(__cplusplus) */
# define __P(protos) () /* traditional C preprocessor */
# ifndef __CONCAT
# define __CONCAT(x,y) x/**/y
# endif /* ! __CONCAT */
# define __STRING(x) "x"
# ifndef __GNUC__
# define __const /* delete pseudo-ANSI C keywords */
# define __inline
# define __signed
# define __volatile
/*
* In non-ANSI C environments, new programs will want ANSI-only C keywords
* deleted from the program and old programs will want them left alone.
* When using a compiler other than gcc, programs using the ANSI C keywords
* const, inline etc. as normal identifiers should define -DNO_ANSI_KEYWORDS.
* When using "gcc -traditional", we assume that this is the intent; if
* __GNUC__ is defined but __STDC__ is not, we leave the new keywords alone.
*/
# ifndef NO_ANSI_KEYWORDS
# define const /* delete ANSI C keywords */
# define inline
# define signed
# define volatile
# endif /* ! NO_ANSI_KEYWORDS */
# endif /* ! __GNUC__ */
# endif /* defined(__STDC__) || defined(__cplusplus) */
/*
* GCC1 and some versions of GCC2 declare dead (non-returning) and
* pure (no side effects) functions using "volatile" and "const";
* unfortunately, these then cause warnings under "-ansi -pedantic".
* GCC2 uses a new, peculiar __attribute__((attrs)) style. All of
* these work for GNU C++ (modulo a slight glitch in the C++ grammar
* in the distribution version of 2.5.5).
*/
# if !defined(__GNUC__) || __GNUC__ < 2 || \
(__GNUC__ == 2 && __GNUC_MINOR__ < 5)
# define __attribute__(x) /* delete __attribute__ if non-gcc or gcc1 */
# if defined(__GNUC__) && !defined(__STRICT_ANSI__)
# define __dead __volatile
# define __pure __const
# endif /* defined(__GNUC__) && !defined(__STRICT_ANSI__) */
# endif /* !defined(__GNUC__) || __GNUC__ < 2 || \ */
/* Delete pseudo-keywords wherever they are not available or needed. */
# ifndef __dead
# define __dead
# define __pure
# endif /* ! __dead */
#endif /* ! _CDEFS_H_ */

View File

@ -1,73 +0,0 @@
/*
* Copyright (c) 1998-2000 Sendmail, Inc. and its suppliers.
* All rights reserved.
*
* By using this file, you agree to the terms and conditions set
* forth in the LICENSE file which can be found at the top level of
* the sendmail distribution.
*
*
* $Id: errstring.h,v 8.6.4.1 2000/05/26 18:24:13 geir Exp $
*/
/*
** ERRSTRING.H -- Error codes.
*/
#include <errno.h>
extern int errno;
/*
** These are used in a few cases where we need some special
** error codes, but where the system doesn't provide something
** reasonable. They are printed in errstring.
*/
#ifndef E_PSEUDOBASE
# define E_PSEUDOBASE 256
#endif /* ! E_PSEUDOBASE */
#define E_SM_OPENTIMEOUT (E_PSEUDOBASE + 0) /* Timeout on file open */
#define E_SM_NOSLINK (E_PSEUDOBASE + 1) /* Symbolic links not allowed */
#define E_SM_NOHLINK (E_PSEUDOBASE + 2) /* Hard links not allowed */
#define E_SM_REGONLY (E_PSEUDOBASE + 3) /* Regular files only */
#define E_SM_ISEXEC (E_PSEUDOBASE + 4) /* Executable files not allowed */
#define E_SM_WWDIR (E_PSEUDOBASE + 5) /* World writable directory */
#define E_SM_GWDIR (E_PSEUDOBASE + 6) /* Group writable directory */
#define E_SM_FILECHANGE (E_PSEUDOBASE + 7) /* File changed after open */
#define E_SM_WWFILE (E_PSEUDOBASE + 8) /* World writable file */
#define E_SM_GWFILE (E_PSEUDOBASE + 9) /* Group writable file */
#define E_SM_GRFILE (E_PSEUDOBASE + 10) /* g readable file */
#define E_SM_WRFILE (E_PSEUDOBASE + 11) /* o readable file */
#define E_DNSBASE (E_PSEUDOBASE + 20) /* base for DNS h_errno */
#define E_SMDBBASE (E_PSEUDOBASE + 40) /* base for libsmdb errors */
#define E_LDAPBASE (E_PSEUDOBASE + 70) /* base for LDAP errors */
/* libsmdb */
#define SMDBE_OK 0
#define SMDBE_MALLOC (E_SMDBBASE + 1)
#define SMDBE_GDBM_IS_BAD (E_SMDBBASE + 2)
#define SMDBE_UNSUPPORTED (E_SMDBBASE + 3)
#define SMDBE_DUPLICATE (E_SMDBBASE + 4)
#define SMDBE_BAD_OPEN (E_SMDBBASE + 5)
#define SMDBE_NOT_FOUND (E_SMDBBASE + 6)
#define SMDBE_UNKNOWN_DB_TYPE (E_SMDBBASE + 7)
#define SMDBE_UNSUPPORTED_DB_TYPE (E_SMDBBASE + 8)
#define SMDBE_INCOMPLETE (E_SMDBBASE + 9)
#define SMDBE_KEY_EMPTY (E_SMDBBASE + 10)
#define SMDBE_KEY_EXIST (E_SMDBBASE + 11)
#define SMDBE_LOCK_DEADLOCK (E_SMDBBASE + 12)
#define SMDBE_LOCK_NOT_GRANTED (E_SMDBBASE + 13)
#define SMDBE_LOCK_NOT_HELD (E_SMDBBASE + 14)
#define SMDBE_RUN_RECOVERY (E_SMDBBASE + 15)
#define SMDBE_IO_ERROR (E_SMDBBASE + 16)
#define SMDBE_READ_ONLY (E_SMDBBASE + 17)
#define SMDBE_DB_NAME_TOO_LONG (E_SMDBBASE + 18)
#define SMDBE_INVALID_PARAMETER (E_SMDBBASE + 19)
#define SMDBE_ONLY_SUPPORTS_ONE_CURSOR (E_SMDBBASE + 20)
#define SMDBE_NOT_A_VALID_CURSOR (E_SMDBBASE + 21)
#define SMDBE_LAST_ENTRY (E_SMDBBASE + 22)
#define SMDBE_OLD_VERSION (E_SMDBBASE + 23)
extern const char *errstring __P((int));

View File

@ -1,63 +0,0 @@
/*
* Copyright (c) 1998, 1999 Sendmail, Inc. and its suppliers.
* All rights reserved.
* Copyright (c) 1995-1997 Eric P. Allman. All rights reserved.
* Copyright (c) 1988, 1993
* The Regents of the University of California. All rights reserved.
*
* By using this file, you agree to the terms and conditions set
* forth in the LICENSE file which can be found at the top level of
* the sendmail distribution.
*
*
* $Id: useful.h,v 8.18 1999/07/13 15:05:57 ca Exp $
*/
#ifndef _USEFUL_H
# define _USEFUL_H
# include <sys/types.h>
/* support for bool type */
typedef int bool;
# ifndef TRUE
# define TRUE 1
# define FALSE 0
# endif /* ! TRUE */
# ifndef NULL
# define NULL 0
# endif /* ! NULL */
/* bit hacking */
# define bitset(bit, word) (((word) & (bit)) != 0)
/* some simple functions */
# ifndef max
# define max(a, b) ((a) > (b) ? (a) : (b))
# define min(a, b) ((a) < (b) ? (a) : (b))
# endif /* ! max */
/* assertions */
# ifndef NASSERT
# define ASSERT(expr, msg, parm)\
if (!(expr))\
{\
fprintf(stderr, "assertion botch: %s:%d: ", __FILE__, __LINE__);\
fprintf(stderr, msg, parm);\
}
# else /* ! NASSERT */
# define ASSERT(expr, msg, parm)
# endif /* ! NASSERT */
/* sccs id's */
# ifndef lint
# ifdef __STDC__
# define SCCSID(arg) static char SccsId[] = #arg;
# else /* __STDC__ */
# define SCCSID(arg) static char SccsId[] = "arg";
# endif /* __STDC__ */
# else /* ! lint */
# define SCCSID(arg)
# endif /* ! lint */
#endif /* ! _USEFUL_H */

View File

@ -1,206 +0,0 @@
/*
* Copyright (c) 1998-2000 Sendmail, Inc. and its suppliers.
* All rights reserved.
* Copyright (c) 1983, 1995-1997 Eric P. Allman. All rights reserved.
* Copyright (c) 1988, 1993
* The Regents of the University of California. All rights reserved.
*
* By using this file, you agree to the terms and conditions set
* forth in the LICENSE file which can be found at the top level of
* the sendmail distribution.
*
*/
#ifndef lint
static char id[] = "@(#)$Id: errstring.c,v 8.8.4.1 2000/05/26 18:16:28 geir Exp $";
#endif /* ! lint */
#include <sendmail.h>
/*
** ERRSTRING -- return string description of error code
**
** Parameters:
** errnum -- the error number to translate
**
** Returns:
** A string description of errnum.
**
** Side Effects:
** none.
*/
const char *
errstring(errnum)
int errnum;
{
#if !HASSTRERROR && !defined(ERRLIST_PREDEFINED)
extern char *sys_errlist[];
extern int sys_nerr;
#endif /* !HASSTRERROR && !defined(ERRLIST_PREDEFINED) */
/*
** Handle special network error codes.
**
** These are 4.2/4.3bsd specific; they should be in daemon.c.
*/
switch (errnum)
{
case EPERM:
/* SunOS gives "Not owner" -- this is the POSIX message */
return "Operation not permitted";
/*
** Error messages used internally in sendmail.
*/
case E_SM_OPENTIMEOUT:
return "Timeout on file open";
case E_SM_NOSLINK:
return "Symbolic links not allowed";
case E_SM_NOHLINK:
return "Hard links not allowed";
case E_SM_REGONLY:
return "Regular files only";
case E_SM_ISEXEC:
return "Executable files not allowed";
case E_SM_WWDIR:
return "World writable directory";
case E_SM_GWDIR:
return "Group writable directory";
case E_SM_FILECHANGE:
return "File changed after open";
case E_SM_WWFILE:
return "World writable file";
case E_SM_GWFILE:
return "Group writable file";
case E_SM_GRFILE:
return "Group readable file";
case E_SM_WRFILE:
return "World readable file";
/*
** DNS error messages.
*/
#if NAMED_BIND
case HOST_NOT_FOUND + E_DNSBASE:
return "Name server: host not found";
case TRY_AGAIN + E_DNSBASE:
return "Name server: host name lookup failure";
case NO_RECOVERY + E_DNSBASE:
return "Name server: non-recoverable error";
case NO_DATA + E_DNSBASE:
return "Name server: no data known";
#endif /* NAMED_BIND */
/*
** libsmdb error messages.
*/
case SMDBE_MALLOC:
return "Memory allocation failed";
case SMDBE_GDBM_IS_BAD:
return "GDBM is not supported";
case SMDBE_UNSUPPORTED:
return "Unsupported action";
case SMDBE_DUPLICATE:
return "Key already exists";
case SMDBE_BAD_OPEN:
return "Database open failed";
case SMDBE_NOT_FOUND:
return "Key not found";
case SMDBE_UNKNOWN_DB_TYPE:
return "Unknown database type";
case SMDBE_UNSUPPORTED_DB_TYPE:
return "Support for database type not compiled into this program";
case SMDBE_INCOMPLETE:
return "DB sync did not finish";
case SMDBE_KEY_EMPTY:
return "Key is empty";
case SMDBE_KEY_EXIST:
return "Key already exists";
case SMDBE_LOCK_DEADLOCK:
return "Locker killed to resolve deadlock";
case SMDBE_LOCK_NOT_GRANTED:
return "Lock unavailable";
case SMDBE_LOCK_NOT_HELD:
return "Lock not held by locker";
case SMDBE_RUN_RECOVERY:
return "Database panic, run recovery";
case SMDBE_IO_ERROR:
return "I/O error";
case SMDBE_READ_ONLY:
return "Database opened read-only";
case SMDBE_DB_NAME_TOO_LONG:
return "Name too long";
case SMDBE_INVALID_PARAMETER:
return "Invalid parameter";
case SMDBE_ONLY_SUPPORTS_ONE_CURSOR:
return "Only one cursor allowed";
case SMDBE_NOT_A_VALID_CURSOR:
return "Invalid cursor";
case SMDBE_OLD_VERSION:
return "Berkeley DB file is an old version, recreate it";
}
/*
** LDAP error messages.
*/
#ifdef LDAPMAP
if (errnum >= E_LDAPBASE)
return ldap_err2string(errnum - E_LDAPBASE);
#endif /* LDAPMAP */
#if HASSTRERROR
return strerror(errnum);
#else /* HASSTRERROR */
if (errnum > 0 && errnum < sys_nerr)
return sys_errlist[errnum];
else
{
static char buf[MAXLINE];
(void) snprintf(buf, sizeof buf, "Error %d", errnum);
return buf;
}
#endif /* HASSTRERROR */
}

View File

@ -1,91 +0,0 @@
/*
* Copyright (c) 1999-2000 Sendmail, Inc. and its suppliers.
* All rights reserved.
*
* By using this file, you agree to the terms and conditions set
* forth in the LICENSE file which can be found at the top level of
* the sendmail distribution.
*
*/
#ifndef lint
static char id[] = "@(#)$Id: strl.c,v 8.5.14.2 2000/09/17 17:04:24 gshapiro Exp $";
#endif /* ! lint */
#include <sendmail.h>
#if !HASSTRL
/*
** strlcpy -- copy string obeying length and '\0' terminate it
**
** terminates with '\0' if len > 0
**
** Parameters:
** dst -- "destination" string.
** src -- "from" string.
** len -- length of space available in "destination" string.
**
** Returns:
** total length of the string tried to create (=strlen(src))
** if this is greater than len then an overflow would have
** occurred.
*/
size_t
strlcpy(dst, src, len)
register char *dst;
register const char *src;
size_t len;
{
register size_t i;
if (len-- <= 0)
return strlen(src);
for (i = 0; i < len && (dst[i] = src[i]) != 0; i++)
continue;
dst[i] = '\0';
if (src[i] == '\0')
return i;
else
return i + strlen(src + i);
}
/*
** strlcat -- catenate strings obeying length and '\0' terminate it
**
** strlcat will append at most len - strlen(dst) - 1 chars.
** terminates with '\0' if len > 0
**
** Parameters:
** dst -- "destination" string.
** src -- "from" string.
** len -- max. length of "destination" string.
**
** Returns:
** total length of the string tried to create
** (= initial length of dst + length of src)
** if this is greater than len then an overflow would have
** occurred.
*/
size_t
strlcat(dst, src, len)
register char *dst;
register const char *src;
size_t len;
{
register size_t i, j, o;
o = strlen(dst);
if (len < o + 1)
return o + strlen(src);
len -= o + 1;
for (i = 0, j = o; i < len && (dst[j] = src[i]) != 0; i++, j++)
continue;
dst[j] = '\0';
if (src[i] == '\0')
return j;
else
return j + strlen(src + i);
}
#endif /* !HASSTRL */

View File

@ -1,525 +0,0 @@
/*
* Copyright (c) 1999-2001 Sendmail, Inc. and its suppliers.
* All rights reserved.
*
* By using this file, you agree to the terms and conditions set
* forth in the LICENSE file which can be found at the top level of
* the sendmail distribution.
*
* Contributed by Exactis.com, Inc.
*
*/
#ifndef lint
static char id[] = "@(#)$Id: bf_portable.c,v 8.25.4.6 2001/05/03 17:24:01 gshapiro Exp $";
#endif /* ! lint */
#if SFIO
# include <sfio/stdio.h>
#endif /* SFIO */
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <stdlib.h>
#include <string.h>
#include <sys/uio.h>
#include <errno.h>
#if !SFIO
# include <stdio.h>
#endif /* !SFIO */
#ifdef BF_STANDALONE
# define sm_free free
# define xalloc malloc
#else /* BF_STANDALONE */
# include "sendmail.h"
#endif /* BF_STANDALONE */
#include "bf_portable.h"
#include "bf.h"
/*
** BFOPEN -- create a new buffered file
**
** Parameters:
** filename -- the file's name
** fmode -- what mode the file should be created as
** bsize -- amount of buffer space to allocate (may be 0)
** flags -- if running under sendmail, passed directly to safeopen
**
** Returns:
** a FILE * which may then be used with stdio functions, or NULL
** on failure. FILE * is opened for writing (mode "w+").
**
** Side Effects:
** none.
**
** Sets errno:
** ENOMEM -- out of memory
** ENOENT -- illegal empty filename specified
** any value of errno specified by open()
** any value of errno specified by fdopen()
** any value of errno specified by funopen()
*/
#ifdef BF_STANDALONE
# define OPEN(fn, omode, cmode, sff) open(fn, omode, cmode)
#else /* BF_STANDALONE */
# define OPEN(fn, omode, cmode, sff) safeopen(fn, omode, cmode, sff)
#endif /* BF_STANDALONE */
/* List of currently-open buffered files */
struct bf *bflist = NULL;
FILE *
bfopen(filename, fmode, bsize, flags)
char *filename;
int fmode;
size_t bsize;
long flags;
{
struct bf *bfp;
FILE *retval;
int fd, l;
fd = OPEN(filename, O_RDWR | O_CREAT | O_TRUNC, fmode, flags);
if (fd == -1)
{
/* errno is set implicitly by open */
return NULL;
}
retval = fdopen(fd, "w+");
/* If failure, return immediately */
if (retval == NULL)
{
/* errno is set implicitly by fdopen */
return NULL;
}
/* Allocate memory */
bfp = (struct bf *)xalloc(sizeof(struct bf));
if (bfp == NULL)
{
(void) fclose(retval);
/* don't care about errors */
(void) unlink(filename);
errno = ENOMEM;
return NULL;
}
if (tTd(58, 8))
dprintf("bfopen(%s): malloced %ld\n",
filename, (long) sizeof(struct bf));
l = strlen(filename) + 1;
bfp->bf_filename = (char *)xalloc(l);
if (bfp->bf_filename == NULL)
{
sm_free(bfp);
(void) fclose(retval);
/* don't care about errors */
(void) unlink(filename);
errno = ENOMEM;
return NULL;
}
(void) strlcpy(bfp->bf_filename, filename, l);
/* Fill in the other fields, then add it to the list */
bfp->bf_key = retval;
bfp->bf_committed = FALSE;
bfp->bf_refcount = 1;
bfinsert(bfp);
/* Whew. Nothing bad happened. We're okay. */
return retval;
}
/*
** BFDUP -- increase refcount on buffered file
**
** Parameters:
** fp -- FILE * to "duplicate"
**
** Returns:
** fp with increased refcount
*/
FILE *
bfdup(fp)
FILE *fp;
{
struct bf *bfp;
/* Get associated bf structure */
bfp = bflookup(fp);
if (bfp == NULL)
return NULL;
/* Increase the refcount */
bfp->bf_refcount++;
return fp;
}
/*
** BFCOMMIT -- "commits" the buffered file
**
** Parameters:
** fp -- FILE * to commit to disk
**
** Returns:
** 0 on success, -1 on error
**
** Side Effects:
** Forces the given FILE * to be written to disk if it is not
** already, and ensures that it will be kept after closing. If
** fp is not a buffered file, this is a no-op.
**
** Sets errno:
** any value of errno specified by open()
** any value of errno specified by write()
** any value of errno specified by lseek()
*/
int
bfcommit(fp)
FILE *fp;
{
struct bf *bfp;
/* Get associated bf structure */
bfp = bflookup(fp);
/* If called on a normal FILE *, noop */
if (bfp != NULL)
bfp->bf_committed = TRUE;
return 0;
}
/*
** BFREWIND -- rewinds the FILE *
**
** Parameters:
** fp -- FILE * to rewind
**
** Returns:
** 0 on success, -1 on error
**
** Side Effects:
** rewinds the FILE * and puts it into read mode. Normally one
** would bfopen() a file, write to it, then bfrewind() and
** fread(). If fp is not a buffered file, this is equivalent to
** rewind().
**
** Sets errno:
** any value of errno specified by fseek()
*/
int
bfrewind(fp)
FILE *fp;
{
int err;
/* check to see if there is an error on the stream */
err = ferror(fp);
(void) fflush(fp);
/*
** Clear error if tried to fflush()
** a read-only file pointer and
** there wasn't a previous error.
*/
if (err == 0)
clearerr(fp);
/* errno is set implicitly by fseek() before return */
return fseek(fp, 0, SEEK_SET);
}
/*
** BFTRUNCATE -- rewinds and truncates the FILE *
**
** Parameters:
** fp -- FILE * to truncate
**
** Returns:
** 0 on success, -1 on error
**
** Side Effects:
** rewinds the FILE *, truncates it to zero length, and puts it
** into write mode. If fp is not a buffered file, this is
** equivalent to a rewind() and then an ftruncate(fileno(fp), 0).
**
** Sets errno:
** any value of errno specified by fseek()
** any value of errno specified by ftruncate()
*/
int
bftruncate(fp)
FILE *fp;
{
int ret;
if (bfrewind(fp) == -1)
{
/* errno is set implicitly by bfrewind() */
return -1;
}
#if NOFTRUNCATE
/* XXX */
errno = EINVAL;
ret = -1;
#else /* NOFTRUNCATE */
/* errno is set implicitly by ftruncate() before return */
ret = ftruncate(fileno(fp), 0);
#endif /* NOFTRUNCATE */
return ret;
}
/*
** BFFSYNC -- fsync the fd associated with the FILE *
**
** Parameters:
** fp -- FILE * to fsync
**
** Returns:
** 0 on success, -1 on error
**
** Sets errno:
** EINVAL if FILE * not bfcommitted yet.
** any value of errno specified by fsync()
*/
int
bffsync(fp)
FILE *fp;
{
int fd;
struct bf *bfp;
/* Get associated bf structure */
bfp = bflookup(fp);
/* If called on a normal FILE *, noop */
if (bfp != NULL && !bfp->bf_committed)
fd = -1;
else
fd = fileno(fp);
if (tTd(58, 10))
dprintf("bffsync: fd = %d\n", fd);
if (fd < 0)
{
errno = EINVAL;
return -1;
}
return fsync(fd);
}
/*
** BFCLOSE -- close a buffered file
**
** Parameters:
** fp -- FILE * to close
**
** Returns:
** 0 on success, EOF on failure
**
** Side Effects:
** Closes fp. If fp is a buffered file, unlink it if it has not
** already been committed. If fp is not a buffered file, this is
** equivalent to fclose().
**
** Sets errno:
** any value of errno specified by fclose()
*/
int
bfclose(fp)
FILE *fp;
{
int retval;
struct bf *bfp = NULL;
/* Get associated bf structure */
bfp = bflookup(fp);
/* Decrement and check refcount */
if (bfp != NULL && --bfp->bf_refcount > 0)
return 0;
/* If bf, get bf structure and remove from list */
if (bfp != NULL)
bfp = bfdelete(fp);
if (fclose(fp) == EOF)
{
if (tTd(58, 8))
dprintf("bfclose: fclose failed\n");
/* errno is set implicitly by fclose() */
return -1;
}
if (bfp == NULL)
return 0;
/* Success unless we determine otherwise in next block */
retval = 0;
if (bfp != NULL)
{
/* Might have to unlink; certainly will have to deallocate */
if (!bfp->bf_committed)
retval = unlink(bfp->bf_filename);
sm_free(bfp->bf_filename);
sm_free(bfp);
if (tTd(58, 8))
dprintf("bfclose: freed %ld\n",
(long) sizeof(struct bf));
}
else
{
if (tTd(58, 8))
dprintf("bfclose: bfp was NULL\n");
}
return retval;
}
/*
** BFTEST -- test if a FILE * is a buffered file
**
** Parameters:
** fp -- FILE * to test
**
** Returns:
** TRUE if fp is a buffered file, FALSE otherwise.
**
** Side Effects:
** none.
**
** Sets errno:
** never.
*/
bool
bftest(fp)
FILE *fp;
{
return (bflookup(fp) != NULL);
}
/*
** BFINSERT -- insert item in linking list
**
** Parameters:
** datum -- item to insert
**
** Returns:
** none.
**
** Side Effects:
** none.
**
** Sets errno:
** never.
*/
void
bfinsert(datum)
struct bf *datum;
{
datum->bf_cdr = bflist;
bflist = datum;
}
/*
** BFLOOKUP -- lookup FILE * in list
**
** Parameters:
** fp -- FILE * to lookup
**
** Returns:
** bf struct for the FILE *, NULL if not found
**
** Side Effects:
** none.
**
** Sets errno:
** never.
*/
struct bf *
bflookup(key)
FILE *key;
{
struct bf *t;
for (t = bflist; t != NULL; t = t->bf_cdr)
{
if (t->bf_key == key)
{
return t;
}
}
/* If we got this far, we didn't find it */
return NULL;
}
/*
** BFDELETE -- delete a FILE * in list
**
** Parameters:
** fp -- FILE * to delete
**
** Returns:
** bf struct for deleted FILE *, NULL if not found,
**
** Side Effects:
** none.
**
** Sets errno:
** never.
*/
struct bf *
bfdelete(key)
FILE *key;
{
struct bf *t, *u;
if (bflist == NULL)
return NULL;
/* if first element, special case */
if (bflist->bf_key == key)
{
u = bflist;
bflist = bflist->bf_cdr;
return u;
}
for (t = bflist; t->bf_cdr != NULL; t = t->bf_cdr)
{
if (t->bf_cdr->bf_key == key)
{
u = t->bf_cdr;
t->bf_cdr = u->bf_cdr;
return u;
}
}
/* If we got this far, we didn't find it */
return NULL;
}

View File

@ -1,46 +0,0 @@
/*
* Copyright (c) 1999 Sendmail, Inc. and its suppliers.
* All rights reserved.
*
* By using this file, you agree to the terms and conditions set
* forth in the LICENSE file which can be found at the top level of
* the sendmail distribution.
*
* $Id: bf_portable.h,v 8.6 1999/11/04 19:31:25 ca Exp $
*
* Contributed by Exactis.com, Inc.
*
*/
#ifndef BF_PORTABLE_H
#define BF_PORTABLE_H 1
/*
** This implementation will behave differently from the Torek-based code in
** the following major ways:
** - The buffer size argument to bfopen() will be sent in, sent back,
** queried, lost, found, subjected to public inquiry, lost again, and
** finally buried in soft peat and recycled as firelighters.
** - Errors in creating the file (but not necessarily writing to it) will
** always be detected and reported synchronously with the bfopen()
*/
/* Linked structure for storing information about each buffered file */
struct bf
{
FILE *bf_key; /* Unused except as a key for lookup */
bool bf_committed; /* buffered file is on disk */
char *bf_filename; /* Name of disk file */
int bf_refcount; /* Reference count */
struct bf *bf_cdr;
};
/*
** Access routines for looking up bf structures
**
** maybe replace with a faster data structure later
*/
extern void bfinsert __P((struct bf *));
extern struct bf *bflookup __P((FILE *));
extern struct bf *bfdelete __P((FILE *));
#endif /* BF_PORTABLE_H */

View File

@ -1,831 +0,0 @@
/*
* Copyright (c) 1999-2001 Sendmail, Inc. and its suppliers.
* All rights reserved.
*
* By using this file, you agree to the terms and conditions set
* forth in the LICENSE file which can be found at the top level of
* the sendmail distribution.
*
* Contributed by Exactis.com, Inc.
*
*/
#ifndef lint
static char id[] = "@(#)$Id: bf_torek.c,v 8.19.18.6 2001/05/08 06:52:19 gshapiro Exp $";
#endif /* ! lint */
#if SFIO
ERROR README: Can not use bf_torek.c with SFIO.
#endif /* SFIO */
#include <sys/types.h>
#include <sys/uio.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <stdio.h>
#ifdef BF_STANDALONE
# define sm_free free
# define xalloc malloc
#else /* BF_STANDALONE */
# include "sendmail.h"
#endif /* BF_STANDALONE */
#include "bf_torek.h"
#include "bf.h"
/*
** BFOPEN -- create a new buffered file
**
** Parameters:
** filename -- the file's name
** fmode -- what mode the file should be created as
** bsize -- amount of buffer space to allocate (may be 0)
** flags -- if running under sendmail, passed directly to safeopen
**
** Returns:
** a FILE * which may then be used with stdio functions, or NULL
** on failure. FILE * is opened for writing (mode "w+").
**
** Side Effects:
** none.
**
** Sets errno:
** ENOMEM -- out of memory
** ENOENT -- illegal empty filename specified
** any value of errno specified by open()
** any value of errno specified by fdopen()
** any value of errno specified by funopen()
*/
#ifdef BF_STANDALONE
# define OPEN(fn, omode, cmode, sff) open(fn, omode, cmode)
#else /* BF_STANDALONE */
# define OPEN(fn, omode, cmode, sff) safeopen(fn, omode, cmode, sff)
#endif /* BF_STANDALONE */
FILE *
bfopen(filename, fmode, bsize, flags)
char *filename;
int fmode;
size_t bsize;
long flags;
{
struct bf *bfp;
FILE *retval;
int save_errno, l;
struct stat st;
/* Sanity checks */
/* Empty filename string */
if (*filename == '\0')
{
errno = ENOENT;
return NULL;
}
if (stat(filename, &st) == 0)
{
/* file already exists on disk */
errno = EEXIST;
return NULL;
}
/* Allocate memory */
bfp = (struct bf *)xalloc(sizeof(struct bf));
if (bfp == NULL)
{
errno = ENOMEM;
return NULL;
}
/* A zero bsize is valid, just don't allocate memory */
if (bsize > 0)
{
bfp->bf_buf = (char *)xalloc(bsize);
if (bfp->bf_buf == NULL)
{
sm_free(bfp);
errno = ENOMEM;
return NULL;
}
}
else
bfp->bf_buf = NULL;
/* Nearly home free, just set all the parameters now */
bfp->bf_committed = FALSE;
bfp->bf_ondisk = FALSE;
bfp->bf_refcount = 1;
bfp->bf_flags = flags;
bfp->bf_bufsize = bsize;
bfp->bf_buffilled = 0;
l = strlen(filename) + 1;
bfp->bf_filename = (char *)xalloc(l);
if (bfp->bf_filename == NULL)
{
if (bfp->bf_buf != NULL)
sm_free(bfp->bf_buf);
sm_free(bfp);
errno = ENOMEM;
return NULL;
}
(void) strlcpy(bfp->bf_filename, filename, l);
bfp->bf_filemode = fmode;
bfp->bf_offset = 0;
bfp->bf_size = 0;
if (tTd(58, 8))
dprintf("bfopen(%s, %d)\n", filename, bsize);
/* The big test: will funopen accept it? */
retval = funopen((void *)bfp, _bfread, _bfwrite, _bfseek, _bfclose);
if (retval == NULL)
{
/* Just in case free() sets errno */
save_errno = errno;
sm_free(bfp->bf_filename);
if (bfp->bf_buf != NULL)
sm_free(bfp->bf_buf);
sm_free(bfp);
errno = save_errno;
return NULL;
}
else
{
/* Success */
return retval;
}
}
/*
** BFDUP -- increase refcount on buffered file
**
** Parameters:
** fp -- FILE * to "duplicate"
**
** Returns:
** If file is memory buffered, fp with increased refcount
** If file is on disk, NULL (need to use link())
*/
FILE *
bfdup(fp)
FILE *fp;
{
struct bf *bfp;
/* If called on a normal FILE *, noop */
if (!bftest(fp))
return NULL;
/* Get associated bf structure */
bfp = (struct bf *)fp->_cookie;
/* Increase ref count */
bfp->bf_refcount++;
return fp;
}
/*
** BFCOMMIT -- "commits" the buffered file
**
** Parameters:
** fp -- FILE * to commit to disk
**
** Returns:
** 0 on success, -1 on error
**
** Side Effects:
** Forces the given FILE * to be written to disk if it is not
** already, and ensures that it will be kept after closing. If
** fp is not a buffered file, this is a no-op.
**
** Sets errno:
** any value of errno specified by open()
** any value of errno specified by write()
** any value of errno specified by lseek()
*/
int
bfcommit(fp)
FILE *fp;
{
struct bf *bfp;
int retval;
int byteswritten;
/* If called on a normal FILE *, noop */
if (!bftest(fp))
return 0;
/* Get associated bf structure */
bfp = (struct bf *)fp->_cookie;
/* If already committed, noop */
if (bfp->bf_committed)
return 0;
/* Do we need to open a file? */
if (!bfp->bf_ondisk)
{
struct stat st;
if (tTd(58, 8))
dprintf("bfcommit(%s): to disk\n", bfp->bf_filename);
if (stat(bfp->bf_filename, &st) == 0)
{
errno = EEXIST;
return -1;
}
retval = OPEN(bfp->bf_filename, O_RDWR | O_CREAT | O_TRUNC,
bfp->bf_filemode, bfp->bf_flags);
/* Couldn't create file: failure */
if (retval < 0)
{
/* errno is set implicitly by open() */
return -1;
}
bfp->bf_disk_fd = retval;
bfp->bf_ondisk = TRUE;
}
/* Write out the contents of our buffer, if we have any */
if (bfp->bf_buffilled > 0)
{
byteswritten = 0;
if (lseek(bfp->bf_disk_fd, 0, SEEK_SET) < 0)
{
/* errno is set implicitly by lseek() */
return -1;
}
while (byteswritten < bfp->bf_buffilled)
{
retval = write(bfp->bf_disk_fd,
bfp->bf_buf + byteswritten,
bfp->bf_buffilled - byteswritten);
if (retval < 0)
{
/* errno is set implicitly by write() */
return -1;
}
else
byteswritten += retval;
}
}
bfp->bf_committed = TRUE;
/* Invalidate buf; all goes to file now */
bfp->bf_buffilled = 0;
if (bfp->bf_bufsize > 0)
{
/* Don't need buffer anymore; free it */
bfp->bf_bufsize = 0;
sm_free(bfp->bf_buf);
}
return 0;
}
/*
** BFREWIND -- rewinds the FILE *
**
** Parameters:
** fp -- FILE * to rewind
**
** Returns:
** 0 on success, -1 on error
**
** Side Effects:
** rewinds the FILE * and puts it into read mode. Normally one
** would bfopen() a file, write to it, then bfrewind() and
** fread(). If fp is not a buffered file, this is equivalent to
** rewind().
**
** Sets errno:
** any value of errno specified by fseek()
*/
int
bfrewind(fp)
FILE *fp;
{
int err;
/* check to see if there is an error on the stream */
err = ferror(fp);
(void) fflush(fp);
/*
** Clear error if tried to fflush()
** a read-only file pointer and
** there wasn't a previous error.
*/
if (err == 0)
clearerr(fp);
/* errno is set implicitly by fseek() before return */
return fseek(fp, 0, SEEK_SET);
}
/*
** BFTRUNCATE -- rewinds and truncates the FILE *
**
** Parameters:
** fp -- FILE * to truncate
**
** Returns:
** 0 on success, -1 on error
**
** Side Effects:
** rewinds the FILE *, truncates it to zero length, and puts it
** into write mode. If fp is not a buffered file, this is
** equivalent to a rewind() and then an ftruncate(fileno(fp), 0).
**
** Sets errno:
** any value of errno specified by fseek()
** any value of errno specified by ftruncate()
*/
int
bftruncate(fp)
FILE *fp;
{
struct bf *bfp;
if (bfrewind(fp) < 0)
return -1;
if (bftest(fp))
{
/* Get bf structure */
bfp = (struct bf *)fp->_cookie;
bfp->bf_buffilled = 0;
bfp->bf_size = 0;
/* Need to zero the buffer */
if (bfp->bf_bufsize > 0)
memset(bfp->bf_buf, '\0', bfp->bf_bufsize);
if (bfp->bf_ondisk)
return ftruncate(bfp->bf_disk_fd, 0);
else
return 0;
}
else
return ftruncate(fileno(fp), 0);
}
/*
** BFFSYNC -- fsync the fd associated with the FILE *
**
** Parameters:
** fp -- FILE * to fsync
**
** Returns:
** 0 on success, -1 on error
**
** Sets errno:
** EINVAL if FILE * not bfcommitted yet.
** any value of errno specified by fsync()
*/
int
bffsync(fp)
FILE *fp;
{
int fd;
struct bf *bfp;
if (bftest(fp))
{
/* Get bf structure */
bfp = (struct bf *)fp->_cookie;
if (bfp->bf_ondisk && bfp->bf_committed)
fd = bfp->bf_disk_fd;
else
fd = -1;
}
else
fd = fileno(fp);
if (tTd(58, 10))
dprintf("bffsync: fd = %d\n", fd);
if (fd < 0)
{
errno = EINVAL;
return -1;
}
return fsync(fd);
}
/*
** BFCLOSE -- close a buffered file
**
** Parameters:
** fp -- FILE * to close
**
** Returns:
** 0 on success, EOF on failure
**
** Side Effects:
** Closes fp. If fp is a buffered file, unlink it if it has not
** already been committed. If fp is not a buffered file, this is
** equivalent to fclose().
**
** Sets errno:
** any value of errno specified by fclose()
*/
int
bfclose(fp)
FILE *fp;
{
struct bf *bfp;
/* If called on a normal FILE *, call fclose() on it */
if (!bftest(fp))
return fclose(fp);
/* Cast cookie back to correct type */
bfp = (struct bf *)fp->_cookie;
/* Check reference count to see if we actually want to close */
if (bfp != NULL && --bfp->bf_refcount > 0)
return 0;
/*
** In this implementation, just call fclose--the _bfclose
** routine will be called by that
*/
return fclose(fp);
}
/*
** BFTEST -- test if a FILE * is a buffered file
**
** Parameters:
** fp -- FILE * to test
**
** Returns:
** TRUE if fp is a buffered file, FALSE otherwise.
**
** Side Effects:
** none.
**
** Sets errno:
** never.
*/
bool
bftest(fp)
FILE *fp;
{
/*
** Check to see if our special I/O routines are installed
** in this file structure
*/
return ((fp->_close == _bfclose) &&
(fp->_read == _bfread) &&
(fp->_seek == _bfseek) &&
(fp->_write == _bfwrite));
}
/*
** _BFCLOSE -- close a buffered file
**
** Parameters:
** cookie -- cookie of file to close
**
** Returns:
** 0 to indicate success
**
** Side Effects:
** deletes backing file, frees memory.
**
** Sets errno:
** never.
*/
int
_bfclose(cookie)
void *cookie;
{
struct bf *bfp;
/* Cast cookie back to correct type */
bfp = (struct bf *)cookie;
/* Need to clean up the file */
if (bfp->bf_ondisk && !bfp->bf_committed)
unlink(bfp->bf_filename);
/* Need to free the buffer */
if (bfp->bf_bufsize > 0)
sm_free(bfp->bf_buf);
/* Finally, free the structure */
sm_free(bfp);
return 0;
}
/*
** _BFREAD -- read a buffered file
**
** Parameters:
** cookie -- cookie of file to read
** buf -- buffer to fill
** nbytes -- how many bytes to read
**
** Returns:
** number of bytes read or -1 indicate failure
**
** Side Effects:
** none.
**
*/
int
_bfread(cookie, buf, nbytes)
void *cookie;
char *buf;
int nbytes;
{
struct bf *bfp;
int count = 0; /* Number of bytes put in buf so far */
int retval;
/* Cast cookie back to correct type */
bfp = (struct bf *)cookie;
if (bfp->bf_offset < bfp->bf_buffilled)
{
/* Need to grab some from buffer */
count = nbytes;
if ((bfp->bf_offset + count) > bfp->bf_buffilled)
count = bfp->bf_buffilled - bfp->bf_offset;
memcpy(buf, bfp->bf_buf + bfp->bf_offset, count);
}
if ((bfp->bf_offset + nbytes) > bfp->bf_buffilled)
{
/* Need to grab some from file */
if (!bfp->bf_ondisk)
{
/* Oops, the file doesn't exist. EOF. */
goto finished;
}
/* Catch a read() on an earlier failed write to disk */
if (bfp->bf_disk_fd < 0)
{
errno = EIO;
return -1;
}
if (lseek(bfp->bf_disk_fd,
bfp->bf_offset + count, SEEK_SET) < 0)
{
if ((errno == EINVAL) || (errno == ESPIPE))
{
/*
** stdio won't be expecting these
** errnos from read()! Change them
** into something it can understand.
*/
errno = EIO;
}
return -1;
}
while (count < nbytes)
{
retval = read(bfp->bf_disk_fd,
buf + count,
nbytes - count);
if (retval < 0)
{
/* errno is set implicitly by read() */
return -1;
}
else if (retval == 0)
goto finished;
else
count += retval;
}
}
finished:
bfp->bf_offset += count;
return count;
}
/*
** _BFSEEK -- seek to a position in a buffered file
**
** Parameters:
** cookie -- cookie of file to seek
** offset -- position to seek to
** whence -- how to seek
**
** Returns:
** new file offset or -1 indicate failure
**
** Side Effects:
** none.
**
*/
fpos_t
_bfseek(cookie, offset, whence)
void *cookie;
fpos_t offset;
int whence;
{
struct bf *bfp;
/* Cast cookie back to correct type */
bfp = (struct bf *)cookie;
switch (whence)
{
case SEEK_SET:
bfp->bf_offset = offset;
break;
case SEEK_CUR:
bfp->bf_offset += offset;
break;
case SEEK_END:
bfp->bf_offset = bfp->bf_size + offset;
break;
default:
errno = EINVAL;
return -1;
}
return bfp->bf_offset;
}
/*
** _BFWRITE -- write to a buffered file
**
** Parameters:
** cookie -- cookie of file to write
** buf -- data buffer
** nbytes -- how many bytes to write
**
** Returns:
** number of bytes written or -1 indicate failure
**
** Side Effects:
** may create backing file if over memory limit for file.
**
*/
int
_bfwrite(cookie, buf, nbytes)
void *cookie;
const char *buf;
int nbytes;
{
struct bf *bfp;
int count = 0; /* Number of bytes written so far */
int retval;
/* Cast cookie back to correct type */
bfp = (struct bf *)cookie;
/* If committed, go straight to disk */
if (bfp->bf_committed)
{
if (lseek(bfp->bf_disk_fd, bfp->bf_offset, SEEK_SET) < 0)
{
if ((errno == EINVAL) || (errno == ESPIPE))
{
/*
** stdio won't be expecting these
** errnos from write()! Change them
** into something it can understand.
*/
errno = EIO;
}
return -1;
}
count = write(bfp->bf_disk_fd, buf, nbytes);
if (count < 0)
{
/* errno is set implicitly by write() */
return -1;
}
goto finished;
}
if (bfp->bf_offset < bfp->bf_bufsize)
{
/* Need to put some in buffer */
count = nbytes;
if ((bfp->bf_offset + count) > bfp->bf_bufsize)
count = bfp->bf_bufsize - bfp->bf_offset;
memcpy(bfp->bf_buf + bfp->bf_offset, buf, count);
if ((bfp->bf_offset + count) > bfp->bf_buffilled)
bfp->bf_buffilled = bfp->bf_offset + count;
}
if ((bfp->bf_offset + nbytes) > bfp->bf_bufsize)
{
/* Need to put some in file */
if (!bfp->bf_ondisk)
{
/* Oops, the file doesn't exist. */
if (tTd(58, 8))
dprintf("_bfwrite(%s): to disk\n",
bfp->bf_filename);
retval = OPEN(bfp->bf_filename,
O_RDWR | O_CREAT | O_TRUNC,
bfp->bf_filemode, bfp->bf_flags);
/* Couldn't create file: failure */
if (retval < 0)
{
/*
** stdio may not be expecting these
** errnos from write()! Change to
** something which it can understand.
** Note that ENOSPC and EDQUOT are saved
** because they are actually valid for
** write().
*/
if (!((errno == ENOSPC) || (errno == EDQUOT)))
errno = EIO;
return -1;
}
bfp->bf_disk_fd = retval;
bfp->bf_ondisk = TRUE;
}
/* Catch a write() on an earlier failed write to disk */
if (bfp->bf_ondisk && bfp->bf_disk_fd < 0)
{
errno = EIO;
return -1;
}
if (lseek(bfp->bf_disk_fd,
bfp->bf_offset + count, SEEK_SET) < 0)
{
if ((errno == EINVAL) || (errno == ESPIPE))
{
/*
** stdio won't be expecting these
** errnos from write()! Change them into
** something which it can understand.
*/
errno = EIO;
}
return -1;
}
while (count < nbytes)
{
retval = write(bfp->bf_disk_fd, buf + count,
nbytes - count);
if (retval < 0)
{
/* errno is set implicitly by write() */
return -1;
}
else
count += retval;
}
}
finished:
bfp->bf_offset += count;
if (bfp->bf_offset > bfp->bf_size)
bfp->bf_size = bfp->bf_offset;
return count;
}

View File

@ -1,42 +0,0 @@
/*
* Copyright (c) 1999 Sendmail, Inc. and its suppliers.
* All rights reserved.
*
* By using this file, you agree to the terms and conditions set
* forth in the LICENSE file which can be found at the top level of
* the sendmail distribution.
*
* $Id: bf_torek.h,v 8.6 1999/11/04 19:31:25 ca Exp $
*
* Contributed by Exactis.com, Inc.
*
*/
#ifndef BF_TOREK_H
#define BF_TOREK_H 1
/*
** Data structure for storing information about each buffered file
*/
struct bf
{
bool bf_committed; /* Has this buffered file been committed? */
bool bf_ondisk; /* On disk: committed or buffer overflow */
int bf_flags;
int bf_disk_fd; /* If on disk, associated file descriptor */
char *bf_buf; /* Memory buffer */
int bf_bufsize; /* Length of above buffer */
int bf_buffilled; /* Bytes of buffer actually filled */
char *bf_filename; /* Name of buffered file, if ever committed */
mode_t bf_filemode; /* Mode of buffered file, if ever committed */
fpos_t bf_offset; /* Currect file offset */
int bf_size; /* Total current size of file */
int bf_refcount; /* Reference count */
};
/* Our lower-level I/O routines */
extern int _bfclose __P((void *));
extern int _bfread __P((void *, char *, int));
extern fpos_t _bfseek __P((void *, fpos_t, int));
extern int _bfwrite __P((void *, const char *, int));
#endif /* BF_TOREK_H */

View File

@ -1,513 +0,0 @@
/*
* Copyright (c) 1998-2001 Sendmail, Inc. and its suppliers.
* All rights reserved.
* Copyright (c) 1983, 1995-1997 Eric P. Allman. All rights reserved.
* Copyright (c) 1988, 1993
* The Regents of the University of California. All rights reserved.
*
* By using this file, you agree to the terms and conditions set
* forth in the LICENSE file which can be found at the top level of
* the sendmail distribution.
*
*/
#ifndef lint
static char id[] = "@(#)$Id: clock.c,v 8.52.18.18 2001/08/14 16:07:04 ca Exp $";
#endif /* ! lint */
#include <sendmail.h>
#ifndef sigmask
# define sigmask(s) (1 << ((s) - 1))
#endif /* ! sigmask */
static SIGFUNC_DECL sm_tick __P((int));
static void endsleep __P((void));
/*
** SETEVENT -- set an event to happen at a specific time.
**
** Events are stored in a sorted list for fast processing.
** An event only applies to the process that set it.
**
** Parameters:
** intvl -- intvl until next event occurs.
** func -- function to call on event.
** arg -- argument to func on event.
**
** Returns:
** none.
**
** Side Effects:
** none.
*/
static EVENT *volatile EventQueue; /* head of event queue */
static EVENT *volatile FreeEventList; /* list of free events */
EVENT *
setevent(intvl, func, arg)
time_t intvl;
void (*func)();
int arg;
{
register EVENT *ev;
if (intvl <= 0)
{
syserr("554 5.3.0 setevent: intvl=%ld\n", intvl);
return NULL;
}
ENTER_CRITICAL();
if (FreeEventList == NULL)
{
FreeEventList = (EVENT *) xalloc(sizeof *FreeEventList);
FreeEventList->ev_link = NULL;
}
LEAVE_CRITICAL();
ev = sigsafe_setevent(intvl, func, arg);
if (tTd(5, 5))
dprintf("setevent: intvl=%ld, for=%ld, func=%lx, arg=%d, ev=%lx\n",
(long) intvl, (long) (curtime() + intvl),
(u_long) func, arg,
ev == NULL ? 0 : (u_long) ev);
return ev;
}
/*
**
** NOTE: THIS CAN BE CALLED FROM A SIGNAL HANDLER. DO NOT ADD
** ANYTHING TO THIS ROUTINE UNLESS YOU KNOW WHAT YOU ARE
** DOING.
*/
EVENT *
sigsafe_setevent(intvl, func, arg)
time_t intvl;
void (*func)();
int arg;
{
register EVENT **evp;
register EVENT *ev;
auto time_t now;
int wasblocked;
if (intvl <= 0)
return NULL;
wasblocked = blocksignal(SIGALRM);
now = curtime();
/* search event queue for correct position */
for (evp = (EVENT **) (&EventQueue);
(ev = *evp) != NULL;
evp = &ev->ev_link)
{
if (ev->ev_time >= now + intvl)
break;
}
ENTER_CRITICAL();
if (FreeEventList == NULL)
{
/*
** This shouldn't happen. If called from setevent(),
** we have just malloced a FreeEventList entry. If
** called from a signal handler, it should have been
** from an existing event which sm_tick() just added to the
** FreeEventList.
*/
LEAVE_CRITICAL();
return NULL;
}
else
{
ev = FreeEventList;
FreeEventList = ev->ev_link;
}
LEAVE_CRITICAL();
/* insert new event */
ev->ev_time = now + intvl;
ev->ev_func = func;
ev->ev_arg = arg;
ev->ev_pid = getpid();
ENTER_CRITICAL();
ev->ev_link = *evp;
*evp = ev;
LEAVE_CRITICAL();
(void) setsignal(SIGALRM, sm_tick);
intvl = EventQueue->ev_time - now;
(void) alarm((unsigned) intvl < 1 ? 1 : intvl);
if (wasblocked == 0)
(void) releasesignal(SIGALRM);
return ev;
}
/*
** CLREVENT -- remove an event from the event queue.
**
** Parameters:
** ev -- pointer to event to remove.
**
** Returns:
** none.
**
** Side Effects:
** arranges for event ev to not happen.
*/
void
clrevent(ev)
register EVENT *ev;
{
register EVENT **evp;
int wasblocked;
if (tTd(5, 5))
dprintf("clrevent: ev=%lx\n", (u_long) ev);
if (ev == NULL)
return;
/* find the parent event */
wasblocked = blocksignal(SIGALRM);
for (evp = (EVENT **) (&EventQueue);
*evp != NULL;
evp = &(*evp)->ev_link)
{
if (*evp == ev)
break;
}
/* now remove it */
if (*evp != NULL)
{
ENTER_CRITICAL();
*evp = ev->ev_link;
ev->ev_link = FreeEventList;
FreeEventList = ev;
LEAVE_CRITICAL();
}
/* restore clocks and pick up anything spare */
if (wasblocked == 0)
(void) releasesignal(SIGALRM);
if (EventQueue != NULL)
(void) kill(getpid(), SIGALRM);
else
{
/* nothing left in event queue, no need for an alarm */
(void) alarm(0);
}
}
/*
** CLEAR_EVENTS -- remove all events from the event queue.
**
** Parameters:
** none.
**
** Returns:
** none.
*/
void
clear_events()
{
register EVENT *ev;
int wasblocked;
if (tTd(5, 5))
dprintf("clear_events: EventQueue=%lx\n", (u_long) EventQueue);
if (EventQueue == NULL)
return;
/* nothing will be left in event queue, no need for an alarm */
(void) alarm(0);
wasblocked = blocksignal(SIGALRM);
/* find the end of the EventQueue */
for (ev = EventQueue; ev->ev_link != NULL; ev = ev->ev_link)
continue;
ENTER_CRITICAL();
ev->ev_link = FreeEventList;
FreeEventList = EventQueue;
EventQueue = NULL;
LEAVE_CRITICAL();
/* restore clocks and pick up anything spare */
if (wasblocked == 0)
(void) releasesignal(SIGALRM);
}
/*
** SM_TICK -- take a clock sm_tick
**
** Called by the alarm clock. This routine runs events as needed.
** Always called as a signal handler, so we assume that SIGALRM
** has been blocked.
**
** Parameters:
** One that is ignored; for compatibility with signal handlers.
**
** Returns:
** none.
**
** Side Effects:
** calls the next function in EventQueue.
**
** NOTE: THIS CAN BE CALLED FROM A SIGNAL HANDLER. DO NOT ADD
** ANYTHING TO THIS ROUTINE UNLESS YOU KNOW WHAT YOU ARE
** DOING.
*/
/* ARGSUSED */
static SIGFUNC_DECL
sm_tick(sig)
int sig;
{
register time_t now;
register EVENT *ev;
pid_t mypid;
int save_errno = errno;
(void) alarm(0);
FIX_SYSV_SIGNAL(sig, sm_tick);
errno = save_errno;
CHECK_CRITICAL(sig);
mypid = getpid();
while (PendingSignal != 0)
{
int sigbit = 0;
int sig = 0;
if (bitset(PEND_SIGHUP, PendingSignal))
{
sigbit = PEND_SIGHUP;
sig = SIGHUP;
}
else if (bitset(PEND_SIGINT, PendingSignal))
{
sigbit = PEND_SIGINT;
sig = SIGINT;
}
else if (bitset(PEND_SIGTERM, PendingSignal))
{
sigbit = PEND_SIGTERM;
sig = SIGTERM;
}
else if (bitset(PEND_SIGUSR1, PendingSignal))
{
sigbit = PEND_SIGUSR1;
sig = SIGUSR1;
}
else
{
/* If we get here, we are in trouble */
abort();
}
PendingSignal &= ~sigbit;
kill(mypid, sig);
}
now = curtime();
if (tTd(5, 4))
dprintf("sm_tick: now=%ld\n", (long) now);
while ((ev = EventQueue) != NULL &&
(ev->ev_time <= now || ev->ev_pid != mypid))
{
void (*f)();
int arg;
pid_t pid;
/* process the event on the top of the queue */
ENTER_CRITICAL();
ev = EventQueue;
EventQueue = EventQueue->ev_link;
LEAVE_CRITICAL();
if (tTd(5, 6))
dprintf("sm_tick: ev=%lx, func=%lx, arg=%d, pid=%d\n",
(u_long) ev, (u_long) ev->ev_func,
ev->ev_arg, ev->ev_pid);
/* we must be careful in here because ev_func may not return */
f = ev->ev_func;
arg = ev->ev_arg;
pid = ev->ev_pid;
ENTER_CRITICAL();
ev->ev_link = FreeEventList;
FreeEventList = ev;
LEAVE_CRITICAL();
if (pid != mypid)
continue;
if (EventQueue != NULL)
{
if (EventQueue->ev_time > now)
(void) alarm((unsigned) (EventQueue->ev_time - now));
else
(void) alarm(3);
}
/* call ev_func */
errno = save_errno;
(*f)(arg);
(void) alarm(0);
now = curtime();
}
if (EventQueue != NULL)
(void) alarm((unsigned) (EventQueue->ev_time - now));
errno = save_errno;
return SIGFUNC_RETURN;
}
/*
** PEND_SIGNAL -- Add a signal to the pending signal list
**
** Parameters:
** sig -- signal to add
**
** Returns:
** none.
**
** NOTE: THIS CAN BE CALLED FROM A SIGNAL HANDLER. DO NOT ADD
** ANYTHING TO THIS ROUTINE UNLESS YOU KNOW WHAT YOU ARE
** DOING.
*/
void
pend_signal(sig)
int sig;
{
int sigbit;
int save_errno = errno;
/*
** Don't want to interrupt something critical, hence delay
** the alarm for one second. Hopefully, by then we
** will be out of the critical section. If not, then
** we will just delay again. The events to be run will
** still all be run, maybe just a little bit late.
*/
switch (sig)
{
case SIGHUP:
sigbit = PEND_SIGHUP;
break;
case SIGINT:
sigbit = PEND_SIGINT;
break;
case SIGTERM:
sigbit = PEND_SIGTERM;
break;
case SIGUSR1:
sigbit = PEND_SIGUSR1;
break;
case SIGALRM:
/* don't have to pend these */
sigbit = 0;
break;
default:
/* If we get here, we are in trouble */
abort();
/* NOTREACHED */
/* shut up stupid compiler warning on HP-UX 11 */
sigbit = 0;
break;
}
if (sigbit != 0)
PendingSignal |= sigbit;
(void) setsignal(SIGALRM, sm_tick);
(void) alarm(1);
errno = save_errno;
}
/*
** SM_SIGNAL_NOOP -- A signal no-op function
**
** Parameters:
** sig -- signal received
**
** Returns:
** SIGFUNC_RETURN
*/
/* ARGSUSED */
SIGFUNC_DECL
sm_signal_noop(sig)
int sig;
{
int save_errno = errno;
FIX_SYSV_SIGNAL(sig, sm_signal_noop);
errno = save_errno;
return SIGFUNC_RETURN;
}
/*
** SLEEP -- a version of sleep that works with this stuff
**
** Because sleep uses the alarm facility, I must reimplement
** it here.
**
** Parameters:
** intvl -- time to sleep.
**
** Returns:
** none.
**
** Side Effects:
** waits for intvl time. However, other events can
** be run during that interval.
*/
static bool volatile SleepDone;
#ifndef SLEEP_T
# define SLEEP_T unsigned int
#endif /* ! SLEEP_T */
SLEEP_T
sleep(intvl)
unsigned int intvl;
{
int was_held;
if (intvl == 0)
return (SLEEP_T) 0;
SleepDone = FALSE;
(void) setevent((time_t) intvl, endsleep, 0);
was_held = releasesignal(SIGALRM);
while (!SleepDone)
(void) pause();
if (was_held > 0)
(void) blocksignal(SIGALRM);
return (SLEEP_T) 0;
}
static void
endsleep()
{
/*
** NOTE: THIS CAN BE CALLED FROM A SIGNAL HANDLER. DO NOT ADD
** ANYTHING TO THIS ROUTINE UNLESS YOU KNOW WHAT YOU ARE
** DOING.
*/
SleepDone = TRUE;
}