Remove files no longer part of the sendmail 8.12.2 distribution.
This commit is contained in:
parent
4026605903
commit
04bb1e1f17
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/vendor/sendmail/dist/; revision=90809
@ -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
|
@ -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
|
@ -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
|
@ -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
|
@ -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_ */
|
@ -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));
|
@ -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 */
|
@ -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 */
|
||||
}
|
||||
|
@ -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 */
|
@ -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;
|
||||
}
|
@ -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 */
|
@ -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;
|
||||
}
|
@ -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 */
|
@ -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;
|
||||
}
|
Loading…
Reference in New Issue
Block a user