File:  [Power 6/32 Unix Tahoe 4.2BSD] / cci / usr / src / usr.bin / bsc / cmd / batch / sendf.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs
Sun Jul 28 12:26:12 2019 UTC (7 years ago) by root
Branches: bsd, MAIN
CVS tags: v121, HEAD
Power 6/32 Unix version 1.21

/*	D.L.Buck and Associates, Inc. - %H%
 *
 *	COPYRIGHT NOTICE:
 *		Copyright c %H% - An unpublished work by 
 *		D.L.Buck and Associates, Inc.
 *
 *	PROPRIETARY RIGHTS NOTICE:
 *		All rights reserved. This document and program contains
 *		proprietary information of D.L.Buck and Associates,Inc.
 *		of San Jose, California, U.S.A., embodying confidential
 *		information,  ideas, and expressions,  no part of which
 *		may be reproduced, or transmitted in any form or by any
 *		means,  electronic,  mechanical,  or otherwise, without
 *		the written permission of D.L.Buck and Associates, Inc.
 *
 * NAME
 *	sendf
 *
 * SYNOPSIS
 *	sendf(sendfile)
 *	char *sendfile;
 *
 * DESCRIPTION
 *	Send a file -- called from bscd
 */

#include <stdio.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <bsc/bscio.h>
#include "local.h"

#define YES 1
#define NO 0
#define DLE 0x10
#define IUS 0x1f
#define ETX 0x03
#define ASCENQ 0x05
#define ASCETB 0x17
#define ASCSYN 0x16
#define EBCENQ 0x2d
#define EBCETB 0x26
#define EBCSYN 0x32

#ifndef lint
static char sccsid[] = "%W% %Q%";
#endif

extern char note[];
extern char hostname[];
extern char auditlock[];
extern char lockfile[];
extern char user[];
extern char emsg[];

extern int errno;
extern int mail;
extern int recsize;
extern int recblk;
extern int recsep;
extern int ius;
extern int compress;
extern int blksize;
extern int trnsp;
extern int ascii;
extern int blocks;
extern int devfd;
extern int total_bl;
extern int transp_ok;
extern int rviab;
extern int set_trnsp;

extern struct bscio c_params;
extern struct bscio s_params;

char *rdptr;	
char *cpout;
char *inend;
char *outptr;
char *outend;

char inbuff[512];
char outbuff[512];
char temp[1024];
char a_msg[150];

int eof;
int tranrcd;
int rcds;
char *index();
void exit();

sendf(sendfile)
char *sendfile;
{

	int outspace;
	int len = 0;			/* length of record read in */
	int sendfd;			/* sendfile file descriptor */
	unsigned rd_amt;
	int count;

	struct stat s;			/* file statistics structure */

/* assume file to be sent is not transparent, and tell the daemon so */
	ioctl(devfd,BSCNTRNS,0);

/* open file to be sent */
	if ((sendfd = open(sendfile,0)) == -1)
	{	fprintf(stderr,
		"bscd <%s>: cannot open <%s>\n",
		hostname,sendfile);
		sprintf(note,
		"Couldn't open <%s>\n",
		sendfile);
		notefile(user,sendfile,note);
		unlink(auditlock);
		unlink(lockfile);
		exit (1);	}

/* stat to see how big it is */
	stat(sendfile,&s);

/* inform the AUDIT file */
	sprintf(a_msg, "Transmission of <%s> (%ld bytes) begun",
		sendfile,s.st_size);
	write_aud("S",a_msg);

/* set up beginning inbuff and outbuff and their attendant pointers */
	rdptr = cpout = &inbuff[0];
	inend = &inbuff[sizeof inbuff];
	outptr = &outbuff[0];
	outend = &outbuff[blksize] - 4;	/* leave room for STX, ETX... */
	rcds = 0;
	count = 0;
	eof = NO;
	tranrcd = NO;

	rd_amt = (sizeof inbuff) - 1;
	if (ius) --outend;

	len = read(sendfd,inbuff,rd_amt);
	if (len == -1)
		return(-1);
	rdptr = &inbuff[len];

	if (len == 0)
		eof = YES;

/* copy from inbuff to outbuff and process data --
   first read in # of bytes you just copied to the outbuff */
	while (1)
	{	outspace = outend - outptr;
		if (ius)	/* leave room for IUS and 1 or 2 byte CRC */
			outspace -= (ascii)?2:3;

	/* do_copy copies up to recsize or newline bytes into temporary buffer
	   and sets tranrcd if transparent character(s) found */
		count = do_copy(outspace,recsize,sendfd);

		if (count == 0)
			break;

	/* if count is -1, there wasn't enough room for another record.
	   flush outbuff and continue on (merrily) */
		if (count == -1)	{
			if (flushbuf(outbuff,
				     (unsigned)(outptr-outbuff)) == -1)  {
				if (c_params.b_flags != BSCRVI ||
				   (c_params.b_flags == BSCRVI && rviab)) {
					close(sendfd);
					return(-1);
				}
			}

			outptr = &outbuff[0];
			rcds = 0;
			continue;
		}

	/* if normal rcd, replace newline with recsep and cat to outbuff */
		if (!tranrcd)	
		{	if (temp[count-1] != '\n')
				++count;
			temp[count-1] = recsep;
			if (ius && rcds != recblk - 1)
			{	temp[count] = IUS;    /* 2780 unit seperator */
				++count;	
			/* add dummy character(s) to leave room for CRC added
			   by driver; 1 dummy for ascii, 2 dummies for ebcdic.
			*/
				temp[count] = ' ';
				++count;
				if (!ascii)	{
					temp[count] = ' ';
					++count;
				}
			}

			if (!ascii)
				ascebc(temp,count);

			if (compress)
				count = do_compress(temp,count);

	/* copy all characters to outbuff (even nulls) */
			bcopy(outptr,temp,count);

		/* increment buffer pointers, get number of bytes to
		   read next, compute space taken up in inbuff */
			++rcds;
			outptr += count;

			if (rcds == recblk)
			{	if (*--outptr != IUS)
					++outptr;
				if (flushbuf(outbuff,
					     (unsigned)(outptr-outbuff)) == -1) {
					if (c_params.b_flags != BSCRVI ||
					   (c_params.b_flags == BSCRVI && rviab)) {
						close(sendfd);
						return(-1);
					}
				}
				outptr = &outbuff[0];
				rcds = 0;	}

			continue;
		}

	/* transparent data processing */
		if (outptr != outbuff &&
		    flushbuf(outbuff,(unsigned)(outptr-outbuff)) == -1)	{
			close(sendfd);
			return(-1);
		}
		
		ioctl(devfd,BSCTRNSP,0);
		set_trnsp = YES;

		if (flushbuf(temp,(unsigned)count) == -1)	{
			if (c_params.b_flags != BSCRVI ||
			   (c_params.b_flags == BSCRVI && rviab))	{
				close(sendfd);
				return(-1);
			}
		}
			
		ioctl(devfd,BSCNTRNS,0);
		outptr = &outbuff[0];
		rcds = 0;
		continue;
	}
	if (outptr != outbuff)
		if (flushbuf(outbuff,(unsigned)(outptr-outbuff)) == -1)	{
			if (c_params.b_flags != BSCRVI ||
			   (c_params.b_flags == BSCRVI && rviab))	{
				close(sendfd);
				return(-1);
			}
	}

	close(sendfd);
	if (!transp_ok && trnsp)
		return(-1);
	else
		return(0);
}

