|
|
Power 6/32 Unix version 1.21
/* D.L.Buck and Associates, Inc. - %H%
*
* COPYRIGHT NOTICE:
* Copyright c %H% - An unpublished work by
* D.L.Buck and Associates, Inc.
*
* PROPRIETARY RIGHTS NOTICE:
* All rights reserved. This document and program contains
* proprietary information of D.L.Buck and Associates,Inc.
* of San Jose, California, U.S.A., embodying confidential
* information, ideas, and expressions, no part of which
* may be reproduced, or transmitted in any form or by any
* means, electronic, mechanical, or otherwise, without
* the written permission of D.L.Buck and Associates, Inc.
* NAME
* bscd - BISYNC communications daemon
*
* SYNOPSIS
* bscd
*
* DESCRIPTION
* bscd submits files queued by bscbatch to the BISYNC driver (bsc),
* which sends them to a specified remote host via 3780 or 2780
* protocol over telephone lines. It is started by an entry in
* /usr/lib/crontab.
*
* ALGORITHM
* 0. try to create the bsclock file
* a. if already there, another bscd is running; exit
* 1. search all host queues for work
* 2. for each host having file(s) queued to send:
* a. call installation exit "connect"
* b. open bsc device
* c. set bsc device parameters via ioctl call
* d. while there's another queue control file:
* i. open control file
* ii. get control parameters
* iii. set bsc device parameters as directed by
* control file via ioctl call
* iv. close control file
* v. open actual file to be sent
* vi. while not eof:
* format a block
* submit it to the bsc driver via write
* if an error is encountered:
* close file (host is probably trying
* to send to you)
* goto 'e.'
*
* vii. close file
* viii. call installation exit "notefile" if requested by
* control file mail flag
* ix. remove control file if send successful
* e. try to receive files:
* i. while not eof:
* read a block from bsc device
* unformat the block
* write it either to a PR or PU file somehow
* ii. call installation exit "asgnfile"
* iii. repeat from 'i.' until read times out
* f. if another queue control file appeared, go back to step 'd'
* g. close device
* h. call installation exit "disconnect"
* i. unlink bsc lock file
*
* make note in the AUDIT file of host spool directory of each action
* as processing occurs
*/
#include <stdio.h>
#include <sys/types.h>
#include <sys/dir.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <signal.h>
#include <errno.h>
#include "local.h"
#include <bsc/bscio.h>
#if defined BSD42
#include <sys/time.h>
#else
#include <time.h>
#endif
#define libpath "/usr/lib/bscbatch/"
#define spoolpath "/usr/spool/bscbatch/"
#define YES 1
#define NO 0
#define OK 2
#define GS 0x1d /* group separator */
#ifndef lint
static char sccsid[] = "%W% %Q%";
#endif
extern int errno; /* system error numbers get put in here */
extern char *sys_errlist[]; /* Explanatory strings for error numbers */
char hostname[20]; /* contains host name */
char audname[80]; /* temp audit pathname goes here */
char auditlock[80]; /* audit lockfile pathname goes here */
char new_audnm[80]; /* real audit name goes here */
char spool[50]; /* contains host spool directory path */
char hostid[20]; /* host id to check for */
char signon[50]; /* host signon file */
char signoff[50]; /* host signoff file */
char lockfile[50]; /* bsc lock file name */
char emsg[40]; /* contains error message for AUDIT */
char delfile[50]; /* file to delete when through transmitting */
char user[20]; /* user name */
char sys_admin[20] = "/dev/console"; /* system administrator name
for problem mail */
char df_string[40]; /* minspace check command */
char sendfile[50]; /* full name of file to send */
char note[100]; /* mail to system administrator goes in here */
char dname[15]; /* contains name of device to check if
MINSPACE parameter set */
char *strcpy(); /* function copies one string to another */
char *strcat(); /* function appends one string to another */
char *index(); /* function looks for one string in another */
int chk_hostid;
int chk_termid;
int blksize;
int primary = BSCPRIM;
int recsize;
int recblk;
int recsep;
int rviab;
int ius; /* unit separator for 2780 used? */
int pt_to_pt;
int son_file; /* is there a signon file to send? */
int soff_file; /* is there a signoff file to send? */
int mail = NO; /* send mail no matter what? */
int trnsp = NO; /* force a file to be sent transparent? */
int transp_ok = YES; /* transparent transmission ok for this host? */
int blocks; /* tracks number of blocks written to bsc device */
int ascii; /* ascii or ebcdic data? */
int compress = YES; /* compress data ? */
int devfd; /* bsc device file descriptor */
int total_bl = 0; /* total blocks sent or received */
int ctr = 0; /* used to supply unique names to received files */
int set_trnsp = NO; /* have any of sendfile's blocks been sent in
transparent mode, if this is a normal file? */
int sigint(); /* signal interrupt routine */
long maxfsize = 0; /* max size a receive file can be before it must
be truncated */
long minspace = 0; /* minimum space required to receive files from a
host */
long atol(); /* converts ascii to long */
char devname[20];
char ctlfile[50]; /* queue control file name */
FILE *fopen(); /* function opens files */
FILE *popen(); /* initiate I/O to form a process */
FILE *aud; /* host AUDIT file pointer */
struct tm *localtime(); /* function returns current time */
struct tm *t; /* localtime returns time into here */
struct bscio c_params; /* current bsc driver parameters */
struct bscio s_params; /* parameters bsc driver was set with */
long time();
long currtime;
void exit();
#if defined BSD42
DIR *libfd; /* Host Configuration directory fd */
DIR *spoolfd; /* Spool directory fd */
#else
int libfd; /* host config directory file descriptor */
int spoolfd; /* spool directory file descriptor */
#endif
main()
{
int more = YES;
int contention = NO; /*contention error encountered? */
int err; /* get_err or connect error code */
int almost_done; /* are we almost done communicating with
this host? */
long lseek();
#if defined BSD42
struct direct *dir; /* points to libpath directory entry */
struct direct *hdir; /* points to spoolpath directory entry */
#else
struct direct dir; /* libpath directory entry */
struct direct hdir; /* spoolpath directory entry */
#endif
struct stat s; /* points to file status structure */
char cfg_name[50]; /* contains host configuration file name */
char line[100]; /* line of file to be sent read in here */
int lockfd; /* bsc lock file file descriptor */
FILE *pptr; /* stream ptr to be used with popen */
/* catch signals -- if bscd spawned as background process,
allow kill -15 (SIGTERM) to nicely make it go away. */
if (isatty(0))
signal(SIGINT,sigint);
else
signal(SIGTERM,sigint);
/* 1. search all host queues for work */
#if defined BSD42
if ((libfd = opendir(libpath)) == NULL) {
#else
if ((libfd = open(libpath,0)) == -1) {
#endif
fprintf(stderr,
"bscd: can't open <%s> configuration directory\n",
libpath);
exit(1);
}
#if defined BSD42
while ((dir = readdir(libfd)) != NULL) {
if (dir->d_name[0] == '.')
continue;
strcpy(hostname,dir->d_name);
#else
while (read(libfd,&dir,sizeof dir) == sizeof dir) {
if (dir.d_name[0] == '.' || dir.d_ino == 0)
continue;
strcpy(hostname,dir.d_name);
#endif
sprintf(spool,"%s%s",spoolpath,hostname);
/* try to access spool directory; if not there, continue */
#if defined BSD42
if ((spoolfd = opendir(spool)) == NULL) {
#else
if ((spoolfd = open(spool,0)) == -1) {
#endif
sprintf(note,
"bscd <%s>: directory <%s> not readable",
hostname,spool);
fputs(note,stderr);
/* send mail about the problem */
post();
continue;
}
/* try to access the lock file -- if okay, another bscd is running;
abort. */
sprintf(lockfile,"%s/%s",spool,"bsclock");
if (access(lockfile,0) == 0) {
fprintf(stderr,
"bscd <%s>: another bscd process is currently running\n",
hostname);
lockfile[0] = '\0';
continue;
}
/* Create the lock file */
if ( (lockfd = creat(lockfile,0)) < 0) {
fprintf(stderr,
"bscd <%s>: can't create %s\n",hostname,lockfile);
exit(1);
} else
close(lockfd);
/* open the host directory and search for work */
if (searchq(spoolfd) == NO) {
quithost();
continue;
}
/* get host configuration parameters */
sprintf(cfg_name,"%s%s",libpath,hostname);
get_cnfg(cfg_name);
/* construct AUDIT pathname, open AUDIT file */
open_audit();
/* write "ready for connect" msg to AUDIT */
sprintf (note,"Ready for connect via <%s>",
devname);
write_aud("C",note);
/* call connect installation exit */
if (err = connect (hostname, devname)) {
/* skip this host if there were problems */
sprintf(note, "Connection failed, <%s>",emsg);
write_aud("C",note);
/* send mail about it */
post();
quithost();
continue;
}
/* open bsc device */
if ((devfd = open(devname,2)) == -1) {
if (errno == EBUSY) {
fprintf(stderr,
"bscd <%s>: <%s> being used.\n",
hostname, devname);
sprintf(note,
"Open failed, device <%s> busy.", devname);
write_aud("C", note);
/* send mail about problem */
post();
quithost();
goto Disconnect;
}
sprintf(note,
"Connection failed, %s cannot be opened: %s",
devname,sys_errlist[errno]);
fprintf(stderr, "bscd <%s>: %s\n", hostname, note);
/* update AUDIT file with the news */
write_aud("C",note);
/* send mail about problem */
post();
quithost();
goto Disconnect;
}
/* write "connected" message to AUDIT file */
strcpy(note,"Connected");
if (chk_hostid)
sprintf(note,"%s - host id is %s",note,hostid);
write_aud("C",note);
/* set device parameters */
ioctl(devfd,BSCSET,&s_params);
/* if a signon file was specified, send it via send_son
(send_son.c) */
if (son_file) {
if ((more = send_son(signon)) == NO) {
sprintf(note,"Disconnected, <%s>",
emsg);
write_aud("D",note);
goto Disconnect;
}
/* if there's a contention problem, abort sending */
if (c_params.b_flags == BSCONTND) {
contention = YES;
goto Receive_Files;
}
sprintf(note,
"Transmission of SIGNON file <%s> completed (%d blocks)",
signon,blocks);
write_aud("T",note);
total_bl += blocks;
blocks = 0;
}
almost_done = NO;
Send_Files: /* get another queue control file while there is one */
#if defined BSD42
rewinddir(spoolfd);
while ((hdir = readdir(spoolfd)) != NULL) {
if (hdir->d_name[0] != 'C')
continue;
sprintf(ctlfile,"%s/%s",spool,hdir->d_name);
#else
lseek(spoolfd,0L,0);
while (read(spoolfd,&hdir,sizeof hdir) == sizeof hdir) {
if (hdir.d_ino == 0 || hdir.d_name[0] != 'C')
continue;
sprintf(ctlfile,"%s/%s",spool,hdir.d_name);
#endif
/* get queue control parameters */
if (get_params()) /* error */
continue;
/* if no sendfile, look for control file w/sendfile */
if (!sendfile[0])
continue;
/* found something to send; just in case we were sent back
here after getting a receive timeout from the host and
almost_done is YES, we shall set almost_done back to NO. */
almost_done = NO;
/* set secondary ioctl parameters */
if (trnsp)
ioctl(devfd,BSCTRNSP,0);
/* send file */
if (sendf(sendfile) == -1) {
/* get_errors determines error msg */
more = get_errors();
if (!transp_ok && trnsp) {
sprintf(emsg,
"Attempt to send transparent to non-transparent host <%s>",
hostname);
more = NO;
}
sprintf(note,
"bscd <%s> :Transmission of <%s> aborted, <%s>",
hostname,sendfile,emsg);
write_aud("S",note);
/* if we got an rvi abort, remove queue control file
(and delfile, if any), and go down to receive */
if (c_params.b_flags == BSCRVI) {
unlink(ctlfile);
if (delfile)
unlink(delfile);
contention = YES;
goto Receive_Files;
}
/* if there's a contention problem, abort sending */
if (c_params.b_flags == BSCONTND) {
contention = YES;
goto Receive_Files;
}
/* send mail about problem */
post();
if (more == NO) {
sprintf(note,"Disconnected, <%s>",
emsg);
write_aud("D",note);
goto Disconnect;
} else
continue;
}
/* if send successful and q_ctl mail flag set,
call installation exit notefile */
sprintf(note,"bscd: File <%s> sent successfully",sendfile);
notefile(user,sendfile,note);
/* unlink q_ctl and delfile */
unlink(ctlfile);
if (delfile)
unlink(delfile);
/* tell the AUDIT file this file's all done */
sprintf(note,set_trnsp?
"Transmission of <%s> completed (transparent,%d blocks)":
"Transmission of <%s> completed (%d blocks)",
sendfile,blocks);
write_aud("S",note);
total_bl += blocks;
blocks = 0;
set_trnsp = NO;
} /* End of while read hdir (host spool directory) */
/* if this isn't the first time we've been to Send_Files,
we got a receive timeout the last time we were in Receive_Files,
and there was nothing else to send, then almost_done will
be set. That means it's time to disconnect; write disconnect message
and goto Disconnect. */
if (almost_done == 1) {
sprintf(note,"Disconnected, <Receive idle timeout>");
write_aud("D",note);
goto Send_Signoff;
}
/* get transmit status and write to AUDIT */
ioctl(devfd,BSCGET,&c_params);
sprintf(note,
"EOT, sent %d blocks, did %d TTDs, had %d NAKs, %d timeouts, %d WACKs",
total_bl,c_params.b_nttd,c_params.b_nnak,c_params.b_nor,
c_params.b_nwack);
write_aud("T",note);
Receive_Files:
/* try to receive something (rcvf is receive function) */
/* first check minimum space in user area if minspace set */
if (minspace) {
pptr = popen(df_string,"r");
fgets(line,sizeof line,pptr);
if (atol(&line[25]) < minspace) {
sprintf(note,
"bscd <%s>: file system <%s> has less than minimum blocks available. Processing aborted.",
hostname,dname);
write_aud("D",note);
/* send mail about it all */
post();
/* and now, do the disconnect stuff */
goto Send_Signoff;
}
}
total_bl = 0;
/* rcvf returns OK (2) if a file was received successfully;
NO (0) if nothing was received;
YES (1) if an error was encountered */
while ((err = rcvf()) == OK || err == NO) {
if (minspace) {
pptr = popen(df_string,"r");
fgets(line,sizeof line,pptr);
if (atol(&line[25]) < minspace) {
strcpy(note,
"Receiving aborted - minimum space unavailable");
write_aud("D",note);
/* send mail about it all */
post();
}
}
if (contention)
break;
}
/* if contention on the line, go back and try to send file again */
if (contention) {
contention = NO;
goto Send_Files;
}
if (err == YES) { /* rcvf reported problem */
get_errors();
/* if receive timeout, go back to send to check if there's
anything else to transmit */
if (c_params.b_flags == BSCRXTO) {
almost_done = 1;
/* update AUDIT with status of receive */
ioctl(devfd,BSCGET,&c_params);
sprintf(note,
"EOT, received %d blocks, did %d WACKs and %d NAKs, had %d TTDs, %d overruns",
total_bl,c_params.b_nwack,c_params.b_nnak,
c_params.b_nttd,c_params.b_nor);
write_aud("T",note);
goto Send_Files;
}
sprintf(note,"Receiving aborted, <%s>",emsg);
write_aud("R",note);
sprintf(note,"Disconnected, <%s>",emsg);
write_aud("D",note);
goto Disconnect;
}
/* update AUDIT with status of receive */
ioctl(devfd,BSCGET,&c_params);
sprintf(note,
"EOT, received %d blocks, did %d WACKs and %d NAKs, had %d TTDs, %d overruns",
total_bl,c_params.b_nwack,c_params.b_nnak,c_params.b_nttd,
c_params.b_nor);
write_aud("T",note);
/* if a new queue control file appeared, go back and send it */
#if defined BSD42
rewinddir(spoolfd);
#else
lseek(spoolfd,0L,0); /* rewind host directory */
#endif
if (searchq(spoolfd) == YES)
{ stat(ctlfile,&s);
if (s.st_size > 0)
goto Send_Files;
}
Send_Signoff:
/* if there's a signoff file, send it (soff_send.c) */
if (soff_file) {
total_bl = 0;
if ((more = soff_send(signoff)) == NO) {
sprintf(note,"Disconnected, <%s>",
emsg);
write_aud("D",note);
goto Disconnect;
}
sprintf(note,
"Transmission of SIGNOFF file <%s> completed (%d blocks)",
signoff,blocks);
write_aud("D",note);
total_bl += blocks;
ioctl(devfd,BSCGET,&c_params);
sprintf(note,
"EOT, sent %d blocks, did %d TTDs, had %d NAKs, %d timeouts, %d WACKs",
total_bl,c_params.b_nttd,c_params.b_nnak,
c_params.b_nor,c_params.b_nwack);
write_aud("T",note);
blocks = 0;
}
Disconnect:
quithost();
}
}
/* search the host directory for files queued to send */
searchq(wfd)
#if defined BSD42
DIR *wfd;
#else
int wfd;
#endif
{
int work = NO;
#if defined BSD42
struct direct *d;
while ((d = readdir(wfd)) != NULL)
if (d->d_name[0] == 'C')
{ work = YES;
sprintf(ctlfile,"%s/%s",spool,d->d_name);
break; }
#else
struct direct d;
while (read(wfd,&d,sizeof d) == sizeof d)
if (d.d_ino != 0 && d.d_name[0] == 'C')
{ work = YES;
sprintf(ctlfile,"%s/%s",spool,d.d_name);
break; }
#endif
return (work);
}
/* quithost -- cleanup at end of host processing */
quithost()
{
if (devfd > 0) {
close(devfd);
devfd = -1;
/* do any necessary disconnect cleanup */
disconnect(hostname,devname);
}
if (lockfile[0]) {
unlink(lockfile);
lockfile[0] = '\0';
}
if (auditlock[0]) {
unlink(auditlock);
auditlock[0] = '\0';
}
if (aud) {
fclose(aud);
aud = (FILE *)0;
if (link(audname,new_audnm) >= 0) {
unlink(audname);
}
}
#if defined BSD42
if (spoolfd) {
closedir(spoolfd);
spoolfd = (DIR *)0;
}
#else
if (spoolfd > 0) {
close(spoolfd);
spoolfd = -1;
}
#endif
}
/* sigint -- do signal interrupt processing */
sigint(sig)
int sig;
{
char msg[80];
sprintf(msg,"Signal %d received",sig);
/* update the audit file */
write_aud("D",msg);
quithost();
exit(0);
}
/* param_err - invalid keyword parameter error */
param_err(kword,fname)
char *kword;
char *fname;
{
/* send mail about problem */
sprintf(note,"Invalid parameter for keyword <%s>\n in <%s>\n",
kword,fname);
post();
fputs(note,stderr);
quithost();
exit(1);
}
/* post - post mail to the system administrator about problems encountered */
post()
{
FILE *popen(),*pptr;
char address[50];
sprintf(address,"mail %s",sys_admin);
if (sys_admin[0] == '/') {
pptr = fopen(sys_admin,"a");
fputs(note,pptr);
fclose(pptr);
} else {
pptr = popen(address,"w");
fputs(note,pptr);
pclose(pptr);
}
}
/* get_cnfg - get host configuration parameters
The function bcopy used herein does the same thing as strncpy, only
it actually does copy n characters, and doesn't stop at NULL. Very
convenient for binary or transparent data which contains NULLs...
bcopy(to,from,nbytes) */
get_cnfg(config_file)
char config_file[];
{
FILE *fptr; /* file pointer returned by fopen */
int counter = 0; /* tracks line of config file being read */
int i = 0; /* convenient index */
/* default b_flags parameter values */
int halfdup = 0;
int irs = 0;
char *index();
char *pos; /* general buffer position pointer */
char *dptr; /* dname position pointer */
char cline[50]; /* contains one configuration line */
s_params.b_blks = 508; /* default block size */
blksize = 508; /* as above */
recsize = 503;
recblk = 503;
recsep = 0x1e;
rviab = BSCRVIABT; /* abort on receiving rvi */
maxfsize = 0L;
minspace = 0L;
s_params.b_nbid = 0; /* default number of bids limit */
s_params.b_nnak = 16; /* default number of naks allowed */
s_params.b_nretry = 15; /* default number of retrys allowed */
s_params.b_nttd = 120; /* default number of temp. txt delays */
s_params.b_nwack = 120; /* default number of wacks allowed */
s_params.b_nor = 60; /* default timeout */
pt_to_pt = 0;
chk_hostid = NO;
son_file = NO;
soff_file = NO;
chk_termid = NO;
strcpy(devname,"/dev/bsc"); /* default device name */
strcpy(sys_admin,"/dev/console"); /* default system administrator
name for problem mail */
ascii = NO;
compress = YES;
/* read host configuration file for actual parameters */
if ((fptr = fopen(config_file,"r")) == NULL) {
fprintf(stderr,
"bscd: can't open <%s> configuration file \n",hostname);
quithost();
exit(1);
}
while ((fgets(cline,sizeof cline,fptr)) != NULL) {
++counter;
if (strncmp(cline,"BLKSIZE=",8) == 0) {
pos = &cline[8];
s_params.b_blks = atoi(pos);
blksize = s_params.b_blks;
if (s_params.b_blks < 32 || s_params.b_blks > 512)
param_err("BLKSIZE",config_file);
continue;
}
if (strncmp(cline,"CODE=",5) == 0) {
pos = &cline[5];
if(strncmp(pos,"ASCII",5) != 0 &&
strncmp(pos,"EBCDIC",6) != 0)
param_err("CODE",config_file);
ascii = strncmp(pos,"ASCII",5) == 0?BSCASCII:NO;
continue;
}
if (strncmp(cline,"COMPRESS=",9) == 0) {
pos = &cline[9];
if (strncmp(pos,"YES",3) != 0 &&
strncmp(pos,"NO",2) != 0)
param_err("COMPRESS",config_file);
compress =strncmp(pos,"YES",3)==0?YES:NO;
continue;
}
if (strncmp(cline,"DEVICE=",7) == 0) {
pos = &cline[7];
strcpy(devname,pos);
devname[strlen(devname)-1] = '\0';
continue;
}
if(strncmp(cline,"DUPLEX=",7) == 0) {
pos = &cline[7];
if (strncmp(pos,"HALF",4) != 0 &&
strncmp(pos,"FULL",4) != 0)
param_err("DUPLEX",config_file);
halfdup =strncmp(pos,"HALF",4)==0?0:BSCFDX;
continue;
}
if (strncmp(cline,"IDCHECK=",8) ==0) {
pos = &cline[8];
strcpy(s_params.b_hostid,pos);
chk_hostid = BSCCKHOST;
continue;
}
if (strncmp(cline,"MAIL=",5) == 0) {
pos = &cline[5];
strcpy(sys_admin,pos);
continue;
}
if (strncmp(cline,"MAXFSIZE=",9) == 0) {
pos = &cline[9];
maxfsize = atol(pos);
if (maxfsize > 1000000000L)
param_err("MAXFSIZE",config_file);
continue;
}
if (strncmp(cline,"MINSPACE=",9) == 0) {
if ((pos = index(cline,',')) == NULL)
param_err("MINSPACE",config_file);
++pos;
minspace = atol(pos);
if (minspace > 1000000000L)
param_err("MINSPACE",config_file);
pos = &cline[9];
dptr = &dname[0];
while(*pos != ',')
*dptr++ = *pos++;
*dptr = '\0';
sprintf(df_string,"df -f %s\n",dname);
continue;
}
if (strncmp(cline,"MPTADDR=",8) == 0) {
pos = &cline[8];
strcpy(s_params.b_termid,pos);
pt_to_pt = BSCMPT;
continue;
}
if (strncmp(cline,"NBID=",5) == 0) {
pos = &cline[5];
s_params.b_nbid = atoi(pos);
if (s_params.b_nbid > 127 || s_params.b_nbid < 0)
param_err("NBID",config_file);
continue;
}
if (strncmp(cline,"NNAK=",5) == 0) {
pos = &cline[5];
s_params.b_nnak = atoi(pos);
if (s_params.b_nnak > 127 || s_params.b_nnak < 0)
param_err("NNAK",config_file);
continue;
}
if (strncmp(cline,"NRETRY=",7) == 0) {
pos = &cline[7];
s_params.b_nretry = atoi(pos);
if (s_params.b_nretry > 127 || s_params.b_nretry < 0)
param_err("NRETRY",config_file);
continue;
}
if (strncmp(cline,"NTTD=",5) == 0) {
pos = &cline[5];
s_params.b_nttd = atoi(pos);
if (s_params.b_nttd > 127 || s_params.b_nttd < 0)
param_err("NTTD",config_file);
continue;
}
if (strncmp(cline,"NWACK=",6) == 0) {
pos = &cline[6];
s_params.b_nwack = atoi(pos);
if (s_params.b_nwack > 127 || s_params.b_nwack < 0)
param_err("NWACK",config_file);
continue;
}
if (strncmp(cline,"RECBLK=",7) == 0) {
pos = &cline[7];
recblk = atoi(pos);
if (recblk > 507)
param_err("RECBLK",config_file);
continue;
}
if (strncmp(cline,"RECSEP=",7) == 0) {
pos = &cline[7];
irs =strncmp(pos,"IRS",3)==0?0:BSCIUS;
recsep = (irs == 0)?0x1e:0x19;
continue;
}
if (strncmp(cline,"RECSIZE=",8) == 0) {
pos = &cline[8];
recsize = atoi(pos);
if (recsize > 507)
recsize = 507;
continue;
}
if (strncmp(cline,"RVIMODE=",8) == 0) {
pos = &cline[8];
if (strncmp(pos,"ABORT",5) != 0 &&
strncmp(pos,"IGNORE",6) != 0)
param_err("RVIMODE",config_file);
rviab =strncmp(pos,"ABORT",5)==0?BSCRVIABT:NO;
continue;
}
if (strncmp(cline,"SIGNON=",7) == 0) {
strcpy(signon,&cline[7]);
signon[strlen(signon)-1] = '\0';
son_file = YES;
continue;
}
if (strncmp(cline,"SIGNOFF=",8) == 0) {
strcpy(signoff,&cline[8]);
signoff[strlen(signoff)-1] = '\0';
soff_file = YES;
continue;
}
if (strncmp(cline,"STATION=",8) == 0) {
pos = &cline[8];
if (strncmp(pos,"PRIMARY",7) != 0 &&
strncmp(pos,"SECONDARY",9) != 0)
param_err("STATION",config_file);
primary =strncmp(pos,"PRIMARY",7)==0?BSCPRIM:NO;
continue;
}
if (strncmp(cline,"TERMID=",7) == 0) {
pos = &cline[7];
bcopy(s_params.b_termid,pos,strlen(pos)-1);
chk_termid = YES;
continue;
}
if (strncmp(cline,"TIMEOUT=",8) == 0) {
pos = &cline[8];
i = atoi(pos);
if (i > 0 && i <= 3000)
s_params.b_nor = atoi(pos);
else
param_err("TIMEOUT",config_file);
continue;
}
if (strncmp(cline,"TRANSPARENT=",12) == 0) {
pos = &cline[12];
if (strncmp(pos,"YES",3) != 0 &&
strncmp(pos,"NO",2) != 0)
param_err("TRANSPARENT",config_file);
transp_ok =strncmp(pos,"YES",3)==0?YES:NO;
continue;
}
if (strncmp(cline,"UNITSEP=",8) == 0) {
pos = &cline[8];
ius = (strncmp(pos,"YES",3) == 0)? BSCIUS:NO;
continue;
}
/* invalid keyword parameter error */
sprintf(note,
"bscd <%s>: Unrecognized keyword, line %d in <%s>\n",
hostname,counter,config_file);
fputs(note,stderr);
post();
quithost();
exit(1);
}
/* insure that the record size is smaller than the block size */
if (recsize > blksize - 5)
recsize = blksize - 5;
s_params.b_flags = ascii | halfdup | ius | rviab |
primary | chk_hostid | pt_to_pt;
/* translate termid if one given and ebcdic */
if (!ascii && chk_termid)
ascebc(s_params.b_termid,strlen(s_params.b_termid));
/* close configuration file */
fclose(fptr);
}
/* open_audit - open the host's AUDIT file */
open_audit()
{
int audfd;
/* construct AUDIT file pathname */
sprintf(audname,"%s/%s",spool,"AUDIT");
sprintf(new_audnm,"%s/%s",spool,"AUDIT");
if (access(audname,0) == 0) {
sprintf(auditlock,"%s/%s",spool,"auditlock");
if ((audfd = creat(auditlock,0)) < 0) {
auditlock[0] = '\0';
bsc_audnm();
} else {
close(audfd);
aud = fopen(audname,"a");
}
}
}
char *usr_name; /* ptr returned by getlogin */
/* write_aud - write message to audit file */
write_aud(type,msg)
char *type;
char *msg;
{
char *getlogin(); /* returns ptr to login name for this
process */
if (aud == NULL)
return;
/* if first time, get login name */
if (usr_name == NULL)
if ((usr_name=getlogin()) == NULL)
usr_name="unknown";
/* get current time */
currtime = time((long*)0);
t = localtime(&currtime);
fprintf (aud, "%s %s %02d%02d%02d%02d%02d %s\n",
usr_name, type, t->tm_year, (t->tm_mon) + 1,
t->tm_mday, t->tm_hour, t->tm_min, msg);
fflush(aud);
}
/* do_compress - replace blanks with group separator and count of blanks */
do_compress(string,llen)
char *string;
register int llen; /* line length */
{
register int blanks; /* count of blanks */
register char *s, *r;
char blank;
blank = ascii?' ':0x40;
r = s = string;
while (1) {
/* "copy" characters into string as long as they aren't blank */
while (llen > 0 && *s != blank) {
--llen;
*r++ = *s++;
}
if (llen == 0) /* no blanks were found */
break;
/* skip over blanks in string, keep count to encode as group separator
(GS) followed by number of blanks -- encode only if more than
two blanks are found */
blanks = 0;
while (llen > 0 && *s == blank){
++blanks;
--llen;
++s;
}
if (blanks > 2)
{ *r++ = GS;
if (blanks <= 63)
*r++ = 0x40 + blanks;
else {
*r++ = 0x40 + 63;
*r++ = GS;
*r++ = 0x40 + (blanks - 63);
}
continue;
}
else if (blanks == 2)
*r++ = blank;
*r++ = blank;
}
*r = '\0';
return(r-string);
}
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.