home *** CD-ROM | disk | FTP | other *** search
Text File | 1992-02-01 | 56.2 KB | 1,516 lines |
- Newsgroups: comp.sources.unix
- From: sir-alan!ispin!lbartz@iuvax.cs.indiana.edu (Larry Bartz)
- Subject: v25i120: Indianapolis Standard Printer Interface for Networked printers, Part09/15
- Sender: sources-moderator@pa.dec.com
- Approved: vixie@pa.dec.com
-
- Submitted-By: sir-alan!ispin!lbartz@iuvax.cs.indiana.edu (Larry Bartz)
- Posting-Number: Volume 25, Issue 120
- Archive-Name: ispin/part09
-
- #! /bin/sh
- # This is a shell archive. Remove anything before this line, then unpack
- # it by saving it into a file and typing "sh file". To overwrite existing
- # files, type "sh file -c". You can also feed this as standard input via
- # unshar, or by typing "sh <file", e.g.. If this archive is complete, you
- # will see the following message at the end:
- # "End of archive 9 (of 15)."
- # Contents: ISPIN/src/ISPIN.c.ac ISPIN/doc/LPinstall.doc
- # ISPIN/misc/ISPIT.dr/README ISPIN/misc/ISPIT.dr/passwd.entry
- # Wrapped by socrates@indy6 on Tue Jan 28 15:26:56 1992
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f 'ISPIN/src/ISPIN.c.ac' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'ISPIN/src/ISPIN.c.ac'\"
- else
- echo shar: Extracting \"'ISPIN/src/ISPIN.c.ac'\" \(30636 characters\)
- sed "s/^X//" >'ISPIN/src/ISPIN.c.ac' <<'END_OF_FILE'
- X signal(SIGRES, SIG_IGN); /* ignore "restart" signal */
- X signal(SIGBACK, SIG_IGN); /* ignore "back-up" signal */
- X signal(SIGSTOP, my_error); /* trap "stop" signal */
- X#endif
- X
- X time_out = 1;
- X return;
- X}
- X
- X
- Xnegotiate()
- X{
- X int got_chars = 0; /* how many chars were read? */
- X int n = 0;
- X ushort not_yet = 1; /* while loop controller */
- X
- X
- X
- X
- X /* set all of our list pointers to point at heads of the lists */
- X busy_list = busy_curr = busy_head;
- X dead_list = dead_curr = dead_head;
- X quit_list = quit_curr = quit_head;
- X disc_list = disc_curr = disc_head;
- X expt_list = expt_curr = expt_head;
- X send_list = send_curr = send_head;
- X
- X /* advise IQUEUER of our current state */
- X notify(CONNECTING);
- X
- X /* commence negotiations. Read from the output file (device) */
- X /* don't read so many chars that there isn't room left to NULL terminate */
- X
- X /* Maybe there is no EXPECT/SEND necessary for this printer */
- X /* Configuring no EXPECT/SEND allows specification of direct connect printer */
- X if(expt_curr->next != NULL)
- X {
- X while(not_yet)
- X {
- X
- X signal(SIGALRM, my_error);
- X time_out = 0; /* assume no timeout */
- X alarm(30); /* wait a few seconds for characters */
- X
- X
- X /* set the no delay bit so we can do a quickie read */
- X /* fcntl(out_file,F_SETFL,flgs_ndelay); */
- X
- X got_chars = read(out_file,in_buf,(BUFSIZ -1));
- X
- X /* turn the delay bit back on, so we can accomodate flow control */
- X /* fcntl(out_file,F_SETFL,flgs_delay); */
- X
- X
- X
- X alarm(0); /* turn off the alarm clock */
- X signal(SIGALRM, SIG_IGN);
- X
- X if(got_chars <= 0)
- X {
- X strcpy(in_buf,"gOt nO cHaRaCtERs aT aLl, sO nO mAtCh");
- X }
- X else
- X {
- X /* NULL terminate the string we received */
- X in_buf[got_chars] = '\0';
- X }
- X
- X/*****************************************************************************/
- X/* get rid of the non-printable chars we received */
- X
- X check_char = keep_char = 0;
- X
- X while(in_buf[check_char] != '\0')
- X {
- X if(isprint(in_buf[check_char]))
- X {
- X in_buf[keep_char++] = in_buf[check_char];
- X }
- X ++check_char;
- X }
- X in_buf[keep_char] = '\0';
- X/*****************************************************************************/
- X
- X
- X /* is this string what we are hoping for? */
- X
- X /* go to (not goto!) the next EXPECT string */
- X if(expt_curr->next == NULL)
- X {
- X /* need to send out an error msg */
- X /* format an error message */
- X time(&tloc);
- X nowtime = (struct tm *)localtime(&tloc);
- X time_str = asctime(nowtime);
- X
- X sprintf(errmsg,"ISPIN: printer %s: EXPECT: couldn't match <<%s>>\n\n",dest,in_buf);
- X sprintf(errmsg2," USER: %s\n",from);
- X strcat(errmsg,errmsg2);
- X if(usr_addr)
- X {
- X sprintf(errmsg2," ADDR: %s\n",usr_strng);
- X strcat(errmsg,errmsg2);
- X }
- X if(port_open == 1)
- X {
- X sprintf(errmsg2," DEV: %s\n",GO_dev);
- X strcat(errmsg,errmsg2);
- X }
- X#ifdef NQ
- X sprintf(errmsg2," FILE: %s\n",fyle);
- X#else
- X sprintf(errmsg2," FILE: %s\n",fyles[0]);
- X#endif
- X strcat(errmsg,errmsg2);
- X sprintf(errmsg2," TIME: %s\n",time_str);
- X strcat(errmsg,errmsg2);
- X
- X /* call the error routine, never come back */
- X my_error(SYSERR);
- X
- X }
- X expt_curr = expt_curr->next;
- X
- X /* is this an "expect nothing" EXPECT string? */
- X if(strlen(expt_curr->expt_strg) != 0)
- X {
- X
- X
- X /* is this a compound EXPECT-SEND-EXPECT string? */
- X cpnd_send = strchr(expt_curr->expt_strg,'-');
- X if(cpnd_send != NULLCHARPTR)
- X {
- X
- X
- X /* we have at least one dash */
- X cpnd_expt = strrchr(expt_curr->expt_strg,'-');
- X if(cpnd_send != cpnd_expt)
- X {
- X /* we have at least two dashes */
- X /* move our pointers past the dashes */
- X ++cpnd_send;
- X ++cpnd_expt;
- X /* now parse our original into three */
- X /* get the first one */
- X /* how many characters before the first dash ? */
- X /* Allocate memory to store the string and */
- X /* aim our pointer at it. */
- X /* Need one extra byte for the terminating NULL */
- X n = strcspn(expt_curr->expt_strg,"-");
- X expt1 = (char *) calloc(1, (n + 1));
- X strncpy(expt1,expt_curr->expt_strg,n);
- X expt1[n] = '\0';
- X
- X
- X
- X /* get the next one */
- X /* how many characters before the next dash ? */
- X /* Allocate memory to store the string and */
- X /* aim our pointer at it. */
- X /* Need one extra byte for the terminating NULL */
- X n = strcspn(cpnd_send,"-");
- X c_send = (char *) calloc(1, (n + 1));
- X strncpy(c_send,cpnd_send,n);
- X c_send[n] = '\0';
- X
- X
- X
- X /* get the third one */
- X /* how many characters after the last dash ? */
- X /* Allocate memory to store the string and */
- X /* aim our pointer at it. */
- X /* Need one extra byte for the terminating NULL */
- X expt2 = (char *) calloc(1, ((strlen(cpnd_expt))+1));
- X strcpy(expt2,cpnd_expt);
- X
- X
- X
- X /* compare the first EXPECT to what we got */
- X if(matcher(in_buf,expt1) == 1)
- X {
- X /* not a match */
- X
- X
- X /* compare to BUSY and DEAD (in separate functions) */
- X
- X
- X
- X n = busyordead();
- X
- X /* If it is neither BUSY nor DEAD, send the internal SEND, */
- X /* read for the second EXPECT of the compound construct, */
- X /* and test the second EXPECT just as normal, non-compound */
- X /* EXPECT. */
- X
- X /* Doesn't match, is neither BUSY nor DEAD */
- X
- X /* send the imbedded send string */
- X
- X
- X n = write_net(c_send);
- X
- X
- X
- X /* what's the answer? */
- X
- X signal(SIGALRM, my_error);
- X time_out = 0; /* assume no timeout */
- X alarm(30); /* wait a few seconds for characters */
- X
- X
- X /* set the no delay bit so we can do a quickie read */
- X /* fcntl(out_file,F_SETFL,flgs_ndelay); */
- X
- X got_chars = read(out_file,in_buf,(BUFSIZ -1));
- X
- X /* turn the delay bit back on, so we can accomodate flow control */
- X /* fcntl(out_file,F_SETFL,flgs_delay); */
- X
- X
- X
- X alarm(0); /* turn off the alarm clock */
- X signal(SIGALRM, SIG_IGN);
- X
- X
- X if(got_chars <= 0)
- X /* if((got_chars <= 0)||(time_out)) */
- X {
- X strcpy(in_buf,"gOt nO cHaRaCtERs aT aLl, sO nO mAtCh");
- X }
- X else
- X {
- X /* NULL terminate the string we received */
- X in_buf[got_chars] = '\0';
- X }
- X
- X
- X
- X/*****************************************************************************/
- X/* get rid of the non-printable chars we received */
- X
- X check_char = keep_char = 0;
- X
- X while(in_buf[check_char] != '\0')
- X {
- X if(isprint(in_buf[check_char]))
- X {
- X in_buf[keep_char++] = in_buf[check_char];
- X }
- X ++check_char;
- X }
- X in_buf[keep_char] = '\0';
- X/*****************************************************************************/
- X /* compare the second EXPECT to what we got */
- X if(matcher(in_buf,expt2) == 1)
- X {
- X /* no match on the second EXPECT
- X /* not a match */
- X /* compare to BUSY and DEAD (in separate functions) */
- X
- X n = busyordead();
- X /* Doesn't match, is neither BUSY nor DEAD */
- X
- X /* need to send out an error msg */
- X /* format an error message */
- X time(&tloc);
- X nowtime = (struct tm *)localtime(&tloc);
- X time_str = asctime(nowtime);
- X
- X sprintf(errmsg,"ISPIN: printer %s:\n EXPECTED: <<%s>>\n RECEIVED: <<%s>>\n\n",dest,expt2,in_buf);
- X sprintf(errmsg2," USER: %s\n",from);
- X strcat(errmsg,errmsg2);
- X if(usr_addr)
- X {
- X sprintf(errmsg2," ADDR: %s\n",usr_strng);
- X strcat(errmsg,errmsg2);
- X }
- X if(port_open == 1)
- X {
- X sprintf(errmsg2," DEV: %s\n",GO_dev);
- X strcat(errmsg,errmsg2);
- X }
- X#ifdef NQ
- X sprintf(errmsg2," FILE: %s\n",fyle);
- X#else
- X sprintf(errmsg2," FILE: %s\n",fyles[0]);
- X#endif
- X strcat(errmsg,errmsg2);
- X sprintf(errmsg2," TIME: %s\n",time_str);
- X strcat(errmsg,errmsg2);
- X
- X /* call the error routine, never come back */
- X my_error(SYSERR);
- X }
- X
- X
- X }
- X
- X
- X /* if it does match, we just fall through */
- X /* free the allocated memory */
- X free(expt1);
- X free(c_send);
- X free(expt2);
- X }
- X }
- X else
- X {
- X /* this is not a compound EXPECT-SEND-EXPECT */
- X /* compare what we got to the EXPECT */
- X if(matcher(in_buf,expt_curr->expt_strg) == 1)
- X {
- X /* not a match */
- X /* compare to BUSY and DEAD (in separate functions) */
- X
- X n = busyordead();
- X
- X /* Doesn't match, is neither BUSY nor DEAD */
- X /* need to send out an error msg */
- X /* format an error message */
- X time(&tloc);
- X nowtime = (struct tm *)localtime(&tloc);
- X time_str = asctime(nowtime);
- X
- X sprintf(errmsg,"ISPIN: printer %s:\n EXPECTED: <<%s>>\n RECEIVED: <<%s>>\n\n",dest,expt_curr->expt_strg,in_buf);
- X sprintf(errmsg2," USER: %s\n",from);
- X strcat(errmsg,errmsg2);
- X if(usr_addr)
- X {
- X sprintf(errmsg2," ADDR: %s\n",usr_strng);
- X strcat(errmsg,errmsg2);
- X }
- X if(port_open == 1)
- X {
- X sprintf(errmsg2," DEV: %s\n",GO_dev);
- X strcat(errmsg,errmsg2);
- X }
- X#ifdef NQ
- X sprintf(errmsg2," FILE: %s\n",fyle);
- X#else
- X sprintf(errmsg2," FILE: %s\n",fyles[0]);
- X#endif
- X strcat(errmsg,errmsg2);
- X sprintf(errmsg2," TIME: %s\n",time_str);
- X strcat(errmsg,errmsg2);
- X
- X /* call the error routine, never come back */
- X my_error(SYSERR);
- X }
- X
- X
- X /* if it does match, we just fall through */
- X }
- X
- X }
- X /* This is where normal write of SEND takes place. */
- X /* After the last send, we'll set not_yet = 1. */
- X
- X /* take one step through the SEND list */
- X if(send_curr->next != NULL)
- X {
- X send_curr = send_curr->next;
- X }
- X
- X /* don't write anything if it is intended as "send nothing" */
- X if(strlen(send_curr->send_strg) != 0)
- X {
- X n = write_net(send_curr->send_strg);
- X
- X
- X }
- X
- X /* if this is the end of the SEND list, terminate the loop */
- X if(send_curr->next == NULL)
- X {
- X not_yet = 0;
- X }
- X
- X /* the following right curly ends while(not_yet) */
- X }
- X }
- X else
- X {
- X
- X /* We only listen for SIGHUP on a hard-wired printer. */
- X
- X /* Now that the device is our control terminal, do something if SIGHUP. */
- X /* If this is not our first time through, there is a chance that the */
- X /* GO_dev is not our control terminal. Remember, we only get one chance */
- X /* to choose the control terminal (unless we fork, which could ruin our */
- X /* relationship with our parent, the native queuer). If this is not our */
- X /* first time here (due to a previous BUSY condition), IQUEUER could */
- X /* tell us to use a terminal other than our control terminal. In that */
- X /* case, we do not want to listen for SIGHUP which may be issued by a */
- X /* terminal we aren't even using. */
- X
- X if(strcmp(GO_dev,ctrl_tty) == 0)
- X {
- X signal(SIGHUP, my_error);
- X }
- X
- X }
- X
- X/* Remember, the funky Sequent SVAE won't let us do a half-baked mode. */
- X/* Now that we are patched through to the printer, go back to cooked */
- X/* mode so that we can do ONLCR as we write. */
- X
- X if(ioctl(out_file, TCGETA, &T_COOK) == -1)
- X {
- X /* need to send out an error msg */
- X /* format an error message */
- X time(&tloc);
- X nowtime = (struct tm *)localtime(&tloc);
- X time_str = asctime(nowtime);
- X
- X sprintf(errmsg,"ISPIN: printer %s: ioctl %s: %s.\n",dest,GO_dev,sys_errlist[errno]);
- X sprintf(errmsg2," USER: %s\n",from);
- X strcat(errmsg,errmsg2);
- X if(usr_addr)
- X {
- X sprintf(errmsg2," ADDR: %s\n",usr_strng);
- X strcat(errmsg,errmsg2);
- X }
- X#ifdef NQ
- X sprintf(errmsg2," FILE: %s\n",fyle);
- X#else
- X sprintf(errmsg2," FILE: %s\n",fyles[0]);
- X#endif
- X strcat(errmsg,errmsg2);
- X sprintf(errmsg2," TIME: %s\n",time_str);
- X strcat(errmsg,errmsg2);
- X
- X /* call the error routine, never come back */
- X my_error(SYSERR);
- X
- X }
- X
- X if(raw < 1)
- X {
- X /* the flag for absolutely RAW is not set */
- X
- X T_COOK.c_lflag |= (ICANON);
- X T_COOK.c_oflag |= (OPOST|ONLCR);
- X if(tab_expand > 0)
- X {
- X T_COOK.c_oflag |= (TAB3);
- X }
- X }
- X
- X /* turn the delay bit on, so we can accomodate flow control */
- X fcntl(out_file,F_SETFL,flgs_delay);
- X
- X
- X if(ioctl(out_file, TCSETA, &T_COOK) == -1)
- X {
- X /* need to send out an error msg */
- X /* format an error message */
- X time(&tloc);
- X nowtime = (struct tm *)localtime(&tloc);
- X time_str = asctime(nowtime);
- X
- X sprintf(errmsg,"ISPIN: printer %s: ioctl %s: %s.\n",dest,GO_dev,sys_errlist[errno]);
- X sprintf(errmsg2," USER: %s\n",from);
- X strcat(errmsg,errmsg2);
- X if(usr_addr)
- X {
- X sprintf(errmsg2," ADDR: %s\n",usr_strng);
- X strcat(errmsg,errmsg2);
- X }
- X#ifdef NQ
- X sprintf(errmsg2," FILE: %s\n",fyle);
- X#else
- X sprintf(errmsg2," FILE: %s\n",fyles[0]);
- X#endif
- X strcat(errmsg,errmsg2);
- X sprintf(errmsg2," TIME: %s\n",time_str);
- X strcat(errmsg,errmsg2);
- X
- X /* call the error routine, never come back */
- X my_error(SYSERR);
- X
- X }
- X
- X return(0);
- X}
- X
- X
- X/************************************************************************/
- X/* MATCHER */
- X/* This function receives (pointer to) the string to be checked. The */
- X/* (pointer to) the string we hope to match is expected. */
- X
- X
- X
- Xmatcher(received,expected)
- Xchar *received, *expected;
- X{
- X char *ep_p;
- X int esize;
- X
- X esize = (strlen(received) + BUFSIZ);
- X
- X ep_p = (char *) calloc(1, esize);
- X
- X
- X
- X
- X
- X
- X /* This is a regexp(5) call. See /usr/include/regexp.h */
- X compile(expected, ep_p, &ep_p[esize - 1], '\0');
- X
- X
- X /* This is a regexp(5) call. See /usr/include/regexp.h */
- X if(step(received,ep_p) == 1)
- X {
- X /* success on match */
- X free(ep_p);
- X return(0);
- X }
- X else
- X {
- X /* no match */
- X free(ep_p);
- X return(1);
- X }
- X}
- X
- X
- Xsetuptty()
- X{
- X /* We want to be able to recognize SIGHUP from the port we are using to */
- X /* access the printer. In order for that to happen, that port must be */
- X /* our control terminal. Only a process group leader may determine its */
- X /* own control terminal, so this process must become its own process */
- X /* group leader. The setpgrp() call will see to that. Then the first */
- X /* terminal we open will become our control terminal. Of course, this */
- X /* can only come to pass as long as our terminal is not already the */
- X /* control terminal of another process group. This is the reason it's SO*/
- X /* CRITICAL that the native queuer is never wise as to which tty we are */
- X /* using. The best thing is to tell DQUEUER or LP (as your case may be) */
- X /* that this member's device is /dev/null. This will avoid any fubar. */
- X /* It is also possible that the device we want is already the control */
- X /* terminal of another process group, in which case the kernel will not */
- X /* allow it to become our control terminal. This is why we do not depend*/
- X /* solely upon SIGHUP to let us know of a disconnect. */
- X
- X int tmp_open;
- X
- X
- X if(netloop == 0)
- X {
- X /* only if this is the first time through */
- X setpgrp();
- X strcpy(ctrl_tty,GO_dev);
- X }
- X
- X
- X
- X /* open the device */
- X /* GO_dev is the device IQUEUER told us to use */
- X
- X signal(SIGALRM, my_error);
- X time_out = 0; /* set up timeout for file open */
- X alarm(10); /* wait a few seconds for carrier */
- X /* 04/16/89: I found out via one of the beta test */
- X /* sites that, depending upon how someone else */
- X /* chooses to pin their cables, a carrier may */
- X /* never come. So, we open with no delay. */
- X /***********************************************/
- X
- X#ifndef NQ
- X if((netloop != 0)&&((strcmp(ctrl_tty,GO_dev) == 0)))
- X {
- X /* re-use the file descriptor we got the first time if same device */
- X out_file = ctrltty;
- X }
- X else
- X#endif
- X {
- X out_file = open(GO_dev,O_RDWR|O_NDELAY);
- X if((out_file == -1) || (time_out))
- X {
- X /* need to send out an error msg */
- X /* format an error message */
- X time(&tloc);
- X nowtime = (struct tm *)localtime(&tloc);
- X time_str = asctime(nowtime);
- X
- X sprintf(errmsg,"ISPIN: printer %s: open %s: %s.\n",dest,GO_dev,sys_errlist[errno]);
- X sprintf(errmsg2," USER: %s\n",from);
- X strcat(errmsg,errmsg2);
- X if(usr_addr)
- X {
- X sprintf(errmsg2," ADDR: %s\n",usr_strng);
- X strcat(errmsg,errmsg2);
- X }
- X#ifdef NQ
- X sprintf(errmsg2," FILE: %s\n",fyle);
- X#else
- X sprintf(errmsg2," FILE: %s\n",fyles[0]);
- X#endif
- X strcat(errmsg,errmsg2);
- X sprintf(errmsg2," TIME: %s\n",time_str);
- X strcat(errmsg,errmsg2);
- X
- X /* call the error routine, never come back */
- X my_error(SYSERR);
- X
- X }
- X /***********************************************/
- X alarm(0); /* turn off the alarm clock */
- X signal(SIGALRM, SIG_IGN);
- X /***********************************************/
- X
- X if(netloop == 0 )
- X {
- X ctrltty = out_file;
- X }
- X
- X flgs_ndelay = fcntl(out_file,F_GETFL,0);
- X flgs_delay = (flgs_ndelay & ~(O_NDELAY));
- X }
- X
- X port_open = 1;
- X
- X /* turn the delay bit on, so we can accomodate flow control */
- X /* fcntl(out_file,F_SETFL,flgs_delay); */
- X
- X if(ioctl(out_file, TCGETA, &T) == -1)
- X {
- X /* need to send out an error msg */
- X /* format an error message */
- X time(&tloc);
- X nowtime = (struct tm *)localtime(&tloc);
- X time_str = asctime(nowtime);
- X
- X sprintf(errmsg,"ISPIN: printer %s: ioctl %s: %s.\n",dest,GO_dev,sys_errlist[errno]);
- X sprintf(errmsg2," USER: %s\n",from);
- X strcat(errmsg,errmsg2);
- X if(usr_addr)
- X {
- X sprintf(errmsg2," ADDR: %s\n",usr_strng);
- X strcat(errmsg,errmsg2);
- X }
- X#ifdef NQ
- X sprintf(errmsg2," FILE: %s\n",fyle);
- X#else
- X sprintf(errmsg2," FILE: %s\n",fyles[0]);
- X#endif
- X strcat(errmsg,errmsg2);
- X sprintf(errmsg2," TIME: %s\n",time_str);
- X strcat(errmsg,errmsg2);
- X
- X /* call the error routine, never come back */
- X my_error(SYSERR);
- X
- X }
- X
- X ioctl(out_file, TCGETA, &Tsav);
- X
- X T.c_cflag &= ~CBAUD;
- X switch(speed)
- X {
- X case 9600:
- X T.c_cflag |= B9600;
- X break;
- X case 1200:
- X T.c_cflag |= B1200;
- X break;
- X case 75:
- X T.c_cflag |= B75;
- X break;
- X case 110:
- X T.c_cflag |= B110;
- X break;
- X case 134:
- X T.c_cflag |= B134;
- X break;
- X case 150:
- X T.c_cflag |= B150;
- X break;
- X case 200:
- X T.c_cflag |= B200;
- X break;
- X case 300:
- X T.c_cflag |= B300;
- X break;
- X case 600:
- X T.c_cflag |= B600;
- X break;
- X case 1800:
- X T.c_cflag |= B1800;
- X break;
- X case 2400:
- X T.c_cflag |= B2400;
- X break;
- X case 4800:
- X T.c_cflag |= B4800;
- X break;
- X case 19200:
- X T.c_cflag |= B19200;
- X break;
- X default:
- X T.c_cflag |= B9600;
- X break;
- X }
- X
- X /***************************************************************************/
- X /* The funky Sequent DYNIX SVAE can't do the "half-baked" mode which is so */
- X /* convenient in a true Sys V environment. It has to be either cooked or */
- X /* raw. So, just to be portable ... */
- X /***************************************************************************/
- X
- X T.c_iflag &= ~(INLCR|BRKINT|PARMRK|INPCK|ICRNL|IUCLC|IXOFF);
- X T.c_iflag |= (IGNBRK|IGNPAR|ISTRIP|IGNCR|IXON);
- X T.c_oflag &= ~(OLCUC|NLDLY|CRDLY|TABDLY|BSDLY|VTDLY|FFDLY|OCRNL|ONOCR|OFILL|OFDEL);
- X T.c_oflag &= ~(OPOST|ONLCR);
- X T.c_cflag &= ~(CSTOPB|PARENB);
- X T.c_cflag &= ~(CLOCAL);
- X T.c_cflag |= (CS8|HUPCL|CREAD);
- X T.c_lflag &= ~(ISIG|ICANON|ECHO|ECHOE|ECHOK|ECHONL|XCASE|NOFLSH);
- X T.c_cc[VMIN] = 0;
- X T.c_cc[VTIME] = 75;
- X
- X if(ioctl(out_file, TCSETA, &T) == -1)
- X {
- X /* need to send out an error msg */
- X /* format an error message */
- X time(&tloc);
- X nowtime = (struct tm *)localtime(&tloc);
- X time_str = asctime(nowtime);
- X
- X sprintf(errmsg,"ISPIN: printer %s: ioctl %s: %s.\n",dest,GO_dev,sys_errlist[errno]);
- X sprintf(errmsg2," USER: %s\n",from);
- X strcat(errmsg,errmsg2);
- X if(usr_addr)
- X {
- X sprintf(errmsg2," ADDR: %s\n",usr_strng);
- X strcat(errmsg,errmsg2);
- X }
- X#ifdef NQ
- X sprintf(errmsg2," FILE: %s\n",fyle);
- X#else
- X sprintf(errmsg2," FILE: %s\n",fyles[0]);
- X#endif
- X strcat(errmsg,errmsg2);
- X sprintf(errmsg2," TIME: %s\n",time_str);
- X strcat(errmsg,errmsg2);
- X
- X /* call the error routine, never come back */
- X my_error(SYSERR);
- X
- X }
- X
- X /* save the raw setting so we can toggle later */
- X ioctl(out_file, TCGETA, &T_RAW);
- X T_RAW.c_cc[VMIN] = 0;
- X T_RAW.c_cc[VTIME] = 15;
- X
- X /* flush input and output queues for a nice clean tty */
- X ioctl(out_file,TCFLSH,2);
- X
- X}
- X
- X
- Xmy_error(reason)
- Xint reason;
- X{
- X
- X switch(reason)
- X {
- X case NO_EXIT:
- X if((logfile = fopen(LOGFILE,"a+")) != NULL)
- X {
- X fprintf(logfile,errmsg);
- X fclose(logfile);
- X }
- X return(0);
- X break;
- X case SIGALRM:
- X signal(SIGALRM, my_error);
- X
- X /* take care of the signals */
- X signal(SIGINT, SIG_IGN); /* ignore "interrupt" signal <DEL> */
- X signal(SIGHUP, SIG_IGN); /* ignore "hang up" signal */
- X signal(SIGQUIT, SIG_IGN); /* ignore "quit" signal */
- X signal(SIGTERM, my_error);
- X#ifdef NQ
- X signal(SIGRES, SIG_IGN); /* ignore "restart" signal */
- X signal(SIGBACK, SIG_IGN); /* ignore "back-up" signal */
- X signal(SIGSTOP, my_error); /* trap "stop" signal */
- X#endif
- X
- X time_out = 1;
- X break;
- X case SIGTERM:
- X /************************************************************************/
- X /* Reset traps on all signals! */
- X /* We don't want to be interrupted when we already know we're */
- X /* on our way out! */
- X /************************************************************************/
- X
- X/* take care of the signals */
- X signal(SIGINT, SIG_IGN); /* ignore "interrupt" signal <DEL> */
- X signal(SIGHUP, SIG_IGN); /* ignore "hang up" signal */
- X signal(SIGQUIT, SIG_IGN); /* ignore "quit" signal */
- X signal(SIGALRM, SIG_IGN);
- X signal(SIGTERM, my_error);
- X#ifdef NQ
- X signal(SIGRES, SIG_IGN); /* ignore "restart" signal */
- X signal(SIGBACK, SIG_IGN); /* ignore "back-up" signal */
- X signal(SIGSTOP, my_error); /* ignore "stop" signal */
- X#endif
- X /* format an error message */
- X time(&tloc);
- X nowtime = (struct tm *)localtime(&tloc);
- X time_str = asctime(nowtime);
- X
- X sprintf(errmsg,"ISPIN: printer %s: received SIGTERM.\n",dest);
- X sprintf(errmsg2," USER: %s\n",from);
- X strcat(errmsg,errmsg2);
- X if(usr_addr)
- X {
- X sprintf(errmsg2," ADDR: %s\n",usr_strng);
- X strcat(errmsg,errmsg2);
- X }
- X if(port_open == 1)
- X {
- X sprintf(errmsg2," DEV: %s\n",GO_dev);
- X strcat(errmsg,errmsg2);
- X }
- X#ifdef NQ
- X sprintf(errmsg2," FILE: %s\n",fyle);
- X#else
- X sprintf(errmsg2," FILE: %s\n",fyles[0]);
- X#endif
- X strcat(errmsg,errmsg2);
- X sprintf(errmsg2," TIME: %s\n",time_str);
- X strcat(errmsg,errmsg2);
- X
- X if((logfile = fopen(LOGFILE,"a+")) != NULL)
- X {
- X fprintf(logfile,errmsg);
- X fclose(logfile);
- X }
- X
- X if(port_open == 1)
- X {
- X savd_errno = SIGTERM;
- X stayt = QUITTING;
- X if(quit_once > 0)
- X {
- X LONGJMP(kwit, quit_once);
- X }
- X else
- X {
- X ret_val = quit_net();
- X }
- X }
- X
- X my_exit(reason);
- X break;
- X case SIGHUP:
- X case DISCONNECTING:
- X case TIMEOUT:
- X case NET_TIME:
- X /************************************************************************/
- X /* Reset traps on all signals! */
- X /* We don't want to be interrupted when we already know we're */
- X /* on our way out! */
- X /************************************************************************/
- X
- X/* take care of the signals */
- X signal(SIGINT, SIG_IGN); /* ignore "interrupt" signal <DEL> */
- X signal(SIGHUP, my_error);
- X signal(SIGQUIT, SIG_IGN); /* ignore "quit" signal */
- X signal(SIGALRM, SIG_IGN);
- X signal(SIGTERM, my_error);
- X#ifdef NQ
- X signal(SIGRES, SIG_IGN); /* ignore "restart" signal */
- X signal(SIGBACK, SIG_IGN); /* ignore "back-up" signal */
- X signal(SIGSTOP, my_error); /* trap "stop" signal */
- X#endif
- X /* format an error message */
- X time(&tloc);
- X nowtime = (struct tm *)localtime(&tloc);
- X time_str = asctime(nowtime);
- X switch(reason)
- X {
- X case SIGHUP:
- X sprintf(errmsg,"ISPIN: printer %s: received SIGHUP, so looping.\n",dest);
- X break;
- X case DISCONNECTING:
- X sprintf(errmsg,"ISPIN: printer %s: detected DISCONNECT, so looping.\n",dest);
- X break;
- X case TIMEOUT:
- X sprintf(errmsg,"ISPIN: printer %s: write to printer timed out after %d secs, so looping.\n",dest, WRITEWAIT);
- X break;
- X case NET_TIME:
- X if(stayt == CONNECTING)
- X {
- X sprintf(errmsg,"ISPIN: printer %s: connecting negotiation write timed out after %d secs, so looping.\n",dest, NETWAIT);
- X }
- X break;
- X }
- X sprintf(errmsg2," USER: %s\n",from);
- X strcat(errmsg,errmsg2);
- X if(usr_addr)
- X {
- X sprintf(errmsg2," ADDR: %s\n",usr_strng);
- X strcat(errmsg,errmsg2);
- X }
- X if(port_open == 1)
- X {
- X sprintf(errmsg2," DEV: %s\n",GO_dev);
- X strcat(errmsg,errmsg2);
- X }
- X#ifdef NQ
- X sprintf(errmsg2," FILE: %s\n",fyle);
- X#else
- X sprintf(errmsg2," FILE: %s\n",fyles[0]);
- X#endif
- X strcat(errmsg,errmsg2);
- X sprintf(errmsg2," TIME: %s\n",time_str);
- X strcat(errmsg,errmsg2);
- X
- X if((logfile = fopen(LOGFILE,"a+")) != NULL)
- X {
- X fprintf(logfile,errmsg);
- X fclose(logfile);
- X }
- X /* If we get HUPed or disconnected, try again. Maybe it was a mistake. */
- X if((netloop <= MAXNET_TRY)&&(stayt != QUITTING))
- X {
- X /* try again */
- X again();
- X }
- X else
- X {
- X /* need to send out an error msg */
- X /* format an error message */
- X time(&tloc);
- X nowtime = (struct tm *)localtime(&tloc);
- X time_str = asctime(nowtime);
- X
- X if(stayt == QUITTING)
- X {
- X sprintf(errmsg,"ISPIN: printer %s: disconnecting write timed out after %d secs, so quitting.\n",dest, NETWAIT);
- X }
- X else
- X {
- X sprintf(errmsg,"ISPIN: printer %s: %d BUSY LOOPS, so quitting.\n",dest,netloop);
- X }
- X sprintf(errmsg2," USER: %s\n",from);
- X strcat(errmsg,errmsg2);
- X if(usr_addr)
- X {
- X sprintf(errmsg2," ADDR: %s\n",usr_strng);
- X strcat(errmsg,errmsg2);
- X }
- X if(port_open == 1)
- X {
- X sprintf(errmsg2," DEV: %s\n",GO_dev);
- X strcat(errmsg,errmsg2);
- X }
- X#ifdef NQ
- X sprintf(errmsg2," FILE: %s\n",fyle);
- X#else
- X sprintf(errmsg2," FILE: %s\n",fyles[0]);
- X#endif
- X strcat(errmsg,errmsg2);
- X sprintf(errmsg2," TIME: %s\n",time_str);
- X strcat(errmsg,errmsg2);
- X
- X /* call the error routine, never come back */
- X /* INTENTIONALLY RECURSIVE */
- X my_error(MYERR);
- X }
- X break;
- X#ifdef NQ
- X case SIGSTOP:
- X /************************************************************************/
- X /* Reset traps on all signals! */
- X /* We don't want to be interrupted when we already know we're */
- X /* on our way out! */
- X /************************************************************************/
- X
- X/* take care of the signals */
- X signal(SIGINT, SIG_IGN); /* ignore "interrupt" signal <DEL> */
- X signal(SIGHUP, SIG_IGN); /* ignore "hang up" signal */
- X signal(SIGQUIT, SIG_IGN); /* ignore "quit" signal */
- X signal(SIGALRM, SIG_IGN); /* ignore "alarm" signal */
- X signal(SIGTERM, my_error);
- X signal(SIGRES, SIG_IGN); /* ignore "restart" signal */
- X signal(SIGBACK, SIG_IGN); /* ignore "back-up" signal */
- X signal(SIGSTOP, my_error); /* ignore "stop" signal */
- X
- X /* format an error message */
- X time(&tloc);
- END_OF_FILE
- if test 30636 -ne `wc -c <'ISPIN/src/ISPIN.c.ac'`; then
- echo shar: \"'ISPIN/src/ISPIN.c.ac'\" unpacked with wrong size!
- fi
- # end of 'ISPIN/src/ISPIN.c.ac'
- fi
- if test -f 'ISPIN/doc/LPinstall.doc' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'ISPIN/doc/LPinstall.doc'\"
- else
- echo shar: Extracting \"'ISPIN/doc/LPinstall.doc'\" \(17620 characters\)
- sed "s/^X//" >'ISPIN/doc/LPinstall.doc' <<'END_OF_FILE'
- X
- X The installation script and these following procedures must be
- X executed by the superuser.
- X
- X1. cd to ISPIN.rel_2.2/ISPIN/h
- X Edit the file localcnfg.h
- X Edit the SITELINE constant definition to reflect the name of your site.
- X Modify ONLY what is between the asterisks, keeping the overall width of
- X the line the same as what is already there.
- X
- X/********************************************************************/
- X
- X SPECIAL NOTE for Sequent and Pyramid: all of the executables in
- X this application MUST be COMPILED AND RUN in the "att" universe!
- X
- X/********************************************************************/
- X
- X2. cd to ISPIN.rel_2.2/ISPIN/install.
- X Edit the file "Makefile" and make sure the SPOOLER is set to the proper
- X value -
- X ZILOGNQ if your system is a Zilog which uses the nq spooler
- X ZILOGLP if your system is a Zilog which uses the lp spooler
- X DYNIX if your system is a Sequent which uses the lp spooler
- X CCI if your system is a CCI with "dirent"-style directories
- X 3B1 if your system is an AT&T 3B1 which uses the lp spooler
- X UNISYS if your system is a UNISYS 5000 which uses the lp spooler
- X LP if your system is another type of system which uses the lp spooler
- X
- X Execute the command "make" to compile all of the C programs which are
- X used by ISPIN.
- X
- X3. You are now ready to install the C programs which were just compiled.
- X Take a look at the program "install.sh" to make sure your are comfortable
- X with what it does. Now, execute the command "make install" (make will execute
- X the program install.sh).
- X
- X4. Copy the executable iq to a directory to which your users have
- X a path for execution ( such as, generally, /usr/local/bin ).
- X
- X5. Make provision in your system start-up script(s) (i.e., /etc/rc2)
- X to invoke /usr/spool/lp/ISPIN/iqueuer (the daemon) every start-up.
- X Execute it now, just for the first start-up.
- X
- X Sequent and Pyramid users make sure to call the iqueuer with "att".
- X *
- X * *
- X * *
- X * *
- X * *
- X NOTE
- X *
- X *
- X *
- X *
- X *
- X
- X
- X6. Edit your system's startup and (if any) re-start script(s). The
- X names of these scripts vary, but will almost always be something
- X like "/etc/rc", "/etc/rc_csh", "/etc/rc2". You get the idea. These
- X scripts usually also invoke other scripts along the way. Find the
- X point at which the script gets rid of "old" lock files (files
- X with names like "/usr/spool/uucp/LCK..tty*"). Usually the line
- X in the script says:
- X rm -f /usr/spool/uucp/LCK..tty*
- X or:
- X rm -f /usr/spool/locks/LCK..tty*
- X or:
- X rm -f /usr/spool/uucp//LCK/LCK..tty*
- X
- X CHANGE IT TO READ:
- X rm -fr /usr/spool/uucp/LCK..tty*
- X or:
- X rm -fr /usr/spool/locks/LCK..tty*
- X or:
- X rm -fr /usr/spool/uucp//LCK/LCK..tty*
- X
- X The reason for this change is that the lock files ISPIN creates
- X are actually directories. Adding the "r" flag to the rm(1) arg
- X list permits the removal of any such lock files which remain on
- X the system subsequent to an unexpected or otherwise ungraceful
- X shutdown.
- X
- X7. Choose the tty(s) through which ISPIN will contact printer(s).
- X Releases 2.0 (and later) of ISPIN support lock files.
- X The tty(s) you choose may be used for other purposes, such as cu(1)
- X and uucp(1) and also support of the ISPIN printer(s). You may, however,
- X support several such printers via one or more tty(s).
- X Also refer to your SA manual. As with any other port which supports
- X a printer, if the tty had previously been in use as a login port,
- X the getty must be permanently disabled.
- X
- X ISPIN does, however, cooperate quite well with uugetty. So if you
- X have a need for bi-directionality (as I do with my little AT&T 3B1)
- X ISPIN is ready to oblige.
- X
- X8. Connect tty(s) to network. Have your Data Communications Specialist
- X do this while you read ALL of the documentation which came with this
- X release.
- X
- X Seriously, I can't make specific recommendations for every possible
- X combo of cpu/data switch and printer/data switch. I will make a strong
- X general recommendation that you connect all valid modem control
- X signals. Don't try to fool the cpu or the switch by feeding their own
- X modem control signals back to them. If you do this, you'll make your
- X data communications less reliable, less fault-tolerant.
- X
- X IN GENERAL: If the cpu is DTE and the data switch is DCE and you're
- X using RS-232 25-pin "D" connectors, the pinning will be 1 through 8
- X and 20, all straight through. If your cpu's ttys are DCE (and switch
- X also DCE), you'll need null modem adapter or null modem pinning.
- X
- X Some switches do end-to-end modem signal mapping and the pins on which
- X certain signals are listened-for and asserted-upon are different from
- X "normal" RS-232. For some switches, this can also vary depending upon
- X how a given channel is configured.
- X
- X Most switches I've seen or heard of (Tellabs, Equinox, David, Gandolph,
- X Mitron, etc) allow channels or groups of channels to be configured to
- X support software flow control, XON/XOFF. ISPIN needs this at both the
- X cpu and printer sides. By the way, the less-expensive "dumb" Equinox
- X which merely passes XON/XOFF from end-to-end with no internal buffering
- X is not adequate (you'll lose characters due to flow control problems).
- X The more sophisticated Equinox is fine.
- X
- X Our X.25 asynchronous pads allow this to be set "on the fly", during a
- X connect session. Under this facility, we can turn on software flow control
- X via ISPIN's rtab entry for printing, and turn off software flow control
- X from uucp's L.sys (or Systems) entry to allow uucp "G" protocol.
- X
- X9. Connect printer(s) to network. Be sure to configure your printer(s) for
- X software (XON/XOFF) flow control. Disable hardware (CTS/DTR) flow control.
- X The same goes for all links in your network hardware (the ports or
- X channels to which the cpu and printer are connected).
- X
- X Some printers allow XON/XOFF flow control to be enabled or disabled,
- X but they won't let you disable hardware flow control. I'm thinking
- X specifically of the HP LaserJets, but there may be others. In these
- X cases, you'll have to disable hardware flow control through creative
- X pinning. In my case, the printer is DTE, my X.25 async pad is DCE, and
- X all signals are asserted-upon/listened-for on what we consider "normal"
- X RS-232 pin positions. Most of my pad-to-printer cables are straight
- X 1-8 & 20. My cable for the HPLJ has pins 4 & 20 swapped.
- X
- X10. Edit the /usr/spool/lp/ISPIN/rtab to add a line of
- X connect info for each remote printer. If you have some experience
- X setting up a uucp L.sys (or HoneyDanBer's Systems) file, rtab
- X should be a snap.
- X
- X The directory ISPIN.rel_2.2/ISPIN/install/lib_rtab contains a
- X README file. READ IT!
- X
- X The rtab file supplied with this release includes extensive
- X comment lines as documentation. Don't delete them. The rtab also
- X includes commented-out printer entries as examples. Take a look.
- X It's pretty straight-forward once you weed out the \p's and \d's.
- X Most of what I'm about to describe is also included in rtab's
- X comments. There are many IMPORTANT details included in rtab but
- X not addressed here.
- X
- X
- X Notice that each entry is all one line. As you add an entry for your
- X printer(s), allow the line to wrap around. Line feed or carriage
- X return terminates the entry. I have made no provision for escaping
- X newline with a backslash.
- X
- X Leading # comments-out the entire line. (Do not use blank lines.)
- X
- X The first field is the name by which the printer will be known.
- X This name absolutely must be the same as the name by which the
- X native lp spooler knows the queue member. Your choice of printer name
- X is thus restricted to what is allowable under the lp regime.
- X See lpadmin(M).
- X
- X The second field defines the serial port(s) through which ISPIN
- X may attempt to contact the printer. You chose these in item 6,
- X above. This entry specifies primary and subsequent ports,
- X separated by commas. A one port entry is just as acceptable.
- X Eleven ports is max.
- X
- X The third field specifies the speed setting for the port.
- X
- X The "-B" flag & arg fields define portions of various "network
- X busy" messages which may be encountered when ISPIN attempts
- X to negotiate through the network. In the case of one example,
- X because we are calling out from the cpu, into a Tellabs data
- X switch, then out into the X.25 async pad, I have included unique
- X parts of "busy" messages from both the Tellabs and X.25 async pad
- X environments. The usage of the "-B" flag and arguments is, like
- X the other two flags, optional.
- X
- X I VERY STRONGLY suggest that your rtab entries include as many
- X of these "busy" flags and args as you can possibly identify. They
- X add immeasureably to the robustness of the application. Otherwise,
- X the ISPIN won't be able to re-attempt contact of a network-supported
- X printer which is currently being used by another ISPIN from the
- X same (or different) cpu, or (heaven forbid) by an MDQS process,
- X or which is otherwise busy for whatever reason. All looping which
- X occurs under these conditions is strictly under the control of
- X the ISPIN and the IQUEUER. The native lp spooler has no idea any
- X re-try is going on. Of course, the native cancel command may terminate
- X the ISPIN at any time.
- X
- X A "-I" flag and argument field defines a portion of a
- X network message which would be encountered when/if the line, the
- X destination device, or some intermediate device is just plain dead.
- X Define "-I" flags only for messages which indicate network conditions
- X under which you would prefer that the requested print job simply
- X give up and terminate itself.
- X
- X I personally would prefer my jobs to re-try even under such conditions.
- X The looping algorithm for the "-B" cases described above is not
- X going to cause your system to thrash. So I say "let 'em loop".
- X You or the user who requested the print job should eventually notice
- X things are not moving along. If the job is looping, you'll have an
- X opportunity to correct the network problem or other problem and
- X never lose a print request. Of course, if network conditions are so
- X bad that you know the ISPIN will never get through, the job may be
- X terminated by the native cancel(1) command.
- X
- X The arguments to the "-D" flags are unique protions of strings which
- X are messages we expect the network(s) to return when/if the printer
- X is powered-down or disconnected. After each burst of characters which
- X is written by ISPIN to the printer, ISPIN checks the port to see if
- X there are any characters to be read. Normally there will be none.
- X If, however, the printer has been powered-down or otherwise disconnected,
- X we expect the network device to recognize the situation and give us
- X a message. If we have correctly specified parts of these messages as
- X args to the "-D" flags, the program will immediately detect the "disconnect"
- X situation and loop, attempting to re-establish contact with the printer.
- X Once the connection is re-established, the job will be printed in its
- X entirety. Since the letter "e" is the most frequently used letter in
- X the alphabet, I'll usually have a "-De" field. This way, if we're
- X disconnected from the printer and all the chars we send out are being
- X echoed back to ISPIN, we'll detect the error condition very quickly.
- X
- X The "-Q" fields define, in sequence, what signals or
- X messages should be issued to the network to accomplish a clean break
- X at the end of a successful connect session. Let your knowledge of
- X your own local switch (if applicable) be your guide. What
- X do you have to enter at your keyboard to assure a clean break?
- X For the moment, ignore the \p's (1 sec pause) and \d's (3 sec delay).
- X
- X In one example, remember, we went from cpu, to Tellabs, to X.25 async pad,
- X to the printer. Now to disconnect, we conduct a clean break of each
- X virtual connection under our control.
- X The first "-Q" argument is "\K", which rtab's documentation tells us
- X results in the issuance of a <BREAK>. This is the signal X.25 async pad needs
- X to put the printer's channel into command mode.
- X The next "-Q" argument is "clr" and carriage return, a readily recog-
- X nizable X.25 async pad command which drops the virtual connection.
- X The next two "-Q" flags and arguments issue <BREAK>bye to the local
- X Tellabs data switch. This is my locally defined disconnect sequence
- X for the Tellabs data switch in Indy.
- X
- X Before we proceed to a discussion of the EXPECT and SEND sequences,
- X I'll explain the necessity for all of the pauses and delays. In my
- X testing, I found that when ISPIN is running on a lightly loaded cpu
- X and conversing with the X.25 async pad, the program is capable of shifting
- X between writing to the network and reading from the network MUCH
- X faster than the network is capable of responding. Before long, the
- X EXPECT/SEND sequence gets lost. Rather than "hard code" the necessary
- X delays into the application, I chose to allow the specification of
- X pauses and delays by the user (you). This approach permits the greatest
- X amount of flexibility in implementation. Experiment for yourself.
- X Also, many printers need time to print the contents of their buffers
- X after all characters have been issued by the cpu, but before the network
- X connection is dropped. Increasing delay time in the first "-Q" sequence
- X is the answer. If the last several lines of a document are being lost,
- X try adding a "\w" or "\L" immediately after the first "-Q" flag.
- X If you need more or less pause or delay, adjust your rtab entry.
- X
- X Now for the EXPECT/SEND sequences.
- X EXPECT and SEND are pairs.
- X You must begin with EXPECT.
- X You must end with a null SEND field.
- X The best way to figure out what you need to say in these sequences
- X is to call out through the port(s) you are using with cu(1).
- X Once you have made a successful connection all the way through to
- X the printer, any subsequent keyboard activity on your part should
- X show up on the printer.
- X In our example, notice the liberal usage of the compound construction,
- X EXPECT-SEND-EXPECT. This construct exactly mimics uucp's similar
- X feature. Use of this feature significantly enhances your chances of
- X making a successful connection.
- X There is a lot more info on rtab in rtab's comments.
- X
- X The directory ISPIN.rel_2.2/ISPIN/install/lib_rtab contains a
- X README file. READ IT!
- X
- X11. Creation of a FIFO for each printer in /usr/spool/lp/ISPIN/FIFO
- X need not be done manually. The application will create a FIFO for
- X each queue member as needed.
- X
- X If you observe the example rtab entry, you'll note the printer is
- X named "LSB1". The first time a request is issued to this queue member,
- X the FIFO /usr/spool/lp/ISPIN/FIFO/LSB1 will be created.
- X
- X12.Shut down the lp scheduler by executing:
- X lpshut
- X
- X13. Add each remote printer as a member of the native queuer by
- X executing: lpadmin -pyour_printer_name -iispintrfce -v/dev/null
- X
- X Observe the example entry in the rtab file. The example printer's
- X name is "LSB1". In this case, the appropriate lpadmin command is:
- X
- X lpadmin -pLSB1 -iispintrfce -v/dev/null
- X
- X Two SIGNIFICANT items in this command:
- X
- X - The "ispintrfce" argument to the "-i" flag assumes that the
- X executable ispintrfce is in the current working directory.
- X The "make install" puts a copy in /usr/spool/lp/ISPIN.
- X
- X - The device specified as the argument to the "-v" flag is
- X /dev/null.
- X
- X IT IS VITALLY IMPORTANT THAT THE NATIVE QUEUER DOES NOT
- X KNOW THE DEVICE(S) ISPIN WILL ACTUALLY BE USING.
- X
- X14. Use the lp-family commands "accept" and "enable" to activate the
- X new queue member.
- X
- X15. Re-start the lp scheduler by executing lpsched.
- X
- X16. Use the new printer.
- X The native lp and lpsched commands will function exactly normally
- X as they relate to the ISPIN-supported printer(s). cancel still retains
- X its control over the life and death of the print job.
- X
- X17. Also use the iq command to inquire the iqueuer daemon. In an active
- X IQUEUER/ISPIN situation, lpstat may show several print processes as
- X "now printing" simultaneously when you know they can't all possibly be
- X printing simultaneously. This situation could arise when/if several
- X ISPIN-supported members of the native queue have been configured by
- X you to all use the same tty for access out to the network. As far as
- X lp and lpstat are concerned, once the "backend" process has been
- X invoked, the process is "now printing". This is the situation the IQUEUER
- X daemon is designed to accomodate. IQUEUER manages the ISPINs which
- X are competing for the scarce resource. iq will show you which of the
- X ISPIN processes are actually running or are actually waiting.
- X
- X18. Look to /usr/spool/lp/ISPIN/log for ISPIN error messages and event
- X logging.
- END_OF_FILE
- if test 17620 -ne `wc -c <'ISPIN/doc/LPinstall.doc'`; then
- echo shar: \"'ISPIN/doc/LPinstall.doc'\" unpacked with wrong size!
- fi
- # end of 'ISPIN/doc/LPinstall.doc'
- fi
- if test -f 'ISPIN/misc/ISPIT.dr/README' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'ISPIN/misc/ISPIT.dr/README'\"
- else
- echo shar: Extracting \"'ISPIN/misc/ISPIT.dr/README'\" \(4517 characters\)
- sed "s/^X//" >'ISPIN/misc/ISPIT.dr/README' <<'END_OF_FILE'
- X
- Xrtab.entry - see do_ispit.sh. Notice that this rtab entry requires that
- X this queue member be called by an lp(1) command which
- X must include a sane value for the "-o" flag.
- X The arg to the "-o" is used by ISPIN at the point in the
- X rtab where "\U" appears.
- X Note also the use of the "-R" flag for really raw output.
- X
- Xdo_ispit.sh - the shell script which is executed by the source system.
- X
- X The lp command line contains some interesting features.
- X
- X The string passed as the argument to the "-o" flag is
- X actually made up of two arguments which are delimited by
- X the "@" symbol. These two arguments are processed by
- X the special interface script on the source system.
- X
- X The first "argument" to lp's "-o" flag is processed
- X by ispin and inserted in a "sent" network negotiation
- X string where a "\U" appears. On the destination system,
- X ispit.sh picks this up as the name of the output file.
- X
- X Also notice that the second "argument" to the "-o" flag
- X is /tmp/$nowfile. This file is a named pipe, created "on
- X the fly". The lp/interface file (special for this purpose)
- X reads from the named pipe which was created and filled by
- X do_ispit.sh.
- X
- X The "filename" argument to the lp command is /etc/passwd.
- X This file is not actually transmitted by the ispit/ispin
- X process. We use /etc/passwd as a placeholder on the
- X command line since lp will not queue a request without a
- X valid non-null filename.
- X
- X do_ispit.sh requires three arguments:
- X
- X - First is the name of the source file to be transferred.
- X
- X - Second is the destination file name on the destination
- X system. This argument should be a full path name. All
- X elements of the path must exist. The destination directory
- X must be writable by the user "ispit" on the remote system.
- X If this argument is less than a fully qualified path, the
- X remote system will interpret the argument relative to
- X ispit's home directory.
- X
- X - Third is the (lp) queue member which will process the
- X request.
- X
- X On dual universe machines, the calls to "compress", "btoa",
- X "cut", and "lp" may have to be preceded by the appropriate
- X universe call. Path names to commands may also require
- X adjustment.
- X
- Xinterface - This shell script is the lp interface file for ispit on
- X the source system.
- X
- Xeot_trap.c * - source for a filter program which watches for an ascii
- X "EOT" character. eot_trap filters the input
- X on the receiving system. The source system's rtab entry
- X for the "ispit" queue member sends EOT as the first action
- X of the ispin quit sequence. eot_trap exits, ending the
- X login session, so ispit exits. This dependence upon
- X EOT makes it IMPERATIVE that all output be converted by
- X btoa(1). See do_ispit.sh.
- X
- Xispit.sh * - see passwd.entry, below. This is the script which is invoked
- X upon login by and for the ispit user. Notice that ispit.sh
- X expects (actually requires) that a variable
- X "OF" is assigned a sane value. This value is passed at login
- X time by the user "ispit". See rtab.entry for the "\U".
- X
- X NOTE: ispit.sh calls the executable "eot_trap", assuming
- X that the executable is located in ispit's home
- X directory.
- X
- Xpasswd.entry * - this is the /etc/passwd entry for the ispit user on the
- X destination machine. The last field of the entry is the full
- X path name of the ispit.sh script. Change the location of
- X ispit's home directory as you see fit.
- X
- X
- X
- X * - denotes this file, data, or program exists on the
- X destination machine. All else exists on the source
- X machine.
- END_OF_FILE
- if test 4517 -ne `wc -c <'ISPIN/misc/ISPIT.dr/README'`; then
- echo shar: \"'ISPIN/misc/ISPIT.dr/README'\" unpacked with wrong size!
- fi
- # end of 'ISPIN/misc/ISPIT.dr/README'
- fi
- if test -f 'ISPIN/misc/ISPIT.dr/passwd.entry' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'ISPIN/misc/ISPIT.dr/passwd.entry'\"
- else
- echo shar: Extracting \"'ISPIN/misc/ISPIT.dr/passwd.entry'\" \(56 characters\)
- sed "s/^X//" >'ISPIN/misc/ISPIT.dr/passwd.entry' <<'END_OF_FILE'
- Xispit:9CKYrm.On.kVs:437:4::/zb/ispit:/zb/ispit/ispit.sh
- END_OF_FILE
- if test 56 -ne `wc -c <'ISPIN/misc/ISPIT.dr/passwd.entry'`; then
- echo shar: \"'ISPIN/misc/ISPIT.dr/passwd.entry'\" unpacked with wrong size!
- fi
- # end of 'ISPIN/misc/ISPIT.dr/passwd.entry'
- fi
- echo shar: End of archive 9 \(of 15\).
- cp /dev/null ark9isdone
- MISSING=""
- for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 ; do
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have unpacked all 15 archives.
- rm -f ark[1-9]isdone ark[1-9][0-9]isdone
- else
- echo You still need to unpack the following archives:
- echo " " ${MISSING}
- fi
- ## End of shell archive.
- exit 0
-
-