!C99Shell v. 1.0 pre-release build #13!

Software: Apache/2.0.54 (Unix) mod_perl/1.99_09 Perl/v5.8.0 mod_ssl/2.0.54 OpenSSL/0.9.7l DAV/2 FrontPage/5.0.2.2635 PHP/4.4.0 mod_gzip/2.0.26.1a 

uname -a: Linux snow.he.net 4.4.276-v2-mono-1 #1 SMP Wed Jul 21 11:21:17 PDT 2021 i686 

uid=99(nobody) gid=98(nobody) groups=98(nobody) 

Safe-mode: OFF (not secure)

/usr/src/linux-2.4.18-xfs-1.1/drivers/s390/char/   drwxr-xr-x
Free 318.35 GB of 458.09 GB (69.5%)
Home    Back    Forward    UPDIR    Refresh    Search    Buffer    Encoder    Tools    Proc.    FTP brute    Sec.    SQL    PHP-code    Update    Feedback    Self remove    Logout    


Viewing file:     tubtty.c (23.16 KB)      -rw-r--r--
Select action/file-type:
(+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
/*
 *  IBM/3270 Driver -- Copyright (C) 2000, 2001 UTS Global LLC
 *
 *  tubtty.c -- Linemode tty driver
 *
 *
 *
 *
 *
 *  Author:  Richard Hitt
 */
#include <linux/config.h>
#include "tubio.h"

/* Initialization & uninitialization for tubtty */
int tty3270_init(void);
void tty3270_fini(void);

/* Interface routines from the upper tty layer to the tty driver */
static int tty3270_open(struct tty_struct *, struct file *);
static void tty3270_close(struct tty_struct *, struct file *);
static int tty3270_write(struct tty_struct *, int,
        const unsigned char *, int);
static void tty3270_put_char(struct tty_struct *, unsigned char);
static void tty3270_flush_chars(struct tty_struct *);
static int tty3270_write_room(struct tty_struct *);
static int tty3270_chars_in_buffer(struct tty_struct *);
static int tty3270_ioctl(struct tty_struct *, struct file *,
    unsigned int cmd, unsigned long arg);
static void tty3270_set_termios(struct tty_struct *, struct termios *);
static void tty3270_hangup(struct tty_struct *);
static void tty3270_flush_buffer(struct tty_struct *);
static int tty3270_read_proc(char *, char **, off_t, int, int *, void *);
static int tty3270_write_proc(struct file *, const char *,
    unsigned long, void *);

/* tty3270 utility functions */
static void tty3270_bh(void *);
       void tty3270_sched_bh(tub_t *);
static int tty3270_wait(tub_t *, long *);
       void tty3270_int(tub_t *, devstat_t *);
       int tty3270_try_logging(tub_t *);
static void tty3270_start_input(tub_t *);
static void tty3270_do_input(tub_t *);
static void tty3270_do_enter(tub_t *, char *, int);
static void tty3270_do_showi(tub_t *, char *, int);
       int tty3270_io(tub_t *);
static int tty3270_show_tube(int, char *, int);

int tty3270_major = -1;
struct tty_driver tty3270_driver;
int tty3270_refcount;
struct tty_struct *tty3270_table[TUBMAXMINS];
struct termios *tty3270_termios[TUBMAXMINS];
struct termios *tty3270_termios_locked[TUBMAXMINS];
#ifdef CONFIG_TN3270_CONSOLE
int con3270_major = -1;
struct tty_driver con3270_driver;
int con3270_refcount;
struct tty_struct *con3270_table[1];
struct termios *con3270_termios[1];
struct termios *con3270_termios_locked[1];
#endif /* CONFIG_TN3270_CONSOLE */

int tty3270_proc_index;
int tty3270_proc_data;
int tty3270_proc_misc;
enum tubwhat tty3270_proc_what;

/*
 * tty3270_init() -- Register the tty3270 driver
 */
int
tty3270_init(void)
{
    struct tty_driver *td = &tty3270_driver;
    int rc;

    /* Initialize for tty driver */
    td->magic = TTY_DRIVER_MAGIC;
    td->driver_name = "tty3270";
    td->name = "tty3270";
    td->major = IBM_TTY3270_MAJOR;
    td->minor_start = 0;
    td->num = TUBMAXMINS;
    td->type = TTY_DRIVER_TYPE_SYSTEM;
    td->subtype = SYSTEM_TYPE_TTY;
    td->init_termios = tty_std_termios;
    td->flags = TTY_DRIVER_RESET_TERMIOS;
#ifdef CONFIG_DEVFS_FS
    td->flags |= TTY_DRIVER_NO_DEVFS;
#endif
    td->refcount = &tty3270_refcount;
    td->table = tty3270_table;
    td->termios = tty3270_termios;
    td->termios_locked = tty3270_termios_locked;

    td->open = tty3270_open;
    td->close = tty3270_close;
    td->write = tty3270_write;
    td->put_char = tty3270_put_char;
    td->flush_chars = tty3270_flush_chars;
    td->write_room = tty3270_write_room;
    td->chars_in_buffer = tty3270_chars_in_buffer;
    td->ioctl = tty3270_ioctl;
    td->ioctl = NULL;
    td->set_termios = tty3270_set_termios;
    td->throttle = NULL;
    td->unthrottle = NULL;
    td->stop = NULL;
    td->start = NULL;
    td->hangup = tty3270_hangup;
    td->break_ctl = NULL;
    td->flush_buffer = tty3270_flush_buffer;
    td->set_ldisc = NULL;
    td->wait_until_sent = NULL;
    td->send_xchar = NULL;
    td->read_proc = tty3270_read_proc;
    td->write_proc = tty3270_write_proc;

    rc = tty_register_driver(td);
    if (rc) {
        printk(KERN_ERR "tty3270 registration failed with %d\n", rc);
    } else {
        tty3270_major = IBM_TTY3270_MAJOR;
        if (td->proc_entry != NULL)
            td->proc_entry->mode = S_IRUGO | S_IWUGO;
    }
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0))
#ifdef CONFIG_TN3270_CONSOLE
    if (CONSOLE_IS_3270) {
        tty3270_con_driver = *td;
        td = &tty3270_con_driver;
        td->driver_name = "con3270";
        td->name = "con3270";
        td->major = MAJOR(S390_CONSOLE_DEV);
        td->minor_start = MINOR(S390_CONSOLE_DEV);
        td->num = 1;
        td->refcount = &con3270_refcount;
        td->table = con3270_table;
        td->termios = con3270_termios;
        td->termios_locked = con3270_termios_locked;

        rc = tty_register_driver(td);
        if (rc) {
            printk(KERN_ERR
                   "con3270 registration failed with %d\n", rc);
        } else {
            con3270_major = MAJOR(S390_CONSOLE_DEV);
            if (td->proc_entry != NULL)
                td->proc_entry->mode = S_IRUGO | S_IWUGO;
        }
    }
