|
|
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: * rcvf
18: *
19: * SYNOPSIS
20: * rcvf()
21: *
22: * DESCRIPTION
23: * receive a file -- called from bscd
24: */
25:
26: #include <stdio.h>
27: #include <sys/types.h>
28: #include <sys/stat.h>
29: #include <sys/ioctl.h>
30: #include <bsc/bscio.h>
31: #include "local.h"
32:
33: #define YES 1
34: #define NO 0
35: #define DC1 0x11
36: #define DC2 0x12
37: #define DC3 0x13
38: #define ESC 0x1b
39: #define GS 0x1d
40: #define RCDSEP 0x1e
41: #define EM 0x19
42: #define US 0x1f
43: #define EBESC 0x27
44: #define EB4 0xf4 /* ebcdic 4; used to check for ESC 4 sequences */
45:
46: #ifndef lint
47: static char sccsid[] = "%W% %Q%";
48: #endif
49:
50: extern struct bscio c_params;
51: extern char hostname[];
52: extern char auditlock[];
53: extern char lockfile[];
54: extern char spool[];
55: extern char emsg[];
56: extern char user[];
57: extern int devfd;
58: extern int ascii;
59: extern int trnsp;
60: extern int total_bl;
61: extern int ctr;
62: extern int ius;
63: extern long maxfsize;
64: extern long minspace;
65: void exit();
66: char *strcpy();
67:
68: rcvf()
69: {
70: int len; /* length of read-in rbuff */
71: int rfd = 0; /* receive file descriptor */
72: int pid; /* process id goes in here; used to make
73: unique receive file name */
74: int sw;
75: int blocks = 0; /* number of blocks received */
76: int nblnks; /* number of blanks in compressed string */
77: int c_writes = 0; /* number of chars written to received file */
78: int write_ok = YES; /* whether or not it's ok to write to receive
79: file (used with maxfsize) */
80: int write_amt; /* number of chars to write to receive file */
81:
82: long c_count = 0; /* count of total characters written to receive
83: file (used with maxfsize) */
84: char fname[80]; /* receive file name */
85: char rbuff[512]; /* stuff gets received in here */
86: char type[6]; /* print or punch file */
87: char rtype[3]; /* PRint or PUnch */
88: char expandarea[1024]; /* place to de-compress blocks */
89: char blank;
90: char a_msg[150]; /* audit file message */
91:
92: register char *r; /* receive buffer pointer */
93: register char *exptr; /* expand area pointer */
94: register char *pos; /* pointer returned by bstrchr */
95: char *bstrchr(); /* fn rtns ptr to given char in string */
96:
97: struct stat s; /* points to file status structure */
98:
99: FILE *popen();
100:
101: blank = ascii?' ':0x40;
102:
103: pid = getpid(); /* get process id for this process */
104: sw = 0;
105:
106: while ((len = read(devfd,rbuff,sizeof rbuff)) > 0) {
107: if (write_ok)
108: ++blocks;
109: ioctl(devfd,BSCGET,&c_params);
110: if (!sw)
111: { /* do first-time stuff */
112: /* if first character in receive buffer is DC2, DC3, or ESC
113: followed by 4, this is a punch file. If first character
114: is DC1, this is a print file. */
115: r = rbuff;
116: /* if it isn't ascii, translate it before testing it */
117: if (!ascii) ebcasc(rbuff, 2);
118: if (*r == DC2 || *r == DC3 ||
119: (*r == ESC && *(r+1) == '4')) {
120: strcpy(rtype,"PU");
121: strcpy(type,"punch");
122: } else {
123: strcpy(rtype,"PR");
124: strcpy(type,"print");
125: }
126: /* translate it back to ebcdic so it won't be confused later */
127: if (!ascii) ascebc(rbuff, 2);
128:
129: sprintf(fname,"%s/%s%04d%d",spool,rtype,ctr,pid);
130:
131: /* create the file in the host's spool directory
132: with read/write permission for everyone */
133: if ((rfd = creat(fname,0666)) == -1)
134: { fprintf(stderr,
135: "bscd <%s>: file <%s> can't be created\n",
136: hostname,fname);
137: unlink(auditlock);
138: unlink(lockfile);
139: exit(1); }
140:
141: ++sw;
142:
143: /* update AUDIT file */
144: if (c_params.b_flags == BSCTXP)
145: sprintf(a_msg,
146: "Receiving <%s> file, transparent mode",
147: type);
148: else
149: sprintf(a_msg,
150: "Receiving <%s> file",type);
151:
152: write_aud("R",a_msg);
153: }
154:
155: if (c_params.b_flags == BSCTXP)
156: { write(rfd,rbuff,(unsigned)len); /* take as is */
157: continue; }
158:
159: /* de-block */
160: exptr = expandarea;
161: r = rbuff;
162: r[len] = '\0';
163:
164: while(pos = bstrchr(r,GS,len - ((int)(r-rbuff))))
165: { if (pos-r)
166: bcopy(exptr,r,(int)(pos-r));
167: exptr += pos - r;
168: ++pos;
169: nblnks = *pos++ - 0x40;
170: while(--nblnks >= 0)
171: *exptr++ = blank;
172: r = pos;
173: }
174: bcopy(exptr,r,len - ((int)(r-rbuff)));
175: exptr += len - (r - rbuff);
176: len = exptr - expandarea;
177:
178: /* translate is necessary */
179: if (!ascii)
180: ebcasc(expandarea,len);
181:
182: /* check that there's a US or EM at the end of the buffer */
183: if (*(exptr-1) != RCDSEP && *(exptr-1) != EM &&
184: *(exptr-1) != US) {
185: *exptr++ = '\n';
186: ++len;
187: }
188:
189: /* Accept either RS (1E), EM (19), or US (1F) as record terminators.
190: The latter two are used in 2780 mode, and the EM occurs if the
191: record is shorter (or longer) than would normally be expected
192: (usually 80 characters). Thus, if an EM character is found, ignore
193: a US character if it immediately follows. If only a US terminator is
194: found for a record, it is replaced by a newline.
195: Sound confusing? That's comm for you. */
196:
197: pos = expandarea;
198: while ( (r = bstrchr(pos,EM,len - (int)(pos-expandarea)))||
199: (r = bstrchr(pos,RCDSEP,len - (int)(pos-expandarea))) ){
200: *r++ = '\n';
201: pos = r;
202: }
203:
204: pos = expandarea;
205: while ( pos = bstrchr(pos,US,len - (int)(pos - expandarea))) {
206: if (pos > expandarea && pos[-1] == '\n'){
207: bcopy(pos,pos+1,len-(int)(pos+1 - expandarea));
208: --len;
209: --exptr;
210: }
211: else
212: *pos++ = '\n';
213: }
214:
215: if (write_ok && (!maxfsize || c_count < maxfsize)) {
216: write_amt = (maxfsize && (c_count+(exptr-expandarea) > maxfsize))?
217: maxfsize - c_count: exptr - expandarea;
218:
219: c_writes = write(rfd,expandarea,(unsigned)write_amt);
220: if (c_writes == -1) {
221: fprintf(stderr,
222: "bscd <%s>: can't write to file <%s>\n",
223: hostname,fname);
224: unlink(auditlock);
225: unlink(lockfile);
226: exit(1);
227: }
228:
229: c_count += c_writes;
230: if (maxfsize && c_count >= maxfsize) {
231: strcpy(a_msg,
232: "Receive file truncated, <maximum file size encountered>");
233: write_aud("R",a_msg);
234: /* send msg to user about it */
235: notefile(user," ",a_msg);
236:
237: write_ok = NO;
238: }
239: }
240: }
241:
242: /* check for errors on receive */
243: if (len < 0) {
244: ioctl(devfd, BSCGET, &c_params);
245: get_errors();
246: sprintf(a_msg,"Receiving aborted, <%s>",emsg);
247: write_aud("R",a_msg);
248: return(1); }
249:
250: if (rfd > 0)
251: close(rfd);
252:
253: if (!sw) /* nothing received -- just return */
254: return(0);
255:
256: /* call asgnfile - give a more meaningful name to received file */
257: asgnfile(hostname,fname);
258:
259: /* receive done - update AUDIT */
260: stat(fname,&s);
261: sprintf(a_msg,
262: "Receiving complete (%ld bytes, %d blocks), assigned to file <%s>",
263: s.st_size,blocks,fname);
264: write_aud("R",a_msg);
265: total_bl += blocks;
266: ++ctr;
267: return(2);
268: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.