home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / usenet / compsrcs / misc / volume05 / autobaud < prev    next >
Encoding:
Internet Message Format  |  1991-08-27  |  13.6 KB

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