From: Eduard.Vopicka@vse.cs (Eduard Vopicka)
Newsgroups: comp.unix.wizards
Subject: (none)
Date: 10 Sep 92 13:00:18 GMT

~s Sendmail/IDA and frozen config files

Hi all you UNIX wizards!

I am (hopefully) done with sendmail-6.67a8/IDA-1.5 port to SCO 3.2.2.
I have had no significant problems while doing this. Now I am trying
to get the same program working under Interactive UNIX. And here is my
problem - I cannot get easily over it:

The sendmail/IDA frozen configuration files are known not to work
under various UNIX implementations, in my case under Interactive UNIX.
This fact is evidently known - quick scan through source files shows
the frozen config file option being carefully automatically excluded
while compiling sendmail/IDA under Interactive UNIX.

This is normally not a problem but if the mail load on the machine is
heavy things are getting unacceptably slow. I have heard some rumors that
both the source of the problem and the solution are known, but I failed to
find the answer. (Of course the solution must be known, the sendmail binary
supplied with the Interactive operating system supports the frozen config
files.)

So I have tried to forcibly enable the frozen config files option. But
no fun. I have observed that sendmail fails on the malloc() after the
frozen config file is read. malloc() returns NULL and sendmail then
complains with "Out of memory!!" and exits.

Please does any of you UNIX wizards know the solution and can you kick me
in the right direction. Any help will be highly appreciated - my goal is
to have the same sendmail/IDA running on all our UNIXes here at Prague
School of Economics. And the frozen configuration files seem to be
essential in our environment.

Please can you send any answers to this list or directly to eda@vse.cs.

Thanks in advance,

Ed

============================================================================
= Eduard Vopicka                             e-mail: Eduard.Vopicka@vse.cs =
= Computing Centre                              fax: +42 2 235 85 09       =
= Prague School of Economics                                               =
= W. Churchill square 4                                                    =
= CS 130 67 Prague 3                      ("There is always one more bug") =
============================================================================

Attached are two excerpts from the sendmail's main.c, the freeze() and
thaw() procedures.

/*
 * Copyright (c) 1983 Eric P. Allman
 * Copyright (c) 1988 Regents of the University of California.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *	This product includes software developed by the University of
 *	California, Berkeley and its contributors.
 * 4. Neither the name of the University nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

static void freeze __P((char *));
static thaw __P((char *));

#ifdef _PATH_SENDMAILFC
/*
**  FREEZE -- freeze BSS & allocated memory
**
**	This will be used to efficiently load the configuration file.
**
**	Parameters:
**		freezefile -- the name of the file to freeze to.
**
**	Returns:
**		none.
**
**	Side Effects:
**		Writes BSS and malloc'ed memory to freezefile
*/

union frz
{
	char		frzpad[BUFSIZ];	/* insure we are on a BUFSIZ boundary */
	struct
	{
		TIME_TYPE frzstamp;	/* timestamp on this freeze */
		char	*frzbrk;	/* the current break */
		char	*frzedata;	/* address of edata */
		char	*frzend;	/* address of end */
		char	frzver[252];	/* sendmail version */
		char	frzdatecompiled[64];	/* sendmail compilation date */
	} frzinfo;
};

static void
freeze(freezefile)
	char *freezefile;
{
	int f;
	union frz fhdr;
	extern int edata, end;
# if defined(__hpux)
	extern void *sbrk __P((int));
# else /* !__hpux */
	extern char *sbrk __P((int));
# endif /* __hpux */
	extern char Version[];
	extern char datecompiled[];

	if (freezefile == NULL)
		return;
# ifdef notdef
	{
		/*
		** NIS (nee YP) state is saved in the freeze, the readback
		** of the freeze file destroys similar information.  This
		** causes strange results later due to the unexpected closing
		** of a file descriptor using a stale copy.
		*/

		char *domain;
		if (yp_get_default_domain(&domain) == 0)
			yp_unbind(domain);
	}
# endif /* YP */

	/* try to open the freeze file */
	if ((f = open(freezefile, O_WRONLY|O_CREAT|O_TRUNC, FileMode)) < 0)
	{
		syserr("Cannot freeze %s", freezefile);
		errno = 0;
		return;
	}

	/* build the freeze header */
	fhdr.frzinfo.frzstamp = curtime();
	fhdr.frzinfo.frzbrk = sbrk(0);
	fhdr.frzinfo.frzedata = (char *) &edata;
	fhdr.frzinfo.frzend = (char *) &end;
	(void) strcpy(fhdr.frzinfo.frzver, Version);
	(void) strcpy(fhdr.frzinfo.frzdatecompiled, datecompiled);

	/* write out the freeze header */
	if (write(f, (char *) &fhdr, sizeof fhdr) != sizeof fhdr ||
	    write(f, (char *) &edata, (int) (fhdr.frzinfo.frzbrk - (char *) &edata)) !=
					(int) (fhdr.frzinfo.frzbrk - (char *) &edata))
	{
		syserr("Cannot freeze %s", freezefile);
	}

	/* fine, clean up */
	(void) close(f);
}