#endif /* ifdef CONFIG_TN3270_CONSOLE */
#endif /* if LINUX_VERSION_CODE */

    return rc;
}

/*
 * tty3270_fini() -- Uninitialize linemode tubes
 */
void
tty3270_fini(void)
{
    if (tty3270_major != -1) {
        tty_unregister_driver(&tty3270_driver);
        tty3270_major = -1;
    }
#ifdef CONFIG_TN3270_CONSOLE
    if (CONSOLE_IS_3270 && con3270_major != -1) {
        tty_unregister_driver(&con3270_driver);
        con3270_major = -1;
    }
#endif
}

static int 
tty3270_open(struct tty_struct *tty, struct file *filp)
{
    tub_t *tubp;
    long flags;
    int rc;
    int cmd;

    if ((tubp = TTY2TUB(tty)) == NULL) {
        return -ENODEV;
    }

    tub_inc_use_count();
    if ((rc = tty3270_wait(tubp, &flags)) != 0)
        goto do_fail;
    if (tubp->lnopen > 0) {
        tubp->lnopen++;
        TUBUNLOCK(tubp->irq, flags);
        return 0;
    }
    if (tubp->flags & TUB_OPEN_STET) {
        cmd = TBC_UPDLOG;
    } else {
        cmd = TBC_OPEN;
        tubp->flags &= ~TUB_SIZED;
    }
    if ((rc = tty3270_size(tubp, &flags)) != 0)
        goto do_fail;
    if ((rc = tty3270_rcl_init(tubp)) != 0)
        goto do_fail;
    if ((rc = tty3270_aid_init(tubp)) != 0)
        goto do_fail;
    if ((rc = tty3270_scl_init(tubp)) != 0)
        goto do_fail;
    tubp->mode = TBM_LN;
    tubp->intv = tty3270_int;
    tubp->tty = tty;
    tubp->lnopen = 1;
    tty->driver_data = tubp;
    tty->winsize.ws_row = tubp->geom_rows;
    tty->winsize.ws_col = tubp->geom_cols;
    tubp->tty_inattr = TF_INPUT;
    tubp->cmd = cmd;
    tty3270_build(tubp);
    TUBUNLOCK(tubp->irq, flags);
    return 0;

do_fail:
    tty3270_scl_fini(tubp);
    tty3270_aid_fini(tubp);
    tty3270_rcl_fini(tubp);
    TUBUNLOCK(tubp->irq, flags);
    tub_dec_use_count();
    return rc;
}

