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 + -
显示快捷键?