|
|
1.1 root 1: /* D.L.Buck and Associates, Inc. - %H%
2: *
3: * COPYRIGHT NOTICE:
4: * Copyright c %H% - An unpublished work by
5: * D.L.Buck and Associates, Inc.
6: *
7: * PROPRIETARY RIGHTS NOTICE:
8: * All rights reserved. This document and program contains
9: * proprietary information of D.L.Buck and Associates,Inc.
10: * of San Jose, California, U.S.A., embodying confidential
11: * information, ideas, and expressions, no part of which
12: * may be reproduced, or transmitted in any form or by any
13: * means, electronic, mechanical, or otherwise, without
14: * the written permission of D.L.Buck and Associates, Inc.
15: *
16: * NAME
17: * sendf
18: *
19: * SYNOPSIS
20: * sendf(sendfile)
21: * char *sendfile;
22: *
23: * DESCRIPTION
24: * Send a file -- called from bscd
25: */
26:
27: #include <stdio.h>
28: #include <errno.h>
29: #include <sys/types.h>
30: #include <sys/stat.h>
31: #include <sys/ioctl.h>
32: #include <bsc/bscio.h>
33: #include "local.h"
34:
35: #define YES 1
36: #define NO 0
37: #define DLE 0x10
38: #define IUS 0x1f
39: #define ETX 0x03
40: #define ASCENQ 0x05
41: #define ASCETB 0x17
42: #define ASCSYN 0x16
43: #define EBCENQ 0x2d
44: #define EBCETB 0x26
45: #define EBCSYN 0x32
46:
47: #ifndef lint
48: static char sccsid[] = "%W% %Q%";
49: #endif
50:
51: extern char note[];
52: extern char hostname[];
53: extern char auditlock[];
54: extern char lockfile[];
55: extern char user[];
56: extern char emsg[];
57:
58: extern int errno;
59: extern int mail;
60: extern int recsize;
61: extern int recblk;
62: extern int recsep;
63: extern int ius;
64: extern int compress;
65: extern int blksize;
66: extern int trnsp;
67: extern int ascii;
68: extern int blocks;
69: extern int devfd;
70: extern int total_bl;
71: extern int transp_ok;
72: extern int rviab;
73: extern int set_trnsp;
74:
75: extern struct bscio c_params;
76: extern struct bscio s_params;
77:
78: char *rdptr;
79: char *cpout;
80: char *inend;
81: char *outptr;
82: char *outend;
83:
84: char inbuff[512];
85: char outbuff[512];
86: char temp[1024];
87: char a_msg[150];
88:
89: int eof;
90: int tranrcd;
91: int rcds;
92: char *index();
93: void exit();
94:
95: sendf(sendfile)
96: char *sendfile;
97: {
98:
99: int outspace;
100: int len = 0; /* length of record read in */
101: int sendfd; /* sendfile file descriptor */
102: unsigned rd_amt;
103: int count;
104:
105: struct stat s; /* file statistics structure */
106:
107: /* assume file to be sent is not transparent, and tell the daemon so */
108: ioctl(devfd,BSCNTRNS,0);
109:
110: /* open file to be sent */
111: if ((sendfd = open(sendfile,0)) == -1)
112: { fprintf(stderr,
113: "bscd <%s>: cannot open <%s>\n",
114: hostname,sendfile);
115: sprintf(note,
116: "Couldn't open <%s>\n",
117: sendfile);
118: notefile(user,sendfile,note);
119: unlink(auditlock);
120: unlink(lockfile);
121: exit (1); }
122:
123: /* stat to see how big it is */
124: stat(sendfile,&s);
125:
126: /* inform the AUDIT file */
127: sprintf(a_msg, "Transmission of <%s> (%ld bytes) begun",
128: sendfile,s.st_size);
129: write_aud("S",a_msg);
130:
131: /* set up beginning inbuff and outbuff and their attendant pointers */
132: rdptr = cpout = &inbuff[0];
133: inend = &inbuff[sizeof inbuff];
134: outptr = &outbuff[0];
135: outend = &outbuff[blksize] - 4; /* leave room for STX, ETX... */
136: rcds = 0;
137: count = 0;
138: eof = NO;
139: tranrcd = NO;
140:
141: rd_amt = (sizeof inbuff) - 1;
142: if (ius) --outend;
143:
144: len = read(sendfd,inbuff,rd_amt);
145: if (len == -1)
146: return(-1);
147: rdptr = &inbuff[len];
148:
149: if (len == 0)
150: eof = YES;
151:
152: /* copy from inbuff to outbuff and process data --
153: first read in # of bytes you just copied to the outbuff */
154: while (1)
155: { outspace = outend - outptr;
156: if (ius) /* leave room for IUS and 1 or 2 byte CRC */
157: outspace -= (ascii)?2:3;
158:
159: /* do_copy copies up to recsize or newline bytes into temporary buffer
160: and sets tranrcd if transparent character(s) found */
161: count = do_copy(outspace,recsize,sendfd);
162:
163: if (count == 0)
164: break;
165:
166: /* if count is -1, there wasn't enough room for another record.
167: flush outbuff and continue on (merrily) */
168: if (count == -1) {
169: if (flushbuf(outbuff,
170: (unsigned)(outptr-outbuff)) == -1) {
171: if (c_params.b_flags != BSCRVI ||
172: (c_params.b_flags == BSCRVI && rviab)) {
173: close(sendfd);
174: return(-1);
175: }
176: }
177:
178: outptr = &outbuff[0];
179: rcds = 0;
180: continue;
181: }
182:
183: /* if normal rcd, replace newline with recsep and cat to outbuff */
184: if (!tranrcd)
185: { if (temp[count-1] != '\n')
186: ++count;
187: temp[count-1] = recsep;
188: if (ius && rcds != recblk - 1)
189: { temp[count] = IUS; /* 2780 unit seperator */
190: ++count;
191: /* add dummy character(s) to leave room for CRC added
192: by driver; 1 dummy for ascii, 2 dummies for ebcdic.
193: */
194: temp[count] = ' ';
195: ++count;
196: if (!ascii) {
197: temp[count] = ' ';
198: ++count;
199: }
200: }
201:
202: if (!ascii)
203: ascebc(temp,count);
204:
205: if (compress)
206: count = do_compress(temp,count);
207:
208: /* copy all characters to outbuff (even nulls) */
209: bcopy(outptr,temp,count);
210:
211: /* increment buffer pointers, get number of bytes to
212: read next, compute space taken up in inbuff */
213: ++rcds;
214: outptr += count;
215:
216: if (rcds == recblk)
217: { if (*--outptr != IUS)
218: ++outptr;
219: if (flushbuf(outbuff,
220: (unsigned)(outptr-outbuff)) == -1) {
221: if (c_params.b_flags != BSCRVI ||
222: (c_params.b_flags == BSCRVI && rviab)) {
223: close(sendfd);
224: return(-1);
225: }
226: }
227: outptr = &outbuff[0];
228: rcds = 0; }
229:
230: continue;
231: }
232:
233: /* transparent data processing */
234: if (outptr != outbuff &&
235: flushbuf(outbuff,(unsigned)(outptr-outbuff)) == -1) {
236: close(sendfd);
237: return(-1);
238: }
239:
240: ioctl(devfd,BSCTRNSP,0);
241: set_trnsp = YES;
242:
243: if (flushbuf(temp,(unsigned)count) == -1) {
244: if (c_params.b_flags != BSCRVI ||
245: (c_params.b_flags == BSCRVI && rviab)) {
246: close(sendfd);
247: return(-1);
248: }
249: }
250:
251: ioctl(devfd,BSCNTRNS,0);
252: outptr = &outbuff[0];
253: rcds = 0;
254: continue;
255: }
256: if (outptr != outbuff)
257: if (flushbuf(outbuff,(unsigned)(outptr-outbuff)) == -1) {
258: if (c_params.b_flags != BSCRVI ||
259: (c_params.b_flags == BSCRVI && rviab)) {
260: close(sendfd);
261: return(-1);
262: }
263: }
264:
265: close(sendfd);
266: if (!transp_ok && trnsp)
267: return(-1);
268: else
269: return(0);
270: }
271:
272: /* do_copy - copy recsize (or to newline size) chunk from inbuff to
273: temp buff for processing and replenish the inbuff */
274: char asctrans[7] = {DLE,IUS,ETX,ASCENQ,ASCETB,ASCSYN};
275:
276: do_copy(availspace,size,sfd)
277: int availspace,size,sfd;
278: {
279: register char *tmptr;
280: register char *cp = cpout;
281: register int count = 0;
282: int len;
283: unsigned rdamt;
284: unsigned part_amt;
285: int dlecount = 0;
286:
287: char c;
288:
289: tmptr = &temp[0];
290: if (trnsp)
291: tranrcd = YES;
292:
293: while (count < size && cp != rdptr && (tmptr-&temp[0] < availspace))
294: { ++count;
295: *tmptr++ = c = *cp++;
296: if (cp== inend)
297: cp= &inbuff[0];
298:
299: if (!tranrcd) {
300: tranrcd = (index(asctrans,c))?YES:NO;
301: if (tranrcd && !transp_ok) {
302: outptr = outbuff;
303: trnsp = YES;
304: return(0);
305: }
306: }
307:
308: if (tranrcd)
309: { if (c == DLE)
310: { ++dlecount;
311: ++count;
312: *tmptr++ = DLE; }
313: }
314: else if (c == '\n')
315: break;
316: }
317: if (tmptr - &temp[0] >= availspace)
318: return(-1);
319: rdamt = count - dlecount;
320: if (!tranrcd && *cp == '\n' && tmptr[-1] != '\n' && count >= size) {
321: ++cp;
322: if (cp == inend)
323: cp = &inbuff[0];
324: }
325: cpout = cp;
326:
327: /* read the next # of bytes into inbuff */
328: if (!eof && rdamt) {
329: if ((rdptr + rdamt) > inend) {
330: part_amt = (int)(inend - rdptr);
331:
332: len = read(sfd,rdptr,part_amt);
333: if (len == part_amt) {
334: rdptr = inbuff;
335: rdamt -= part_amt;
336: }
337: else {
338: eof = YES;
339: rdamt = 0;
340: }
341: }
342:
343: if (rdamt) {
344: len = read(sfd,rdptr,rdamt);
345: if (len != rdamt)
346: eof = YES;
347: }
348: /* position the read ptr after what's been read in */
349: rdptr += len;
350: if (rdptr >= inend)
351: rdptr -= sizeof inbuff;
352: }
353:
354: return(count);
355: }
356:
357: /* flushbuf -- write contents of outbuff to the bsc device */
358: flushbuf(buffer,count)
359: register char *buffer;
360: register unsigned count;
361: {
362: /* if eof was encountered, set BSCLAST flag */
363: if (eof && cpout == rdptr)
364: ioctl(devfd,BSCLAST,0);
365:
366: if (!tranrcd && (count >2) && (outptr[-2] == IUS || outptr[-3] == IUS))
367: count -= (outptr[-2] == IUS)?2:3;
368:
369: if (write(devfd,buffer,count) == count)
370: { ++blocks;
371: return(0); }
372: if (errno == EINVAL && count > s_params.b_blks)
373: abort();
374: ioctl(devfd, BSCGET, &c_params);
375: return(-1);
376: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.