static void
tty3270_close(struct tty_struct *tty, struct file *filp)
{
    tub_t *tubp;
    long flags;

    if ((tubp = tty->driver_data) == NULL)
        return;

    tty3270_wait(tubp, &flags);
    if (--tubp->lnopen > 0)
        goto do_return;
    tubp->tty = NULL;
    tty->driver_data = NULL;
    tty3270_aid_fini(tubp);
    tty3270_rcl_fini(tubp);
    tty3270_scl_fini(tubp);
do_return:
    tub_dec_use_count();
    TUBUNLOCK(tubp->irq, flags);
}

static int 
tty3270_write(struct tty_struct *tty, int fromuser,
        const unsigned char *buf, int count)
{
    tub_t *tubp;
    long flags;
    bcb_t obcb;
    int rc = 0;

    if ((tubp = tty->driver_data) == NULL)
        return -1;

#ifdef CONFIG_TN3270_CONSOLE
    if (CONSOLE_IS_3270 && tub3270_con_tubp == tubp)
        tub3270_con_copy(tubp);
#endif /* CONFIG_TN3270_CONSOLE */

    obcb.bc_buf = (char *)buf;
    obcb.bc_len = obcb.bc_cnt = obcb.bc_wr = count;
    obcb.bc_rd = 0;

    TUBLOCK(tubp->irq, flags);
    rc = tub3270_movedata(&obcb, &tubp->tty_bcb, fromuser);
    tty3270_try_logging(tubp);
    TUBUNLOCK(tubp->irq, flags);
    return rc;


static void
tty3270_put_char(struct tty_struct *tty, unsigned char ch)
{
    long flags;
    tub_t *tubp;
    bcb_t *ob;

    if ((tubp = tty->driver_data) == NULL)
        return;

    TUBLOCK(tubp->irq, flags);
    ob = &tubp->tty_bcb;
    if (ob->bc_cnt < ob->bc_len) {
        ob->bc_buf[ob->bc_wr++] = ch;
        if (ob->bc_wr == ob->bc_len)
            ob->bc_wr = 0;
        ob->bc_cnt++;
    }
    tty3270_try_logging(tubp);
    TUBUNLOCK(tubp->irq, flags);
}

static void
tty3270_flush_chars(struct tty_struct *tty)
{
    tub_t *tubp;
    long flags;

    if ((tubp = tty->driver_data) == NULL)
        return;

    TUBLOCK(tubp->irq, flags);
    tty3270_try_logging(tubp);
    TUBUNLOCK(tubp->irq, flags);
}

static int 
tty3270_write_room(struct tty_struct *tty)
{
    tub_t *tubp;
    bcb_t *ob;

    if ((tubp = tty->driver_data) == NULL)
        return -1;

    ob = &tubp->tty_bcb;
    return ob->bc_len - ob->bc_cnt;
}

static int
tty3270_chars_in_buffer(struct tty_struct *tty)
{
    tub_t *tubp;
    bcb_t *ob;

    if ((tubp = tty->driver_data) == NULL)
        return -1;

    ob = &tubp->tty_bcb;
    return ob->bc_cnt;
}

static int
tty3270_ioctl(struct tty_struct *tty, struct file *file,
        unsigned int cmd, unsigned long arg)
{
    tub_t *tubp;
    long flags;
    int ret = 0;
    struct termios termios;

    if ((tubp = tty->driver_data) == NULL)
        return -ENODEV;

    TUBLOCK(tubp->irq, flags);
    if (tty->flags * (1 << TTY_IO_ERROR)) {
        ret = -EIO;
        goto do_return;
    }
    switch(cmd) {
    case TCGETS:
        ret = -ENOIOCTLCMD;
        goto do_return;
    case TCFLSH:            /* arg:  2 or 0 */
        ret = -ENOIOCTLCMD;
        goto do_return;
    case TCSETSF:
        if (user_termios_to_kernel_termios(&termios,
            (struct termios *)arg)) {
            ret = -EFAULT;
            goto do_return;
        }
        ret = -ENOIOCTLCMD;
        goto do_return;
    case TCGETA:
        ret = -ENOIOCTLCMD;
        goto do_return;
    case TCSETA:
        if (user_termio_to_kernel_termios(&termios,
            (struct termio *)arg)) {
            ret = -EFAULT;
            goto do_return;
        }
        ret = -ENOIOCTLCMD;
        goto do_return;
    default:
        ret = -ENOIOCTLCMD;
        break;
    }

do_return:
    TUBUNLOCK(tubp->irq, flags);
    return ret;
}

static void
tty3270_set_termios(struct tty_struct *tty, struct termios *old)
{
    tub_t *tubp;
    long flags;
    int new;

    if ((tubp = tty->driver_data) == NULL)
        return;

    if (tty3270_wait(tubp, &flags) != 0) {
        TUBUNLOCK(tubp->irq, flags);
        return;
    }
    new = L_ICANON(tty)? L_ECHO(tty)? TF_INPUT: TF_INPUTN:
        tubp->tty_inattr;
    if (new != tubp->tty_inattr) {
        tubp->tty_inattr = new;
        tubp->cmd = TBC_CLRINPUT;
        tty3270_build(tubp);
    }

    TUBUNLOCK(tubp->irq, flags);
}

static void
tty3270_flush_buffer(struct tty_struct *tty)
{
    tub_t *tubp;
    bcb_t *ob;
    long flags;

    if ((tubp = tty->driver_data) == NULL)
        return;

    if (tubp->mode == TBM_FS && tubp->fs_pid != 0) {
        kill_proc(tubp->fs_pid, SIGHUP, 1);
    }

    if ((tubp->flags & TUB_OPEN_STET) == 0) {
        ob = &tubp->tty_bcb;
        TUBLOCK(tubp->irq, flags);
        ob->bc_rd = 0;
        ob->bc_wr = 0;
        ob->bc_cnt = 0;
        TUBUNLOCK(tubp->irq, flags);
    }
    wake_up_interruptible(&tty->write_wait);
    if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
        tty->ldisc.write_wakeup)
        (tty->ldisc.write_wakeup)(tty);
}

