home *** CD-ROM | disk | FTP | other *** search
- /*
- * callback0 - get symbolic phone # from user & dial modem
- */
-
- #ifndef lint
- static char _cpyrgt[] = "Copyright 1990 Howard Lee Gayle";
- #endif lint
-
- /*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 1,
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
- #include <stdio.h>
- #include <howard/port.h>
- #include <howard/version.h>
- #include <howard/usage.h>
-
- MAINVER ("@(#)$Header: callback0.c,v 1.6 89/12/28 10:34:27 howard Exp $");
- USAGE ("flag name");
-
- #include <fcntl.h>
- #include <signal.h>
- #include "callback.h"
-
- #define MLINE 80 /* Max input line length.*/
- #define MCTLL 1024 /* Max control file line.*/
-
- PRIVATE byteT lb[MLINE]; /* Input line.*/
- PRIVATE boolT talking; /* Talking to user.*/
-
- PRIVATE void ws();
-
- /* getmcs - look up modem control line */
-
- PRIVATE void getmcs (ks, mcs)
- R4 cStrT ks; /* Key string. Must end in space.*/
- R5 cStrT mcs; /* Store modem control string here.*/
-
- /* Function:
- * Search the control file for a line starting with the given key.
- * Algorithm:
- * Linear search. Call getlic() to read each line and strip comments.
- * Returns:
- * On success, mcs points to the string to send to the modem to dial
- * the number. On error, mcs points to the empty string.
- * Notes:
- * 1) There is no overflow checking when copying into mcs.
- */
- {
- R2 streamT cs; /* Modem control file stream.*/
- unsigned ln = 0; /* Input line number.*/
- R3 boolT m; /* Loop control.*/
- R1 bStrT p; /* Returned by prefix (3 -lhoward).*/
- byteT ib[MCTLL]; /* Input line buffer.*/
- extern bStrT getlic() ; /* (3 -lhoward).*/
-
- cs = mfopen (ctlfn, "r");
- for (m = TRUE; m;)
- {
- if (NULBSTR == getlic (ib, MCTLL, cs, ctlfn, &ln, 1, ';'))
- {
- mcs[0] = EOS;
- m = FALSE;
- }
- else if (NULBSTR != (p = prefix (ks, ib)))
- {
- while ((EOS != *p) && (' ' == *p))
- ++p;
- if (EOS == *p) malf1 ("%s: %u: No control string", ctlfn, ln);
- STRCPY (mcs, p);
- STRCAT (mcs, "\n");
- m = FALSE;
- }
- }
- mfclose (cs, ctlfn);
- }
-
- /* rs - read string from fd 0 */
-
- PRIVATE void rs()
-
- /* Function:
- * Read a line from standard input and log it.
- * Algorithm:
- * Call read(). On error call malf1(). If characters are read,
- * NUL-terminate the result. Treat EOF as an empty string.
- * Write the result on the log file.
- * Returns:
- * The result is stored in lb[].
- * Notes:
- *
- */
- {
- R1 int i; /* Number of bytes read.*/
-
- i = read (0, lb, MLINE);
- if (-1 == i) malf1 ("Read error on fd 0");
- if (i > 0)
- lb[i - 1] = EOS;
- else if (0 == i)
- lb[0] = EOS;
- logMMSS();
- FPUTS (lb, ls);
- PUTC ('\n', ls);
- FFLUSH (ls);
- }
-
- /* sigalrm - print message if signal arrives */
-
- PRIVATE void sigalrm ()
-
- /* Function:
- * This function is called on timeout. Write a message to the user and
- * the log file, then exit.
- * Algorithm:
- *
- * Notes:
- * 1) The sleep() is to give the output tty time to flush before closing.
- */
- {
- logMMSS();
- FPUTS ("timeout\n", ls);
- FFLUSH (ls);
- if (talking) ws ("TIMEOUT timeout\n");
- sleep (1);
- exit (3);
- }
-
- /* ws - write a string on fd 1 */
-
- PRIVATE void ws (s)
- R1 cStrT s; /* String to write.*/
-
- /* Function:
- * Write string s on standard output and to the log file.
- * Algorithm:
- *
- * Notes:
- * 1) If s does not end in a newline, an extra newline is written
- * to the logfile.
- */
- {
- R2 int i; /* Length of string.*/
-
- i = strlen (s);
- if (i != write (1, s, i)) malf1 ("Write error on fd 1");
- PUTC ('>', ls);
- FPUTS (s, ls);
- if ('\n' != s[i - 1]) PUTC ('\n', ls);
- FFLUSH (ls);
- }
-
- /* main - main function */
-
- PUBLIC int main (argc, argv)
- int argc; /* Number of arguments.*/
- R6 bStrT *argv; /* Points to array of argument strings.*/
-
- /* Function:
- * Do callback.
- * Algorithm:
- * Set real and effective group ID to 0. Initialize. Set tty
- * for user interaction. Prompt user and get symbolic phone number.
- * Look it up in modem control file. On failure, write error message,
- * sleep a little to discourage brute force attacks, and repeat until
- * success or timeout. On success, hang up the line. Sleep long
- * enough to make sure the line is really hung up. Open the dial-out
- * (cua) device. Write the string from the control file, read
- * the responses, and throw them away until one matches a prefix
- * in the modem reply code table. Retry if the table says to,
- * until timeout. On success, turn off the hang-up-on-close bit,
- * create the state file, and exit.
- * Notes:
- * 1) This program is exec'ed by the speciall getty instead of login,
- * so the tty is already set up correctly (speed, parity, case, etc.)
- * 2) Turning off the HUPCL bit just before exiting means the line
- * does not get dropped on exit. On exit, init starts up a new
- * callback process, which, because the state file is present,
- * execs a normal login.
- */
-
- {
- R2 boolT m; /* Loop control.*/
- R1 mrcT *rp; /* Steps through mrctab[].*/
- R4 streamT ss; /* State file stream.*/
- ulongT sp; /* Line speed as code.*/
- R5 cStrT sps; /* Line speed as string.*/
- R3 unsigned tries = 0; /* Callback tries.*/
- stateT st; /* Contents of state file.*/
- struct termios ts; /* TTY status.*/
- char prompt[12]; /* Prompt for user.*/
- char mcs[MCTLL]; /* Modem control string.*/
- char key[2 * MLINE]; /* Key in control file.*/
- extern cStrT ttyname(); /* (3).*/
-
- if (-1 == setregid (0, 0)) exit (3);
- initTty ((bStrT) tn, (bStrT) ttyname (0));
- initLog (S("callback0"));
- logArgs (S("argv:"), argv);
- if ((argc < 3) || (strlen ((cStrT) argv[2]) > 8)) usage();
- gts (&ts);
- ts.c_iflag |= (IGNPAR | IMAXBEL);
- ts.c_lflag |= (ECHO | ECHOE | ECHOK | TOSTOP | ECHOCTL | ECHOKE);
- sts (&ts);
- sp = CBAUD & ts.c_cflag;
- if ((sp < B50) || (sp > B38400)) malf1 ("Bad line speed: %lu", sp);
- sps = speeds[sp];
- FPRINTF (ls, "Speed %lu = %s\n", sp, sps);
- FFLUSH (ls);
- SPRINTF (prompt, "%s %s", sps, sps);
- if (-1 == (int) signal (SIGALRM, sigalrm)) malf1 ("Can not signal");
- talking = TRUE;
- (void) alarm (ABORTSEC);
- for (m = TRUE; m;)
- {
- ws (prompt);
- rs();
- if (EOS != lb[0])
- {
- SPRINTF (key, "%s@%s ", lb, sps);
- getmcs (key, mcs);
- if (EOS != mcs[0])
- m = FALSE;
- else
- {
- sleep (1);
- ws (umNo);
- sleep (4);
- }
- }
- }
- talking = FALSE;
- ws (umBye);
- (void) alarm (ABORTSEC);
- st.stCflag = ts.c_cflag;
- STRCPY (st.stName, (cStrT) argv[2]);
- sleep (1);
- FPUTS ("Closing 1\n", ls);
- FFLUSH (ls);
- if (close (1)) malf1 ("Can not close 1");
- ts.c_cflag &= ~(CBAUD | CIBAUD | HUPCL);
- FPUTS ("TCSETS\n", ls);
- FFLUSH (ls);
- if (-1 == ioctl (0, TCSETS, &ts)) malf1 ("TCSETS failed");
- FPUTS ("TCFLSH\n", ls);
- FFLUSH (ls);
- if (-1 == ioctl (0, TCFLSH, 2)) malf1 ("TCFLSH failed");
- FPUTS ("Closing 0\n", ls);
- FFLUSH (ls);
- if (close (0)) malf1 ("Can not close 0");
- FPUTS ("sleep...", ls);
- FFLUSH (ls);
- sleep (DROPSEC);
- FPUTS ("ok\n", ls);
- FFLUSH (ls);
- if (0 != open (cun, O_RDWR)) malf1 ("%s: Can not open read/write", cun);
- if (1 != dup (0)) malf1 ("Can not dup 1");
- gts (&ts);
- ts.c_iflag |= (IGNPAR | IMAXBEL);
- ts.c_cflag = st.stCflag;
- ts.c_lflag &= ~ECHO;
- sts (&ts);
- for (m = TRUE; m;)
- {
- ++tries;
- ws (mcs);
- do
- {
- rs();
- rp = mrctab;
- while ((NULBSTR != rp->mrcStr) && (NULBSTR == prefix (rp->mrcStr, lb)))
- ++rp;
- }
- while (NULBSTR == rp->mrcStr);
- m = rp->mrcRetry;
- }
- (void) alarm (0);
- ts.c_cflag = st.stCflag & (~HUPCL);
- ts.c_lflag |= ECHO;
- sts (&ts);
- ss = mfopen (statefn, "w");
- if ((1 != fwrite ((cStrT) &st, sizeof (stateT), 1, ss)) || ferror (ss))
- malf1 ("%s: Write error", statefn);
- mfclose (ss, statefn);
- SPRINTF (prompt, "%s %u %s\n", sps, tries, sps);
- ws (prompt);
- FPUTS ("Closing stdin\n", ls);
- FFLUSH (ls);
- if (close (0)) malf1 ("Can not close 0");
- FPUTS ("Closing stdout\n", ls);
- FFLUSH (ls);
- if (close (1)) malf1 ("Can not close 1");
- FPUTS ("Exit\n", ls);
- FFLUSH (ls);
- exit (0);
- #ifdef lint
- return (SUCCESS);
- #endif
- }
-