!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/char/   drwxr-xr-x
Free 318.38 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:     busmouse.c (10.04 KB)      -rw-r--r--
Select action/file-type:
(+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
/*
 * linux/drivers/char/busmouse.c
 *
 * Copyright (C) 1995 - 1998 Russell King <linux@arm.linux.org.uk>
 *  Protocol taken from original busmouse.c
 *  read() waiting taken from psaux.c
 *
 * Medium-level interface for quadrature or bus mice.
 */

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/signal.h>
#include <linux/slab.h>
#include <linux/errno.h>
#include <linux/mm.h>
#include <linux/poll.h>
#include <linux/miscdevice.h>
#include <linux/random.h>
#include <linux/init.h>
#include <linux/smp_lock.h>

#include <asm/uaccess.h>
#include <asm/system.h>
#include <asm/io.h>

#include "busmouse.h"

/* Uncomment this if your mouse drivers expect the kernel to
 * return with EAGAIN if the mouse does not have any events
 * available, even if the mouse is opened in blocking mode.
 * Please report use of this "feature" to the author using the
 * above address.
 */
/*#define BROKEN_MOUSE*/

struct busmouse_data {
    struct miscdevice    miscdev;
    struct busmouse        *ops;
    spinlock_t        lock;

    wait_queue_head_t    wait;
    struct fasync_struct    *fasyncptr;
    char            active;
    char            buttons;
    char            ready;
    int            dxpos;
    int            dypos;
};

#define NR_MICE            15
#define FIRST_MOUSE        0
#define DEV_TO_MOUSE(dev)    MINOR_TO_MOUSE(MINOR(dev))
#define MINOR_TO_MOUSE(minor)    ((minor) - FIRST_MOUSE)

/*
 *    List of mice and guarding semaphore. You must take the semaphore
 *    before you take the misc device semaphore if you need both
 */
 
static struct busmouse_data *busmouse_data[NR_MICE];
static DECLARE_MUTEX(mouse_sem);

/**
 *    busmouse_add_movement - notification of a change of mouse position
 *    @mousedev: mouse number
 *    @dx: delta X movement
 *    @dy: delta Y movement
 *    @buttons: new button state
 *
 *    Updates the mouse position and button information. The mousedev
 *    parameter is the value returned from register_busmouse. The
 *    movement information is updated, and the new button state is
 *    saved.  A waiting user thread is woken.
 */
 
void busmouse_add_movementbuttons(int mousedev, int dx, int dy, int buttons)
{
    struct busmouse_data *mse = busmouse_data[mousedev];
    int changed;

    spin_lock(&mse->lock);
    changed = (dx != 0 || dy != 0 || mse->buttons != buttons);

    if (changed) {
        add_mouse_randomness((buttons << 16) + (dy << 8) + dx);

        mse->buttons = buttons;
        mse->dxpos += dx;
        mse->dypos += dy;
        mse->ready = 1;

        /*
         * keep dx/dy reasonable, but still able to track when X (or
         * whatever) must page or is busy (i.e. long waits between
         * reads)
         */
        if (mse->dxpos < -2048)
            mse->dxpos = -2048;
        if (mse->dxpos > 2048)
            mse->dxpos = 2048;
        if (mse->dypos < -2048)
            mse->dypos = -2048;
        if (mse->dypos > 2048)
            mse->dypos = 2048;
    }

    spin_unlock(&mse->lock);

    if (changed) {
        wake_up(&mse->wait);

        kill_fasync(&mse->fasyncptr, SIGIO, POLL_IN);
    }
}

/**
 *    busmouse_add_movement - notification of a change of mouse position
 *    @mousedev: mouse number
 *    @dx: delta X movement
 *    @dy: delta Y movement
 *
 *    Updates the mouse position. The mousedev parameter is the value
 *    returned from register_busmouse. The movement information is
 *    updated, and a waiting user thread is woken.
 */
 
void busmouse_add_movement(int mousedev, int dx, int dy)
{
    struct busmouse_data *mse = busmouse_data[mousedev];

    busmouse_add_movementbuttons(mousedev, dx, dy, mse->buttons);
}

/**
 *    busmouse_add_buttons - notification of a change of button state
 *    @mousedev: mouse number
 *    @clear: mask of buttons to clear
 *    @eor: mask of buttons to change
 *
 *    Updates the button state. The mousedev parameter is the value
 *    returned from register_busmouse. The buttons are updated by:
 *        new_state = (old_state & ~clear) ^ eor
 *    A waiting user thread is woken up.
 */
 
void busmouse_add_buttons(int mousedev, int clear, int eor)
{
    struct busmouse_data *mse = busmouse_data[mousedev];

    busmouse_add_movementbuttons(mousedev, 0, 0, (mse->buttons & ~clear) ^ eor);
}

static int busmouse_fasync(int fd, struct file *filp, int on)
{
    struct busmouse_data *mse = (struct busmouse_data *)filp->private_data;
    int retval;

    retval = fasync_helper(fd, filp, on, &mse->fasyncptr);
    if (retval < 0)
        return retval;
    return 0;
}

static int busmouse_release(struct inode *inode, struct file *file)
{
    struct busmouse_data *mse = (struct busmouse_data *)file->private_data;
    int ret = 0;

    lock_kernel();
    busmouse_fasync(-1, file, 0);

    if (--mse->active == 0) {
        if (mse->ops->release)
            ret = mse->ops->release(inode, file);
           if (mse->ops->owner)
            __MOD_DEC_USE_COUNT(mse->ops->owner);
        mse->ready = 0;
    }
    unlock_kernel();

    return ret;
}

static int busmouse_open(struct inode *inode, struct file *file)
{
    struct busmouse_data *mse;
    unsigned int mousedev;
    int ret;

    mousedev = DEV_TO_MOUSE(inode->i_rdev);
    if (mousedev >= NR_MICE)
        return -EINVAL;

    down(&mouse_sem);
    mse = busmouse_data[mousedev];
    ret = -ENODEV;
    if (!mse || !mse->ops)    /* shouldn't happen, but... */
        goto end;

    if (mse->ops->owner && !try_inc_mod_count(mse->ops->owner))
        goto end;

    ret = 0;
    if (mse->ops->open) {
        ret = mse->ops->open(inode, file);
        if (ret && mse->ops->owner)
            __MOD_DEC_USE_COUNT(mse->ops->owner);
    }

    if (ret)
        goto end;

    file->private_data = mse;

    if (mse->active++)
        goto end;

    spin_lock_irq(&mse->lock);

    mse->ready   = 0;
    mse->dxpos   = 0;
    mse->dypos   = 0;
    mse->buttons = mse->ops->init_button_state;

    spin_unlock_irq(&mse->lock);
end:
    up(&mouse_sem);
    return ret;
}

static ssize_t busmouse_write(struct file *file, const char *buffer, size_t count, loff_t *ppos)
{
    return -EINVAL;
}

static ssize_t busmouse_read(struct file *file, char *buffer, size_t count, loff_t *ppos)
{
    struct busmouse_data *mse = (struct busmouse_data *)file->private_data;
    DECLARE_WAITQUEUE(wait, current);
    int dxpos, dypos, buttons;

    if (count < 3)
        return -EINVAL;

    spin_lock_irq(&mse->lock);

    if (!mse->ready) {
#ifdef BROKEN_MOUSE
        spin_unlock_irq(&mse->lock);
        return -EAGAIN;
#else
        if (file->f_flags & O_NONBLOCK) {
            spin_unlock_irq(&mse->lock);
            return -EAGAIN;
        }

        add_wait_queue(&mse->wait, &wait);
repeat:
        set_current_state(TASK_INTERRUPTIBLE);
        if (!mse->ready && !signal_pending(current)) {
            spin_unlock_irq(&mse->lock);
            schedule();
            spin_lock_irq(&mse->lock);
            goto repeat;
        }

        current->state = TASK_RUNNING;
        remove_wait_queue(&mse->wait, &wait);

        if (signal_pending(current)) {
            spin_unlock_irq(&mse->lock);
            return -ERESTARTSYS;
        }
#endif
    }

    dxpos = mse->dxpos;
    dypos = mse->dypos;
    buttons = mse->buttons;

    if (dxpos < -127)
        dxpos =- 127;
    if (dxpos > 127)
        dxpos = 127;
    if (dypos < -127)
        dypos =- 127;
    if (dypos > 127)
        dypos = 127;

    mse->dxpos -= dxpos;
    mse->dypos -= dypos;

    /* This is something that many drivers have apparantly
     * forgotten...  If the X and Y positions still contain
     * information, we still have some info ready for the
     * user program...
     */
    mse->ready = mse->dxpos || mse->dypos;

    spin_unlock_irq(&mse->lock);

    /* Write out data to the user.  Format is:
     *   byte 0 - identifer (0x80) and (inverted) mouse buttons
     *   byte 1 - X delta position +/- 127
     *   byte 2 - Y delta position +/- 127
     */
    if (put_user((char)buttons | 128, buffer) ||
        put_user((char)dxpos, buffer + 1) ||
        put_user((char)dypos, buffer + 2))
        return -EFAULT;

    if (count > 3 && clear_user(buffer + 3, count - 3))
        return -EFAULT;

    file->f_dentry->d_inode->i_atime = CURRENT_TIME;

    return count;
}

/* No kernel lock held - fine */
static unsigned int busmouse_poll(struct file *file, poll_table *wait)
{
    struct busmouse_data *mse = (struct busmouse_data *)file->private_data;

    poll_wait(file, &mse->wait, wait);

    if (mse->ready)
        return POLLIN | POLLRDNORM;

    return 0;
}

struct file_operations busmouse_fops=
{
    owner:        THIS_MODULE,
    read:        busmouse_read,
    write:        busmouse_write,
    poll:        busmouse_poll,
    open:        busmouse_open,
    release:    busmouse_release,
    fasync:        busmouse_fasync,
};

/**
 *    register_busmouse - register a bus mouse interface
 *    @ops: busmouse structure for the mouse
 *
 *    Registers a mouse with the driver. The return is mouse number on
 *    success and a negative errno code on an error. The passed ops
 *    structure most not be freed until the mouser is unregistered
 */
 
int register_busmouse(struct busmouse *ops)
{
    unsigned int msedev = MINOR_TO_MOUSE(ops->minor);
    struct busmouse_data *mse;
    int ret;

    if (msedev >= NR_MICE) {
        printk(KERN_ERR "busmouse: trying to allocate mouse on minor %d\n",
               ops->minor);
        return -EINVAL;
    }

    mse = kmalloc(sizeof(*mse), GFP_KERNEL);
    if (!mse)
        return -ENOMEM;

    down(&mouse_sem);
    if (busmouse_data[msedev])
    {
        up(&mouse_sem);
        kfree(mse);
        return -EBUSY;
    }

    memset(mse, 0, sizeof(*mse));

    mse->miscdev.minor = ops->minor;
    mse->miscdev.name = ops->name;
    mse->miscdev.fops = &busmouse_fops;
    mse->ops = ops;
    mse->lock = (spinlock_t)SPIN_LOCK_UNLOCKED;
    init_waitqueue_head(&mse->wait);

    busmouse_data[msedev] = mse;

    ret = misc_register(&mse->miscdev);
    if (!ret)
        ret = msedev;
    up(&mouse_sem);
    
    return ret;
}

/**
 *    unregister_busmouse - unregister a bus mouse interface
 *    @mousedev: Mouse number to release
 *
 *    Unregister a previously installed mouse handler. The mousedev
 *    passed is the return code from a previous call to register_busmouse
 */
 

int unregister_busmouse(int mousedev)
{
    int err = -EINVAL;

    if (mousedev < 0)
        return 0;
    if (mousedev >= NR_MICE) {
        printk(KERN_ERR "busmouse: trying to free mouse on"
               " mousedev %d\n", mousedev);
        return -EINVAL;
    }

    down(&mouse_sem);
    
    if (!busmouse_data[mousedev]) {
        printk(KERN_WARNING "busmouse: trying to free free mouse"
               " on mousedev %d\n", mousedev);
        goto fail;
    }

    if (busmouse_data[mousedev]->active) {
        printk(KERN_ERR "busmouse: trying to free active mouse"
               " on mousedev %d\n", mousedev);
        goto fail;
    }

    err = misc_deregister(&busmouse_data[mousedev]->miscdev);

    kfree(busmouse_data[mousedev]);
    busmouse_data[mousedev] = NULL;
fail:
    up(&mouse_sem);
    return err;
}

EXPORT_SYMBOL(busmouse_add_movementbuttons);
EXPORT_SYMBOL(busmouse_add_movement);
EXPORT_SYMBOL(busmouse_add_buttons);
EXPORT_SYMBOL(register_busmouse);
EXPORT_SYMBOL(unregister_busmouse);

MODULE_LICENSE("GPL");

:: 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.0299 ]--