static int
tty3270_read_proc(char *buf, char **start, off_t off, int count,
        int *eof, void *data)
{
    tub_t *tubp;
    int begin = 0;
    int i;
    int rc;
    int len = 0;

    if (tty3270_proc_what == TW_CONFIG) {
        /*
         * Describe the 3270 configuration in ascii lines.
         * Line 1:        0 <fsmajor> 0
         * Console line:    <devnum> CONSOLE <minor>
         * Other lines:        <devnum> <ttymajor> <minor>
         */
        len += sprintf(buf + len, "0 %d 0\n", fs3270_major);
        for (i = 1; i <= tubnummins; i++) {
            tubp = (*tubminors)[i];
#ifdef CONFIG_TN3270_CONSOLE
            if (CONSOLE_IS_3270 && tubp == tub3270_con_tubp)
                len += sprintf(buf + len, "%.3x CONSOLE %d\n",
                           tubp->devno, i);
            else
#endif
                len += sprintf(buf + len, "%.3x %d %d\n",
                           tubp->devno, tty3270_major, i);
            if (begin + len > off + count)
                break;
            if (begin + len < off) {
                begin += len;
                len = 0;
            }
        }
        if (i > tubnummins)
            *eof = 1;
        if (off >= begin + len) {
            rc = 0;
        } else {
            *start = buf + off - begin;
            rc = MIN(count, begin + len - off);
        }
        if (*eof && rc == 0)
            tty3270_proc_what = TW_BOGUS;
        return rc;
    }

    len += sprintf(buf, "There are %d devices.  fs major is %d, "
        "tty major is %d.\n", tubnummins, fs3270_major,
        tty3270_major);
    len += sprintf(buf+len, "        index=%d data=%d misc=%d\n",
        tty3270_proc_index,
        tty3270_proc_data,
        tty3270_proc_misc);

    /*
     * Display info for the tube with minor nr in index
     */
    len += tty3270_show_tube(tty3270_proc_index, buf+len, count-len);

    *eof = 1;
    if (off >= begin + len)
        return 0;
    *start = buf + off - begin;
    return MIN(count, begin + len - off);
}