/*
**  THAW -- read in the frozen configuration file.
**
**	Parameters:
**		freezefile -- the name of the file to thaw from.
**
**	Returns:
**		TRUE if it successfully read the freeze file.
**		FALSE otherwise.
**
**	Side Effects:
**		reads freezefile in to BSS area.
*/

static int
thaw(freezefile)
	char *freezefile;
{
	int f;
	union frz fhdr;
	extern int edata, end;
	extern char Version[];
	extern char datecompiled[];
# if defined(__hpux)
	extern int brk __P((const void *));
# else /* !__hpux */
	extern char *brk __P((const char *));
# endif /* __hpux */

	if (freezefile == NULL)
		return (FALSE);

	/* open the freeze file */
	if ((f = open(freezefile, O_RDONLY, 0)) < 0)
	{
# ifdef LOG
		if (OpMode == MD_DAEMON)
			syslog(LOG_WARNING, "Cannot open frozen config file %s: %m", freezefile);
# endif /* LOG */
		errno = 0;
		return (FALSE);
	}
# ifdef notdef
	{
		/*
		** NIS (nee YP) state is saved in the freeze, the readback
		** of the freeze file destroys similar information.  This
		** causes strange results later due to the unexpected closing
		** of a file descriptor using a stale copy.
		*/

		char *domain;
		if (yp_get_default_domain(&domain) == 0)
			yp_unbind(domain);
	}
# endif /* YP */

	/* read in the header */
	if (read(f, (char *) &fhdr, sizeof fhdr) < sizeof fhdr)
	{
		syserr("Cannot read frozen config file");
		(void) close(f);
		return (FALSE);
	}
	{
		char why[40];

		*why = '\0';
		if (fhdr.frzinfo.frzedata != (char *) &edata)
			(void) strcat(why, "Edata");
		if (fhdr.frzinfo.frzend != (char *) &end)
			(void) strcat(why, "End");
		if (strcmp(fhdr.frzinfo.frzver, Version))
			(void) strcat(why, "Version");
		if (strcmp(fhdr.frzinfo.frzdatecompiled, datecompiled))
			(void) strcat(why, "Datecompiled");
		if (*why)
		{
			if (tTd(0, 1))
				printf("Wrong version of frozen config file (%s mismatch)\n", why);
# ifdef LOG
			syslog(LOG_WARNING, "Wrong version of frozen config file (%s mismatch)", why);
# endif /* LOG */
			(void) close(f);
			return (FALSE);
		}
	}

	/* arrange to have enough space */
	if ((int)brk(fhdr.frzinfo.frzbrk) == -1)
	{
		syserr("Cannot break to %x", fhdr.frzinfo.frzbrk);
		(void) close(f);
		return (FALSE);
	}

	/* now read in the freeze file */
	if (read(f, (char *) &edata, (int) (fhdr.frzinfo.frzbrk - (char *) &edata)) !=
					(int) (fhdr.frzinfo.frzbrk - (char *) &edata))
	{
		syserr("Cannot read frozen config file");
		/* oops!  we have trashed memory..... */
		(void) write(2, "Cannot read freeze file\n", 24);
		_exit(EX_SOFTWARE);
	}

	(void) close(f);
	return (TRUE);
}
#endif /* _PATH_SENDMAILFC */
Newsgroups: comp.unix.wizards