🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Thread View: sub.sources.os9
1 messages
1 total messages Started by Frank Kaefer Sat, 22 Jun 1991 12:44
v02i004: Ptyman 1.3 Sources - Part 2/2
#4
Author: Frank Kaefer
Date: Sat, 22 Jun 1991 12:44
1356 lines
46085 bytes
Posting-number: Volume 2, Issue 4
Submitted-by: ram@ramsys.UUCP (Reimer A. Mellin)
Archive-name: ptyman1.3_src2

#! /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 2 (of 2)."
# Contents:  funcs.c ptyman.c
# Wrapped by ram@ramsys on Sun Jun 23 11:05:16 1991
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'funcs.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'funcs.c'\"
else
echo shar: Extracting \"'funcs.c'\" \(21278 characters\)
sed "s/^X//" >'funcs.c' <<'END_OF_FILE'
X/*       This software is copyright (C) 1989 by Reimer Mellin        *
X*                                                                    *
X*        Permission is granted to reproduce and distribute           *
X*        this package by any means so long as no fee is charged      *
X*        above a nominal handling fee and so long as this            *
X*        notice is always included in the copies.                    *
X*        Commerical use or incorporation into commercial software    *
X*        is prohibited without the written permission of the         *
X*        author.                                                     *
X*                                                                    *
X*        Other rights are reserved except as explicitly granted      *
X*        by written permission of the author.                        *
X*                Reimer Mellin                                       *
X*                                                                    *
X*                Sulenstr.8                                          *
X*                D-8000 Muenchen 71 (Federal Republic of Germany)    *
X*                                                                    *
X*           EMAIL:                                                   *
X*                mellin@lan.informatik.tu-muenchen.dbp.de            *
X*                ram@altger.UUCP                                     *
X*                ram%ramsys@chiuur.sub.org (home)                    *
X*                                                                    */
X/*  */
X
X/*
X * Funcs.c : Unterfunktionen zum Pty-FileManager.
X *
X * $Header: /h0/USR/REIMER/PTYMAN/RCS/funcs.c_v 1.3 91/06/08 01:20:27 ram Exp $
X *
X * $Log:	funcs.c_v $
X * Revision 1.3  91/06/08  01:20:27  ram
X * Added SS_IOCONT & SS_IOSTOP, various bugfixes, ftp-release on smilodon,
X * please share and distribute !!
X * 
X * Revision 1.2.1.2  89/09/04  13:12:41  ram
X * added some comments
X * 
X * Revision 1.2.1.1  89/08/31  12:24:51  ram
X * negative Read/Write Counts are made positive
X * 
X * Revision 1.2  89/07/16  01:04:51  ram
X * minor changes to Sub-net release
X * 
X * Revision 1.1.1.1  89/07/14  19:48:36  ram
X * Fixed: kbich, kbach. Sub-net Beta-Release
X * 
X * Revision 1.1  89/07/13  23:21:10  ram
X * Initial revision
X * 
X */
X
X#include <types.h>
X#include <MACHINE/reg.h>
X#include "ptyman.h"
X#include <path.h>
X#include <sg_codes.h>
X#include <procid.h>
X#include <signal.h>
X#include <modes.h>
X#include <errno.h>
X
X#include "misc.h"
X
Xextern union pathdesc pd;
X
Xint
Xhangup(procdesc)
Xregister   procid    *procdesc;
X{
X    /* TRUE:
X     *          - pty-typ is a tty
X     *          - and correspondent pty has gone
X     * Action:    send a offsig, if conection was severed by server
X     */
X
X    if(pd.ptypvt.typ == TTY && pd.ptypvt.pty == (union pathdesc *) 0) {
X        errno = E_HANGUP;
X        return TRUE;
X    }
X    return FALSE;
X}
X
Xint inline
Xdosleep( procdesc )
Xregister    procid  *procdesc;
X{
X    /*
X     * 0:   - if wakedup by SIGWAKE
X     * -1:  - if signal is < 32 ( ENOENT ) orseq process has been aborted
X     * 0:   - other
X     */
X
X    if( tsleep(0) == 0 && procdesc->_signal == 0)
X        return 0;
X    if( (errno = procdesc->_signal) < 32
X      || procdesc->_state & (P_DEAD|P_CONDEMNED))
X        return -1;
X    return 0;
X}
X
X/*
X * Falls Echo angeschaltet ist, schreibe einen Charakter in den Echobuffer
X * 1:   - falls echo ausgeschaltet ist oder echo erfolgreich
X * -1:  - Fehler bei Ausgabe (z.b. Prozess aborted)
X */
Xint
Xechochar( ch, buf, procdesc)
Xregister    u_char          ch;
Xregister    struct  ptybuf *buf;
X            procid         *procdesc;
X{   register    int rv;
X
X    /*
X     * if echo is off, return success
X     */
X    if( pd.ptyopt.pd_eko == '\0')
X        return(1);
X
X    /*
X     * wait for other I/O, and register for SIGINT,SIGQUIT (set lpd )
X     */
X    iowait( buf->wpid);
X    buf->wsig = SIGWAKE;
X    buf->lpd = &pd;
X
X    /*
X     * my standard output-loop
X     */
X    while( buf->wptr >= (buf->buf + buf->size)) {
X        /* stopped means STOP, so hang around and do not WakeUp */
X        if( !(buf->flags & STOPPED))
X          WAKE(buf->rpid, buf->rsig);
X        buf->wpid = procdesc->_id;
X        do {
X            if( dosleep(procdesc) < 0) {
X                rv = -1;
X                goto outloop;
X            }
X        } while( buf->wpid);
X    }
X    *(buf->wptr)++ = ch;
X    rv = 1;
Xoutloop:
X    buf->wpid = 0;
X        /* stopped means STOP, so do not WakeUp */
X    if( !(buf->flags & STOPPED))
X      WAKE(buf->rpid, buf->rsig);
X    return( rv );
X}
X
X/*
X * Lese cnt-Bytes im Raw-modus ein. Kein Echo, Lineediting etc....
X * 0:   - cnt-bytes gelesen
X * x:   - (cnt-x) bytes gelesen
X * -x:  - nach (cnt-x) ist Fehler aufgetreten (Interupted, Hangup etc.)
X */
Xint
Xcpinraw(buf, echobuf, ustack, procdesc)
Xregister    struct  ptybuf *buf;
Xregister    struct  ptybuf *echobuf;
X            REGISTERS      *ustack;
X            procid         *procdesc;
X{   register    int     cnt = ustack->d[1] & 0x7fffffff; /* no neg. counts */
X    register    u_char *dest = (u_char *) ustack->a[0];
X    register    u_char ch;
X
X    /*
X     * this can only happen if _ss_sign() was set
X     */
X    if( buf->rpid == procdesc->_id) {
X        errno = E_NOTRDY;
X        return -cnt;
X    }
X
X    /* wait for other processes to finish */
X    iowait( buf->rpid);
X    buf->rsig = SIGWAKE;
X
X    /* copy cnt bytes */
X    for(; cnt > 0; --cnt) {
X        /* if read-ptr reached write-ptr synchronize with partner */
X        while( buf->rptr >= buf->wptr ) {
X            /* reset ptr */
X            buf->wptr = buf->rptr = buf->buf;
X
X            /* stopped means STOP, so hang around and do not WakeUp */
X            if( !(buf->flags & STOPPED))
X              WAKE(buf->wpid, buf->wsig);
X
X            buf->rpid = procdesc->_id;
X            do {
X                if( dosleep(procdesc) < 0) {
X                    cnt = -cnt;
X                    goto outloop;
X                }
X            } while ( buf->rpid);
X        }
X        /*
X         * in read, one has still to check for SIGQUIT etc..
X         * the signal is sent by the writing-process
X         */
X        if( ch = getctrlchar( (*dest++ = *(buf->rptr)++), &pd))
X          switch( ch ) {
X            case INT:
X                errno = SIGINT;
X                cnt = - (--cnt);
X                goto outloop;
X
X            case QUT:
X                errno = SIGQUIT;
X                cnt = - (--cnt);
X                goto outloop;
X
X            case EOR:
X                pd.ptypvt.line = 0;
X                break;
X          }
X    }
Xoutloop:
X    buf->rpid = 0;
X    if(buf->rptr >= buf->wptr ) {
X        buf->wptr = buf->rptr = buf->buf;
X        /* stopped means STOP, so do not WakeUp */
X        if( !(buf->flags & STOPPED))
X          WAKE(buf->wpid, buf->wsig);
X    }
X    return( cnt);
X}
X
X/*
X * Lese cnt-Bytes. Echo, Lineediting, vorzeitiger Abbruch bei Lesen von CR
X * 0:   - cnt-bytes gelesen
X * x:   - (cnt-x) bytes gelesen
X * -x:  - nach (cnt-x) ist Fehler aufgetreten (Interupted, Hangup etc.)
X */
Xint
Xcpin(buf, echobuf, ustack, procdesc)
Xregister    struct  ptybuf *buf;
X            struct  ptybuf *echobuf;
X            REGISTERS      *ustack;
X            procid         *procdesc;
X{   register    int     cnt = ustack->d[1] & 0x7fffffff; /* no neg. counts */
X    register    u_char *dest = (u_char *) ustack->a[0];
X    register    u_char *old  = pd.path.pd_buf;
X    register    u_char  ch;
X
X    /*
X     * this can only happen if _ss_sign() was set
X     */
X    if( buf->rpid == procdesc->_id) {
X        errno = E_NOTRDY;
X        return -cnt;
X    }
X
X    /* wait for other processes to finish */
X    iowait( buf->rpid);
X    buf->rsig = SIGWAKE;
X
X    for(; cnt > 0; --cnt) {
X        /* if read-ptr reached write-ptr synchronize with partner */
X        while( buf->rptr >= buf->wptr ) {
X            /* reset ptr */
X            buf->wptr = buf->rptr = buf->buf;
X
X            /* stopped means STOP, so do not WakeUp */
X            if( !(buf->flags & STOPPED))
X              WAKE(buf->wpid, buf->wsig);
X
X            buf->rpid = procdesc->_id;
X            do {
X                if( dosleep(procdesc) < 0) {
X                    cnt = -cnt;
X                    goto outloop;
X                }
X            } while( buf->rpid);
X        }
X#ifdef UPCHAR
X        ch = ( pd.ptyopt.pd_upc ? upchar(*(buf->rptr)++) : *(buf->rptr)++);
X#else
X        ch = *(buf->rptr)++;
X#endif
X        switch( getctrlchar(ch, &pd) ) {
X
X            case BSP:
X               /*
X                * look in the Tech. manual to see what is meant here
X                */
X               if( ( pd.ptyopt.pd_bso ?
X                   (echochar( pd.ptyopt.pd_bse, echobuf, procdesc) +
X                    echochar( ' ' ,echobuf, procdesc) +
X                    echochar( pd.ptyopt.pd_bse, echobuf, procdesc) < 3) :
X                   (echochar( pd.ptyopt.pd_bse, echobuf, procdesc) < 1))) {
X                        cnt = -cnt;
X                        goto outloop;
X                }
X                dest--; old--;
X                dest = MAX( (dest), ((u_char *) ustack->a[0]));
X                old  = MAX( (old ), pd.path.pd_buf);
X                if( cnt == ustack->d[1] )
X                    cnt = ustack->d[1]+1;
X                else
X                    cnt += 2;
X                break;
X
X            case EOR:
X                /*
X                 * EOR resets pd_line and finishes
X                 */
X                pd.ptypvt.line = 0;
X                *old++ = *dest++ = ch;
X                if( ( echochar( ch, echobuf, procdesc) < 0
X                    || ( pd.ptyopt.pd_alf
X                        && echochar( '\l', echobuf, procdesc) < 0))) {
X                    cnt = -cnt;
X                    goto outloop;
X                }
X                cnt--;
X                goto outloop;
X
X            case INT:
X                *old = *dest = ch;
X                errno = SIGINT;
X                cnt = - (--cnt);
X                goto outloop;
X
X            case QUT:
X                *old = *dest = ch;
X                errno = SIGQUIT;
X                cnt = - (--cnt);
X                goto outloop;
X
X            case EOF:
X                /*
X                 * EOF only as first character !
X                 */
X                if( old == pd.path.pd_buf) {
X                    errno = E_EOF;
X                    cnt = -cnt;
X                    goto outloop;
X                }
X
X            case DEL:
X                if( pd.ptyopt.pd_dlo != '\0' ) {
X                  for(; old > pd.path.pd_buf; --old,cnt++)
X                    if(( pd.ptyopt.pd_bso ?
X                       (echochar( pd.ptyopt.pd_bse, echobuf, procdesc) +
X                        echochar( ' ' ,echobuf, procdesc) +
X                        echochar( pd.ptyopt.pd_bse, echobuf, procdesc) < 3) :
X                       (echochar( pd.ptyopt.pd_bse, echobuf, procdesc) < 1))) {
X                          cnt = -cnt;
X                          goto outloop;
X                    }
X                }
X                else
X                   if( (echochar( pd.ptyopt.pd_eor, echobuf, procdesc)
X                      + echochar( '\l', echobuf, procdesc) < 2)) {
X                            cnt = -cnt;
X                            goto outloop;
X                   }
X                dest = (u_char *) ustack->a[0];
X                old  = pd.path.pd_buf;
X                cnt  = ustack->d[1]+1;
X                break;
X
X            case DUP:
X                for(; cnt > 0 ; --cnt) {
X                  if((ch = *dest++ = *old++) == pd.ptyopt.pd_eor &&
X                      pd.ptyopt.pd_eor) {
X                           dest--; old--;
X                           break;
X                  }
X                  if( echochar( (ch < ' ' ? '.': ch), echobuf, procdesc) < 0) {
X                           cnt = - (--cnt);
X                           goto outloop;
X                  }
X                }
X                break;
X
X            case RPR:
X                *old = *dest = pd.ptyopt.pd_eor;
X                if(( echochar( *old, echobuf, procdesc) < 0 ||
X                    (pd.ptyopt.pd_alf && echochar( '\l', echobuf, procdesc) < 0))) {
X                      cnt = -cnt;
X                      goto outloop;
X                }
X                {
X                    register u_char *tmp = pd.path.pd_buf;
X
X                    for(; tmp < old; tmp++)
X                        if( echochar( *tmp, echobuf, procdesc) < 0) {
X                            cnt = - cnt;
X                            goto outloop;
X                        }
X		}
X                break;
X
X            default:
X                *old++ = *dest++ = ch;
X                if( echochar( (ch < ' ' ? '.': ch), echobuf, procdesc) < 0) {
X                    cnt = - (--cnt);
X                    goto outloop;
X                }
X        }
X    }
Xoutloop:
X    buf->rpid = 0;
X    if( buf->rptr >= buf->wptr ) {
X        buf->wptr = buf->rptr = buf->buf;
X        /* stopped means STOP, so do not WakeUp */
X        if( !(buf->flags & STOPPED))
X          WAKE(buf->wpid, buf->wsig);
X    }
X    return( cnt);
X}
X
X/*
X * Schreibe cnt-Bytes im Raw-modus. Kein Alf etc....
X * 0:   - cnt-bytes geschrieben
X * x:   - (cnt-x) bytes geschrieben
X * -x:  - nach (cnt-x) ist Fehler aufgetreten (Interupted, Hangup etc.)
X */
Xint
Xcpoutraw(buf, echobuf, ustack, procdesc)
Xregister    struct  ptybuf *buf;
Xregister    struct  ptybuf *echobuf;
X            REGISTERS      *ustack;
X            procid         *procdesc;
X{   register    int               cnt = ustack->d[1] & 0x7fffffff;
X    register    u_char            *src = (u_char *) ustack->a[0];
X    register    union   pathdesc  *echopd = echobuf->lpd;
X    register    u_char            ch;
X    register    u_int             bufend = (u_int) buf->buf + buf->size;
X
X    iowait( buf->wpid);
X    buf->wsig = SIGWAKE;
X    buf->lpd = &pd;
X
X    for(; cnt > 0; --cnt) {
X        while( (buf->wptr >= (u_char *) bufend)) {
X            if( !(buf->flags & STOPPED))
X              WAKE(buf->rpid, buf->rsig);
X            buf->wpid = procdesc->_id;
X            do {
X                if( dosleep(procdesc) < 0) {
X                    cnt = -cnt;
X                    goto outloop;
X                }
X	    } while( buf->wpid);
X        }
X        ch = *(buf->wptr)++ = *src++;
X        if( echopd )
X          switch( getctrlchar( ch, echopd )) {
X            /*
X             * Pause-Char: set pause-stop and remove char
X             */
X            case PSC:
X              echobuf->flags |= PSCSTOP;
X              (buf->wptr)--; /* dont send */
X              break;
X
X            /*
X             * XOFF-char .. set xoff-stop and remove char
X             */
X            case XOFF:
X              echobuf->flags |= XOFFSTOP;
X              (buf->wptr)--; /* dont send */
X              break;
X
X            /*
X             * XON-char .. remove xoff-stop and remove char
X             * we have to Wake the stopped process !!
X             */
X            case XON:
X              echobuf->flags &= ~XOFFSTOP;
X              (buf->wptr)--; /* dont send */
X              WAKE(echobuf->wpid, echobuf->wsig);
X              break;
X
X            /*
X             * here the INT and QUIT signals are sent to the
X             * last writing process ( echopd )
X             */
X            case INT:
X            case QUT:
X              if( ch == echopd->ptyopt.pd_int)
X                kill(echopd->path.pd_lproc,SIGINT);
X              else
X                kill(echopd->path.pd_lproc,SIGQUIT);
X              /* fall through ?! */
X
X            default:
X              /*
X               * any char removes the pause-stop !!!
X               * but the char gets clobbered
X               */
X              if( echobuf->flags & PSCSTOP ) {
X                echobuf->flags &= ~PSCSTOP;
X                (buf->wptr)--; /* dont send */
X                WAKE(echobuf->wpid, echobuf->wsig);
X              }
X              break;
X          }
X    }
Xoutloop:
X    buf->wpid = 0;
X    /*
X     * only send WAKEUP if we output any char !! (XON/PSC-stop!
X     * otherwise this may get confused with _ss_sigs !!
X     */
X    if( buf->wptr > buf->rptr && !(buf->flags & STOPPED ))
X      WAKE(buf->rpid, buf->rsig);
X    return( cnt);
X}
X
X/*
X * Schreibe cnt-Bytes. Alf, Tab-expanding, Pause-behandlung, Abbruch bei
X * vorzeitigem CR
X * 0:   - cnt-bytes geschrieben
X * x:   - (cnt-x) bytes geschrieben
X * -x:  - nach (cnt-x) ist Fehler aufgetreten (Interupted, Hangup etc.)
X */
Xint
Xcpout(buf, echobuf, ustack, procdesc)
Xregister    struct  ptybuf *buf;
Xregister    struct  ptybuf *echobuf;
X            REGISTERS      *ustack;
X            procid         *procdesc;
X{   register    int               cnt = ustack->d[1] & 0x7fffffff;
X    register    u_char            *src = (u_char *) ustack->a[0];
X    register    union   pathdesc  *echopd = echobuf->lpd;
X    register    u_char            ch;
X    register    u_int             bufend = (u_int) buf->buf + buf->size;
X
X    iowait( buf->wpid );
X    buf->wsig = SIGWAKE;
X    buf->lpd = &pd;
X
X    for(; cnt > 0; --cnt) {
X        while( (buf->wptr >= (u_char *) bufend)) {
X            if( !(buf->flags & STOPPED))
X              WAKE(buf->rpid, buf->rsig);
X            buf->wpid = procdesc->_id;
X            do {
X                if( dosleep(procdesc) < 0) {
X                    cnt = -cnt;
X                    goto outloop;
X                }
X            } while( buf->wpid);
X        }
X        pd.ptyopt.pd_Col++;
X        ch = *(buf->wptr)++ = *src++;
X        if( ch ) {
X          if( echopd )
X            switch( getctrlchar( ch, echopd )) {
X             /*
X              * Pause-Char: set pause-stop and remove char
X              */
X              case PSC:
X                echobuf->flags |= PSCSTOP;
X                (buf->wptr)--; /* dont send */
X                break;
X
X             /*
X              * XOFF-char .. set xoff-stop and remove char
X              */
X              case XOFF:
X                echobuf->flags |= XOFFSTOP;
X                (buf->wptr)--; /* dont send */
X                break;
X
X             /*
X              * XON-char .. remove xoff-stop and remove char
X              * we have to Wake to stopped process !!
X              */
X              case XON:
X                echobuf->flags &= ~XOFFSTOP;
X                (buf->wptr)--; /* dont send */
X                WAKE(echobuf->wpid, echobuf->wsig);
X                break;
X
X             /*
X              * QUIT and INT signals to last writing device
X              */
X              case INT:
X              case QUT:
X                if( ch == echopd->ptyopt.pd_int)
X                  kill(echopd->path.pd_lproc,SIGINT);
X                else
X                  kill(echopd->path.pd_lproc,SIGQUIT);
X                /* fall through ?? */
X
X              /*
X               * any char removes the pause-stop !!!
X               * but the char gets clobbered
X               */
X              default:
X                if( echobuf->flags & PSCSTOP ) {
X                  echobuf->flags &= ~PSCSTOP;
X                  (buf->wptr)--; /* dont send */
X                  WAKE(echobuf->wpid, echobuf->wsig);
X                }
X                break;
X            }
X          if( ch == pd.ptyopt.pd_eor ) {
X            pd.ptyopt.pd_Col = 0;
X            if( pd.ptyopt.pd_pau && ++pd.ptypvt.line == pd.ptyopt.pd_pag ) {
X                pd.ptypvt.line = 0;
X                iowait( echobuf->rpid);
X                if( !(echobuf->flags & STOPPED))
X                  WAKE(echobuf->wpid, echobuf->wsig);
X                echobuf->rpid = procdesc->_id;
X                do {
X                   if( dosleep(procdesc) < 0) {
X                      cnt = -cnt;
X                      goto outloop;
X                   }
X                } while( echobuf->rpid);
X                echobuf->rptr++;
X            }
X            if( pd.ptyopt.pd_alf ) {
X                if( buf->wptr >= (buf->buf + buf->size)) {
X                    if( !(echobuf->flags & STOPPED))
X                      WAKE(buf->rpid, buf->rsig);
X                    buf->wpid = procdesc->_id;
X                    do {
X                        if( dosleep(procdesc) < 0) {
X                            cnt = -cnt;
X                            goto outloop;
X                        }
X                    } while( buf->wpid);
X		}
X                *(buf->wptr)++ = '\l';
X            }
X            --cnt;
X            break;
X          } else
X            if( pd.ptyopt.pd_Tabs && pd.ptyopt.pd_Tab && ch == pd.ptyopt.pd_Tab) {
X                register short i = (pd.ptyopt.pd_Col-1) % pd.ptyopt.pd_Tabs;
X                (buf->wptr)--;
X                for(; i > 0; i--) {
X                    while( buf->wptr >= (buf->buf + buf->size)) {
X                        if( !(buf->flags & STOPPED))
X                          WAKE(buf->rpid, buf->rsig);
X                        buf->wpid = procdesc->_id;
X                        do {
X                            if( dosleep(procdesc) < 0) {
X                                cnt = -cnt;
X                                goto outloop;
X                            }
X                        } while( buf->wpid);
X                    }
X                    *(buf->wptr)++ = ' ';
X                }
X            }
X        }
X    }
Xoutloop:
X    buf->wpid = 0;
X    /*
X     * only send WAKEUP if we output any char !! (XON/PSC-stop!
X     * otherwise this may get confused with _ss_sigs !!
X     */
X    if( buf->wptr > buf->rptr && !(buf->flags & STOPPED ))
X      WAKE(buf->rpid, buf->rsig);
X    return( cnt);
X}
END_OF_FILE
if test 21278 -ne `wc -c <'funcs.c'`; then
    echo shar: \"'funcs.c'\" unpacked with wrong size!