static int
tty3270_write_proc(struct file *file, const char *buffer,
        unsigned long count, void *data)
{
    char mybuf[GEOM_MAXINPLEN];
    int mycount;
    tub_t *tubp;
    struct tty_struct *tty;
    kdev_t device;
    int rc;

    mycount = MIN(count, sizeof mybuf - 1);
    if (copy_from_user(mybuf, buffer, mycount) != 0)
        return -EFAULT;
    mybuf[mycount] = '\0';

    /*
     * User-mode settings affect only the current tty ---
     */
    tubp = NULL;
    tty = current->tty;
    device = tty? tty->device: 0;
    if (device) {
        if (MAJOR(device) == IBM_TTY3270_MAJOR)
            tubp = (*tubminors)[MINOR(device)];
#ifdef CONFIG_TN3270_CONSOLE
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0))
        if (CONSOLE_IS_3270 && device == S390_CONSOLE_DEV)
            tubp = tub3270_con_tubp;
#endif /* LINUX_VERSION_CODE */
#endif /* CONFIG_TN3270_CONSOLE */
    }
    if (tubp) {
        if ((rc = tty3270_aid_set(tubp, mybuf, mycount + 1)))
            return rc > 0? count: rc;
        if ((rc = tty3270_rcl_set(tubp, mybuf, mycount + 1)))
            return rc > 0? count: rc;
        if ((rc = tty3270_scl_set(tubp, mybuf, mycount + 1)))
            return rc > 0? count: rc;
    }

    /*
     * Superuser-mode settings affect the driver overall ---
     */
    if (!suser()) {
        return -EPERM;
    } else if (strncmp(mybuf, "index=", 6) == 0) {
        tty3270_proc_index = simple_strtoul(mybuf + 6, 0,0);
        return count;
    } else if (strncmp(mybuf, "data=", 5) == 0) {
        tty3270_proc_data = simple_strtoul(mybuf + 5, 0, 0);
        return count;
    } else if (strncmp(mybuf, "misc=", 5) == 0) {
        tty3270_proc_misc = simple_strtoul(mybuf + 5, 0, 0);
        return count;
    } else if (strncmp(mybuf, "what=", 5) == 0) {
        if (strcmp(mybuf+5, "bogus") == 0)
            tty3270_proc_what = 0;
        else if (strncmp(mybuf+5, "config", 6) == 0)
            tty3270_proc_what = TW_CONFIG;
        return count;
    } else {
        return -EINVAL;
    }
}

static void
tty3270_hangup(struct tty_struct *tty)
{
    tub_t *tubp;
    extern void fs3270_release(tub_t *);

    if ((tubp = tty->driver_data) == NULL)
        return;
    tty3270_rcl_purge(tubp);
    tty3270_aid_reinit(tubp);
    fs3270_release(tubp);
}


/*
 * tty3270_bh(tubp) -- Perform back-half processing
 */
static void
tty3270_bh(void *data)
{
    long flags;
    tub_t *tubp;
    struct tty_struct *tty;

    tubp = data;
    TUBLOCK(tubp->irq, flags);
    tubp->flags &= ~TUB_BHPENDING;
    tty = tubp->tty;

    if (tubp->flags & TUB_UNSOL_DE) {
        tubp->flags &= ~TUB_UNSOL_DE;
        if (tty != NULL) {
            tty_hangup(tty);
            wake_up_interruptible(&tubp->waitq);
            goto do_unlock;
        }
    }

    if (tubp->flags & TUB_IACTIVE) {        /* If read ended, */
        tty3270_do_input(tubp);
        tubp->flags &= ~TUB_IACTIVE;
    }

    if ((tubp->flags & TUB_WORKING) == 0) {
        if (tubp->flags & TUB_ATTN) {
            tty3270_start_input(tubp);
            tubp->flags &= ~TUB_ATTN;
        } else if (tty3270_try_logging(tubp) == 0) {
            wake_up_interruptible(&tubp->waitq);
        }
    }

    if (tty != NULL) {
        if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
            tty->ldisc.write_wakeup != NULL)
            (tty->ldisc.write_wakeup)(tty);
        wake_up_interruptible(&tty->write_wait);
    }
do_unlock:
    TUBUNLOCK(tubp->irq, flags);
}

/*
 * tty3270_sched_bh(tubp) -- Schedule the back half
 * Irq lock must be held on entry and remains held on exit.
 */
