home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / misc / volume5 / autobaud < prev    next >
Encoding:
Text File  |  1989-02-03  |  13.5 KB  |  467 lines

  1. Path: xanth!nic.MR.NET!hal!ncoast!allbery
  2. From: davev@spked.UUCP
  3. Newsgroups: comp.sources.misc
  4. Subject: v05i020: autobauding getty for System V (ported from 4BSD)
  5. Message-ID: <8810201858.AA06671@ucdavis.ucdavis.edu>
  6. Date: 28 Oct 88 03:15:05 GMT
  7. Sender: allbery@ncoast.UUCP
  8. Reply-To: davev@spked.UUCP
  9. Lines: 455
  10. Approved: allbery@ncoast.UUCP
  11.  
  12. Posting-number: Volume 5, Issue 20
  13. Submitted-by: "A. Nonymous" <davev@spked.UUCP>
  14. Archive-name: autobaud
  15.  
  16. [I consider these things black magic:  it's too easy for the modem to pick
  17. up at the wrong spot or something and get the wrong bit pattern.  Or so I
  18. believe....
  19.  
  20. Various spots in the code are BSD-ish, others are System-V-ish.  It probably
  21. won't work unmodified on anyone else's system.  And some of the things in
  22. this code can only be called kluges.  ++bsa]
  23.  
  24. # This is a shell archive.  Remove anything before this line, then
  25. # unpack it by saving it in a file and typing "sh file".  (Files
  26. # unpacked will be owned by you and have default permissions.)
  27. #
  28. # This archive contains:
  29. # auto.c autolocal.h autobaud.8 README
  30.  
  31. echo x - auto.c
  32. cat > "auto.c" << '//E*O*F auto.c//'
  33. /*  autobaud.c - determine tty speed of standard input  (for 4.3 BSD Unix)
  34.  *
  35.  *  Autobaud reads standard input at 2400 baud.  Assuming a carriage return
  36.  *  is typed, the bit pattern received is used to select and set the "true"
  37.  *  speed.  This works for speeds of 300, 1200, 2400, and 9600 baud.  In theory
  38.  *  600 should also work, but empirically a 00 character is read and it doesn't.
  39.  *  Any other speed, or any character other than a carriage return, is likely
  40.  *  to give a wrong result.
  41.  *
  42.  *  Autobaud is primarily intended as a replacement for getty(8), and as such
  43.  *  it also sets a few terminal parameters such as the kill character to
  44.  *  default values.  However, it can also be run from a shell for testing.
  45.  *
  46.  *  usage:  autobaud [-l] [tty_name]
  47.  *
  48.  *  -l        sets "login" mode and execs login after the speed is set
  49.  *  tty_name    specifies a device to autobaud (/dev/tty_name) instead of stdin
  50.  *
  51.  *  Gregg Townsend
  52.  *  University of Arizona
  53.  *  April, 1987
  54.  *
  55.  * -------------------------------------------------------------
  56.  *
  57.  *  David P. van De Kerk, U.S. Army Corps of Engineers,
  58.  *  Sacramento District.  CESPK-ED-T-AMU.
  59.  *  ucdavis.ucdavis.edu!spked!davev
  60.  *
  61.  *  Modified 10/09/88  to work on a Unisys 5000/80 computer,
  62.  *  running System 5 R 2.  In a sense, this is a System 5 port,
  63.  *  although the program does NOT run on an NCR Tower running
  64.  *  System 5 release 1.
  65.  *
  66.  *  Modified the recognition sequences for what was read on Sys V
  67.  *  Changed from sgtty to termio's tty ioctl structure.
  68.  *
  69.  *  Added a bunk, but working, delay sequence, and used sockets on
  70.  *  those systems capable of using them.  Note, while this should work
  71.  *  in theory on our system, which has NET-5000, it doesn't.
  72.  *
  73.  *  Put the terminal type read from the getty defs in the environment
  74.  *
  75.  *  Clear the screen before giving login banner, using the
  76.  *  environment's terminal type, as gotten from inittab.
  77.  *
  78.  *  Note:  Instead of reading inittab for the right stty parameters,
  79.  *  there is one fixed setting for everyone.
  80.  *
  81.  */
  82.  
  83. #define PGMNAME "autobaud"        /* program name (for diagnostics) */
  84. #define LOGIN "/bin/login"        /* location of login program */
  85. #define ISSUE "/etc/issue"        /* location of pre-login message */
  86. #define STRSIZ 100            /* string size for host and tty names */
  87.  
  88. #include <signal.h>
  89. #include <curses.h>
  90. #include <stdio.h>
  91. #include <sys/types.h>
  92. #include <sys/file.h>
  93. /*
  94. #include <sys/termio.h>
  95. */
  96. #include <time.h>
  97. #include <malloc.h>
  98. #ifdef SOCKETS
  99. #include <NET-5000/sys/socket.h>
  100. #endif
  101.  
  102. #include "autolocal.h"
  103.  
  104. /* beware these definitions */
  105. #define    TIOCHPCL    (('t'<<8)|2)
  106. #define  TIOCSETN TCSETA
  107. #define  TIOCFLUSH TCFLSH
  108.  
  109. char *sp[] = {   "0",   "50",   "75",  "110",  "134",  "150",  "200",  "300",
  110.            "600", "1200", "1800", "2400", "4800", "9600", "EXTA", "EXTB"};
  111.  
  112. int login = 0;                /* set nonzero if to exec login */
  113. char tty_name[STRSIZ] = "/dev/";        /* buffer for explicit tty name */
  114. char hostname[STRSIZ];            /* buffer for hostname */
  115.  
  116.  
  117.  
  118. /*  main program  */
  119. extern char **environ;
  120.  
  121. main(argc,argv)
  122. int argc;
  123. char **argv;
  124. {
  125.     struct termio ttyb;
  126.     unsigned char c;
  127.     char s;
  128.     int zero = 0;
  129.     char *dev_name;  /* the name of the user's device */
  130.     char alloc_dev [30];  /* space to put the above into */
  131.  
  132.     argv++;                    /* skip program name */
  133.  
  134.     if (*argv && !strcmp(*argv,"-l"))
  135.     login++, argv++;            /* if "-l", set login flag */
  136.     dev_name = (char *) alloc_dev;
  137.     dev_name = ttyname (0);
  138.     if (*argv)  {                
  139.     strcpy(tty_name+5,*argv++);        /* if tty given, build name */
  140.     close(0);                /* close previous stdin */
  141.     close(1);                /* close previous stdout */
  142.     close(2);                /* close previous stderr */
  143.     argv++;  /* go past next entry, which is the getty def */
  144. /* if there's another entry, assume it's a desired term type */
  145.     if (*argv)  {
  146.         char term_cmd [30];
  147.         sprintf (term_cmd,"TERM=%s",*argv);
  148.         putenv (term_cmd);
  149.         }
  150.  
  151.     if (login)  {
  152.         nap(2000);                /* hold DTR down for 2 sec */
  153.         chown(tty_name,0,0);            /* make root the owner */
  154.         chmod(tty_name,0622);        /* and set the protections */
  155.     }
  156.     if (open(tty_name,2) != 0)        /* open once for stdin */
  157.         abort(tty_name);
  158.     dup(0);                    /* dup for stdout */
  159.     dup(0);                    /* dup for stderr */
  160.     }
  161.  
  162.     ioctl(0,TCGETA,&ttyb);
  163.     ttyb.c_cflag = B2400 | CS8;    /* sample line at 2400 baud, 8 bit */
  164.     ttyb.c_cc[2] = ttyb.c_cc[3] = -1;        /* no editing characters */
  165.     ttyb.c_iflag = ttyb.c_iflag | ICRNL;
  166.     ttyb.c_oflag = ttyb.c_oflag | ONLCR;
  167.     ttyb.c_lflag = ttyb.c_lflag  & (~ICANON);
  168.     if (ioctl(0,TIOCSETN,&ttyb) <0)        /* set tty parameters */
  169.     abort("ioctl");
  170.     s = 0;
  171. /* yes, it's gross, but it works. */
  172.     system ("stty nl -lcase");
  173.     while (!s)  {
  174.     nap(100);                /* wait .1 sec for line quiet */
  175.     ioctl(0,TIOCFLUSH,&zero);        /* flush input & output */
  176.     if (read(0,&c,1) != 1)            /* read a character */
  177.         {
  178.         exit(1);
  179.         }
  180. #ifdef DEBUG
  181.     /* select baud rate based on pattern received */
  182.     display (c);
  183. #endif
  184.     /* select baud rate based on pattern received */
  185.     if (c >= 0xF0)
  186.         s = B9600;
  187.     else switch (c)  {
  188.         case 0x80: s = B300;  break;
  189.         case 0x78: s = B600;  break;
  190.         case 0xE6: s = B1200; break;
  191.         case 0x0D: s = B2400; break;
  192.         case 0x8D: s = B2400; break;
  193.         default:   s = 0;     break;
  194.     }
  195.     }
  196.     nap(100);                    /* let slow input finish */
  197.     ttyb.c_iflag = ttyb.c_iflag  | ICRNL |IXON|IXANY;
  198.     ttyb.c_oflag = ttyb.c_oflag  | ONLCR;
  199.     ttyb.c_cflag = (s & ~PARENB )| CS8;    /* set speeds */
  200.     ttyb.c_cc[0] =  'C' & 037;            /*  ^C = interrupt */
  201.     ttyb.c_cc[2] =  '\b';            /* \b for char correction */
  202.     ttyb.c_cc[3] = 'U' & 037;            /* ^U for line kill */
  203.     ttyb.c_cc[4] =  'D' & 037;            /*  eof = ^D*/
  204.     ttyb.c_lflag = ICANON | ECHO;/* any parity, -TABS, CR, ECHO*/
  205.     ioctl(0,TIOCSETN,&ttyb);            /* set parameters */
  206.     ioctl(0,TIOCFLUSH,&zero);            /* flush I/O */
  207.     ioctl(0,TIOCHPCL,0);            /* set hangup on last close */
  208.     if (login)  {
  209.     sprintf (hostname,SITE_NAME);  /* no gethostname call, so ... */
  210.     initscr();  /* get the environment's idea of what kind of
  211.                  * terminal we're on */
  212.     clear();    /* clear and home */
  213.     echo();     /* add echo to user input */
  214.     move (0,0);
  215.     refresh();  /* update the window.  Note, no endwin.  That
  216.                  * would drop the cursor to the last line. */
  217. /* well, this kind of brute forse sets us to what the getty would
  218. expect upon login.  Sleazy, isn't it ? */
  219. system ("stty echo cs8 hupcl ixon erase ixon ixany icrnl istrip ignpar erase '^H' brkint opost onlcr cread isig icanon echok echo tab3");
  220. /* and while we're at it, display our system */
  221. printf("%s on %s\n",sp[s], hostname);
  222.     cat (ISSUE);    /* display  /etc/issue banner */
  223.     fflush(stdout);                /* flush it */
  224.     execl(LOGIN,"login",NULL);        /* exec login */
  225.     abort("can't exec login");
  226.     } else {
  227. /* well, this kind of brute forse sets us to what the getty would
  228. expect upon login.  Sleazy, isn't it ? */
  229. system ("stty echo cs8 hupcl ixon erase ixon ixany icrnl istrip ignpar erase '^H' brkint opost onlcr cread isig icanon echok echo tab3");
  230.     printf("%s baud\n",sp[s]);        /* from shell,just print speed*/
  231.     exit(0);
  232.     }
  233. }
  234.  
  235.  
  236.  
  237. /*  abort(s) - abort, for reason given in string s, calling perror first
  238.  *
  239.  *  (It's not totally clear what we should do, but we'll do it here for
  240.  *   uniformity.)
  241.  */
  242.  
  243. abort(s)
  244. char *s;
  245. {
  246.     fprintf(stderr,"%s: ",PGMNAME);    /* display program name */
  247.     perror(s);                /* display detail, and error message */
  248.     if (login)
  249.     nap(5000);            /* prevent fast looping in login mode */
  250.     exit(1);
  251. }
  252.  
  253.  
  254.  
  255.  
  256. /*  nap(n) - delay for n milliseconds.
  257.  *
  258.  *  if #ifdef SOCKETS, try to use the select function of sockets to
  259.  *  delay that many milliseconds, but it doesn't work right.
  260.  *
  261.  *  What does work is weird, but ... it works.
  262.  *  Put a terminal on a tty port.  Set it to 9600 baud.  Then lock it
  263.  *  away and ignore it, because delays will be obtained by writing 100
  264.  *  characters to this terminal.
  265.  */
  266.  
  267. static int nap_flag = -1;
  268. static nap_done() { nap_flag = 0; }
  269.  
  270. nap(n)
  271. int n;
  272. {
  273. #ifdef SOCKETS
  274. int nfound,nfds;
  275. long timeout;
  276. timeout = n;  /* sleep n milliseconds */
  277.     nfound = select (nfds,(int *) 0,(int *) 0,timeout);
  278. #endif
  279. #ifndef SOCKETS
  280.     FILE *fp,*fopen();
  281.     int i;
  282.     if (n > 1000)
  283. /* sleep the correct # of seconds */
  284.         sleep (n/1000);
  285.     else
  286.         {
  287. /* bloody hack time here ... open up a tty that's 9600 baud that
  288. there's an unused device on */
  289.         if ((fp = fopen(DELAY_TTY,"w"))== NULL)
  290.             {
  291. /* if we can't open the line, sleep one second, a safe amount */
  292.                 sleep (1);
  293.             }
  294.         else
  295.         {
  296. /* fudge factor delay, figuring 960 chars a second */
  297.     for (i=0;i<n;i++)
  298.         fprintf (fp,"%c",'\n');
  299. /* and close our tty */
  300.         fclose (fp);
  301.         }
  302.         }
  303. #endif
  304. }
  305.  
  306.  
  307. #ifdef DEBUG
  308. display(n)
  309. /* put out to a file the proper settings for the line, for debug
  310. *  purposes. This way, we know what the getty thought the baud rate was.
  311. */
  312. int n;
  313. {
  314.     FILE *fp,*fopen();
  315.         if ((fp = fopen("parity.err","a"))== NULL)
  316.             {
  317. printf ("fail 18\n");
  318. /* if we can't, sleep one second, a safe amount */
  319.             }
  320.         else
  321.         {
  322.         fprintf (fp,"char = %x\n",n);
  323. /* and close our tty */
  324.         fclose (fp);
  325.         }
  326. }
  327.  
  328. #endif
  329. /*
  330. *  list the file on the screen.  Note, this is taken from BSA's BBS, ua.
  331. *  although, BBS specific stuff has been stripped out.  This routine
  332. *  is used to display the /etc/issue file.
  333. */
  334. cat(file)
  335.     char *file;
  336.     {
  337.     FILE *f;
  338.     char ch;
  339.  
  340.     if ((f = fopen(file, "r")) == NULL)
  341.     {
  342.     fprintf (stderr,"Cannot open file %s\n.",file);
  343.     return;
  344.     }
  345.     while ((ch = getc(f)) != EOF)
  346.         putchar(ch);
  347.     fclose(f);
  348.     return (1);
  349. }
  350. //E*O*F auto.c//
  351.  
  352. echo x - autolocal.h
  353. cat > "autolocal.h" << '//E*O*F autolocal.h//'
  354. /*
  355. *
  356. *  CESPK-ED-T-AMU, David P. van De Kerk, U.S. Army COE,
  357. *  Sacramento District.  20 Oct 88
  358. *
  359. */
  360.  
  361. #define SITE_NAME "spked"  /* our host name */
  362. #define DELAY_TTY "/dev/hty10"  /* the tty we're sending, at 9600 baud,
  363.                                 * junk to so we can delay .1 seconds */
  364. //E*O*F autolocal.h//
  365.  
  366. echo x - autobaud.8
  367. cat > "autobaud.8" << '//E*O*F autobaud.8//'
  368. .TH AUTOBAUD 8 "20 October 1988" "U.S. Army COE"
  369. .SH NAME
  370. autobaud \- terminal speed detection
  371. .SH SYNOPSIS
  372. \fB/etc/autobaud [ \-l ] [ \fIttyname\fB ]
  373. .SH DESCRIPTION
  374. .I Autobaud
  375. is a simpler replacement for
  376. .IR getty (8),
  377. the crucial difference being that
  378. .I autobaud
  379. performs line speed detection as distinguished from cycling.
  380. The speeds recognized are 300, 1200, 2400, and 9600 baud.
  381. Autobaud expects the user to type a carriage return and will loop
  382. until one is received.
  383. .PP
  384. If
  385. .I ttyname
  386. is given,
  387. .I autobaud
  388. samples
  389. .RI /dev/ ttyname
  390. instead of standard input.
  391. The
  392. .B \-l
  393. option is normally set in /etc/inittab
  394. and causes
  395. .I autobaud
  396. to exec
  397. .IR login (1)
  398. after determining the speed.
  399. Here is an example inittab entry:
  400. .br
  401. h0a0:1:respawn:/etc/autobaud -l hty00 ignored svt100
  402. .br
  403. and clears the screen, according to curses.
  404. .PP
  405. Autobaud sets these terminal parameters:  no parity, no tabs, echo,
  406. erase ^H, kill ^U, interrupt ^C.
  407. .SH FILES
  408. .PP
  409. /etc/inittab
  410. .br
  411. /dev/\fIttyname\fP
  412. .br
  413. /etc/issue
  414. .br
  415. /dev/\fIdelay_tty\fP
  416. .br
  417. /usr/lib/terminfo
  418. .SH "SEE ALSO"
  419. init(8), getty(8), inittab (4), issue (4), login(1)
  420. .SH BUGS
  421. .PP
  422. BREAK and NUL have no effect, but typing any other character is
  423. likely to cause
  424. .I autobaud
  425. to set the speed incorrectly.  If this happens, wait two minutes,
  426. WITHOUT touching the keyboard.  The login process will die, and autobaud
  427. will fire up again, allowing another attempt.
  428. .PP
  429. Theory says that 600 baud should also work, but it doesn't.
  430. .SH HISTORY
  431. .PP
  432. Originally written for 4.3 BSD at the University of Arizona.  Hacked
  433. for Sys V.
  434. //E*O*F autobaud.8//
  435.  
  436. echo x - README
  437. cat > "README" << '//E*O*F README//'
  438.     David P. van De Kerk, U.S. Army Corps of Engineers,
  439.     Sacramento District.  CESPK-ED-T-AMU.
  440.     ucdavis.ucdavis.edu!spked!davev
  441.     20-OCT-88
  442.  
  443.     This is an autobauding getty.  It was originally written for 4.3 BSD,
  444.     by Gregg Townsend, University of Arizona, April, 1987
  445.   
  446.     but has been modified for a Unisys 5000/80 computer running Unisys's
  447.     Sys V r2.  Note:  While it runs on the Unisys 5000/80, I make NO
  448.     claims about it running on any other machine.
  449.  
  450.     PLEASE carefully read nap() in auto.c.
  451.  
  452. Manifest -----------------------------------------------------
  453.  
  454. README      -- This is it.
  455. auto.c      -- Main sources.
  456. autolocal.h -- Put your site name in there
  457. autobaud.8  -- Manual page
  458. Makefile    -- Make file for the program, tags, and shar file.
  459. //E*O*F README//
  460.  
  461. exit 0
  462. ---
  463. The contents of this message are totally unauthorized, and represent no person
  464. or entity within any agency, nor any statement of policy.
  465.             Standard Form 1 Disclaimer (Rev. 4-87)
  466.     {{seismo|ihnp4!}lll-crg|sdcsvax|{decvax!}ucbvax}!ucdavis!spked!davev
  467.