home *** CD-ROM | disk | FTP | other *** search
Text File | 1993-04-05 | 87.6 KB | 3,689 lines |
- Newsgroups: comp.sources.unix
- From: lab@cgl.se (Lars Berntzon)
- Subject: v26i104: modempool - modem pool handler, with dialback, Part01/01
- Sender: unix-sources-moderator@vix.com
- Approved: paul@vix.com
-
- Submitted-By: lab@cgl.se (Lars Berntzon)
- Posting-Number: Volume 26, Issue 104
- Archive-Name: modempool/part01
-
- Modempool is a program that handles a pool of modems. When a user calls a
- modempool controlled modem he/she is requested a name, password and,
- sometimes, a phone number. If everything is ok, modempool will dialup the
- user and start a login prompt. Modempool has the following features:
-
- - Your site only have to have one external phone line and still have many
- modems on local lines.
-
- - Users do only have to known one number, this makes it easier for both
- the system administrator and the user who does't have to try many numbers
- to find a free line.
-
- - A user can have a list of valid phone numbers or asterisk for
- any number.
-
- - If compiled with the RLOGIN-switch callback will login a user
- on a specified machine.
-
- - Extensive logging of users loging in and of problems with the
- modem and lines.
-
- #! /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 1 (of 1)."
- # Contents: Greetings.te MANIFEST Makefile README Users.templa db.c
- # dialup.c getargs.c lock.c login.c modem.c modempool.1 modempool.c
- # modempool.h modempool.te patchlevel.h poolstat.1 poolstat.c slot.c
- # support.c termios.c termios.h tty.c utmplist.c
- # Wrapped by vixie@gw.home.vix.com on Tue Apr 6 03:46:51 1993
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f 'Greetings.te' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'Greetings.te'\"
- else
- echo shar: Extracting \"'Greetings.te'\" \(25 characters\)
- sed "s/^X//" >'Greetings.te' <<'END_OF_FILE'
- Are you allowed to login
- END_OF_FILE
- if test 25 -ne `wc -c <'Greetings.te'`; then
- echo shar: \"'Greetings.te'\" unpacked with wrong size!
- fi
- # end of 'Greetings.te'
- fi
- if test -f 'MANIFEST' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'MANIFEST'\"
- else
- echo shar: Extracting \"'MANIFEST'\" \(858 characters\)
- sed "s/^X//" >'MANIFEST' <<'END_OF_FILE'
- X File Name Archive # Description
- X-----------------------------------------------------------
- X Greetings.te 1
- X MANIFEST 1 This shipping list
- X Makefile 1
- X README 1
- X Users.templa 1
- X db.c 1
- X dialup.c 1
- X getargs.c 1
- X lock.c 1
- X login.c 1
- X modem.c 1
- X modempool.1 1
- X modempool.c 1
- X modempool.h 1
- X modempool.te 1
- X patchlevel.h 1
- X poolstat.1 1
- X poolstat.c 1
- X slot.c 1
- X support.c 1
- X termios.c 1
- X termios.h 1
- X tty.c 1
- X utmplist.c 1
- END_OF_FILE
- if test 858 -ne `wc -c <'MANIFEST'`; then
- echo shar: \"'MANIFEST'\" unpacked with wrong size!
- fi
- # end of 'MANIFEST'
- fi
- if test -f 'Makefile' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'Makefile'\"
- else
- echo shar: Extracting \"'Makefile'\" \(1463 characters\)
- sed "s/^X//" >'Makefile' <<'END_OF_FILE'
- X#
- X# @(#)Makefile 4.5 92/04/22 - Makefile for modempool.
- X#
- DESTDIR = /etc/local/modempool
- X#
- X# Unkomment for systems without stdlib.h
- X#
- X#NOSTDLIB = -DNOSTDLIB
- X#
- X# For systems without termios.
- X#
- X#TINCLUDE = -I.
- X#TOFILES = termios.o
- X#THFILES = termios.h
- X#
- X# If you want the rlogin functionality.
- X#
- RLOGIN= -DRLOGIN
- X#
- X# If you want debug printouts to stdout ?
- X# DEBUG=-DDEBUG
- CFLAGS = -g $(RLOGIN) $(TINCLUDE) $(NOSTDLIB) $(DEBUG)
- X#
- OFILES = modempool.o support.o tty.o slot.o lock.o modem.o db.o \
- X dialup.o login.o getargs.o $(TOFILES)
- HFILES = modempool.h $(THFILES)
- X#
- X# Unkomment for gcc
- X#
- X#CC=gcc -traditional
- CC=gcc
- COMPILE.c= $(CC) $(CFLAGS) $(CPPFLAGS) -c
- X
- all: modempool poolstat
- X
- modempool: $(OFILES)
- X $(CC) -g -o modempool $(OFILES)
- X
- poolstat: poolstat.o
- X $(CC) -o poolstat poolstat.o
- X
- X$(OFILES) : $(HFILES)
- X
- install: all
- X test -d $(DESTDIR) || mkdir -p $(DESTDIR)
- X cp poolstat modempool $(DESTDIR)
- X touch $(DESTDIR)/Users $(DESTDIR)/log $(DESTDIR)/errlog \
- X $(DESTDIR)/Greetings $(DESTDIR)/serverdb
- X chown root $(DESTDIR)/Users $(DESTDIR)/log $(DESTDIR)/errlog \
- X $(DESTDIR)/Greetings
- X chmod 600 $(DESTDIR)/log $(DESTDIR)/errlog $(DESTDIR)/serverdb
- X chmod 400 $(DESTDIR)/Users $(DESTDIR)/Greetings
- X chmod 500 $(DESTDIR)/modempool
- X chmod 4111 $(DESTDIR)/poolstat
- X @echo "modempool installed"
- X
- clean:
- X sccs clean
- X -rm -f poolstat.o $(OFILES) modempool poolstat modempool.aux modempool.dvi \
- X modempool.dlog modempool.log
- END_OF_FILE
- if test 1463 -ne `wc -c <'Makefile'`; then
- echo shar: \"'Makefile'\" unpacked with wrong size!
- fi
- # end of 'Makefile'
- fi
- if test -f 'README' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'README'\"
- else
- echo shar: Extracting \"'README'\" \(1626 characters\)
- sed "s/^X//" >'README' <<'END_OF_FILE'
- X
- X M o d e m p o o l
- X
- X Copyright (c) 1992, Lars Berntzon
- X All rights reserved.
- X
- X This program is free software; you can redistribute it and/or modify
- X it under the terms of the GNU General Public License as published by
- X the Free Software Foundation
- X
- Modempool is a program that handles a pool of modems. When a user calls a
- modempool controlled modem he/she is requested a name, password and,
- sometimes, a phone number. If everything is ok, modempool will dialup the
- user and start a login prompt. Modempool has the following features:
- X
- X - Your site only have to have one external phone line and still have many
- X modems on local lines.
- X
- X - Users do only have to known one number, this makes it easier for both
- X the system administrator and the user who does't have to try many numbers
- X to find a free line.
- X
- X - A user can have a list of valid phone numbers or asterisk for
- X any number.
- X
- X - If compiled with the RLOGIN-switch callback will login a user
- X on a specified machine.
- X
- X - Extensive logging of users loging in and of problems with the
- X modem and lines.
- X
- To compile modempool you should first decide whether to use -DRLOGIN switch.
- If you will not use it, edit the Makefile to turn it off.
- X
- Then do:
- X
- X make
- X
- If everyting worked do as root:
- X
- X make install
- X
- Also remember to read the manuals.
- X
- You should now start the modempool process in /etc/inittab (SYSV) or
- X/etc/ttytab (BSD), and add users to the /etc/local/modempool/Users-file.
- X
- X
- X
- Please mail bugreports or questions to me.
- X
- Lars Berntzon E-Mail: lab@cgl.se
- Cap Gemini Logic AB
- END_OF_FILE
- if test 1626 -ne `wc -c <'README'`; then
- echo shar: \"'README'\" unpacked with wrong size!
- fi
- # end of 'README'
- fi
- if test -f 'Users.templa' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'Users.templa'\"
- else
- echo shar: Extracting \"'Users.templa'\" \(87 characters\)
- sed "s/^X//" >'Users.templa' <<'END_OF_FILE'
- jerry:foo:123456:jerryws
- tom:mot:555626/555623:tomserver
- emergency:owjdojw:*:localhost
- END_OF_FILE
- if test 87 -ne `wc -c <'Users.templa'`; then
- echo shar: \"'Users.templa'\" unpacked with wrong size!
- fi
- # end of 'Users.templa'
- fi
- if test -f 'db.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'db.c'\"
- else
- echo shar: Extracting \"'db.c'\" \(3525 characters\)
- sed "s/^X//" >'db.c' <<'END_OF_FILE'
- X/*******************************************************************
- X *
- X * Module: @(#)db.c 4.2
- X *
- X * Description:
- X * Handle user database functions.
- X *
- X * Revision:
- X * Date By Reason
- X * ---- -- ------
- X * 910414 Lars Berntzon Created
- X * 910124 Lars H Carlsson Changed pid format to %10d\n
- X * 910124 Lars H Carlsson Changed mode of lockfile to 0444
- X * 910129 Lars Berntzon Changed to termio for eightbit tty.
- X * 910224 Lars Berntzon Newline right when loggin in.
- X * 910227 Lars Berntzon The loggfile now reopens everytime.
- X *
- X *******************************************************************/
- static char SccsId[] = "@(#)db.c 4.2 92/04/16";
- X
- X#include <stdio.h>
- X#include <string.h>
- X#include <fcntl.h>
- X#include <stdarg.h>
- X
- X#include "modempool.h"
- X
- X/*
- X * Local stuff.
- X */
- static FILE *db_fp = NULL;
- X
- static db_open(char *filename);
- static db_read(char **ptrs, int n_ptrs);
- static db_close(void);
- X
- X/*******************************************************************
- X * D B _ F I N D
- X * -------------
- X *
- X * Description:
- X * Lookup user in database.
- X *
- X * Arguments:
- X * filename - Name of users database.
- X * ptrs - Pointers to result vectors.
- X * n_ptrs - Number of vectors.
- X * key_fiels - Key-field index.
- X * key - Value to match.
- X *
- X * Return:
- X * E_OK
- X * E_FAIL - Internal error.
- X * E_NOTFOUND - Key not found.
- X *
- X *******************************************************************/
- db_find(char *filename, char **ptrs, int n_ptrs, int key_field, char *key)
- X{
- X if (key == NULL) {
- X logerr("db_find: programming error: null-key");
- X return E_FAIL;
- X }
- X
- X if (key_field >= n_ptrs) {
- X logerr("db_find: programming error: key_field >= n_ptrs");
- X }
- X
- X if (db_open(filename) != E_OK) {
- X return E_FAIL;
- X }
- X
- X while(db_read(ptrs, n_ptrs) == E_OK)
- X {
- X if (ptrs[key_field] != NULL && strcmp(ptrs[key_field], key) == 0)
- X {
- X db_close();
- X return E_OK;
- X }
- X }
- X
- X db_close();
- X return E_NOTFOUND;
- X}
- X
- X/*******************************************************************
- X * D B _ R E A D
- X * -------------
- X *
- X * Description:
- X * Read one row in users database.
- X *
- X * Arguments:
- X * ptrs - Pointers to result vectors.
- X * n_ptrs - Number of verctors.
- X *
- X * Return:
- X * E_OK
- X * E_EOF - No more users.
- X *
- X *******************************************************************/
- static db_read(char **ptrs, int n_ptrs)
- X{
- X static char in_line[NAME_SIZE];
- X char *p;
- X int i;
- X
- X while (fgets(in_line, sizeof in_line, db_fp) != NULL)
- X {
- X p = strtok(in_line, ":\n");
- X
- X for(i = 0; i < n_ptrs; i++) {
- X ptrs[i] = p;
- X if (p != NULL) p = strtok(NULL, ":\n");
- X }
- X if (ptrs[0] == NULL || ptrs[0][0] == '#') continue;
- X
- X return E_OK;
- X }
- X
- X return E_EOF;
- X}
- X
- X/*******************************************************************
- X * D B _ O P E N
- X * -------------
- X *
- X * Description:
- X * Open the users database.
- X *
- X * Arguments:
- X * filename - the users database filename.
- X *
- X *******************************************************************/
- static db_open(char *filename)
- X{
- X if ((db_fp = fopen(filename, "r")) == NULL) {
- X logerr("db_open: failed to open user database");
- X return E_FAIL;
- X }
- X
- X return E_OK;
- X}
- X
- X/*******************************************************************
- X * D B _ C L O S E
- X * ---------------
- X *
- X * Description:
- X * Close the users database.
- X *
- X *******************************************************************/
- static db_close(void)
- X{
- X if (db_fp) fclose(db_fp);
- X db_fp = NULL;
- X
- X return E_OK;
- X}
- END_OF_FILE
- if test 3525 -ne `wc -c <'db.c'`; then
- echo shar: \"'db.c'\" unpacked with wrong size!
- fi
- # end of 'db.c'
- fi
- if test -f 'dialup.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'dialup.c'\"
- else
- echo shar: Extracting \"'dialup.c'\" \(5769 characters\)
- sed "s/^X//" >'dialup.c' <<'END_OF_FILE'
- X/*******************************************************************
- X *
- X * Module: @(#)dialup.c 4.2 92/04/16
- X *
- X * Description:
- X * Dialup routines.
- X *
- X * Revision:
- X * Date By Reason
- X * ---- -- ------
- X * 920309 Lars Berntzon Created
- X *
- X *******************************************************************/
- static char SccsId[] = "@(#)dialup.c 4.2 92/04/16";
- X
- X#include <stdio.h>
- X#ifndef NOSTDLIB
- X#include <stdlib.h>
- X#endif
- X#include <unistd.h>
- X#include <string.h>
- X#include <signal.h>
- X#include <fcntl.h>
- X#include <termios.h>
- X#include <ctype.h>
- X
- X#include "modempool.h"
- X
- X#ifdef RLOGIN
- X#include <pwd.h>
- X#endif
- X
- X/*******************************************************************
- X *
- X * callback
- X * --------
- X *
- X * Description:
- X * Does the actual calling.
- X *
- X *******************************************************************/
- callback(slot_t *sp)
- X{
- X struct slot free_slot;
- X int main_port = 0;
- X int fd;
- X int id;
- X int rc;
- X
- X /*
- X * Find free available line.
- X */
- X slot_lock();
- X slot_open();
- X while((rc = slot_traverse(&free_slot)) == E_OK) {
- X
- X /* I will only use myself in last resort */
- X if (free_slot.pid == getpid()) {
- X continue;
- X }
- X
- X /* Of cause don't use a busy server */
- X if (free_slot.status != SLOT_FREE) {
- X continue;
- X }
- X
- X /* Maybe the port us taken by someone else, dont use it then */
- X if (lock_line(free_slot.line, free_slot.pid) != E_OK) {
- X continue;
- X }
- X
- X /* Now a free server is found */
- X break;
- X }
- X
- X /*
- X * Use myself if no other servers was found.
- X */
- X if (rc != E_OK) {
- X debug("callback: using myself");
- X memcpy(&free_slot, &slot, sizeof free_slot);
- X }
- X
- X mod_put(MSG_CALLING);
- X
- X /*
- X * Write command to slot e.i. tell server to dial.
- X */
- X free_slot.status = SLOT_BUSY;
- X strncpy(free_slot.phone, sp->phone, sizeof free_slot.phone);
- X strncpy(free_slot.name, sp->name, sizeof free_slot.name);
- X#ifdef RLOGIN
- X strncpy(free_slot.host, sp->host, sizeof free_slot.host);
- X#endif
- X free_slot.baud = sp->baud;
- X debug("calling: slotid: %d, phone: %s, name: %s, baud: %d",
- X free_slot.id, free_slot.phone, free_slot.name, free_slot.baud);
- X
- X /*
- X * Write the data and unlock server database.
- X */
- X slot_write(&free_slot);
- X slot_unlock();
- X
- X /* Send signal to server to read its database (dont signal myself) */
- X if (free_slot.pid != getpid()) {
- X kill(free_slot.pid, SIG_SERVER);
- X }
- X else {
- X if ( dialup() != E_OK) {
- X log("dialup failed");
- X return E_FAIL;
- X }
- X }
- X
- X return E_OK;
- X}
- X
- X/*******************************************************************
- X *
- X * DIALUP
- X * ------
- X *
- X * Description:
- X * Dials a number for this server.
- X *
- X *******************************************************************/
- dialup()
- X{
- X#ifdef RLOGIN
- X char name[NAME_SIZE]; /* Temporary name */
- X struct passwd *pw; /* Pointer to passwd struct */
- X#endif
- X int retry; /* Retry counter */
- X int baud = 0; /* Connected baudrate */
- X int rc;
- X
- X /* Turn of signalled flag */
- X signalled = 0;
- X
- X /* Hangup line before dialing */
- X tty_hangup();
- X tty_close();
- X
- X /* Wait some before dialing */
- X sleep(DIALUP_DELAY);
- X
- X /* Read baudrate and phone number to dial */
- X if (slot_read(&slot) != E_OK) {
- X logerr("dialup: failed to read slot");
- X return E_FAIL;
- X }
- X
- X /* log dialing */
- X log("dialup: dialing #%s baud %d", slot.phone, slot.baud);
- X
- X /* Open port again */
- X if (tty_open(portname, slot.baud, O_NDELAY) != E_OK) {
- X logerr("dialup: failed to open port");
- X return E_FAIL;
- X }
- X
- X /* Try three times to dialup */
- X for(retry = 0; retry < 3; retry++)
- X {
- X /* Send modem command */
- X mod_put("ATDT");
- X mod_put(prefix);
- X mod_put(slot.phone);
- X mod_put("\r");
- X
- X /* Expect connection in 20 sec */
- X rc = mod_exp(MOD_ANY, DIALUP_TMOUT);
- X debug("dial: got %d\n", rc);
- X
- X switch(rc)
- X {
- X case MOD_CONNECT:
- X case MOD_CONNECT_300:
- X baud = 300;
- X case MOD_CONNECT_1200:
- X if (baud == 0) baud = 1200;
- X case MOD_CONNECT_2400:
- X if (baud == 0) baud = 2400;
- X case MOD_CONNECT_4800:
- X if (baud == 0) baud = 4800;
- X case MOD_CONNECT_9600:
- X if (baud == 0) baud = 9600;
- X
- X sleep(2); /* Let modem settle */
- X tty_flush();
- X tty_local(0);
- X tty_baud(baud);
- X tty_sane();
- X log("dialup: connected");
- X mod_put("\r\n\r\n");
- X
- X /*
- X * Mark current baudrate in the server database.
- X */
- X slot.baud = baud;
- X slot_write(&slot);
- X
- X#ifdef RLOGIN
- X /*
- X * Get login name.
- X */
- X retry = 0;
- X do {
- X rc = prompt(MSG_LOGIN, name, NAME_SIZE, LOGIN_TMOUT);
- X } while(rc == E_OK && strlen(name) == 0);
- X
- X if ((pw = getpwnam(name)) == NULL) {
- X mod_put(MSG_LOGINFAIL);
- X return E_FAIL;
- X }
- X
- X /*
- X * Don't even try to login as same uid as this process.
- X */
- X if (pw->pw_uid < 10 || pw->pw_uid == getuid()) {
- X log("pseudouser '%s' tried to log in as '%s'", slot.name, name);
- X mod_put(MSG_LOGINFAIL);
- X return E_FAIL;
- X }
- X#endif
- X
- X /*
- X * Redirect port to stdin, stdout and stderr.
- X */
- X if (tty_redirect() != E_OK) {
- X logerr("redirection failed");
- X return E_FAIL;
- X }
- X
- X#ifdef RLOGIN
- X execl("/usr/ucb/rlogin", "rlogin", "-l", name, slot.host, NULL);
- X logerr("dialup: failed to exec rlogin");
- X#else
- X execl("/bin/login", "login", NULL);
- X logerr("dialup: failed to exec login");
- X#endif
- X return E_FAIL;
- X
- X case MOD_NO_CARRIER:
- X logerr("dialup: got no carrier for number '%s'", slot.phone);
- X break; /* Retry */
- X
- X case MOD_BUSY:
- X sleep(7);
- X break; /* Retry */
- X
- X case MOD_OK:
- X default:
- X logerr("dialup: got %d from modem", rc);
- X break; /* Retry */
- X }
- X sleep(5);
- X }
- X
- X /*
- X * Failed to dialup.
- X */
- X
- X return E_FAIL;
- X}
- END_OF_FILE
- if test 5769 -ne `wc -c <'dialup.c'`; then
- echo shar: \"'dialup.c'\" unpacked with wrong size!
- fi
- # end of 'dialup.c'
- fi
- if test -f 'getargs.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'getargs.c'\"
- else
- echo shar: Extracting \"'getargs.c'\" \(1381 characters\)
- sed "s/^X//" >'getargs.c' <<'END_OF_FILE'
- X/*******************************************************************
- X *
- X * Module: @(#)getargs.c 4.2 92/04/16
- X *
- X * Description:
- X * Get commandline arguments.
- X *
- X * Revision:
- X * Date By Reason
- X * ---- -- ------
- X * 920309 Lars Berntzon Created
- X *
- X *******************************************************************/
- static char SccsId[] = "@(#)getargs.c 4.2 92/04/16";
- X
- X#include <stdio.h>
- X#ifndef NOSTDLIB
- X#include <stdlib.h>
- X#endif
- X#include <unistd.h>
- X#include <string.h>
- X#include <signal.h>
- X#include <fcntl.h>
- X#include <stdarg.h>
- X#include <termios.h>
- X#include <ctype.h>
- X
- X#include "modempool.h"
- X
- X/*******************************************************************
- X * G E T A R G S
- X * -------------
- X * Description:
- X * Examine command line options.
- X *
- X *******************************************************************/
- int
- getargs(int *argc, char ***argv)
- X{
- X /*
- X * Get arguments
- X */
- X while((*argv)[1] != NULL && (*argv)[1][0] == '-')
- X {
- X switch((*argv)[1][1])
- X {
- X case 'd':
- X debug_lvl++;
- X break;
- X
- X case 'p':
- X (*argv)++, (*argc)--;
- X if ((*argv)[1] == NULL) usage();
- X strcpy(prefix, (*argv)[1]);
- X break;
- X
- X case 'i':
- X (*argv)++, (*argc)--;
- X if((*argv)[1] == NULL) usage();
- X initstr = (*argv)[1];
- X break;
- X }
- X (*argv)++, (*argc)--;
- X }
- X
- X /* Check args */
- X if ((*argc) != 3) usage();
- X
- X return E_OK;
- X}
- END_OF_FILE
- if test 1381 -ne `wc -c <'getargs.c'`; then
- echo shar: \"'getargs.c'\" unpacked with wrong size!
- fi
- # end of 'getargs.c'
- fi
- if test -f 'lock.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'lock.c'\"
- else
- echo shar: Extracting \"'lock.c'\" \(4969 characters\)
- sed "s/^X//" >'lock.c' <<'END_OF_FILE'
- X/*******************************************************************
- X *
- X * Module: @(#)lock.c 4.2 92/04/16
- X *
- X * Description:
- X * Handle various lockfile functions.
- X *
- X * Revision:
- X * Date By Reason
- X * ---- -- ------
- X * 920306 Lars Berntzon Created
- X *
- X *******************************************************************/
- static char SccsId[] = "@(#)lock.c 4.2 92/04/16";
- X
- X#include <stdio.h>
- X#include <string.h>
- X#include <unistd.h>
- X#include <fcntl.h>
- X#include <assert.h>
- X#include <stdarg.h>
- X
- X#include "modempool.h"
- X/*******************************************************************
- X * L O C K _ L I N E
- X * -----------------
- X *
- X * Description:
- X * Lock a tty-port the old UNIX way.
- X *
- X * Arguments:
- X * line - Name of tty device.
- X *
- X *******************************************************************/
- int
- lock_line(char *line, int pid)
- X{
- X char fname[NAME_SIZE];
- X char id[NAME_SIZE];
- X int fd;
- X
- X sprintf(fname, "%s/LCK..%s", LOCKDIR, line);
- X
- X /*
- X * Check that lockdirectory is writeable.
- X */
- X if (access(LOCKDIR, O_WRONLY) != 0) {
- X logerr("lock_line: lock directory not writeable");
- X return E_FAIL;
- X }
- X
- X /*
- X * First try to create own lockfile.
- X */
- X while(1)
- X {
- X if ((fd = open(fname, O_RDWR | O_CREAT | O_EXCL, 0666)) >= 0)
- X {
- X /* Succeded, break out of retry loop */
- X break;
- X }
- X else
- X {
- X /*
- X * File allready existed, try to open it without creation.
- X */
- X if ((fd = open(fname, O_RDONLY)) < 0) {
- X logerr("lock_line: can't read file '%s'", fname);
- X return E_LOCK;
- X }
- X
- X id[0] = 0;
- X if (read(fd, id, sizeof id) < 0)
- X {
- X close(fd);
- X debug("lock_line: failed to read");
- X return E_READ;
- X }
- X close(fd);
- X
- X /*
- X * If I own the lock, it's all right.
- X */
- X if (atoi(id) == pid) {
- X debug("lock_line: i allready owned the lock");
- X break;
- X }
- X
- X /*
- X * Process owning lock does exists so i can't use the line.
- X */
- X if (kill(atoi(id), 0) >= 0)
- X {
- X debug("lock_line: process exists");
- X return E_PROC_EXIST;
- X }
- X if (unlink(fname) < 0)
- X {
- X debug("lock_line: failed to unlink");
- X return E_UNLINK;
- X }
- X }
- X }
- X
- X /*
- X * Here our own lock file has been created.
- X */
- X lseek(fd, 0, 0);
- X sprintf(id, "%10d\n", pid);
- X write(fd, id, strlen(id));
- X close(fd);
- X
- X debug("lock_line: ok");
- X
- X return E_OK;
- X}
- X
- X/*******************************************************************
- X * R E L O C K _ L I N E
- X * ---------------------
- X *
- X * Description:
- X * Relock the line
- X *
- X * Arguments:
- X * line - Name of tty device.
- X *
- X *******************************************************************/
- int
- relock_line(char *line)
- X{
- X char fname[NAME_SIZE];
- X char id[NAME_SIZE];
- X int fd;
- X
- X sprintf(fname, "%s/LCK..%s", LOCKDIR, line);
- X
- X /* Open lockfile */
- X if ((fd = open(fname, O_WRONLY | O_TRUNC)) < 0) return E_OPEN;
- X
- X /* Write pid to lockfile */
- X sprintf(id, "%10d\n", getpid());
- X if (write(fd, id, strlen(id)) < 0) {
- X return E_WRITE;
- X }
- X
- X close(fd);
- X return E_OK;
- X}
- X
- X/*******************************************************************
- X * U N L O C K _ L I N E
- X * ---------------------
- X *
- X * Description:
- X * Unlock line.
- X *
- X * Arguments:
- X * line - Name of tty device.
- X *
- X *******************************************************************/
- int
- unlock_line(char *line)
- X{
- X char fname[NAME_SIZE];
- X sprintf(fname, "%s/LCK..%s", LOCKDIR, line);
- X unlink(fname);
- X return E_OK;
- X}
- X
- X/*******************************************************************
- X * L O C K _ W A I T
- X * -----------------
- X *
- X * Description:
- X * Wait until lock goes away.
- X *
- X *******************************************************************/
- int
- lock_wait(char *line)
- X{
- X int fd = -1;
- X char fname[NAME_SIZE], id[NAME_SIZE];
- X
- X if (line == NULL) {
- X logerr("lock_wait: programming error: line = NULL");
- X return E_FAIL;
- X }
- X
- X sprintf(fname, "%s/LCK..%s", LOCKDIR, line);
- X
- X /*
- X * This one never times out when line is locked.
- X */
- X while(1)
- X {
- X /*
- X * Check if lockfile exists.
- X */
- X if (access(fname, F_OK) != 0) {
- X return E_OK;
- X }
- X
- X /*
- X * Open lockfile.
- X */
- X if ((fd = open(fname, O_RDONLY)) < 0) {
- X fatal("lockfile not readable");
- X }
- X
- X id[0] = 0;
- X if (read(fd, id, sizeof id) < 0) {
- X logerr("lock_wait: failed to read lockfile");
- X close(fd);
- X return E_FAIL;
- X }
- X
- X /*
- X * If I hold the lock, remove it and return.
- X */
- X if (atoi(id) == getpid()) {
- X debug("lock_wait: i owned the lock");
- X unlock_line(line);
- X close(fd);
- X return E_OK;
- X }
- X
- X /*
- X * If no owner of lock, remove it and return.
- X */
- X if (kill(atoi(id), 0) != 0) {
- X debug("lock_wait: no owner of lock");
- X unlock_line(line);
- X close(fd);
- X return E_OK;
- X }
- X
- X close(fd);
- X sleep(5);
- X }
- X}
- END_OF_FILE
- if test 4969 -ne `wc -c <'lock.c'`; then
- echo shar: \"'lock.c'\" unpacked with wrong size!
- fi
- # end of 'lock.c'
- fi
- if test -f 'login.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'login.c'\"
- else
- echo shar: Extracting \"'login.c'\" \(6000 characters\)
- sed "s/^X//" >'login.c' <<'END_OF_FILE'
- X/*******************************************************************
- X *
- X * Module: @(#)login.c 4.4 92/04/21
- X *
- X * Description:
- X * Handle login during user callup.
- X *
- X * Revision:
- X * Date By Reason
- X * ---- -- ------
- X * 920309 Lars Berntzon Created
- X *
- X *******************************************************************/
- static char SccsId[] = "@(#)login.c 4.4 92/04/21";
- X
- X#include <stdio.h>
- X#ifndef NOSTDLIB
- X#include <stdlib.h>
- X#endif
- X#include <unistd.h>
- X#include <string.h>
- X#include <ctype.h>
- X#include <errno.h>
- X
- X#include "modempool.h"
- X
- X#ifdef RLOGIN
- X#include <pwd.h>
- X#endif
- X
- X/*******************************************************************
- X * H D L _C O N N E C T
- X * --------------------
- X *
- X * Description:
- X * Handles initial connection to callback server.
- X *
- X * Arguments:
- X * mod_rc - Return code from modem specifying connection.
- X *
- X *******************************************************************/
- int
- hdl_connect(int mod_rc)
- X{
- X slot_t msg_slot; /* A message carrier between do_login and callback */
- X int rc;
- X
- X switch(mod_rc)
- X {
- X case MOD_CONNECT:
- X case MOD_CONNECT_300:
- X slot.baud = 300;
- X break;
- X
- X case MOD_CONNECT_1200:
- X slot.baud = 1200;
- X break;
- X
- X case MOD_CONNECT_2400:
- X slot.baud = 2400;
- X break;
- X
- X case MOD_CONNECT_4800:
- X slot.baud = 4800;
- X break;
- X
- X case MOD_CONNECT_9600:
- X slot.baud = 9600;
- X break;
- X
- X case MOD_RING:
- X case MOD_OK:
- X return E_RETRY;
- X
- X default:
- X logerr("connect: unknown modem code: %d", mod_rc);
- X return E_FAIL;
- X }
- X
- X /*
- X * Don't accept dialup orders during login.
- X */
- X slot.status = SLOT_LOGIN;
- X slot_write(&slot);
- X
- X log("connected at baud %d", slot.baud);
- X /* Also set the message data to correct baud */
- X msg_slot.baud = slot.baud;
- X
- X /*
- X * Setup port in sane mode.
- X */
- X tty_baud(slot.baud);
- X tty_local(0);
- X tty_sane();
- X tty_flush();
- X
- X /*
- X * Request everything from calling user.
- X */
- X rc = do_login(&msg_slot);
- X
- X tty_raw();
- X
- X /* Turn back off DCD checking */
- X tty_local(1);
- X
- X /* If login successful, do a callback.
- X * If I'm the only free server left, the
- X * call to callback will never return.
- X */
- X if (rc != E_OK) {
- X return E_FAIL;
- X }
- X
- X mod_put(MSG_HANGUP);
- X if (callback(&msg_slot) != E_OK) {
- X logerr("callback failed");
- X return E_FAIL;
- X }
- X
- X return E_OK;
- X}
- X
- X/*******************************************************************
- X *
- X * DO_LOGIN
- X * --------
- X *
- X * Description:
- X * Reads username and password, does a check and return phone number
- X *
- X *******************************************************************/
- int
- do_login(slot_t *sp)
- X{
- X char passwd[NAME_SIZE]; /* Temporary password */
- X char str[200]; /* Temporary string */
- X char *field[N_FIELDS]; /* Fields in the USERS file */
- X int rc; /* Return code */
- X int retry; /* Retry counter */
- X FILE *fp; /* Temporary file pointer */
- X char *p; /* Temporary char pointer */
- X
- X /*
- X * Give greetings message.
- X */
- X if ((fp = fopen(GREETINGSFILE, "r")) != NULL) {
- X while(fgets(str, sizeof str, fp) != NULL) {
- X mod_put(str);
- X mod_put("\r");
- X }
- X fclose(fp);
- X }
- X else {
- X logerr("failed to open greetings file");
- X }
- X
- X for(retry = 0; retry < MAX_RETRY; retry++)
- X {
- X /* Get login name */
- X do {
- X rc = prompt(MSG_NAME, sp->name, sizeof sp->name, LOGIN_TMOUT);
- X }
- X while(rc == E_OK && strlen(sp->name) == 0);
- X
- X if (rc != E_OK) {
- X if (rc == E_TMOUT) {
- X debug("do_login: timeout");
- X mod_put(MSG_LOGINFAIL);
- X return E_FAIL;
- X }
- X debug("do_login: login: rc = %d, errno = %d", rc, errno);
- X mod_put(MSG_LOGINFAIL);
- X continue;
- X }
- X
- X /* Get passwd */
- X tty_noecho();
- X rc = prompt(MSG_PASSWD, passwd, sizeof passwd, LOGIN_TMOUT);
- X tty_echo();
- X mod_put("\r\n");
- X
- X if (rc != E_OK) {
- X debug("do_login: passwd: rc = %d, errno = %d", rc, errno);
- X mod_put(MSG_LOGINFAIL);
- X continue;
- X }
- X
- X /* Get user data */
- X if (db_find(USERS, field, sizeof field / sizeof field[0], 0, sp->name) != E_OK)
- X {
- X debug("do_login: db_find: rc = %d, errno = %d", rc, errno);
- X mod_put(MSG_LOGINFAIL);
- X continue;
- X }
- X
- X /* Check validity */
- X if (field[0] == NULL || field[1] == NULL || field[2] == NULL
- X#ifdef RLOGIN
- X || field[3] == NULL
- X#endif
- X )
- X {
- X logerr("do_login: illegal data for user '%s'", sp->name);
- X mod_put(MSG_LOGINFAIL);
- X return E_FAIL;
- X }
- X
- X /* Check if password is ok */
- X if (strcmp(field[1], passwd) != 0) {
- X debug("do_login: wrong password");
- X mod_put(MSG_LOGINFAIL);
- X continue;
- X }
- X
- X /* Login succeded */
- X strncpy(sp->name, field[0], sizeof sp->name);
- X#ifdef RLOGIN
- X strncpy(sp->host, field[3], sizeof sp->host);
- X#endif
- X
- X /*
- X * Check if wildcard phonenumber or phonenumber list.
- X */
- X if ((strchr(field[2], '*') != NULL) || (strchr(field[2], '/') != NULL)) {
- X /*
- X * Request phonenumber from user.
- X */
- X do {
- X rc = prompt(MSG_PHONE, sp->phone, sizeof sp->phone, LOGIN_TMOUT);
- X }
- X while(rc == E_OK && strlen(sp->phone) == 0);
- X if (rc != E_OK) {
- X log("failed to read phone number");
- X mod_put(MSG_LOGINFAIL);
- X continue;
- X }
- X
- X /*
- X * Check entered number against list.
- X */
- X for(p = strtok(field[2], "/"); p != NULL; p = strtok(NULL, "/"))
- X {
- debug("trying '%s' vs. '%s'\n", p, sp->phone);
- X if ((strcmp(p, "*") == 0) || (strcmp(p, sp->phone) == 0)) {
- X break;
- X }
- X }
- X if (p == NULL) {
- X log("wrong phonenumber");
- X mod_put(MSG_LOGINFAIL);
- X continue;
- X }
- X
- X if (strcmp(p, "*") == 0) {
- X log("privileged user '%s' succeded to login (phone: %s)", sp->name, sp->phone);
- X }
- X else {
- X log("user '%s' succeded to login (phone: %s)", sp->name, sp->phone);
- X }
- X }
- X else {
- X strncpy(sp->phone, field[2], sizeof sp->phone);
- X log("user '%s' succeded to login", sp->name);
- X }
- X
- X return E_OK;
- X }
- X log("user '%s' tried to login but failed", sp->name);
- X return E_FAIL;
- X}
- END_OF_FILE
- if test 6000 -ne `wc -c <'login.c'`; then
- echo shar: \"'login.c'\" unpacked with wrong size!
- fi
- # end of 'login.c'
- fi
- if test -f 'modem.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'modem.c'\"
- else
- echo shar: Extracting \"'modem.c'\" \(6023 characters\)
- sed "s/^X//" >'modem.c' <<'END_OF_FILE'
- X/*******************************************************************
- X *
- X * Module: @(#)modem.c 4.2 92/04/16
- X *
- X * Description:
- X * Handle various modem functions.
- X *
- X * Revision:
- X * Date By Reason
- X * ---- -- ------
- X * 920306 Lars Berntzon Created
- X *
- X *******************************************************************/
- static char SccsId[] = "@(#)modem.c 4.2 92/04/16";
- X
- X#include <stdio.h>
- X#include <string.h>
- X#include <stdarg.h>
- X#include <ctype.h>
- X
- X#include "modempool.h"
- X
- X#define N_MOD_CMDS (sizeof mod_cmds / sizeof mod_cmds[0])
- static char *mod_cmds[] = {
- X "*", "CONNECT\r", "CONNECT 300\r", "CONNECT 1200\r", "CONNECT 2400\r",
- X "RING\r", "BUSY\r", "ERROR\r", "NO CARRIER\r", "OK\r",
- X "CONNECT 4800\r", "CONNECT 9600\r"
- X};
- X
- static char *cmd_str(int n);
- X
- X/*
- X * Routines.
- X */
- X
- X/*******************************************************************
- X *
- X * M O D _ S E T U P
- X * -----------------
- X *
- X * Description:
- X * Sets the modem to a correct state.
- X *
- X *******************************************************************/
- X
- int
- mod_setup(void)
- X{
- X int retry;
- X int rc = 0;
- X
- X for(retry = 0; retry < 2; retry++) {
- X if ((rc = mod_put(initstr)) == E_OK &&
- X (rc = mod_put("\r")) == E_OK &&
- X (rc = mod_exp(MOD_OK, 0)) == E_OK) return E_OK;
- X }
- X
- X logerr("setup_modem: failed ( %d)", rc);
- X return rc;
- X}
- X
- X/*******************************************************************
- X * M O D _ P U T
- X * -------------
- X *
- X * Description:
- X * Initialize the modem (hayes commands).
- X *
- X *******************************************************************/
- mod_put(char *msg)
- X{
- X int rc;
- X
- X debug("mod_put(\"%s\")", msg);
- X
- X trig(2);
- X rc = tty_write(msg, strlen(msg));
- X if (istimeout()) {
- X return E_TMOUT;
- X }
- X
- X if (rc < 0) {
- X logerr("mod_put: failed to write");
- X return E_WRITE;
- X }
- X
- X return E_OK;
- X}
- X
- X/*******************************************************************
- X * M O D _ E X P
- X * -------------
- X *
- X * Description:
- X * Expect answer from modem.
- X *
- X * Arguments:
- X * expected - Answer type (integern enumeration)
- X * tmout - Timeout (0 means default)
- X *
- X *******************************************************************/
- mod_exp(int expected, int tmout)
- X{
- X va_list arg = NULL;
- X int exp_len = 0;
- X char buf[MATCH_SIZE];
- X int buf_len;
- X int pos = 0;
- X int i = 0;
- X
- X /* Used default timeout if none specified */
- X if (tmout == 0) tmout = MODEM_TMOUT;
- X
- X debug("expecting(\"%s\")", cmd_str(expected));
- X /* Read until text matches but not more than can fit into bufer */
- X while(pos < MATCH_SIZE)
- X {
- X buf[pos] = 0;
- X
- X /* Read with timeout */
- X trig(tmout);
- X buf_len = tty_read(buf + pos++, 1);
- X if(istimeout()) {
- X return E_TMOUT;
- X }
- X
- X /*
- X * Some one called us ?.
- X */
- X if (buf_len <= 0 && signalled) {
- X return E_TMOUT;
- X }
- X
- X if (buf_len < 0) return E_READ;
- X
- X if (!isprint(buf[pos - 1])) {
- X debugnonl("(0x%X)", buf[pos - 1]);
- X }
- X else {
- X debugnonl("%c", buf[pos - 1]);
- X }
- X
- X /* Check if any was right */
- X for(i = 0; i < N_MOD_CMDS; i++)
- X {
- X exp_len = strlen(mod_cmds[i]);
- X if (pos < exp_len) continue;
- X if (memcmp(mod_cmds[i], buf + pos - exp_len, exp_len) == 0) break;
- X }
- X if (i < N_MOD_CMDS)
- X {
- X buf[pos + 1] = 0;
- X debug("gotten(\"%s\")", cmd_str(i));
- X if (expected == MOD_ANY || expected == i)
- X {
- X /* Return what arrived if awaited for any */
- X if (expected == MOD_ANY) return i;
- X
- X /*
- X * Otherwise just return that what had been awaited for
- X * has arrived OK.
- X */
- X return E_OK;
- X }
- X }
- X }
- X
- X logerr("mod_exp: never got any sane answer from modem (%s)", buf);
- X return E_FAIL;
- X}
- X
- X/************************************************************************
- X *
- X * MOD_DIAL
- X * --------
- X * Description:
- X * Dials a number
- X *
- X * Arguments:
- X * prefix - Prefix telephone number, like '0w' to get external line.
- X * phone - The phone number.
- X *
- X ************************************************************************/
- mod_dial(char *prefix, char *phone)
- X{
- X int rc;
- X int i;
- X
- X /* Retry 3 times*/
- X for(i = 0; i < 5; i++)
- X {
- X /* Dialup */
- X mod_put("ATDT");
- X mod_put(prefix);
- X mod_put(phone);
- X mod_put("\r");
- X
- X /* Wait for answer */
- X switch(mod_exp(MOD_ANY, 15))
- X {
- X case MOD_CONNECT:
- X case MOD_CONNECT_1200:
- X case MOD_CONNECT_2400:
- X log("dialup: succeded to dial '%s'", phone);
- X return E_OK;
- X
- X case MOD_BUSY:
- X log("dialup: busy");
- X break;
- X
- X case MOD_NO_CARRIER:
- X logerr("dialup: no carrier for phone '%s'", phone);
- X }
- X }
- X}
- X
- X/*******************************************************************
- X *
- X * PROMPT
- X * ------
- X *
- X * Description:
- X * Writes prompt to port and reads line.
- X *
- X * Arguments:
- X * msg - Prompt message.
- X * dest - Where to store answer.
- X * size - Dont read more than this.
- X * tmout - Timeout, 0 means no timeout.
- X *
- X *******************************************************************/
- int prompt(char *msg, char *dest, int size, int tmout)
- X{
- X int i;
- X if (mod_put(msg) < 0)
- X {
- X logerr("prompt: failed to write to port");
- X return E_FAIL;
- X }
- X
- X trig(tmout);
- X size = tty_read(dest, size);
- X if (istimeout()) {
- X return E_TMOUT;
- X }
- X
- X if (size < 0) {
- X logerr("prompt: failed to read");
- X return E_READ;
- X }
- X
- X /* User pressed EOF */
- X if (size == 0)
- X {
- X mod_put(MSG_ABORTED);
- X return E_FAIL;
- X }
- X
- X /* Remove leading blanks */
- X for(i = 0; i < size && isspace(dest[i]); i++)
- X ;
- X
- X memcpy(dest, dest + i, size -= i);
- X
- X /* Remove trailing blanks */
- X for(i = size - 1; i >= 0 && isspace(dest[i]); i--,size --)
- X ;
- X
- X dest[i + 1] = 0;
- X
- X return E_OK;
- X}
- X
- X/***************************************
- X * Return ascii value for modem answers.
- X ***************************************/
- static char *cmd_str(int n)
- X{
- X if (n < 0 || n > N_MOD_CMDS) {
- X return "[unknown]";
- X }
- X
- X return mod_cmds[n];
- X}
- END_OF_FILE
- if test 6023 -ne `wc -c <'modem.c'`; then
- echo shar: \"'modem.c'\" unpacked with wrong size!
- fi
- # end of 'modem.c'
- fi
- if test -f 'modempool.1' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'modempool.1'\"
- else
- echo shar: Extracting \"'modempool.1'\" \(2338 characters\)
- sed "s/^X//" >'modempool.1' <<'END_OF_FILE'
- X.\" @(#)modempool.1 4.1
- X.TH MODEMPOOL 1V "920421"
- X.SH NAME
- modempool \- Program for handling modempools
- X.SH SYNOPSIS
- X.B modempool
- X[
- X.B \-d
- X]
- X[
- X.B \-p
- prefix
- X]
- X[
- X.B \-i
- initstring
- X]
- X.B speed line
- X.SH DESCRIPTION
- modempool is a program for handling a pool of modems. For each modem
- connected to the system there should be a modempool process running.
- All modempool processes communicate with each other and when a
- users calls one modem, the modempool server checks that the user is
- allowed to log in and then tells another modempool process to do the
- callback.
- This has the effect that only one modem phone number has to be known by
- the users, i.e. modempool works as a switchboard. Also users doesn't
- have to try to call different numbers until he finds a free line, modempool
- will do that for him.
- XFinally only one external telephone line has to exist, the other modems
- can sit on local lines but with the -p option set (usually to '0w').
- X.ne 8
- X.SH OPTIONS
- X.TP
- X.B \-d
- Turn on debugging mode. All output goes to the log-file.
- X.TP
- X.B \-p
- Specify what prefix to use before phonenumber. This usually is '0w' to
- get an external line on many switchboards.
- X.TP
- X.B \-i
- Specify initialization string for the modem. The default string is: 'AT&FQ0E0S0=1&D2&C1'
- but you may also try: 'AT&FQ0E0S0=1&D2&C1*G0&I0'.
- X.TP
- X.B speed
- This is the initial baudrate modempool will use.
- X.TP
- X.B line
- The is the name of the tty-device with the path '/dev/' removed,
- ex. tty00h.
- X.SH FILES
- X.PD 0
- X.TP 20
- X.B /etc/local/modempool/Users
- This is a list of users allowed to log in. Each row contains a couple
- of fields separated by colons. The first field is the user name, the second is
- his dialup password (don't use the real user password), the third field is a slash-separated
- list of valid phonenumbers for user (or asterisk for any number). The fourth field is
- the host to rlogin to when user loggs in (only if compiled with the -DRLOGIN flag).
- X.TP 20
- X.B /etc/local/modempool/Greetings
- Text to print when modempool is called.
- X.TP 20
- X.B /etc/local/modempool/serverdb
- Database file where all modempool servers register.
- X.TP 20
- X.B /etc/local/modempool/log
- Log of all users loggin in.
- X.TP 20
- X.B /etc/local/modempool/errlog
- Log of all errors detected by modempool.
- X.SH "SEE ALSO"
- X.PD
- X.BR poolstat (1V)
- X.br
- X.ne 5
- X.SH BUGS
- X.LP
- Currently only Hayes modems is supported.
- END_OF_FILE
- if test 2338 -ne `wc -c <'modempool.1'`; then
- echo shar: \"'modempool.1'\" unpacked with wrong size!
- fi
- # end of 'modempool.1'
- fi
- if test -f 'modempool.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'modempool.c'\"
- else
- echo shar: Extracting \"'modempool.c'\" \(5892 characters\)
- sed "s/^X//" >'modempool.c' <<'END_OF_FILE'
- X/*******************************************************************
- X *
- X * Module: @(#)modempool.c 4.2 92/04/16
- X *
- X * Description:
- X * Main file for the modempool daemon.
- X *
- X * Revision:
- X * Date By Reason
- X * ---- -- ------
- X * 910114 Lars Berntzon Created
- X * 910124 Lars H Carlsson Lock line before calling /bin/login
- X * 910129 Lars Berntzon Lockfile is removed at startup,
- X * lockfile would otherwise stay after
- X * user has logged out.
- X * 910129 Lars Berntzon Using termio to make port eightbit.
- X *
- X *******************************************************************/
- static char SccsId[] = "@(#)modempool.c 4.2 92/04/16";
- X
- X#include <stdio.h>
- X#ifndef NOSTDLIB
- X#include <stdlib.h>
- X#endif
- X#include <unistd.h>
- X#include <string.h>
- X#include <signal.h>
- X#include <fcntl.h>
- X#include <stdarg.h>
- X#include <termios.h>
- X#include <ctype.h>
- X
- X#include "modempool.h"
- X
- X#ifdef RLOGIN
- X#include <pwd.h>
- X#endif
- X
- X/*
- X * G l o b a l d e f i n i t i o n .
- X */
- char line[NAME_SIZE]; /* Line this server uses */
- char portname[NAME_SIZE]; /* Full pathname for this line */
- char prefix[NAME_SIZE]; /* Prefix for dialing, ex. '0W' */
- int signalled; /* Indicates that serves should dialup */
- int debug_lvl = 0; /* Of non zero debugging is one */
- char *initstr = INITSTRING; /* Modem initializing string */
- slot_t slot; /* Slot record for this server */
- X
- X
- X/*
- X * L o c a l s t u f f .
- X */
- static void hdl_signal(void);
- X
- X/*
- X * M a i n r o u t i n e .
- X */
- int
- main(int argc, char **argv)
- X{
- X char phone[NAME_SIZE]; /* User phone number */
- X char name[NAME_SIZE]; /* User name */
- X#ifdef RLOGIN
- X char host[NAME_SIZE]; /* Host name */
- X#endif
- X int baud = 0; /* Connected baudrate */
- X int default_baud; /* Default baudrate (command line arg) */
- X int fd; /* Port file descriptor */
- X int rc; /* Return code */
- X
- X /*
- X * Setup signals.
- X */
- X signal(SIGALRM, SIG_IGN);
- X signal(SIGCLD, SIG_IGN);
- X signal(SIGINT, SIG_IGN);
- X signal(SIGQUIT, SIG_IGN);
- X#ifdef SV_INTERRUPT
- X /*
- X * Use sigvec if exists.
- X */
- X {
- X struct sigvec vec;
- X vec.sv_handler = hdl_signal;
- X vec.sv_mask = 0;
- X vec.sv_flags = SV_INTERRUPT;
- X sigvec(SIG_SERVER, &vec, NULL);
- X }
- X#else
- X signal(SIG_SERVER, hdl_signal);
- X#endif
- X
- X /*
- X * Get commandline arguments.
- X */
- X getargs(&argc, &argv);
- X
- X /*
- X * Save args into globals
- X */
- X if ((default_baud = atoi(argv[1])) == 0) usage();
- X
- X strcpy(line, argv[2]);
- X sprintf(portname, "/dev/%s", line);
- X
- X chmod(portname, 0777);
- X
- X /*
- X * Make own processgroup, thereby make port as the controlling terminal.
- X */
- X#ifdef _POSIX_JOB_CONTROL
- X if (setsid() < 0) fatal("failed to setsid");
- X#else
- X if (setpgrp() < 0) fatal("failed to setpgrp");
- X#endif
- X
- X /*
- X * Allocate slot for this server in the server database (only once).
- X */
- X if (slot_alloc(&slot) != E_OK) {
- X fatal("failed to allocate slot");
- X }
- X
- X /*
- X * Output start message.
- X */
- X if (log("modempool started with %d baud", default_baud) != E_OK) {
- X fatal("failed to open log file");
- X }
- X
- X /*
- X * Loop through modem-setup and login-wait.
- X */
- X while(1)
- X {
- X /*
- X * Wait for port to become free.
- X */
- X lock_wait(line);
- X
- X /*
- X * Open port for seting up modem.
- X */
- X if (tty_open(portname, default_baud, O_NDELAY) != E_OK) {
- X logerr("failed to open main port");
- X slot.status = SLOT_FAULT;
- X slot_write(&slot);
- X sleep(5);
- X continue;
- X }
- X if (mod_setup() != E_OK) {
- X logerr("failed to setup modem");
- X slot.status = SLOT_FAULT;
- X slot_write(&slot);
- X tty_hangup();
- X tty_close();
- X continue;
- X }
- X
- X debug("modem setup ok");
- X
- X /*
- X * I will accept dialup command.
- X */
- X slot.status = SLOT_FREE;
- X slot_write(&slot);
- X
- X /*
- X * This open will hang until carrier detect ( = someone called),
- X * signalled or timeout.
- X */
- X tty_local(0);
- X trig(OPEN_TMOUT);
- X fd = open(portname, O_RDONLY);
- X if (fd < 0) {
- X if (!signalled) {
- X if (!istimeout()) {
- X logerr("failed to open port");
- X }
- X continue;
- X }
- X }
- X close(fd);
- X debug("port opened with no CLOCAL");
- X
- X /*
- X * If signalled it means i've got a phone number to dial.
- X */
- X if (signalled)
- X {
- X debug("signalled in tty_open, doing dialup");
- X dialup();
- X /*
- X * Should never get here - mark as free again.
- X */
- X log("dialup failed");
- X unlock_line(line);
- X slot_free(&slot);
- X tty_hangup();
- X tty_close();
- X continue;
- X }
- X
- X
- X /*
- X * Check if it's for me.
- X */
- X if (lock_line(line, getpid()) != E_OK) {
- X debug("line was not free");
- X continue;
- X }
- X debug("line was for me");
- X
- X /*
- X * Read commands from modem and take action.
- X */
- X while(1)
- X {
- X rc = mod_exp(MOD_ANY, RESET_TMOUT);
- X debug("got %d from modem", rc);
- X
- X /*
- X * Got signal, do dialup.
- X */
- X if (signalled) {
- X debug("signaled in mod_exp, doing dialup");
- X dialup();
- X log("dialup failed");
- X break;
- X }
- X
- X rc = hdl_connect(rc);
- X if (rc == E_RETRY) {
- X continue;
- X }
- X else {
- X break;
- X }
- X }
- X
- X slot_free(&slot);
- X unlock_line(line);
- X tty_hangup();
- X tty_close();
- X debug("restarting");
- X }
- X
- X logerr("modempool: slipped out of main loop");
- X exit(1);
- X}
- X
- X/**********************************************************
- X * H D L _ S I G N A L
- X * -------------------
- X *
- X * Description:
- X * This gets called when a server is told to dialup.
- X *
- X **********************************************************/
- static void hdl_signal(void)
- X{
- X#ifdef SV_INTERRUPT
- X /*
- X * Use sigvec if exists.
- X */
- X {
- X struct sigvec vec;
- X vec.sv_handler = hdl_signal;
- X vec.sv_mask = 0;
- X vec.sv_flags = SV_INTERRUPT;
- X sigvec(SIG_SERVER, &vec, NULL);
- X }
- X#else
- X signal(SIG_SERVER, hdl_signal);
- X#endif
- X
- X signalled = 1;
- X debug("(signalled)");
- X}
- END_OF_FILE
- if test 5892 -ne `wc -c <'modempool.c'`; then
- echo shar: \"'modempool.c'\" unpacked with wrong size!
- fi
- # end of 'modempool.c'
- fi
- if test -f 'modempool.h' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'modempool.h'\"
- else
- echo shar: Extracting \"'modempool.h'\" \(6494 characters\)
- sed "s/^X//" >'modempool.h' <<'END_OF_FILE'
- X/*******************************************************************
- X *
- X * Module: @(#)modempool.h 4.4 92/04/22
- X *
- X * Description:
- X * Header file fore the modempool package.
- X *
- X * Revision:
- X * Date By Reason
- X * ---- -- ------
- X * 910414 Lars Berntzon Created
- X *
- X *******************************************************************/
- X#include "patchlevel.h"
- X
- static char SccsId_modempool_h[] = "@(#)modempool.h 4.4 92/04/22";
- X
- X#ifndef _MODEMPOOL_H
- X#define _MODEMPOOL_H
- X
- X#ifdef DEBUG
- X# define USERS "Users"
- X# define LINES "Lines"
- X# define LOGFILE "log"
- X# define ERRLOGFILE "errlog"
- X# define GREETINGSFILE "Greetings"
- X# define GREETINGSFILE "Greetings"
- X# define SERVERDB "serverdb"
- X# define LOCKFILE "serverdb.lock"
- X#else
- X# define USERS "/etc/local/modempool/Users"
- X# define LINES "/etc/local/modempool/Lines"
- X# define LOGFILE "/etc/local/modempool/log"
- X# define ERRLOGFILE "/etc/local/modempool/errlog"
- X# define GREETINGSFILE "/etc/local/modempool/Greetings"
- X# define SERVERDB "/etc/local/modempool/serverdb"
- X# define LOCKFILE "/etc/local/modempool/serverdb.lock"
- X#endif
- X#define LOCKDIR "/usr/spool/locks"
- X
- X#define E_OK 0 /* No errors */
- X#define E_FAIL -1 /* Generic fail */
- X#define E_TMOUT -2 /* Got timeout */
- X#define E_SYNTAX -3 /* Syntax error */
- X#define E_OPEN -4 /* Failed to open file */
- X#define E_READ -5 /* Failed to read file */
- X#define E_WRITE -6 /* Failed to write file */
- X#define E_LOCK -7 /* Failed to lock */
- X#define E_UNLINK -8 /* Failed to unlink */
- X#define E_PROC_EXIST -9 /* Process alldready exist */
- X#define E_LOGIN -10 /* Failed to login */
- X#define E_NOTFOUND -11 /* Key not found */
- X#define E_EOF -12 /* Reached enf of file/data */
- X#define E_RETRY -13 /* Not completely wrong, try again */
- X
- X#define INITSTRING "AT&FQ0E0S0=1&D2&C1\r" /* Modem init string */
- X
- X
- X/*
- X * Various messages to user.
- X */
- X#define MSG_LOGIN "login: "
- X#define MSG_NAME "Name: "
- X#define MSG_PASSWD "Password: "
- X#define MSG_ABORTED "login aborted\r\n"
- X#define MSG_LOGINFAIL "login failed\r\n"
- X#define MSG_HANGUP "hanging up\r\n"
- X#define MSG_TIMEOUT "timed out\r\n"
- X#define MSG_CALLING "I will call you back, hang on.\r\n"
- X#define MSG_NOLINES "There are currently no free lines.\r\n"
- X#define MSG_USAGE "usage: modempool [-p prefix] [-i initstr] [-d] speed ttyxx\r\n"
- X#define MSG_PHONE "Phone: "
- X
- X/*
- X * Return codes and arguments to/from mod_exp.
- X */
- X#define MOD_ANY 0 /* Wait for any of the below */
- X#define MOD_CONNECT 1
- X#define MOD_CONNECT_300 2
- X#define MOD_CONNECT_1200 3
- X#define MOD_CONNECT_2400 4
- X#define MOD_RING 5
- X#define MOD_BUSY 6
- X#define MOD_ERRO 7
- X#define MOD_NO_CARRIER 8
- X#define MOD_OK 9
- X#define MOD_CONNECT_4800 10
- X#define MOD_CONNECT_9600 11
- X
- X#define NAME_SIZE 200 /* Generic string size */
- X#define MATCH_SIZE 400 /* Maximum size of expected data from modem */
- X#define MAX_RETRY 3
- X#define OPEN_TMOUT (10*60) /* Timeout for opening the tty port */
- X#define LOGIN_TMOUT 30 /* Timeout for login */
- X#define MODEM_TMOUT 1 /* Default timeout for avaiting modem answer */
- X#define RESET_TMOUT 180 /* Interval for resetting modem when waiting */
- X#define DIALUP_TMOUT 60 /* Time for dialing a number */
- X#define DIALUP_DELAY 15 /* Time to wait before dialing */
- X#ifdef RLOGIN
- X#define N_FIELDS 4 /* Number if valid fields in user database */
- X#else
- X#define N_FIELDS 3
- X#endif
- X
- X#define SLOT_FREE 0 /* Server is free for allocation */
- X#define SLOT_BUSY 1 /* Server is busy dialing person */
- X#define SLOT_LOGIN 2 /* Server is handling login */
- X#define SLOT_FAULT 3 /* Server has detected fault */
- X
- X#define SIG_SERVER SIGUSR1
- X
- X/*
- X * Types and structs.
- X */
- X
- struct slot {
- X int id; /* Id for this slot */
- X char line[15]; /* Line this server controls */
- X char name[30]; /* Synonym for calling person */
- X#ifdef RLOGIN
- X char host[20]; /* Host for rlogin. */
- X#endif
- X int status; /* Status of server, SLOT_FREE e.t.c. */
- X int pid; /* pid of server */
- X char phone[15]; /* Phone number this server should dial */
- X int baud; /* What baud to use when dialing */
- X};
- typedef struct slot slot_t; /* Type for slots */
- X
- X/*
- X * Globals.
- X */
- extern char line[NAME_SIZE]; /* Name port this program is using */
- extern char portname[NAME_SIZE];/* Full pathname of port */
- extern char prefix[NAME_SIZE]; /* Prefix string before phone number */
- extern slot_t slot; /* Slotid for this server in serverdb */
- extern int signalled; /* Tells server it should dial a number */
- extern int port_fd; /* File descriptor for open port */
- extern int debug_lvl; /* Nonzero if debugging is active */
- extern char *initstr; /* Modem initializing string */
- X
- X/* support routines */
- extern int debug(char *fmt, ...);
- extern int debugnonl(char *fmt, ...);
- extern int log(char *fmt, ...);
- extern int logerr(char *fmt, ...);
- extern void fatal(char *msg);
- extern void usage(void);
- extern int trig(int tmout);
- extern int istimeout(void);
- X
- X/* db routines */
- extern int db_find(char *file, char **ptrs, int n_ptrs,int key, char *key_val);
- X
- X/* mod routines */
- extern mod_put(char *msg);
- extern mod_exp(int cmd, int tmout);
- extern mod_dial(char *prefix, char *phone);
- extern int mod_setup(void);
- X
- X/* slot routines */
- extern int slot_alloc(slot_t *sp);
- extern int slot_free(slot_t *sp);
- extern int slot_open(void);
- extern int slot_close(void);
- extern int slot_traverse(slot_t *sp);
- extern int slot_read(slot_t *sp);
- extern int slot_write(slot_t *sp);
- extern int slot_lock(void);
- extern int slot_unlock(void);
- X
- X/* tty routines */
- extern int tty_open(char *filename, int baud, int flags);
- extern int tty_close(void);
- extern int tty_read(char *buf, int len);
- extern int tty_write(char *buf, int len);
- extern int tty_ndelay(int on);
- extern int tty_hangup(void);
- extern int tty_raw(void);
- extern int tty_sane(void);
- extern int tty_baud(int baud);
- extern int tty_setup(void);
- extern int tty_clocal(void);
- extern int tty_echo(void);
- extern int tty_noecho(void);
- extern int tty_drain(void);
- extern int tty_flush(void);
- X
- X/* lock routines */
- extern int lock_line(char *line, int pid);
- extern int unlock_line(char *line);
- extern int relock_line(char *line);
- extern int lock_wait(char *line);
- X
- X/* getargs */
- extern int getargs(int *argc, char ***argv);
- X
- X/* dialup and login routines */
- extern int do_login(slot_t *sp);
- extern int callback(slot_t *sp);
- X
- X#endif /* _MODEMPOOL_H */
- END_OF_FILE
- if test 6494 -ne `wc -c <'modempool.h'`; then
- echo shar: \"'modempool.h'\" unpacked with wrong size!
- fi
- # end of 'modempool.h'
- fi
- if test -f 'modempool.te' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'modempool.te'\"
- else
- echo shar: Extracting \"'modempool.te'\" \(4253 characters\)
- sed "s/^X//" >'modempool.te' <<'END_OF_FILE'
- X% @(#)modempool.te 4.4 92/04/21 - Modempool.
- X\newcommand{\modempool}{{\em modempool\ }}
- X\documentstyle{article}
- X\begin{document}
- X
- X\title{Modempool}
- X\author{Lars Berntzon}
- X\maketitle
- X
- X\section*{Description}
- X
- Modempool is a modem server that does a security check of a calling user and then calls that
- user back if he/she is permitted.
- Modempool works in two modes simultaniously, either it is listening for
- incomming calls, or it will dial up a user if another \modempool server tells
- it to do so.
- X
- When the first connection is made to the \modempool server the user will be
- prompted for name and password, if not OK the user is disconnected and
- a logg record is written.
- otherwise \modempool will check the file {\em /etc/local/modempool/Users} to see
- what phone number to use for calling the user, it then looks up another free
- modempool server whom it tells to dialup the user, i.e. it does not call the user it
- self but order another server to do so, the reason for this is that it enables
- this port to be used again for a new connection.
- X
- This functionality is usefull for instance for sites that lacks many external phone numbers,
- but instead has many local lines that cannot be dialed from outside but can only be used for
- dialing out.
- X
- Also it simplifies the administration of a modempool by having only one known telephone
- number that everyone dials.
- X
- When the \modempool server is called it checks the connection baudrate and sets the
- terminal port to that speed. This makes it possible to have cheap modems and still handle
- multiple baudrate dialups. When the user later on is called the same baudrate will be used.
- X
- The way a serve finds out other free servers is done by looking in the file
- X{\em /etc/local/modempool/serverdb} where all servers should present it self.
- X
- X
- The program psc can be used to see how the lines is currently being used.
- Output will be in the format:
- X\begin{quote}
- LINE PID STATUS PHONE BAUD NAME (HOST)
- X\end{quote}
- where
- X\begin{description}
- X \item[Line] The /dev/ttyxx line
- X \item[Pid] Process id of \modempool server
- X \item[Status] Either free, busy, fault or login.
- X \item[Phone] If server is busy, this is the dialed phone number.
- X \item[Baud] If server if busy, it is running in this baudrate.
- X \item[Name] Name of calling user. This is not the userid on the system but the
- X the name used for the \modempool server.
- X \item[Host] This is only used if \modempool has been compiled with the -DRLOGIN option
- X and tells what host the user is connected to.
- X\end{description}
- X
- The user database {\em /etc/local/modempool/Users} looks like the passwd file and has the
- following records:
- X\begin{quote}
- X user:password:phone:[host]
- X\end{quote}
- where
- X\begin{description}
- X \item[user] Name of the user, it should not be user-id on the system but rather
- X a pseudonym.
- X \item[password] A unencrypted password for user to enter when \modempool server asks. Don't
- X users real Unix password.
- X \item[phone] Telephone number for user. This can also be a slash-separated list
- X of valid phonenumbers in which case the user will be prompted for
- X which of the numbers to use.
- X
- X The special number {\em *} can be used
- X to permit any number. In this case a special record is written to the
- X log, also here the user is prompted for number.
- X \item[host] If \modempool is compiled with the -DRLOGIN option this field should
- X specify what host the user should be logged into.
- X\end{description}
- X
- X\section*{Installation}
- If you want modempool to automatically login users on their own (or other) machine,
- the flag -DRLOGIN must also be set in CFLAGS.
- After that you just type {\em make}
- X
- X
- If everything goes well you should now install it into the {\em /etc/local/modempool} directory by
- doing {\em make install}.
- XFinally you should modify your initab or ttytab to start modempool for the connected modems.
- X
- Arguments to modempool is as follows:
- X\begin{description}
- X\item[-p prefix] Specifies a prefix to prepend to telephone number, ex. 0w to get
- X a external line on many switchboards.
- X\item[-i initstr] Specifies a alternate modem initiation string.
- X\item[-d] Turn on debugging.
- X\item[tty] Specifies the modem tty device.
- X\end{description}
- X
- X\end{document}
- END_OF_FILE
- if test 4253 -ne `wc -c <'modempool.te'`; then
- echo shar: \"'modempool.te'\" unpacked with wrong size!
- fi
- # end of 'modempool.te'
- fi
- if test -f 'patchlevel.h' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'patchlevel.h'\"
- else
- echo shar: Extracting \"'patchlevel.h'\" \(177 characters\)
- sed "s/^X//" >'patchlevel.h' <<'END_OF_FILE'
- X/*
- X * @(#)patchlevel.h 4.2 92/04/22 - Current release level.
- X */
- X#define PATCHLEVEL "4"
- X#ifndef lint
- static char SccsId_patchlevel_h[] = "@(#)patchlevel.h 4.2 92/04/22";
- X#endif
- END_OF_FILE
- if test 177 -ne `wc -c <'patchlevel.h'`; then
- echo shar: \"'patchlevel.h'\" unpacked with wrong size!
- fi
- # end of 'patchlevel.h'
- fi
- if test -f 'poolstat.1' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'poolstat.1'\"
- else
- echo shar: Extracting \"'poolstat.1'\" \(480 characters\)
- sed "s/^X//" >'poolstat.1' <<'END_OF_FILE'
- X.\" @(#)poolstat.1 4.1
- X.TH POOLSTAT 1V "920421"
- X.SH NAME
- poolstat \- print status of the modempool
- X.SH SYNOPSIS
- X.B poolstat
- X.SH DESCRIPTION
- This command reads the modempool server database and prints each servers status.
- Status can be one of 'free', 'login', 'busy' or 'fail'.
- If status is fail check the errlog-file.
- X.ne 8
- X.SH FILES
- X.PD 0
- X.TP 20
- X.B /etc/local/modempool/serverdb
- Where all modempool servers register.
- X.SH "SEE ALSO"
- X.PD
- X.BR modempool (1V)
- X.br
- X.ne 5
- X.SH BUGS
- X.LP
- END_OF_FILE
- if test 480 -ne `wc -c <'poolstat.1'`; then
- echo shar: \"'poolstat.1'\" unpacked with wrong size!
- fi
- # end of 'poolstat.1'
- fi
- if test -f 'poolstat.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'poolstat.c'\"
- else
- echo shar: Extracting \"'poolstat.c'\" \(1579 characters\)
- sed "s/^X//" >'poolstat.c' <<'END_OF_FILE'
- X/********************************************************************
- X *
- X * Module: @(#)poolstat.c 4.2 92/04/16
- X *
- X * Description:
- X * Lists status of all callback lines, uses the server data base file
- X * calltmp
- X *
- X * Revision:
- X * Ver Date By Reason
- X * --- ---- -- ------
- X * 1 910118 Lars Berntzon Created
- X *
- X ********************************************************************/
- static char SccsId[] = "@(#)poolstat.c 4.2 92/04/16";
- X#include <stdio.h>
- X#include "modempool.h"
- X
- main()
- X{
- X#ifdef RLOGIN
- X static char headfmt[] = "%-15s %-5s %-10s %-15s %-5s %-8s %s\n";
- X static char realfmt[] = "%-15s %-5d %-10s %-15s %-5d %-8s %s\n";
- X#else
- X static char headfmt[] = "%-15s %-5s %-10s %-15s %-5s %-8s\n";
- X static char realfmt[] = "%-15s %-5d %-10s %-15s %-5d %-8s\n";
- X#endif
- X struct slot slot;
- X char *status;
- X int fd;
- X
- X if ((fd = open(SERVERDB, 0)) < 0) {
- X fprintf(stderr, "failed to open server database\n");
- X exit(1);
- X }
- X
- X printf(headfmt, "LINE", "PID", "STATUS", "PHONE", "BAUD", "NAME"
- X#ifdef RLOGIN
- X ,"HOST"
- X#endif
- X );
- X while(read(fd, &slot, sizeof slot) == sizeof slot) {
- X if (kill(slot.pid, 0) >= 0) {
- X switch (slot.status) {
- X case SLOT_FREE:
- X status = "free";
- X break;
- X case SLOT_BUSY:
- X status = "busy";
- X break;
- X case SLOT_LOGIN:
- X status = "login";
- X break;
- X case SLOT_FAULT:
- X status = "fault";
- X break;
- X default:
- X status = "(unknown)";
- X }
- X printf(realfmt, slot.line, slot.pid, status,
- X slot.phone, slot.baud, slot.name
- X#ifdef RLOGIN
- X ,slot.host
- X#endif
- X );
- X }
- X }
- X}
- END_OF_FILE
- if test 1579 -ne `wc -c <'poolstat.c'`; then
- echo shar: \"'poolstat.c'\" unpacked with wrong size!
- fi
- # end of 'poolstat.c'
- fi
- if test -f 'slot.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'slot.c'\"
- else
- echo shar: Extracting \"'slot.c'\" \(7868 characters\)
- sed "s/^X//" >'slot.c' <<'END_OF_FILE'
- X/*******************************************************************
- X *
- X * Module: @(#)slot.c 4.2 92/04/16
- X *
- X * Description:
- X * Handle server database functions.
- X *
- X * Revision:
- X * Date By Reason
- X * ---- -- ------
- X * 920306 Lars Berntzon Created
- X *
- X *******************************************************************/
- static char SccsId[] = "@(#)slot.c 4.2 92/04/16";
- X
- X#include <stdio.h>
- X#include <string.h>
- X#include <stdarg.h>
- X#include <fcntl.h>
- X#include <errno.h>
- X
- X#include "modempool.h"
- X
- X/*
- X * Local stuff.
- X */
- static int slot_fd = -1;
- static int lock_cnt = 0;
- X
- X/*******************************************************************
- X * S L O T _ A L L O C
- X * -------------------
- X *
- X * Description:
- X * Find a free server slot and allocate it.
- X *
- X * Return:
- X * id of allocated slot.
- X *
- X *******************************************************************/
- int
- slot_alloc(slot_t *sp)
- X{
- X int id;
- X
- X if (sp == NULL) {
- X logerr("slot_alloc: programming error: slot = NULL");
- X return E_FAIL;
- X }
- X
- X if (slot_open() != E_OK) {
- X return E_FAIL;
- X }
- X
- X slot_lock();
- X
- X for(sp->id = 0; read(slot_fd, sp, sizeof *sp) == sizeof *sp; sp->id++) {
- X /* If process owning slot does not exists do break */
- X if (kill(sp->pid, 0) < 0) break;
- X }
- X
- X /* Fill in data */
- X slot_free(sp);
- X
- X slot_unlock();
- X
- X slot_close();
- X
- X return E_OK;
- X}
- X
- X/*******************************************************************
- X * S L O T _ F R E E
- X * -----------------
- X *
- X * Description:
- X * Empty and free a slot.
- X *
- X * Arguments:
- X * sp - slot.
- X *
- X *******************************************************************/
- int
- slot_free(slot_t *sp)
- X{
- X /*
- X * Check args.
- X */
- X if (sp == NULL) {
- X logerr("slot_free: programming error: sp = NULL");
- X return E_FAIL;
- X }
- X
- X slot_lock();
- X
- X strncpy(sp->line, line, sizeof sp->line);
- X sp->pid = getpid();
- X strncpy(sp->phone, "", sizeof sp->phone);
- X strncpy(sp->name, "", sizeof sp->name);
- X#ifdef RLOGIN
- X strncpy(sp->host, "", sizeof sp->host);
- X#endif
- X sp->status = SLOT_FREE;
- X sp->baud = 0;
- X slot_write(sp);
- X
- X slot_unlock();
- X}
- X
- X/*******************************************************************
- X * S L O T _ O P E N
- X * -----------------
- X *
- X * Description:
- X * Open server database file.
- X *
- X * Return:
- X * E_OK or E_FAIL
- X *
- X *******************************************************************/
- int
- slot_open(void)
- X{
- X /*
- X * If allready opened, just rewind.
- X */
- X if (slot_fd >= 0) {
- X lseek(slot_fd, 0, 0);
- X return E_OK;
- X }
- X
- X if ((slot_fd = open(SERVERDB, O_RDWR)) < 0 &&
- X (slot_fd = open(SERVERDB, O_RDWR | O_CREAT, 0777)) < 0) {
- X logerr("slot_open: failed");
- X return E_FAIL;
- X }
- X
- X return E_OK;
- X}
- X
- X/*******************************************************************
- X * S L O T _ C L O S E
- X * -------------------
- X *
- X * Description:
- X * Close server database file.
- X *
- X *******************************************************************/
- int
- slot_close(void)
- X{
- X if (slot_fd < 0) return E_OK;
- X close(slot_fd);
- X slot_fd = -1;
- X
- X return E_OK;
- X}
- X
- X/*******************************************************************
- X * S L O T _ F I N D
- X * -----------------
- X *
- X * Description:
- X * Read next slot from server database.
- X *
- X * Argument:
- X * sp - Pointer to slot struct to receive data.
- X *
- X * Return:
- X * E_OK or E_FAIL
- X *
- X *******************************************************************/
- int
- slot_traverse(slot_t *sp)
- X{
- X int rc;
- X
- X if (sp == NULL) {
- X logerr("slot_find: programming error: sp = NULL");
- X return E_FAIL;
- X }
- X
- X
- X /*
- X * Read next slot.
- X */
- X slot_lock();
- X while ((rc = read(slot_fd, sp, sizeof *sp)) == sizeof *sp)
- X {
- X /*
- X * If server alive, slot is found.
- X */
- X if (kill(sp->pid, 0) >= 0) {
- X break;
- X }
- X }
- X slot_unlock();
- X
- X if (rc < 0) {
- X logerr("slot_find: failed to read slot");
- X return E_FAIL;
- X }
- X
- X if (rc != sizeof *sp) {
- X return E_EOF;
- X }
- X
- X return E_OK;
- X}
- X
- X/*******************************************************************
- X * S L O T _ R E A D
- X * -----------------
- X *
- X * Description:
- X * Read data from slot number.
- X *
- X * Arguments:
- X * sp - Slot pointer where data goes.
- X *
- X * Return:
- X * E_OK or E_FAIL
- X *
- X *******************************************************************/
- int
- slot_read(slot_t *sp)
- X{
- X int rc;
- X
- X if (sp == NULL) {
- X logerr("slot_read: programming error: sp = NULL");
- X return E_FAIL;
- X }
- X
- X slot_lock();
- X slot_open();
- X lseek(slot_fd, sp->id * sizeof *sp, 0);
- X rc = read(slot_fd, sp, sizeof *sp);
- X slot_close();
- X slot_unlock();
- X
- X if (rc != sizeof *sp)
- X {
- X logerr("slot_read: failed for slot #%d", sp->id);
- X return E_FAIL;
- X }
- X debug("slot_read: ok");
- X
- X return E_OK;
- X}
- X
- X/*******************************************************************
- X * S L O T _ W R I T E
- X * -------------------
- X *
- X * Description:
- X * Write data from slot into file.
- X *
- X * Arguments:
- X * sp - Pointer to slot data.
- X *
- X * Return:
- X * E_OK or E_FAIL
- X *
- X *******************************************************************/
- int
- slot_write(slot_t *sp)
- X{
- X int rc;
- X if (sp == NULL) {
- X logerr("slot_write: programming error: sp = NULL");
- X return E_FAIL;
- X }
- X
- X slot_lock();
- X slot_open();
- X lseek(slot_fd, sp->id * sizeof *sp, 0);
- X rc = write(slot_fd, sp, sizeof *sp);
- X slot_close();
- X slot_unlock();
- X
- X if (rc != sizeof *sp)
- X {
- X logerr("slot_write: failed for slot #%d", sp->id);
- X return E_FAIL;
- X }
- X debug("slot_write: ok");
- X
- X return E_OK;
- X}
- X
- X/*******************************************************************
- X * S L O T _ L O C K
- X * -----------------
- X *
- X * Description:
- X * Lock the server database file, this to keep two
- X * server to update the file simultaniously. It also allows
- X * recursive locks. If this routine is called twise without
- X * calling slot_unlock a countr keeps track of the depth.
- X *
- X * Return:
- X * E_OK or E_FAIL.
- X *
- X *******************************************************************/
- int
- slot_lock(void)
- X{
- X int retry;
- X int fd;
- X
- X /*
- X * Alloc recursive slot locks.
- X */
- X if (lock_cnt++ > 0) {
- X debug("slot_lock: incrementing lock count");
- X return E_OK;
- X }
- X
- X /*
- X * Lock calltmp, if not succeded in half max tries, remove the lock.
- X * Thereafter try 5 times more to lock file.
- X */
- X for(retry = 0; retry < 10; retry++)
- X {
- X if ((fd = open(LOCKFILE, O_CREAT | O_EXCL, 0777)) >= 0)
- X {
- X debug("slot_lock: locked slot");
- X close(fd);
- X return E_OK;
- X }
- X
- X if (errno != EEXIST)
- X {
- X logerr("slot_lock: failed to create lockfile (errno = %d)", errno);
- X return E_FAIL;
- X }
- X
- X /*
- X * When tried half the times, remove the lockfile.
- X */
- X if (retry == 5) {
- X if (unlink(LOCKFILE) != 0) {
- X logerr("slot_lock: failed to unlink lockfile");
- X }
- X debug("slot_lock: forcibly removed lockfile");
- X }
- X
- X sleep(1);
- X debug("slot_lock: retrying");
- X }
- X
- X logerr("slot_lock: never succeded to lock file");
- X return E_FAIL;
- X}
- X
- X/*******************************************************************
- X * S L O T _ U N L O C K
- X * ---------------------
- X *
- X * Description:
- X * Unlock the server database. If the database has been locked
- X * more than once, a counter is just decremented.
- X *
- X * Return:
- X * E_OK or E_FAIL.
- X *
- X *******************************************************************/
- int
- slot_unlock(void)
- X{
- X /*
- X * Check if allready unlocked.
- X */
- X if (lock_cnt <= 0) {
- X debug("slot_unlock: slot allready unlocked");
- X return E_OK;
- X }
- X
- X /*
- X * Check for recursive locks.
- X */
- X if (--lock_cnt > 0) {
- X debug("slot_unlock: more locks exists");
- X return E_OK;
- X }
- X
- X /*
- X * Do unlocking.
- X */
- X if (unlink(LOCKFILE) != 0) {
- X logerr("slot_unlock: failed to remove lockfile (errno = %d)", errno);
- X return E_FAIL;
- X }
- X debug("slot_unlock: slot unlocked");
- X
- X return E_OK;
- X}
- END_OF_FILE
- if test 7868 -ne `wc -c <'slot.c'`; then
- echo shar: \"'slot.c'\" unpacked with wrong size!
- fi
- # end of 'slot.c'
- fi
- if test -f 'support.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'support.c'\"
- else
- echo shar: Extracting \"'support.c'\" \(4481 characters\)
- sed "s/^X//" >'support.c' <<'END_OF_FILE'
- X/*******************************************************************
- X *
- X * Module: @(#)support.c 4.2
- X *
- X * Description:
- X * Handle various low level functions.
- X *
- X * Revision:
- X * Date By Reason
- X * ---- -- ------
- X * 910414 Lars Berntzon Created
- X * 910124 Lars H Carlsson Changed pid format to %10d\n
- X * 910124 Lars H Carlsson Changed mode of lockfile to 0444
- X * 910129 Lars Berntzon Changed to termio for eightbit tty.
- X * 910224 Lars Berntzon Newline right when loggin in.
- X * 910227 Lars Berntzon The loggfile now reopens everytime.
- X *
- X *******************************************************************/
- static char SccsId[] = "@(#)support.c 4.2 92/04/16";
- X
- X#include <sys/types.h>
- X#include <time.h>
- X#include <stdio.h>
- X#include <string.h>
- X#include <signal.h>
- X#include <setjmp.h>
- X#include <ctype.h>
- X#include <stdarg.h>
- X#include <errno.h>
- X
- X#include "modempool.h"
- X
- X/* L o c a l s t u f f */
- static void call_env(int sig); /* Signal handler */
- static char *curtime(); /* Gev current time in ascii */
- static jmp_buf env; /* Timeout longjump buffer */
- static int tmout_flag = 0; /* true if timeout occured */
- static int active_timeout = 0; /* If trig is in action */
- X
- X/*
- X * Routines.
- X */
- void fatal(char *msg)
- X{
- X logerr("fatal error: %s", msg);
- X exit(1);
- X}
- X
- void usage(void)
- X{
- X fatal(MSG_USAGE);
- X}
- X
- static int unctrl(FILE *fp, char *str)
- X{
- X int i;
- X
- X /* Write output */
- X for(i = 0; str[i] != 0; i++) {
- X if (str[i] == '\r') fputs("\\r", fp);
- X else if (str[i] == '\n') fputs("\\n", fp);
- X else fputc(str[i], fp);
- X }
- X
- X return E_OK;
- X}
- X
- int debug(char *fmt, ...)
- X{
- X FILE *fp = NULL;
- X va_list arg;
- X char str[300];
- X
- X if(debug_lvl == 0) return E_OK;
- X
- X /* Open logfile */
- X if ((fp = fopen(LOGFILE, "a")) == NULL) return E_FAIL;
- X
- X va_start(arg, fmt);
- X vsprintf(str, fmt, arg);
- X#ifdef DEBUG
- X unctrl(stdout, str);
- X fputs("\n\r", stdout);
- X#endif
- X unctrl(fp, str);
- X fputc('\n', fp);
- X
- X fclose(fp);
- X
- X return E_OK;
- X}
- X
- int debugnonl(char *fmt, ...)
- X{
- X FILE *fp = NULL;
- X va_list arg;
- X char str[300];
- X
- X if(debug_lvl == 0) return E_OK;
- X
- X /* Open logfile */
- X if ((fp = fopen(LOGFILE, "a")) == NULL) return E_FAIL;
- X
- X va_start(arg, fmt);
- X vsprintf(str, fmt, arg);
- X#ifdef DEBUG
- X unctrl(stdout, str);
- X#endif
- X unctrl(fp, str);
- X
- X fclose(fp);
- X
- X return E_OK;
- X}
- X
- int log(char *fmt, ...)
- X{
- X FILE *fp = NULL;
- X va_list arg;
- X
- X /* Open logfile */
- X if ((fp = fopen(LOGFILE, "a")) == NULL) return E_FAIL;
- X
- X /* Write output */
- X fprintf(fp, "%s %s: ", curtime(), line);
- X va_start(arg, fmt);
- X#ifdef DEBUG
- X vfprintf(stdout, fmt, arg);
- X fprintf(stdout, "\n\r");
- X#endif
- X vfprintf(fp, fmt, arg);
- X fprintf(fp, "\n");
- X
- X fclose(fp);
- X
- X return E_OK;
- X}
- X
- int logerr(char *fmt, ...)
- X{
- X static FILE *fp = NULL;
- X va_list arg;
- X
- X /* Open logfile */
- X if ((fp = fopen(ERRLOGFILE, "a")) == NULL) return E_FAIL;
- X
- X /* Write output */
- X fprintf(fp, "%s %s: ", curtime(), line);
- X va_start(arg, fmt);
- X#ifdef DEBUG
- X vfprintf(stdout, fmt, arg);
- X fprintf(stdout, "\n\r");
- X#endif
- X vfprintf(fp, fmt, arg);
- X fprintf(fp, "\n");
- X
- X fclose(fp);
- X
- X /*
- X * If program hangs, prevent it from filling the filesystem (in short time)
- X */
- X sleep(1);
- X
- X return E_OK;
- X}
- X
- static char *curtime()
- X{
- X static char buf[50];
- X time_t t;
- X struct tm *tm;
- X
- X /* Get time */
- X t = time(NULL);
- X tm = localtime(&t);
- X sprintf(buf, "%02d%02d%02d %02d:%02d:%02d",
- X tm->tm_year,
- X tm->tm_mon + 1,
- X tm->tm_mday,
- X tm->tm_hour,
- X tm->tm_min,
- X tm->tm_sec);
- X
- X return buf;
- X}
- X
- static void
- call_env(int sig)
- X{
- X#ifdef SV_INTERRUPT
- X /*
- X * Use sigvec if exists.
- X */
- X {
- X struct sigvec vec;
- X vec.sv_handler = SIG_IGN;
- X vec.sv_mask = 0;
- X vec.sv_flags = SV_INTERRUPT;
- X sigvec(SIGALRM, &vec, NULL);
- X }
- X#else
- X signal(SIGALRM, SIG_IGN);
- X#endif
- X tmout_flag = 1;
- X active_timeout = 0;
- X}
- X
- int
- trig(int tmout)
- X{
- X tmout_flag = 0;
- X active_timeout = 1;
- X#ifdef SV_INTERRUPT
- X /*
- X * Use sigvec if exists.
- X */
- X {
- X struct sigvec vec;
- X vec.sv_handler = call_env;
- X vec.sv_mask = 0;
- X vec.sv_flags = SV_INTERRUPT;
- X sigvec(SIGALRM, &vec, NULL);
- X }
- X#else
- X signal(SIGALRM, call_env);
- X#endif
- X alarm(tmout);
- X}
- X
- int
- istimeout(void)
- X{
- X int ret;
- X
- X alarm(0);
- X active_timeout = 0;
- X ret = tmout_flag;
- X tmout_flag = 0;
- X
- X return ret;
- X}
- END_OF_FILE
- if test 4481 -ne `wc -c <'support.c'`; then
- echo shar: \"'support.c'\" unpacked with wrong size!
- fi
- # end of 'support.c'
- fi
- if test -f 'termios.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'termios.c'\"
- else
- echo shar: Extracting \"'termios.c'\" \(808 characters\)
- sed "s/^X//" >'termios.c' <<'END_OF_FILE'
- X/*
- X * Module:
- X * T E R M I O S
- X *
- X * Description:
- X * Emulate termios function.
- X *
- X */
- static char SccsId[] = "@(#)termios.c 4.2 92/04/16";
- X
- X#include <sys/types.h>
- X#include <termio.h>
- X
- int cfsetispeed(struct termio *ttybuf, int baud)
- X{
- X return 0;
- X}
- X
- int cfsetospeed(struct termio *ttybuf, int baud)
- X{
- X ttybuf->c_cflag &= ~CBAUD;
- X ttybuf->c_cflag |= (baud & CBAUD);
- X return 0;
- X}
- X
- int tcflush(int fd, int mode)
- X{
- X return ioctl(fd, TCFLSH, 2);
- X return 0;
- X}
- X
- int tcdrain(int fd)
- X{
- X sleep(3);
- X return 0;
- X}
- X
- int tcgetattr(int fd, struct termio *buf)
- X{
- X if(ioctl(fd, TCGETA, buf) != 0) {
- X perror("ioclt(TCGETA)");
- X return -1;
- X }
- X return 0;
- X}
- X
- int tcsetattr(int fd, int mode, struct termio *buf)
- X{
- X if(ioctl(fd, TCSETA, buf) != 0) {
- X perror("ioclt(TCSETA)");
- X return -1;
- X }
- X}
- X
- END_OF_FILE
- if test 808 -ne `wc -c <'termios.c'`; then
- echo shar: \"'termios.c'\" unpacked with wrong size!
- fi
- # end of 'termios.c'
- fi
- if test -f 'termios.h' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'termios.h'\"
- else
- echo shar: Extracting \"'termios.h'\" \(131 characters\)
- sed "s/^X//" >'termios.h' <<'END_OF_FILE'
- X#include <termio.h>
- X#define TCIFLUSH 0 /* Dummy */
- X#define TCSADRAIN 0
- X#define TCSANOW 0
- X#define termios termio /* Dangerous */
- END_OF_FILE
- if test 131 -ne `wc -c <'termios.h'`; then
- echo shar: \"'termios.h'\" unpacked with wrong size!
- fi
- # end of 'termios.h'
- fi
- if test -f 'tty.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'tty.c'\"
- else
- echo shar: Extracting \"'tty.c'\" \(8930 characters\)
- sed "s/^X//" >'tty.c' <<'END_OF_FILE'
- X/*******************************************************************
- X *
- X * Module: @(#)tty.c 4.2 92/04/16
- X *
- X * Description:
- X * Handle various tty functions.
- X *
- X * Revision:
- X * Date By Reason
- X * ---- -- ------
- X * 920306 Lars Berntzon Created
- X *
- X *******************************************************************/
- static char SccsId[] = "@(#)tty.c 4.2 92/04/16";
- X
- X#include <stdio.h>
- X#include <string.h>
- X#include <fcntl.h>
- X#include <errno.h>
- X#include <termios.h>
- X
- X#include "modempool.h"
- X
- X/* L o c a l s t u f f */
- static int port = -1;
- X
- X/*******************************************************************
- X * T T Y _ O P E N
- X * ---------------
- X *
- X * Description:
- X * Open ttyport and set it right.
- X *
- X * Arguments:
- X * filename - filename of tty device.
- X * baud - Initial baudrate.
- X * flags - Special flags like N_DELAY.
- X *
- X *******************************************************************/
- int
- tty_open(char *filename, int baud, int flags)
- X{
- X
- X /*
- X * If allready open, close it first.
- X */
- X if (port >= 0) {
- X tty_close();
- X }
- X
- X /*
- X * Open with timeout.
- X */
- X trig(OPEN_TMOUT);
- X port = open(filename, O_RDWR | flags);
- X if(istimeout()) {
- X return E_TMOUT;
- X }
- X
- X if (port < 0) {
- X logerr("tty_open: cant open port with flags %d: errno %d", flags, errno);
- X return -1;
- X }
- X
- X /*
- X * Set default parameters.
- X */
- X tty_setup();
- X tty_local(flags & O_NDELAY);
- X tty_ndelay(0);
- X tty_baud(baud);
- X tty_raw();
- X
- X return E_OK;
- X}
- X
- X/*******************************************************************
- X * T T Y _ C L O S E
- X * -----------------
- X *
- X * Description:
- X * Close open tty.
- X *
- X *******************************************************************/
- int
- tty_close(void)
- X{
- X if (port >= 0) {
- X close(port);
- X port = -1;
- X }
- X return E_OK;
- X}
- X
- X/*******************************************************************
- X * T T Y _ R E A D
- X * ---------------
- X *
- X * Description:
- X * Read characters from tty.
- X *
- X *******************************************************************/
- int
- tty_read(char *buf, int len)
- X{
- X return read(port, buf, len);
- X}
- X
- X/*******************************************************************
- X * T T Y _ W R I T E
- X * -----------------
- X *
- X * Description:
- X * Write characters from tty.
- X *
- X *******************************************************************/
- int
- tty_write(char *buf, int len)
- X{
- X return write(port, buf, len);
- X}
- X
- X/*******************************************************************
- X * T T Y _ N D E L A Y
- X * -------------------
- X *
- X * Description:
- X * Control the O_NDELAY flag for tty.
- X *
- X * Arguments:
- X * on - true means O_NDELAY is on.
- X *
- X *******************************************************************/
- int
- tty_ndelay(int on)
- X{
- X int mode;
- X
- X /*
- X * Turn off O_NDELAY
- X */
- X mode = fcntl(port, F_GETFL, 0);
- X
- X if (on) {
- X mode |= O_NDELAY;
- X }
- X else {
- X mode &= ~O_NDELAY;
- X }
- X
- X if (fcntl(port, F_SETFL, mode) != 0) {
- X logerr("tty_open: can't turn off O_NDELAY");
- X }
- X
- X return E_OK;
- X}
- X
- X/*******************************************************************
- X * H A N G U P
- X * -----------
- X * Description:
- X * Hangup tty. After this the modem must be reopened before use.
- X *
- X * Arguments:
- X *
- X *******************************************************************/
- int
- tty_hangup(void)
- X{
- X struct termios ttybuf;
- X
- X tty_drain();
- X tcgetattr(port, &ttybuf);
- X cfsetispeed(&ttybuf, 0);
- X cfsetospeed(&ttybuf, B0);
- X tcsetattr(port, TCSADRAIN, &ttybuf);
- X sleep(3);
- X
- X return E_OK;
- X}
- X
- X/*******************************************************************
- X * T T Y _ S E T U P
- X * -----------------
- X *
- X * Description:
- X * Setup modempool favorite tty settings.
- X *
- X * Arguments:
- X *
- X *******************************************************************/
- int
- tty_setup(void)
- X{
- X static struct termios ttybuf;
- X
- X ttybuf.c_iflag = IGNPAR | ISTRIP | ICRNL | IXON | IXANY; /* iflag */
- X ttybuf.c_oflag = OPOST | ONLCR | TAB3; /* oflag */
- X ttybuf.c_cflag = CS8 | CREAD | CLOCAL | HUPCL | B300; /* cflag */
- X ttybuf.c_lflag = ISIG | ICANON | ECHO | ECHOE | ECHOK; /* lflag */
- X ttybuf.c_cc[0] = 3;
- X ttybuf.c_cc[1] = 28;
- X ttybuf.c_cc[2] = 127;
- X ttybuf.c_cc[3] = 24;
- X ttybuf.c_cc[4] = 4;
- X ttybuf.c_cc[5] = 0;
- X ttybuf.c_cc[6] = 0;
- X ttybuf.c_cc[7] = 0;
- X
- X tcsetattr(port, TCSANOW, &ttybuf);
- X
- X return E_OK;
- X}
- X
- X/*******************************************************************
- X * T T Y _ S A N E
- X * ---------------
- X *
- X * Description:
- X * Like stty sane. Turns on canonic mode, i.e. user friendly
- X * mode.
- X *
- X * Arguments:
- X *
- X *******************************************************************/
- int
- tty_sane(void)
- X{
- X struct termios ttybuf;
- X
- X tcgetattr(port, &ttybuf);
- X ttybuf.c_iflag |= IGNPAR | ISTRIP | ICRNL | IXON | IXANY;
- X ttybuf.c_oflag |= OPOST | ONLCR;
- X ttybuf.c_lflag |= ISIG | ICANON;
- X ttybuf.c_cc[VEOF] = 4;
- X tcsetattr(port, TCSANOW, &ttybuf);
- X tty_echo();
- X
- X return E_OK;
- X}
- X
- X/*******************************************************************
- X * T T Y _ R A W
- X * -------------
- X *
- X * Description:
- X * Turn tty back in raw mode. The opposite from tty_sane.
- X *
- X * Arguments:
- X *
- X *******************************************************************/
- int
- tty_raw(void)
- X{
- X struct termios ttybuf;
- X
- X tcgetattr(port, &ttybuf);
- X ttybuf.c_iflag &= ~IGNPAR & ~ISTRIP & ~ICRNL & ~IXON & ~IXANY;
- X ttybuf.c_oflag &= ~OPOST & ~ONLCR;
- X ttybuf.c_lflag &= ~ISIG & ~ICANON;
- X ttybuf.c_cc[VMIN] = 1;
- X tcsetattr(port, TCSANOW, &ttybuf);
- X tty_noecho();
- X
- X return E_OK;
- X}
- X
- X/*******************************************************************
- X * T T Y _ L O C A L
- X * -----------------
- X *
- X * Description:
- X * Control local mode.
- X *
- X * Arguments:
- X * mode - True means tty turns local mode on.
- X *
- X *******************************************************************/
- int
- tty_local(int mode)
- X{
- X struct termios ttybuf;
- X
- X tcgetattr(port, &ttybuf);
- X if (mode) {
- X ttybuf.c_cflag |= CLOCAL;
- X }
- X else {
- X ttybuf.c_cflag &= ~CLOCAL;
- X }
- X tcsetattr(port, TCSANOW, &ttybuf);
- X
- X return E_OK;
- X}
- X
- X/*******************************************************************
- X * T T Y _ B A U D
- X * ---------------
- X *
- X * Description:
- X * Set baudrate for tty.
- X *
- X * Arguments:
- X * baud - Integer baudrate value.
- X *
- X *******************************************************************/
- int
- tty_baud(int baud)
- X{
- X struct termios ttybuf;
- X int tcbaud;
- X
- X switch(baud)
- X {
- X case 300:
- X tcbaud = B300;
- X break;
- X
- X case 1200:
- X tcbaud = B1200;
- X break;
- X
- X case 2400:
- X default:
- X tcbaud = B2400;
- X break;
- X
- X case 4800:
- X tcbaud = B4800;
- X break;
- X
- X case 9600:
- X tcbaud = B9600;
- X break;
- X }
- X tcgetattr(port, &ttybuf);
- X cfsetispeed(&ttybuf, 0);
- X cfsetospeed(&ttybuf, tcbaud);
- X tcsetattr(port, TCSANOW, &ttybuf);
- X
- X return E_OK;
- X}
- X
- X/*******************************************************************
- X * T T Y _ E C H O
- X * ---------------
- X *
- X * Description:
- X * Turns on echoing for tty.
- X *
- X * Arguments:
- X *
- X *******************************************************************/
- int
- tty_echo(void)
- X{
- X struct termios ttybuf;
- X
- X tcgetattr(port, &ttybuf);
- X ttybuf.c_lflag |= ECHO | ECHOE | ECHOK;
- X tcsetattr(port, TCSANOW, &ttybuf);
- X
- X return E_OK;
- X}
- X
- X/*******************************************************************
- X * T T Y _ N O E C H O
- X * -------------------
- X *
- X * Description:
- X * Turns off echoing for tty.
- X *
- X * Arguments:
- X *
- X *******************************************************************/
- int
- tty_noecho(void)
- X{
- X struct termios ttybuf;
- X
- X tcgetattr(port, &ttybuf);
- X ttybuf.c_lflag &= ~ECHO & ~ECHOE & ~ECHOK;
- X tcsetattr(port, TCSANOW, &ttybuf);
- X
- X return E_OK;
- X}
- X
- X/*******************************************************************
- X * T T Y _ D R A I N
- X * -----------------
- X *
- X * Description:
- X * Wait for output to drain.
- X *
- X *******************************************************************/
- int
- tty_drain(void)
- X{
- X sleep(1);
- X tcdrain(port);
- X return E_OK;
- X}
- X
- X/*******************************************************************
- X * T T Y _ F L U S H
- X * -----------------
- X *
- X * Description:
- X * Flush input data.
- X *
- X *******************************************************************/
- int
- tty_flush(void)
- X{
- X tcflush(port, TCIFLUSH);
- X return E_OK;
- X}
- X
- X/*******************************************************************
- X * T T Y _ R E D I R E C T
- X * -----------------------
- X *
- X * Description:
- X * Redirect stdin, stdout and stderr to port.
- X *
- X *******************************************************************/
- int
- tty_redirect(void)
- X{
- X if (dup2(port, 0) != 0) {
- X logerr("dup!=0");
- X return E_FAIL;
- X }
- X if (dup2(port, 1) != 1) {
- X logerr("dup!=1");
- X return E_FAIL;
- X }
- X if (dup2(port, 2) != 2) {
- X logerr("dup!=2");
- X return E_FAIL;
- X }
- X return E_OK;
- X}
- END_OF_FILE
- if test 8930 -ne `wc -c <'tty.c'`; then
- echo shar: \"'tty.c'\" unpacked with wrong size!
- fi
- # end of 'tty.c'
- fi
- if test -f 'utmplist.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'utmplist.c'\"
- else
- echo shar: Extracting \"'utmplist.c'\" \(706 characters\)
- sed "s/^X//" >'utmplist.c' <<'END_OF_FILE'
- X#include <stdio.h>
- X#include <sys/types.h>
- X#include <utmp.h>
- X
- main()
- X{
- X FILE *fp;
- X struct utmp buf;
- X
- X if ((fp = fopen(UTMP_FILE, "r")) == NULL) {
- X fprintf(stderr, "failed to open UTMP\n");
- X exit(1);
- X }
- X while(fread(&buf, sizeof buf, 1, fp) == 1) {
- X printf("User: %s\n", buf.ut_user);
- X printf("Id: %s\n", buf.ut_id);
- X printf("Line: %s\n", buf.ut_line);
- X printf("Pid: %d\n", buf.ut_pid);
- X printf("Type: %d\n", buf.ut_type);
- X printf("Termination status: %d\n", buf.ut_exit.e_termination);
- X printf("Exit status: %d\n", buf.ut_exit.e_exit);
- X printf("Dead process exit status: %d\n", buf.ut_exit);
- X printf("Time entry was made: %d\n", buf.ut_time);
- X printf("\n");
- X }
- X fclose(fp);
- X}
- END_OF_FILE
- if test 706 -ne `wc -c <'utmplist.c'`; then
- echo shar: \"'utmplist.c'\" unpacked with wrong size!
- fi
- # end of 'utmplist.c'
- fi
- echo shar: End of archive 1 \(of 1\).
- cp /dev/null ark1isdone
- MISSING=""
- for I in 1 ; do
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have the archive.
- rm -f ark[1-9]isdone
- else
- echo You still need to unpack the following archives:
- echo " " ${MISSING}
- fi
- ## End of shell archive.
- exit 0
-