void
tty3270_sched_bh(tub_t *tubp)
{
    if (tubp->flags & TUB_BHPENDING)
        return;
    tubp->flags |= TUB_BHPENDING;
    tubp->tqueue.routine = tty3270_bh;
    tubp->tqueue.data = tubp;
    queue_task(&tubp->tqueue, &tq_immediate);
    mark_bh(IMMEDIATE_BH);
}

/*
 * tty3270_io() -- Perform line-mode reads and writes here
 */
int 
tty3270_io(tub_t *tubp)
{
    int rc;
    ccw1_t *ccwp;

    tubp->flags |= TUB_WORKING;
    tubp->dstat = 0;
    ccwp = &tubp->ttyccw;

    rc = do_IO(tubp->irq, ccwp, tubp->irq, 0, 0);
    return rc;
}

/*
 * tty3270_wait(tubp) -- Wait until TUB_WORKING is off
 * On entry the lock must not be held; on exit it is held.
 */
static int
tty3270_wait(tub_t *tubp, long *flags)
{
    DECLARE_WAITQUEUE(wait, current);

    TUBLOCK(tubp->irq, *flags);
    add_wait_queue(&tubp->waitq, &wait);
    while (!signal_pending(current) &&
        (tubp->flags & TUB_WORKING) != 0) {
        current->state = TASK_INTERRUPTIBLE;
        TUBUNLOCK(tubp->irq, *flags);
        schedule();
        current->state = TASK_RUNNING;
        TUBLOCK(tubp->irq, *flags);
    }
    remove_wait_queue(&tubp->waitq, &wait);
    return signal_pending(current)? -ERESTARTSYS: 0;
}

void
tty3270_int(tub_t *tubp, devstat_t *dsp)
{
#define    DEV_UE_BUSY \
    (DEV_STAT_CHN_END | DEV_STAT_DEV_END | DEV_STAT_UNIT_EXCEP)
#define DEV_NOT_WORKING \
    (DEV_STAT_ATTENTION | DEV_STAT_DEV_END | DEV_STAT_UNIT_CHECK)

    tubp->dstat = dsp->dstat;

    /* Handle CE-DE-UE and subsequent UDE */
    if (dsp->dstat == DEV_UE_BUSY) {
        tubp->flags |= TUB_UE_BUSY;
        return;
    } else if (tubp->flags & TUB_UE_BUSY) {
        tubp->flags &= ~TUB_UE_BUSY;
        if (dsp->dstat == DEV_STAT_DEV_END &&
            (tubp->flags & TUB_WORKING) != 0) {
            tty3270_io(tubp);
            return;
        }
    }

    /* Handle ATTN */
    if (dsp->dstat & DEV_STAT_ATTENTION)
        tubp->flags |= TUB_ATTN;

    if (dsp->dstat & DEV_STAT_CHN_END) {
        tubp->cswl = dsp->rescnt;
        if ((dsp->dstat & DEV_STAT_DEV_END) == 0)
            tubp->flags |= TUB_EXPECT_DE;
        else
            tubp->flags &= ~TUB_EXPECT_DE;
    } else if (dsp->dstat & DEV_STAT_DEV_END) {
        if ((tubp->flags & TUB_EXPECT_DE) == 0)
            tubp->flags |= TUB_UNSOL_DE;
        tubp->flags &= ~TUB_EXPECT_DE;
    }
    if (dsp->dstat & DEV_NOT_WORKING)
        tubp->flags &= ~TUB_WORKING;
    if (dsp->dstat & DEV_STAT_UNIT_CHECK)
        tubp->sense = dsp->ii.sense;
    if ((tubp->flags & TUB_WORKING) == 0)
        tty3270_sched_bh(tubp);
}

/*
 * tty3270_refresh(), called by fs3270_close() when tubp->fsopen == 0.
 * On entry, lock is held.
 */
void
tty3270_refresh(tub_t *tubp)
{
    if (tubp->lnopen) {
        tubp->mode = TBM_LN;
        tubp->intv = tty3270_int;
        tty3270_scl_resettimer(tubp);
        tubp->cmd = TBC_UPDATE;
        tty3270_build(tubp);
    }
}

int
tty3270_try_logging(tub_t *tubp)
{
    if (tubp->flags & TUB_WORKING)
        return 0;
    if (tubp->mode == TBM_FS)
        return 0;
    if (tubp->stat == TBS_HOLD)
        return 0;
    if (tubp->stat == TBS_MORE)
        return 0;
#ifdef CONFIG_TN3270_CONSOLE
    if (CONSOLE_IS_3270 && tub3270_con_tubp == tubp)
        tub3270_con_copy(tubp);
#endif /* CONFIG_TN3270_CONSOLE */
    if (tubp->tty_bcb.bc_cnt == 0)
        return 0;
    if (tubp->intv != tty3270_int)
        return 0;
    tubp->cmd = TBC_UPDLOG;
    return tty3270_build(tubp);
}

