|
|
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.