2780d.c

来自「<B>Digital的Unix操作系统VAX 4.2源码</B>」· C语言 代码 · 共 1,455 行 · 第 1/3 页

C
1,455
字号
#ifdef lintstatic char *sccsid = "@(#)2780d.c	4.1	ULTRIX	7/2/90";#endif/************************************************************************ *									* *			Copyright (c) 1986 by				* *		Digital Equipment Corporation, Maynard, MA		* *			All rights reserved.				* *									* *   This software is furnished under a license and may be used and	* *   copied  only  in accordance with the terms of such license and	* *   with the  inclusion  of  the  above  copyright  notice.   This	* *   software  or  any  other copies thereof may not be provided or	* *   otherwise made available to any other person.  No title to and	* *   ownership of the software is hereby transferred.			* *									* *   This software is  derived  from  software  received  from  the	* *   University    of   California,   Berkeley,   and   from   Bell	* *   Laboratories.  Use, duplication, or disclosure is  subject  to	* *   restrictions  under  license  agreements  with  University  of	* *   California and with AT&T.						* *									* *   The information in this software is subject to change  without	* *   notice  and should not be construed as a commitment by Digital	* *   Equipment Corporation.						* *									* *   Digital assumes no responsibility for the use  or  reliability	* *   of its software on equipment which is not supplied by Digital.	* *									* ************************************************************************/#include <stdio.h>#include <errno.h>#include <sys/types.h> #include <ustat.h>#include <sys/file.h> #include <sys/socket.h>#include <net/if.h>#include <netbsc/bsc_proto.h>#include <netbsc/bsc.h>#include <time.h>#include "rje.h" #include <netbsc/bsc_messages.h>/* * Types of notification messages */#define READY 0			/* output ready */#define SENT 1			/* job transmitted */#define SQUEUED 2		/* file queued */#define JOBACKED 3		/* job acknowledged */#define NOACK 4			/* job not acknowledged */#define UNDELIV 5		/* undeliverable output */#define SOMIS 6			/* missing signon card *//*  *  What files to get when getq is called */#define OFCARDS 1      /* return a q of card files with files to send in them */#define OFOUTP  2      /* return a q of card file containing files to be received (zf) *//* etc */#define BADMAIL "dead.letter"#define QSIZE 6			/* xmitted job queue size */#define NSEARCH  1000		/* number of lines (cards) to search 				   when looking for the usr card */#define TRIES  3		/* tries to reconn if line goes down */#define STRSIZE 80		/* string size */struct jobdat {	char jd_jobnm[9];	char jd_pgrmr[25];	char jd_jobno[9];	char jd_login[9];	char jd_place[128]; 	short jd_lvl;	char *jd_dir;	unsigned jd_uid;};struct jobdat jobdat;int trunc;char  	*SD;				/*spool directory */FILE *acctfp,*fp;			/* acctlog file point. & tmp rec fp */unsigned char test;			/* chars read from input stream */struct b3780_buff d_buff;               /* the recv buffer */unsigned char buff[80];			/* line in data file */int l_count;				/* current line count */long    tempoff1,offset1;               /* position of last getentryincf*/char *name;				/* program name */int jclcardc=0;		 		/* # blocks sent or received */int posinrec=0;				/* position in rec for tabbing */int *tab;				/* tab template */static char etoa[]={                    /* ebcdic to ascii table */#	include "etoa.h"};static char atoe[]={                    /* ascii to ebcdic table */#	include "atoe.h"};/* 	APPLICATION.C	*/main(argc,argv)	int argc;	char *argv[];{	struct sockaddr_bsc sin;	/* for socket, bind, and connect */	register int g, s, n;	struct queue **dirlist;		/* list of names in directory */	int rerror=0,serror=0;		/* recv or send error */	int linerror=0;	int in_sendmode=0,in_recvmode=0,filetosend=0,recvoob;	int pidno,i;	struct stat sb;	struct ustat usb;	char *sendfilename;  		/* name of file to be sent */	char *cardfilename;  		/* name of card/control file */	char *oldcardname=NULL;		/* last control file sent out */	char *donefilename;  /* file symlinked to cardfile after sending */	char *mailnotif;     	     /* name of file, needed with mail   */	char *transpflg;     	     /* Transparent data switch   */	char *spacecomprs;		/* space compression entry */	char *multibuf;     	     /* send files in multirecord format  */	char *d3780;		     /* 3780e executed */	char *signoncard;		/* contents of sign-on card */	unsigned char sign_on[STRSIZE+1]; /* ebcdic signoncard + etx */	char *getentryincardfile();	register struct dsplog *dp;	char *user;			/* owner of cardfile */			char *mailto; 			/* name of person who requested mail */	int b_count;			/* current blocksize */	unsigned char s_buff[b_3780_size+2];	/* largest size buffer to send with eof char and dle if trans data */	int tx_count;		/* keeps track of where chs go in s_buff.tx[] */	int lastrec;		/* last possible start of a new record */	int r_count=0;		/* record count w/in a block */	int mulbufmx;		/* max # of records w/in a buffer/block */	unsigned char recsep=0;		/* record separator IRS or IUS */	unsigned char eob;		/* end of block - ETB of ETX */	FILE *fopen(), *rfp,*cfp,*sfp;	SD = DEFSPOOL;	name=argv[0];	if (chdir(SD) < 0){		printf("cannot chdir to %s",SD);	/* XXXX perr */		exit(1);	}		/* .rjed has pid of daemon in it.  If it's an 		 *  active process then the daemon is already		 *  running.  If the file doesn't exist or it's		 *  not an active process then we want to continue.		 */	rfp=fopen(".rjed","r");	if (rfp != NULL ) {   /* file exists, check if active daemon */		fscanf(rfp,"%d",&pidno);		fclose(rfp);/* what if pidno == 0,  garbage or empty file, bring up daemon */		if (kill(pidno,0)== 0)  /* active daemon */			exit(0);		else if (errno==ESRCH)			unlink(".rjed");		else exit(0);   /* someother kind of error */			}/* no active daemon, continue */	rfp=fopen(".rjed","w");	if (!rfp){		perr("cannot open .rjed");		exit(1);	}	fprintf(rfp,"%d",getpid());	fclose(rfp);/* dp=(struct dsplog *)malloc(sizeof(struct dsplog ));/*dp->d_un.x.d_uid=getuid();		notify((char *) 0,dp->d_un.x.d_uid,SENT,dp->d_un.x.d_file);		acctng(dp->d_un.x.d_file,dp->d_un.x.d_uid,dp->d_un.x.d_cnt);		doresp();		break;*/		/* only if acctlog exists */	if(stat("acctlog",&sb) == 0)		acctfp = fopen("acctlog","a");		oldcardname=malloc(STRSIZE);		if (oldcardname==NULL){ perr("out of memory"); exit;}while(1) {	/*  while there are files in the spool area, or we're		    receiving another file */	linerror=0;	if (( ! in_sendmode) && ( !in_recvmode)){			/* get list of control files from the spool			 * area.  If there are none then we have 			 * nothing to do, so we leave.			 */			/* We keep doing getq in case a priority			 * job has snuck its way to the head of   			 * the queue.			 */		if ((filetosend=getq(&dirlist,OFCARDS)) < 0){			perr("can't scan spool directory");  /* log */			exit(1);		}		if (filetosend)			in_sendmode=1;		else break;	/*  no filetosend so die */	}	if (in_sendmode) {	/* get needed info out of control file */		stat(".",&sb);		ustat(sb.st_dev,&usb);		if (usb.f_tfree < 100){			perr("not enough space in spool to do renames & links");			break;		}		jclcardc=0;		cardfilename=(*dirlist)->q_name;		donefilename=malloc(STRSIZE);		sprintf(donefilename,"z%s",&cardfilename[1]);		cfp=fopen(cardfilename,"r");		if (cfp==NULL){	/* can't open card file */    /* ???? */			unlink(cardfilename);				in_sendmode=0;			continue;		}/*		phonenum=getentryincardfile(cfp,'D');		if (*phonenum == "")			perr("no phone number given to connect");  *//*              	for(i=0;i<14;i++)				sin.sin_addr[i]=(*(phonenum+i));*/		user=getentryincardfile(cfp,'P');		mailto=getentryincardfile(cfp,'M');	 	transpflg=getentryincardfile(cfp,'X');		if (d3780=getentryincardfile(cfp,'3')){			b_size=512;			lastrec=b_size-81;   	/* 80 text, 1 IRS */			if (transpflg)	mulbufmx=1;  else  mulbufmx=7;			recsep=IRS;		}		else {			b_size=400;			lastrec=b_size-80;	/* 80 text chars no IUS */			mulbufmx=2;			recsep=IUS;		}		spacecomprs=getentryincardfile(cfp,'C');		if (multibuf=getentryincardfile(cfp,'B'))			mulbufmx=7;		signoncard=getentryincardfile(cfp,'S');		sflushbuffer(sign_on,STRSIZE+1);		if (signoncard == NULL){			sfp=fopen("signon","r");			if (sfp==NULL){				perr("No signon card available");				fclose(cfp);				remjob(cardfilename);				notify(user,0,SOMIS,cardfilename);				in_sendmode=0;				break;			}			n=0;			while ((test=getc(sfp)) != EOL)				sign_on[n++]=atoe[test];			fclose(sfp);		}		else for(i=0; i<STRSIZE; i++)			sign_on[i]=atoe[signoncard[i]];		sign_on[STRSIZE]=ETX;		sendfilename=getentryincardfile(cfp,'f');		offset1=tempoff1;   			/* if this card file no longer contains any			 * files to be sent then rename it, incase 			 * there are still files to be received listed			 * in it.			 */		if (sendfilename==NULL) {			rename(cardfilename,donefilename);			in_sendmode=0;			continue;		}		if (mailto)			mailnotif=getentryincardfile(cfp,'N');		fclose(cfp);		fp=fopen(sendfilename,"r");		if (fp==NULL){			perr(strcat(sendfilename," cannot be opened"));			Zoutbuf(cardfilename,'?');			continue;		}	/* don't send a signon card for each sendfile	 * within a cardfile, send it just once at the	 * beginning of the user's job.  Watch out for	 * those priority jobs that can slip in between	 * sendfiles.  Another signon would be needed	 * then.	 */	if (*cardfilename != *oldcardname){	/* send the signon card */ 		s = socket(AF_BSC, SOCK_DGRAM, 0);		if (s < 0) {			perr("socket");			cleanup();		}		sin.sin_family = AF_BSC;		bind(s,(char *)&sin,sizeof (sin));		if (connect(s, &sin, sizeof(sin)) < 0) {			perr("connect");			(void) close(s);			cleanup();		}			serror=send(s,sign_on,STRSIZE+1,0);		if (serror < 0){			perr("signon card no good");			notify(user,0,NOACK,"signon card");			remjob(cardfilename);			in_sendmode=0;			break;		}		(void)strcpy(oldcardname,cardfilename);		recvoob=recv(s,d_buff.tx,sizeof(d_buff.tx),1);		if (d_buff.tx[0]==ENQ) { 					in_sendmode=0;				in_recvmode=1;				fclose(fp);				continue;			}		close(s);	}/*  * Hook to the socket (send line bid) and then read what's in the open file. */	s = socket(AF_BSC, SOCK_DGRAM, 0);	if (s < 0) {		perr("socket");		cleanup();	}	sin.sin_family = AF_BSC;	bind(s,(char *)&sin,sizeof (sin));			if (connect(s, &sin, sizeof(sin)) < 0) {		perr("connect");		(void) close(s);		cleanup();	}		test=getc(fp);		while (in_sendmode){				/* send a buffer, check for OOB char.				 * If none keep sending.  If OOB				 * goto receive mode because the remote				 * system wishes to send to us.				 */		/* read in a buffer */			tx_count=0;					l_count=0;			eob=ETB;			if (transpflg)  /* let kernel know it's trans data */				s_buff[tx_count++]=DLE; /* still have 512 for data */			do {		/* fill up send buffer until						card file is empty */		/* fill up the buffer until EOL or buffer is full  **/			if (transpflg)				tfill(); 	/* add DLE chars */			else 	nontfill(spacecomprs);		/* if EOL & buffer is not full, pad out the buffer.		 *      If EOF then put ETX in last position, otherwise		 *	put an ETB there.		 */				if (test == EOL){			    test=getc(fp);				if (test == EOF) 					eob = ETX;			}		/* copy that buffer into the send buffer  */	/*  remember s-buff has chars in it not ints */					for (i=0;(i<l_count);i++)				s_buff[tx_count++]=buff[i];			if (!transpflg)				s_buff[tx_count++]=recsep;			jclcardc++;			l_count=0;			r_count++;			}while ((test!=EOF) && (r_count<mulbufmx) && (tx_count<=lastrec) );			sflushbuffer(&s_buff[tx_count],b_size - tx_count);			r_count=0;					if (!d3780 && !transpflg)					--tx_count;	/* replace IUS with eob */			s_buff[tx_count++]=eob;				/* send the buffer */			serror=send(s,s_buff,tx_count,0);			if (serror < 0){				perr("error in sending");				/* sfail++; */				        notify(user,0,UNDELIV,sendfilename);				Zoutbuf(cardfilename,"Z");					fclose(fp);				unlink(sendfilename);/* zoutbuf will not find the right offset in the case where a send   has started but the ibm side decides to send us something then I   look at the usercard and it matches one in the queue. the offset   will change to point at the outputfile not the sendfile,  so    put in a reinit for offset*/				linerror=1;	/* error on the line *//*				if ((sfail >= 3))	 same block has tried						   3 times to go out and						   failed. file is prob.						   no good or job not						   being sent to 2780 or 3780						   job will be removed.						*/				 in_sendmode=0;				 cleanup();				/*break; */     			}			sflushbuffer(s_buff,b_size+1);			flushbuffer(d_buff.tx,sizeof(d_buff.tx));			sflushbuffer(buff,80);			if (test==EOF){				fclose(fp);				acctng(sendfilename,user,jclcardc);  /* not surewhich filename to use here */

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?