/* tty3270 utility functions */

static void
tty3270_start_input(tub_t *tubp)
{
    tubp->ttyccw.cda = virt_to_phys(&tubp->tty_input);
    tubp->ttyccw.cmd_code = TC_READMOD;
    tubp->ttyccw.count = GEOM_INPLEN;
    tubp->ttyccw.flags = CCW_FLAG_SLI;
    tty3270_io(tubp);
    tubp->flags |= TUB_IACTIVE;
}

static void
tty3270_do_input(tub_t *tubp)
{
    int count;
    char *in;
    int aidflags;
    char *aidstring;

    count = GEOM_INPLEN - tubp->cswl;
    in = tubp->tty_input;
    tty3270_aid_get(tubp, in[0], &aidflags, &aidstring);

    if (aidflags & TA_CLEARKEY) {
        tubp->stat = TBS_RUNNING;
        tty3270_scl_resettimer(tubp);
        tubp->cmd = TBC_UPDATE;
    } else if (aidflags & TA_CLEARLOG) {
        tubp->stat = TBS_RUNNING;
        tty3270_scl_resettimer(tubp);
        tubp->cmd = TBC_CLRUPDLOG;
    } else if (aidflags & TA_DOENTER) {
        if (count <= 6) {
            switch(tubp->stat) {
            case TBS_MORE:
                tubp->stat = TBS_HOLD;
                tty3270_scl_resettimer(tubp);
                break;
            case TBS_HOLD:
                tubp->stat = TBS_MORE;
                tty3270_scl_settimer(tubp);
                break;
            case TBS_RUNNING:
                                tty3270_do_enter(tubp, in + 6, 0);
                break;
            }
            tubp->cmd = TBC_UPDSTAT;
            goto do_build;
        }
        in += 6;
        count -= 6;
        TUB_EBCASC(in, count);
        tubp->cmd = TBC_CLRINPUT;
        tty3270_do_enter(tubp, in, count);
    } else if ((aidflags & TA_DOSTRING) != 0 && aidstring != NULL) {
        tubp->cmd = TBC_KRUPDLOG;
        tty3270_do_enter(tubp, aidstring, strlen(aidstring));
    } else if ((aidflags & TA_DOSTRINGD) != 0 && aidstring != NULL) {
        tty3270_do_showi(tubp, aidstring, strlen(aidstring));
        tubp->cmd = TBC_UPDINPUT;
    } else {
        if (in[0] != 0x60)
            tubp->flags |= TUB_ALARM;
        tubp->cmd = TBC_KRUPDLOG;
    }
do_build:
    tty3270_build(tubp);
}

static void
tty3270_do_enter(tub_t *tubp, char *cp, int count)
{
    struct tty_struct *tty;
    int func = -1;

    if ((tty = tubp->tty) == NULL)
        return;
    if (count < 0)
        return;
    if (count == 2 && (cp[0] == '^' || cp[0] == '\252')) {
        switch(cp[1]) {
        case 'c':  case 'C':
            func = INTR_CHAR(tty);
            break;
        case 'd':  case 'D':
            func = EOF_CHAR(tty);
            break;
        case 'z':  case 'Z':
            func = SUSP_CHAR(tty);
            break;
        }
    } else if (count == 2 && cp[0] == 0x1b) {        /* if ESC */
        int inc = 0;
        char buf[GEOM_INPLEN + 1];
        int len;

        switch(cp[1]) {
        case 'k':  case 'K':
            inc = -1;
            break;
        case 'j':  case 'J':
            inc = 1;
            break;
        }
        if (inc == 0)
            goto not_rcl;
        len = tty3270_rcl_get(tubp, buf, sizeof buf, inc);
        if (len == 0) {
            tubp->flags |= TUB_ALARM;
            return;
        }
        tty3270_do_showi(tubp, buf, len);
        tubp->cmd = TBC_UPDINPUT;
        return;
    }
not_rcl:
    if (func != -1) {
        *tty->flip.flag_buf_ptr++ = TTY_NORMAL;
        *tty->flip.char_buf_ptr++ = func;
        tty->flip.count++;
    } else {
        tty3270_rcl_put(tubp, cp, count);
        memcpy(tty->flip.char_buf_ptr, cp, count);
        /* Add newline unless line ends with "^n" */
        if (count < 2 || cp[count - 1] != 'n' ||
            (cp[count - 2] != '^' && cp[count - 2] != '\252')) {
            tty->flip.char_buf_ptr[count] = '\n';
            count++;
        } else {
            count -= 2;     /* Lop trailing "^n" from text */
        }
        memset(tty->flip.flag_buf_ptr, TTY_NORMAL, count);
        tty->flip.char_buf_ptr += count;
        tty->flip.flag_buf_ptr += count;
        tty->flip.count += count;
    }
    tty_flip_buffer_push(tty);
}