/* do_copy - copy recsize (or to newline size) chunk from inbuff to
   temp buff for processing and replenish the inbuff */
char asctrans[7] = {DLE,IUS,ETX,ASCENQ,ASCETB,ASCSYN};

do_copy(availspace,size,sfd)
int availspace,size,sfd;
{
	register char *tmptr;
	register char *cp = cpout;
	register int count = 0;
	int len;
	unsigned rdamt;
	unsigned part_amt;
	int dlecount = 0;

	char c;

	tmptr = &temp[0];
	if (trnsp)
		tranrcd = YES;

	while (count < size && cp != rdptr && (tmptr-&temp[0] < availspace)) 
	{	++count;
		*tmptr++ = c = *cp++;
		if (cp== inend)
			cp= &inbuff[0];

		if (!tranrcd)	{
			tranrcd = (index(asctrans,c))?YES:NO;
			if (tranrcd && !transp_ok)	{
				outptr = outbuff;
				trnsp = YES;
				return(0);
			}
		}

		if (tranrcd)
		{	if (c == DLE)
			{	++dlecount;
				++count;
				*tmptr++ = DLE;	}
		}
		else if (c == '\n')
			break;
	}
	if (tmptr - &temp[0] >= availspace)
		return(-1);
	rdamt = count - dlecount;
	if (!tranrcd && *cp == '\n' && tmptr[-1] != '\n' && count >= size)	{
		++cp;
		if (cp == inend)
			cp = &inbuff[0];
	}
	cpout = cp;

/* read the next # of bytes into inbuff */
	if (!eof && rdamt)	{
		if ((rdptr + rdamt) > inend)	{
			part_amt = (int)(inend - rdptr);

			len = read(sfd,rdptr,part_amt);
			if (len == part_amt)	{
				rdptr = inbuff;
				rdamt -= part_amt;
			}
			else 	{
				eof = YES;
				rdamt = 0;
			}
		}

		if (rdamt)	{
			len = read(sfd,rdptr,rdamt);
			if (len != rdamt)
				eof = YES;
		}
	/* position the read ptr after what's been read in */
		rdptr += len;
		if (rdptr >= inend)
			rdptr -= sizeof inbuff;
	}	
		
	return(count);
}

/* flushbuf -- write contents of outbuff to the bsc device */
flushbuf(buffer,count)
register char *buffer;
register unsigned count;
{	
/* if eof was encountered, set BSCLAST flag */
	if (eof && cpout == rdptr)
		ioctl(devfd,BSCLAST,0);

	if (!tranrcd && (count >2) && (outptr[-2] == IUS || outptr[-3] == IUS))
		count -= (outptr[-2] == IUS)?2:3;

	if (write(devfd,buffer,count) == count)
	{	++blocks;
		return(0);	}
	if (errno == EINVAL && count > s_params.b_blks)
		abort();
	ioctl(devfd, BSCGET, &c_params);
	return(-1);	
}

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.