190792Sgshapiro/*
2261363Sgshapiro * Copyright (c) 2000-2002 Proofpoint, Inc. and its suppliers.
390792Sgshapiro *      All rights reserved.
490792Sgshapiro * Copyright (c) 1990, 1993
590792Sgshapiro *	The Regents of the University of California.  All rights reserved.
690792Sgshapiro *
790792Sgshapiro * This code is derived from software contributed to Berkeley by
890792Sgshapiro * Chris Torek.
990792Sgshapiro *
1090792Sgshapiro * By using this file, you agree to the terms and conditions set
1190792Sgshapiro * forth in the LICENSE file which can be found at the top level of
1290792Sgshapiro * the sendmail distribution.
1390792Sgshapiro */
1490792Sgshapiro
1590792Sgshapiro#include <sm/gen.h>
16266692SgshapiroSM_RCSID("@(#)$Id: wsetup.c,v 1.21 2013-11-22 20:51:44 ca Exp $")
1790792Sgshapiro#include <stdlib.h>
1890792Sgshapiro#include <errno.h>
1990792Sgshapiro#include <sm/io.h>
2090792Sgshapiro#include "local.h"
2190792Sgshapiro
2290792Sgshapiro/*
2394334Sgshapiro**  SM_WSETUP -- check writing is safe
2490792Sgshapiro**
2590792Sgshapiro**  Various output routines call wsetup to be sure it is safe to write,
2690792Sgshapiro**  because either flags does not include SMMWR, or buf is NULL.
2790792Sgshapiro**  Used in the macro "cantwrite" found in "local.h".
2890792Sgshapiro**
2990792Sgshapiro**	Parameters:
3090792Sgshapiro**		fp -- the file pointer
3190792Sgshapiro**
3290792Sgshapiro**	Results:
3390792Sgshapiro**		Failure: SM_IO_EOF and sets errno
3490792Sgshapiro**		Success: 0 (zero)
3590792Sgshapiro*/
3690792Sgshapiro
3790792Sgshapiroint
3890792Sgshapirosm_wsetup(fp)
3990792Sgshapiro	register SM_FILE_T *fp;
4090792Sgshapiro{
4190792Sgshapiro	/* make sure stdio is set up */
4290792Sgshapiro	if (!Sm_IO_DidInit)
4390792Sgshapiro		sm_init();
4490792Sgshapiro
4590792Sgshapiro	/* If we are not writing, we had better be reading and writing. */
4690792Sgshapiro	if ((fp->f_flags & SMWR) == 0)
4790792Sgshapiro	{
4890792Sgshapiro		if ((fp->f_flags & SMRW) == 0)
4990792Sgshapiro		{
5090792Sgshapiro			errno = EBADF;
5190792Sgshapiro			return SM_IO_EOF;
5290792Sgshapiro		}
5390792Sgshapiro		if (fp->f_flags & SMRD)
5490792Sgshapiro		{
5590792Sgshapiro			/* clobber any ungetc data */
5690792Sgshapiro			if (HASUB(fp))
5790792Sgshapiro				FREEUB(fp);
5894334Sgshapiro
5994334Sgshapiro			/* discard read buffer */
6090792Sgshapiro			fp->f_flags &= ~(SMRD|SMFEOF);
6190792Sgshapiro			fp->f_r = 0;
6290792Sgshapiro			fp->f_p = fp->f_bf.smb_base;
6390792Sgshapiro		}
6490792Sgshapiro		fp->f_flags |= SMWR;
6590792Sgshapiro	}
6690792Sgshapiro
6790792Sgshapiro	/* Make a buffer if necessary, then set w. */
6890792Sgshapiro	if (fp->f_bf.smb_base == NULL)
6990792Sgshapiro		sm_makebuf(fp);
7090792Sgshapiro	if (fp->f_flags & SMLBF)
7190792Sgshapiro	{
7290792Sgshapiro		/*
7390792Sgshapiro		**  It is line buffered, so make lbfsize be -bufsize
7490792Sgshapiro		**  for the sm_putc() macro.  We will change lbfsize back
7590792Sgshapiro		**  to 0 whenever we turn off SMWR.
7690792Sgshapiro		*/
7790792Sgshapiro
7890792Sgshapiro		fp->f_w = 0;
7990792Sgshapiro		fp->f_lbfsize = -fp->f_bf.smb_size;
8090792Sgshapiro	}
8190792Sgshapiro	else
8290792Sgshapiro		fp->f_w = fp->f_flags & SMNBF ? 0 : fp->f_bf.smb_size;
8390792Sgshapiro	return 0;
8490792Sgshapiro}
85