static void
tty3270_do_showi(tub_t *tubp, char *cp, int cl)
{
    if (cl > GEOM_INPLEN)
        cl = GEOM_INPLEN;
    memset(tubp->tty_input, 0, GEOM_INPLEN);
    memcpy(tubp->tty_input, cp, cl);
    TUB_ASCEBC(tubp->tty_input, cl);
}



/* Debugging routine */
static int
tty3270_show_tube(int minor, char *buf, int count)
{
    tub_t *tubp;
    struct tty_struct *tty;
    struct termios *mp;
    int len;

/*012345678901234567890123456789012345678901234567890123456789       */
/*Info for tub_t[dd] at xxxxxxxx:                                    */
/*    geom:  rows=dd cols=dd model=d                                 */
/*    lnopen=dd     fsopen=dd   waitq=xxxxxxxx                       */
/*    dstat=xx      mode=dd     stat=dd     flags=xxxx               */
/*    oucount=dddd  ourd=ddddd  ouwr=ddddd  nextlogx=ddddd           */
/*    tty=xxxxxxxx                                                   */
/*    write_wait=xxxxxxxx read_wait=xxxxxxxx                         */
/*    iflag=xxxxxxxx oflag=xxxxxxxx cflag=xxxxxxxx lflag=xxxxxxxx    */

    if (minor < 0 || minor > tubnummins ||
        (tubp = (*tubminors)[minor]) == NULL)
        return sprintf(buf, "No tube at index=%d\n", minor);
    
    tty = tubp->tty;
    len = 0;

    len += sprintf(buf+len, "Info for tub_t[%d] at %p:\n", minor, tubp);

    len += sprintf(buf+len, "inattr is at %p\n", &tubp->tty_inattr);


    len += sprintf(buf+len, "    geom:  rows=%.2d cols=%.2d model=%.1d\n",
               tubp->geom_rows, tubp->geom_cols, tubp->tubiocb.model);

    len += sprintf(buf+len,
               "    lnopen=%-2d     fsopen=%-2d   waitq=%p\n",
               tubp->lnopen, tubp->fsopen, &tubp->waitq);

    len += sprintf(buf+len, "    dstat=%.2x      mode=%-2d     "
               "stat=%-2d     flags=%-4x\n", tubp->dstat,
               tubp->mode, tubp->stat, tubp->flags);

#ifdef RBH_FIXTHIS
    len += sprintf(buf+len,
               "    oucount=%-4d  ourd=%-5d  ouwr=%-5d"
               "  nextlogx=%-5d\n", tubp->tty_oucount,
               tubp->tty_ourd, tubp->tty_ouwr, tubp->tty_nextlogx);
#endif

    len += sprintf(buf+len, "    tty=%p\n",tubp->tty);

    if (tty)
        len += sprintf(buf+len,
                "    write_wait=%p read_wait=%p\n",
                &tty->write_wait, &tty->read_wait);

    if (tty && ((mp = tty->termios)))
        len += sprintf(buf+len,"    iflag=%.8x oflag=%.8x "
                   "cflag=%.8x lflag=%.8x\n", mp->c_iflag,
                   mp->c_oflag, mp->c_cflag, mp->c_lflag);


    return len;
}

:: Command execute ::

Enter:
 
Select:
 

:: Search ::
  - regexp 

:: Upload ::
 
[ Read-Only ]

:: Make Dir ::
 
[ Read-Only ]
:: Make File ::
 
[ Read-Only ]

:: Go Dir ::
 
:: Go File ::
 

--[ c99shell v. 1.0 pre-release build #13 powered by Captain Crunch Security Team | http://ccteam.ru | Generation time: 0.0059 ]--