Revision 296e14301a7aa23a5ee2bfaa1210af54e594cbbf authored by Guido van Rossum on 07 April 1999, 15:03:39 UTC, committed by Guido van Rossum on 07 April 1999, 15:03:39 UTC
Per writes:

"""
The application where Signum Support uses smtplib needs to be able to
report good error messages to the user when sending email fails.  To
help in diagnosing problems it is useful to be able to report the
entire message sent by the server, not only the SMTP error code of the
offending command.

A lot of the functions in sendmail.py unfortunately discards the
message, leaving only the code.  The enclosed patch fixes that
problem.

The enclosed patch also introduces a base class for exceptions that
include an SMTP error code and error message, and make the code and
message available on separate attributes, so that surrounding code can
deal with them in whatever way it sees fit.  I've also added some
documentation to the exception classes.

The constructor will now raise an exception if it cannot connect to
the SMTP server.

The data() method will raise an SMTPDataError if it doesn't receive
the expected 354 code in the middle of the exchange.

According to section 5.2.10 of RFC 1123 a smtp client must accept "any
text, including no text at all" after the error code.  If the response
of a HELO command contains no text self.helo_resp will be set to the
empty string ("").  The patch fixes the test in the sendmail() method
so that helo_resp is tested against None; if it has the empty string
as value the sendmail() method would invoke the helo() method again.

The code no longer accepts a -1 reply from the ehlo() method in
sendmail().

[Text about removing SMTPRecipientsRefused deleted --GvR]
"""

and also:

"""
smtplib.py appends an extra blank line to the outgoing mail if the
`msg' argument to the sendmail method already contains a trailing
newline.  This patch should fix the problem.
"""

The Dragon writes:

"""
	Mostly I just re-added the SMTPRecipientsRefused exception
(the exeption object now has the appropriate info in it ) [Per had
removed this in his patch --GvR] and tweaked the behavior of the
sendmail method whence it throws the newly added SMTPHeloException (it
was closing the connection, which it shouldn't.  whatever catches the
exception should do that. )

	I pondered the change of the return values to tuples all around,
and after some thinking I decided that regularizing the return values was
too much of the Right Thing (tm) to not do.

	My one concern is that code expecting an integer & getting a tuple
may fail silently.

(i.e. if it's doing :

      x.somemethod() >= 400:
expecting an integer, the expression will always be true if it gets a
tuple instead. )

	However, most smtplib code I've seen only really uses the
sendmail() method, so this wouldn't bother it.  Usually code I've seen
that calls the other methods usually only calls helo() and ehlo() for
doing ESMTP, a feature which was not in the smtplib included with 1.5.1,
and thus I would think not much code uses it yet.
"""
1 parent 630a9a6
Raw File
mymalloc.h
#ifndef Py_MYMALLOC_H
#define Py_MYMALLOC_H
/***********************************************************
Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam,
The Netherlands.

                        All Rights Reserved

Permission to use, copy, modify, and distribute this software and its
documentation for any purpose and without fee is hereby granted,
provided that the above copyright notice appear in all copies and that
both that copyright notice and this permission notice appear in
supporting documentation, and that the names of Stichting Mathematisch
Centrum or CWI or Corporation for National Research Initiatives or
CNRI not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior
permission.

While CWI is the initial source for this software, a modified version
is made available by the Corporation for National Research Initiatives
(CNRI) at the Internet address ftp://ftp.python.org.

STICHTING MATHEMATISCH CENTRUM AND CNRI DISCLAIM ALL WARRANTIES WITH
REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH
CENTRUM OR CNRI BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.

******************************************************************/

/* Lowest-level memory allocation interface */

#ifdef macintosh
#define ANY void
#endif

#ifdef __STDC__
#define ANY void
#endif

#ifdef __TURBOC__
#define ANY void
#endif

#ifdef __GNUC__
#define ANY void
#endif

#ifndef ANY
#define ANY char
#endif

#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif

#ifdef __cplusplus
/* Move this down here since some C++ #include's don't like to be included
   inside an extern "C" */
extern "C" {
#endif

#ifdef SYMANTEC__CFM68K__
#pragma lib_export on
#endif

/* The following should never be necessary */
#ifdef NEED_TO_DECLARE_MALLOC_AND_FRIEND
extern ANY *malloc Py_PROTO((size_t));
extern ANY *calloc Py_PROTO((size_t, size_t));
extern ANY *realloc Py_PROTO((ANY *, size_t));
extern void free Py_PROTO((ANY *)); /* XXX sometimes int on Unix old systems */
#endif

#ifndef NULL
#define NULL ((ANY *)0)
#endif

#ifdef MALLOC_ZERO_RETURNS_NULL
/* XXX Always allocate one extra byte, since some malloc's return NULL
   XXX for malloc(0) or realloc(p, 0). */
#define _PyMem_EXTRA 1
#else
#define _PyMem_EXTRA 0
#endif

#define PyMem_NEW(type, n) \
	( (type *) malloc(_PyMem_EXTRA + (n) * sizeof(type)) )
#define PyMem_RESIZE(p, type, n) \
	if ((p) == NULL) \
		(p) =  (type *) malloc(_PyMem_EXTRA + (n) * sizeof(type)); \
	else \
		(p) = (type *) realloc((ANY *)(p), \
				       _PyMem_EXTRA + (n) * sizeof(type))
#define PyMem_DEL(p) free((ANY *)p)
#define PyMem_XDEL(p) if ((p) == NULL) ; else PyMem_DEL(p)


/* Two sets of function wrappers around malloc and friends; useful if
   you need to be sure that you are using the same memory allocator as
   Python.  Note that the wrappers make sure that allocating 0 bytes
   returns a non-NULL pointer, even if the underlying malloc doesn't.
   The Python interpreter continues to use PyMem_NEW etc. */

/* These wrappers around malloc call PyErr_NoMemory() on failure */
extern DL_IMPORT(ANY *) Py_Malloc Py_PROTO((size_t));
extern DL_IMPORT(ANY *) Py_Realloc Py_PROTO((ANY *, size_t));
extern DL_IMPORT(void) Py_Free Py_PROTO((ANY *));

/* These wrappers around malloc *don't* call anything on failure */
extern DL_IMPORT(ANY *) PyMem_Malloc Py_PROTO((size_t));
extern DL_IMPORT(ANY *) PyMem_Realloc Py_PROTO((ANY *, size_t));
extern DL_IMPORT(void) PyMem_Free Py_PROTO((ANY *));

#ifdef __cplusplus
}
#endif

#endif /* !Py_MYMALLOC_H */
back to top