fi
# end of 'funcs.c'
fi
if test -f 'ptyman.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'ptyman.c'\"
else
echo shar: Extracting \"'ptyman.c'\" \(19781 characters\)
sed "s/^X//" >'ptyman.c' <<'END_OF_FILE'
X/*       This software is copyright (C) 1989 by Reimer Mellin        *
X*                                                                    *
X*        Permission is granted to reproduce and distribute           *
X*        this package by any means so long as no fee is charged      *
X*        above a nominal handling fee and so long as this            *
X*        notice is always included in the copies.                    *
X*        Commerical use or incorporation into commercial software    *
X*        is prohibited without the written permission of the         *
X*        author.                                                     *
X*                                                                    *
X*        Other rights are reserved except as explicitly granted      *
X*        by written permission of the author.                        *
X*                Reimer Mellin                                       *
X*                                                                    *
X*                Sulenstr.8                                          *
X*                D-8000 Muenchen 71 (Federal Republic of Germany)    *
X*                                                                    *
X*           EMAIL:                                                   *
X*                mellin@lan.informatik.tu-muenchen.dbp.de            *
X*                ram@altger.UUCP                                     *
X*                ram%ramsys@chiuur.sub.org (home)                    *
X*                                                                    */
X
X/*  */
X
X/*
X * HauptModul des PtyManagers -- Einsprung-Routinen vom Assembler-Interface
X *
X * $Header: /h0/USR/REIMER/PTYMAN/RCS/ptyman.c_v 1.3 91/06/08 01:19:40 ram Exp $
X *
X * $Log:	ptyman.c_v $
X * Revision 1.3  91/06/08  01:19:40  ram
X * Added SS_IOCONT & SS_IOSTOP, various bugfixes, ftp-release on smilodon,
X * please share and distribute !!
X * 
X * Revision 1.2.1.2  89/09/04  13:14:23  ram
X * added some comments
X * 
X * Revision 1.2.1.1  89/08/31  12:26:06  ram
X * Copyright-message added
X * 
X * Revision 1.2  89/07/16  01:06:12  ram
X * minor changes to Sub-net Release
X * 
X * Revision 1.1.1.1  89/07/14  19:49:56  ram
X * Fixed: SS_SSig Bug. Sub-Net Beta-Release
X * 
X * Revision 1.1  89/07/13  23:22:15  ram
X * Initial revision
X * 
X */
X
X#include <types.h>
X#include <MACHINE/reg.h>
X#include "Ptyman.h"
X#include <path.h>
X#include <sg_codes.h>
X#include <procid.h>
X#include <modes.h>
X#include <sgstat.h>
X#include <setsys.h>
X#include <signal.h>
X#include <errno.h>
X
X#ifdef ST
X#include <stconfuncs.h>
X#endif
X
X#include "misc.h"
X
Xunion pathdesc pd;      /* a6 points to the Path-Descriptor !!! */
X
X/*
X * O P E N
X */
XOpen(procdesc, ustack)
X  procid    *procdesc;
X  REGISTERS *ustack;
X{
X    register    u_char  *name = (u_char *) ustack->a[0];
X    register    int      namcnt,i;
X    register    Pathdesc ptr;
X
X    if( ( namcnt = _prsnam(name)) < 0)
X        return -1;
X
X    pd.ptypvt.typ = (name[1] == 'P' || name[1] == 'p') ? PTY : TTY;
X
X    if( (pd.path.pd_mod & (u_char) ustack->d[0]) != (u_char) ustack->d[0]) {
X        errno = E_BMODE;
X        return -1;
X    }
X
X    pd.path.pd_mod = (u_char) ustack->d[0];
X    if( pd.ptypvt.typ == TTY || !(pd.path.pd_mod & S_IFDIR)) {
X      if( name[namcnt] != '/') {
X        errno = E_BPNAM;
X        return -1;
X      }
X
X      name += namcnt+1;
X
X      if( ( namcnt = _prsnam(name)) < 0 || namcnt > 28
X         || name[namcnt] != '\0') {
X        errno = E_BPNAM;
X        return -1;
X      }
X    }
X
X    for(i=0; i < namcnt;i++)
X        pd.ptyopt.pd_name[i] = upchar(name[i]);
X
X    pd.ptyopt.pd_name[namcnt-1] |= 0x80;
X    
X    pd.ptyopt.pd_namlen = namcnt;
X
X    /* normal ptys have buffers and so on, dir-ptys don't ! */
X    if( !(pd.path.pd_mod & S_IFDIR)) {
X      if( pd.ptypvt.typ != PTY) {
X          /* tty */
X          /* look for correspondent pty in path-list and then look its
X           * tty-list for already openend NON-SHAREABLE ttys ...
X           */
X
X          /*
X           * The start of all open paths on this device
X           * maintained by the kernel (IOMan)
X           */
X          ptr = ((Ptystatic) pd.path.pd_dev->V_stat)->v_sysio.v_paths;
X          for(; ptr ; ptr = ptr->path.pd_paths)
X              if( ptr->ptypvt.typ == PTY
X               && strcmp( ptr->ptyopt.pd_name, pd.ptyopt.pd_name) == 0 ) {
X                  pd.ptypvt.pty = ptr;
X
X                  /*
X                   * look through the connected tty-list of the pty
X                   */
X                  for( ptr = ptr->ptypvt.tty; ptr ; ptr = ptr->ptypvt.tty)
X                    if( S_ISHARE & (pd.path.pd_mod | ptr->path.pd_mod) ) {
X                      errno = E_SHARE;
X                      return -1;
X                    }
X                  /*
X                   * Ok: we found a pty with no NON-SHAREABLES ttys
X                   */
X                  pd.ptypvt.tty = pd.ptypvt.pty->ptypvt.tty;
X                  pd.ptypvt.pty->ptypvt.tty = &pd;
X                  /*
X                   * send the pty on onsig, if requested
X                   */
X                  if( pd.ptypvt.pty->ptypvt.onsig != 0 )
X                      kill((ptr->path.pd_cpr ?
X                              ptr->path.pd_cpr : ptr->path.pd_lproc)
X                           ,pd.ptypvt.pty->ptypvt.onsig);
X                  return 0;
X              }
X          /*
X           * not found ... linger around and wait until connected by the pty
X           * any real i/o will isuue an error
X           */
X          return 0;
X      } else {
X          /* pty */
X          /* if same name exists, exists with error */
X
X          /*
X           * The start of all open paths on this device
X           * maintained by the kernel (IOMan)
X           */
X          ptr = ((Ptystatic) pd.path.pd_dev->V_stat)->v_sysio.v_paths;
X          for(; ptr ; ptr = ptr->path.pd_paths)
X              if( ptr->ptypvt.typ == PTY && ptr != &pd
X               && strcmp( ptr->ptyopt.pd_name, pd.ptyopt.pd_name) == 0 ) {
X                  errno = E_SHARE;
X                  return -1;
X              }
X          /*
X           * Ok: we are the only pty with our name
X           * set buffersize and allocate them; if NOMEM exit with error
X           */
X          pd.ptypvt.rbuf.size = pd.ptypvt.wbuf.size = DEFBUFSIZE;
X          if((pd.ptypvt.rbuf.buf =
X                    (u_char *)_srqmem( (pd.ptypvt.rbuf.size))) == (u_char *)0 ||
X             (pd.ptypvt.wbuf.buf =
X                    (u_char *)_srqmem( (pd.ptypvt.wbuf.size))) == (u_char *)0) {
X              if( pd.ptypvt.wbuf.buf )
X                  (void) _srtmem(pd.ptypvt.wbuf.buf,pd.ptypvt.wbuf.size);
X              if( pd.ptypvt.rbuf.buf )
X                  (void) _srtmem(pd.ptypvt.rbuf.buf,pd.ptypvt.rbuf.size);
X              return -1;
X          }
X
X          pd.ptypvt.rbuf.rptr = pd.ptypvt.rbuf.wptr = pd.ptypvt.rbuf.buf;
X          pd.ptypvt.wbuf.rptr = pd.ptypvt.wbuf.wptr = pd.ptypvt.wbuf.buf;
X
X          /*
X           * The start of all open paths on this device
X           * maintained by the kernel (IOMan)
X           */
X          ptr = ((Ptystatic) pd.path.pd_dev->V_stat)->v_sysio.v_paths;
X          /* look for all lingering ttys and connect them */
X          for(; ptr ; ptr = ptr->path.pd_paths)
X              if( ptr->ptypvt.typ == TTY
X               && strcmp( ptr->ptyopt.pd_name, pd.ptyopt.pd_name) == 0 ) {
X                  ptr->ptypvt.pty = &pd;
X                  ptr->ptypvt.tty = pd.ptypvt.tty;
X                  pd.ptypvt.tty = ptr;
X                  /*
X                   * if they had wished on DCON-sig, give them what they want
X                   */
X                  if( ptr->ptypvt.onsig != 0 )
X                      kill( (ptr->path.pd_cpr ?
X                             ptr->path.pd_cpr : ptr->path.pd_lproc)
X                           , ptr->ptypvt.onsig);
X              }
X      }
X    } else {
X      /*
X       * dir-ptys have a list of ptys to output :-)
X       * misuse the tty-list for that
X       */
X      pd.ptypvt.tty = ((Ptystatic) pd.path.pd_dev->V_stat)->v_sysio.v_paths;
X    }
X    return 0;
X}
X
X/*
X * C l o s e
X */
XClose(procdesc, ustack)
X  procid    *procdesc;
X  REGISTERS *ustack;
X{
X    register    struct ptybuf *bptr;
X
X    if( !(pd.path.pd_mod & S_IFDIR)) {
X      /*
X       * non-dir-ptys have some cleanup to do
X       */
X
X      /* clear _ss_sign() */
X      bptr = ( pd.ptypvt.typ == PTY || pd.ptypvt.pty == 0) ?
X          &pd.ptypvt.rbuf :
X          &((pd.ptypvt.pty)->ptypvt.wbuf);
X      if( bptr->rpid == procdesc->_id )
X          bptr->rpid = 0;
X
X      /* deallocate buffer if we are the last incarnation on this pd */
X      if( pd.path.pd_count == 0 )
X          if( pd.ptypvt.typ == PTY ) {
X              register Pathdesc ptr;
X      /*
X       * and send all listening ttys a HUP and mark that the connection
X       * is severed
X       */
X              for(ptr = pd.ptypvt.tty; ptr ; ptr = ptr->ptypvt.tty) {
X                      ptr->ptypvt.pty = (union pathdesc *) 0;
X                      kill( (ptr->path.pd_cpr ?
X                             ptr->path.pd_cpr : ptr->path.pd_lproc)
X                           ,(ptr->ptypvt.offsig ? ptr->ptypvt.offsig : SIGHUP));
X              }
X              (void) _srtmem( pd.ptypvt.rbuf.buf, pd.ptypvt.rbuf.size);
X              (void) _srtmem( pd.ptypvt.wbuf.buf, pd.ptypvt.wbuf.size);
X          } else {
X              if( pd.ptypvt.pty != 0 ) {
X                register Pathdesc ptr;
X
X              /*
X               * tty: ok remove us from the connected-tty-list in the pty
X               * data-structure
X               */
X                for(ptr = pd.ptypvt.pty; ptr ; ptr = ptr->ptypvt.tty)
X                  if( ptr->ptypvt.tty == &pd )
X                    ptr->ptypvt.tty = pd.ptypvt.tty;
X
X              /*
X               * cancel all references to us ... (for echo or whatever)
X               * and send the pty an sighup if requested
X               */
X                if( (pd.ptypvt.pty)->ptypvt.rbuf.lpd == &pd)
X                  (pd.ptypvt.pty)->ptypvt.rbuf.lpd = NULL;
X                if( (pd.ptypvt.pty)->ptypvt.tty == NULL
X                  && (pd.ptypvt.pty)->ptypvt.offsig != 0)
X                  kill( ((pd.ptypvt.pty)->path.pd_cpr ?
X                         (pd.ptypvt.pty)->path.pd_cpr :
X                         (pd.ptypvt.pty)->path.pd_lproc)
X                       ,(pd.ptypvt.pty)->ptypvt.offsig);
X              }
X              /*
X               * if we had a line-editing-buffer .. free it
X               */
X              if( pd.path.pd_buf )
X                  (void) _srtmem( pd.path.pd_buf, LINEBUFSIZ);
X          }
X    } else {
X      pd.ptypvt.tty = 0;
X    }
X    return(0);
X}
X
XIoRet ( bytes , ustack )
Xint         bytes;
XREGISTERS   *ustack;
X{
X    if( bytes < 0) {
X        ustack->d[1] += bytes;
X        return -1;
X    }
X    ustack->d[1] -= bytes;
X    return(0);
X}
X
XReadDir( ustack )
X  REGISTERS *ustack;
X{
X  register int      i;
X  
X  while( pd.ptypvt.tty && ( pd.ptypvt.tty == &pd
X                        || (pd.ptypvt.tty)->ptypvt.typ != pd.ptypvt.typ))
X    pd.ptypvt.tty = (pd.ptypvt.tty)->path.pd_paths;
X  if( pd.ptypvt.tty ) {
X    i = MIN( 32, ustack->d[1] );
X    memcpy( ustack->a[0], (pd.ptypvt.tty)->ptyopt.pd_name, i);
X    ustack->d[1] = i;
X  } else {
X    errno = E_EOF;
X    return -1;
X  }
X  pd.ptypvt.tty = (pd.ptypvt.tty)->path.pd_paths;
X  return 0;
X}
X
XRead(procdesc, ustack)
X  procid    *procdesc;
X  REGISTERS *ustack;
X{
X
X    if( (pd.path.pd_mod & S_IFDIR)) {
X      return(ReadDir( ustack ));
X    }
X
X    /*
X     * return error if no connection established
X     */
X    if( hangup(procdesc) )
X        return -1;
X
X    /*
X     * select buffer ...
X     */
X    if( pd.ptypvt.typ == PTY ) {
X        return( IoRet( (cpinraw( &pd.ptypvt.rbuf, &pd.ptypvt.wbuf,
X            ustack, procdesc)), ustack ));
X    } else {
X        return( IoRet( (cpinraw( &((pd.ptypvt.pty)->ptypvt.wbuf),
X            &((pd.ptypvt.pty)->ptypvt.rbuf), ustack, procdesc)), ustack));
X    }
X}
X
XReadLn(procdesc, ustack)
X  procid    *procdesc;
X  REGISTERS *ustack;
X{
X    if( (pd.path.pd_mod & S_IFDIR)) {
X      return(ReadDir( ustack ));
X    }
X
X    if( hangup(procdesc) )
X        return -1;
X    /*
X     * the line-editing buffer
X     */
X    if( pd.path.pd_buf == NULL) {
X        if((pd.path.pd_buf = (u_char *) _srqmem(LINEBUFSIZ)) == NULL)
X            return(-1);
X        else
X            initbuf(pd.path.pd_buf, LINEBUFSIZ-1);  /* dont change !! */
X    }
X
X    if( ustack->d[1] > LINEBUFSIZ )
X        ustack->d[1] = LINEBUFSIZ;
X
X    /*
X     * select buffer ...
X     */
X    if( pd.ptypvt.typ == PTY ) {
X        return( IoRet( (cpin( &pd.ptypvt.rbuf, &pd.ptypvt.wbuf,
X                              ustack, procdesc))
X                       , ustack ));
X    } else {
X        return( IoRet( (cpin( &((pd.ptypvt.pty)->ptypvt.wbuf),
X                              &((pd.ptypvt.pty)->ptypvt.rbuf),
X                              ustack, procdesc))
X                       , ustack ));
X    }
X}
X
XWrite(procdesc, ustack)
X  procid    *procdesc;
X  REGISTERS *ustack;
X{
X    if( (pd.path.pd_mod & S_IFDIR)) {
X      errno = E_BMODE;
X      return -1;
X    }
X
X    if( hangup(procdesc) )
X        return -1;
X
X    if( pd.ptypvt.typ == PTY ) {
X        return( IoRet( (cpoutraw( &pd.ptypvt.wbuf, &pd.ptypvt.rbuf,
X                                  ustack, procdesc))
X                       , ustack ));
X    } else {
X        return( IoRet( (cpoutraw( &((pd.ptypvt.pty)->ptypvt.rbuf),
X                                  &((pd.ptypvt.pty)->ptypvt.wbuf),
X                                  ustack, procdesc))
X                       , ustack ));
X    }
X}
X
XWriteLn(procdesc, ustack)
X  procid    *procdesc;
X  REGISTERS *ustack;
X{
X    if( (pd.path.pd_mod & S_IFDIR)) {
X      errno = E_BMODE;
X      return -1;
X    }
X
X    if( hangup(procdesc) )
X        return -1;
X
X    if( pd.ptypvt.typ == PTY ) {
X        return( IoRet( (cpout( &pd.ptypvt.wbuf, &pd.ptypvt.rbuf, 
X                               ustack, procdesc))
X                       , ustack ));
X    } else {
X        return( IoRet( (cpout( &((pd.ptypvt.pty)->ptypvt.rbuf), 
X                               &((pd.ptypvt.pty)->ptypvt.wbuf),
X                               ustack, procdesc))
X                       , ustack));
X    }
X}
X
X
X/*
X * G e t S t a t
X */
XGetStat(procdesc, ustack)
X  procid    *procdesc;
X  REGISTERS *ustack;
X{
X    register struct ptybuf  *ptr;
X
X    switch (ustack->d[1] & 0x0ffff) {
X
X        case SS_DevNm:
X            /*
X             * returns name of the [pt]ty ...
X             */
X            memcpy( ustack->a[0], "tty/", 4);
X            if( pd.ptypvt.typ == PTY)
X                    *((u_char *)ustack->a[0]) = 'p';
X            memcpy( ((u_char *)ustack->a[0]) + 4, pd.ptyopt.pd_name,
X                    pd.ptyopt.pd_namlen);
X            *((u_char *) ustack->a[0] + pd.ptyopt.pd_namlen + 4) = '\0';
X            break;
X
X        case SS_Opt:
X            /*
X             * copy the option-field
X             */
X            memcpy( ustack->a[0], &(pd.ptyopt.pd_dtp), OPTMAX);
X            break;
X
X        case SS_Size:
X            /*
X             * buffer size lesen ?!
X             */
X            ustack->d[2] = pd.path.pd_mod & S_IFDIR ? 32 : DEFBUFSIZE ;
X            break;
X
X        default:
X            if( hangup(procdesc) )
X                return -1;
X            switch (ustack->d[1] & 0x0ffff) {
X
X                case SS_Ready:
X                    /*
X                     * return TRUE if number of chars in buffer > 0 ...
X                     */
X                    ptr = ( pd.ptypvt.typ == PTY) ? &pd.ptypvt.rbuf :
X                         &((pd.ptypvt.pty)->ptypvt.wbuf);
X                    if( (ptr->flags & STOPPED)
X                      || (ustack->d[1] = (ptr->wptr - ptr->rptr)) <= 0 ) {
X                        errno = E_NOTRDY;
X                        return -1;
X                    }
X                    break;
X
X                case SS_EOF:
X                    /*
X                     * always return 0
X                     */
X                    ustack->d[1] = 0;
X                    break;
X
X                case SS_BlkRd:
X                    /*
X                     * like a Read
X                     */
X                    ustack->d[1] = ustack->d[2];
X                    return( Read( procdesc, ustack));
X
X                default:        
X                    pd.path.pd_errno = E_UNKSVC;
X                    return(-1);
X            }
X    }
X    return (0);
X}
X
X
X/*
X * S e t S t a t
X */
XSetStat(procdesc, ustack)
X  procid    *procdesc;
X  REGISTERS *ustack;
X{
X    register struct ptybuf  *ptr;
X
X    switch (ustack->d[1] & 0x0ffff) {
X
X        case SS_EnRTS:
X        case SS_DCOn:
X            /*
X             * set the pd_onsig -- thats all
X             */
X            pd.ptypvt.onsig = (u_short) ustack->d[2];
X            break;
X            
X        case SS_DsRTS:
X        case SS_DCOff:
X            /*
X             * set the pd_offsig -- thats all
X             */
X            pd.ptypvt.offsig = (u_short) ustack->d[2];
X            break;
X
X        case SS_Opt:
X            /*
X             * copy the option-field
X             */
X            memcpy( &(pd.ptyopt.pd_dtp), ustack->a[0], OPTMAX);
X            break;
X
X        default:
X            if( hangup(procdesc) )
X                return -1;
X            switch (ustack->d[1] & 0x0ffff) {
X                register    union pathdesc *sp;
X
X                case SS_IOSTOP:
X                    sp = ( pd.ptypvt.typ == PTY) ?
X                              &pd :
X                               pd.ptypvt.pty;
X                    sp->ptypvt.rbuf.flags |= IOSTOP;
X                    sp->ptypvt.wbuf.flags |= IOSTOP;
X                    break;
X
X                case SS_IOCONT:
X                    sp = ( pd.ptypvt.typ == PTY) ?
X                              &pd :
X                               pd.ptypvt.pty;
X                    sp->ptypvt.rbuf.flags &= ~IOSTOP;
X                    WAKE( sp->ptypvt.rbuf.rpid, sp->ptypvt.rbuf.rsig );
X                    sp->ptypvt.wbuf.flags &= ~IOSTOP;
X                    WAKE( sp->ptypvt.wbuf.rpid, sp->ptypvt.wbuf.rsig );
X                    break;
X
X                case SS_SSig:
X                    /*
X                     * set ssig, if someother is already waiting --> error
X                     * if data is already available --> send sig immediatly
X                     */
X                    ptr = ( pd.ptypvt.typ == PTY) ?
X                              &pd.ptypvt.rbuf :
X                              &((pd.ptypvt.pty)->ptypvt.wbuf);
X                    if( ptr->rpid || (ptr->flags & STOPPED)) {
X                        errno = E_NOTRDY;
X                        return -1;
X                    }
X                    if( ((ptr->wptr - ptr->rptr)) <= 0 ) {
X                        ptr->rpid = procdesc->_id;
X                        ptr->rsig = ustack->d[2];
X                    } else kill(procdesc->_id,ustack->d[2]);
X                    break;
X
X                case SS_Relea:
X                    /*
X                     * clear _ss_sign()
X                     */
X                    ptr = ( pd.ptypvt.typ == PTY) ?
X                              &pd.ptypvt.rbuf :
X                              &((pd.ptypvt.pty)->ptypvt.wbuf);
X                    if( ptr->rpid == procdesc->_id)
X                        ptr->rpid = 0;
X                    break;
X#ifdef ST
X                /*
X                 * like Blkwr
X                 */
X                case SS_Screen:
X                    if( (u_short) ustack->d[2] != ScrOut)
X                        break;
X                    ustack->d[2] = ustack->d[3];
X#endif
X                case SS_BlkWr:
X                /*
X                 * like a Write
X                 */
X                    ustack->d[1] = ustack->d[2];
X                    return( Write( procdesc, ustack));
X
X                default:
X                    pd.path.pd_errno = E_UNKSVC;
X                    return(-1);
X            }
X    }
X    return (0);
X}
END_OF_FILE
if test 19781 -ne `wc -c <'ptyman.c'`; then
    echo shar: \"'ptyman.c'\" unpacked with wrong size!
fi
# end of 'ptyman.c'
fi
echo shar: End of archive 2 \(of 2\).
cp /dev/null ark2isdone
MISSING=""
for I in 1 2 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked both archives.
    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
-- 
| Frank Kaefer | fkk@stasys.sta.sub.org | Starnberg, Germany |
| Compuserve: 72427,2101   | Internet: fkk@Germany.Sun.COM   |
| unido!sunde!fkaefer      |    postmaster@Germany.Sun.COM   |
Thread Navigation

This is a paginated view of messages in the thread with full content displayed inline.

Messages are displayed in chronological order, with the original post highlighted in green.

Use pagination controls to navigate through all messages in large threads.

Back to All Threads