|
|
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);
}
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.