Esempio n. 1
0
/*
 * The additional architecture-specific notes for Cell are various
 * context files in the spu context.
 *
 * This function iterates over all open file descriptors and sees
 * if they are a directory in spufs.  In that case we use spufs
 * internal functionality to dump them without needing to actually
 * open the files.
 */
static struct spu_context *coredump_next_context(int *fd)
{
	struct fdtable *fdt = files_fdtable(current->files);
	struct file *file;
	struct spu_context *ctx = NULL;

	for (; *fd < fdt->max_fds; (*fd)++) {
		if (!FD_ISSET(*fd, fdt->open_fds))
			continue;

		file = fcheck(*fd);

		if (!file || file->f_op != &spufs_context_fops)
			continue;

		ctx = SPUFS_I(file->f_dentry->d_inode)->i_ctx;
		if (ctx->flags & SPU_CREATE_NOSCHED)
			continue;

		/* start searching the next fd next time we're called */
		(*fd)++;
		break;
	}

	return ctx;
}
Esempio n. 2
0
File: app.c Progetto: postgetme/crco
static INT8S fs_init (void)
{
   INT32U retv;

   retv = finit ();

   spi_hi_speed (__TRUE); 

   if (retv == 0) {
      retv = fcheck ("S:");
   }
   else
   {
      retv = fformat ("S:");
      if (retv == 0)
      {
         return 0;
      }
      else
      {
         return -1;
      }
   }

   return 0;
}
Esempio n. 3
0
asmlinkage int sys_dup2(unsigned int oldfd, unsigned int newfd)
{
	int err = -EBADF;

	lock_kernel();
#ifdef FDSET_DEBUG	
	printk (KERN_ERR __FUNCTION__ " 0: oldfd = %d, newfd = %d\n", 
		oldfd, newfd);
#endif
	if (!fcheck(oldfd))
		goto out;
	if (newfd >= NR_OPEN)
		goto out;	/* following POSIX.1 6.2.1 */

	err = newfd;
	if (newfd == oldfd)
		goto out;

	/* We must be able to do the fd setting inside dupfd() without
           blocking after the sys_close(). */
	if ((err = expand_files(current->files, newfd)) < 0)
		goto out;
	
	sys_close(newfd);
	err = dupfd(oldfd, newfd);
out:
#ifdef FDSET_DEBUG	
	printk (KERN_ERR __FUNCTION__ ": return %d\n", err);
#endif
	unlock_kernel();
	return err;
}
Esempio n. 4
0
static void
timod_error(int fd, int prim, int terr, int uerr)
{
	struct file		*fp;
	struct T_primsg		*it;
	struct T_error_ack	*err;

#if defined(CONFIG_ABI_TRACE)
	abi_trace(ABI_TRACE_STREAMS, "TI: %u error prim=%d, TLI=%d, UNIX=%d\n",
			fd, prim, terr, uerr);
#endif

	fp = fcheck(fd);
	it = timod_mkctl(sizeof(struct T_error_ack));
	if (!it)
		return;

	err = (struct T_error_ack *)&it->type;
	err->PRIM_type = T_ERROR_ACK;
	err->ERROR_prim = prim;
	err->TLI_error = terr;
	err->UNIX_error = iABI_errors(uerr);

	it->pri = MSG_HIPRI;
	it->length = sizeof(struct T_error_ack);
	it->next = Priv(fp)->pfirst;

	Priv(fp)->pfirst = it;
	if (!Priv(fp)->plast)
		Priv(fp)->plast = it;
	timod_socket_wakeup(fp);
}
Esempio n. 5
0
static void
timod_ok(int fd, int prim)
{
	struct file		*fp;
	struct T_primsg		*it;
	struct T_ok_ack 	*ok;

#if defined(CONFIG_ABI_TRACE)
	abi_trace(ABI_TRACE_STREAMS, "TI: %u ok ack prim=%d\n", fd, prim);
#endif

	fp = fcheck(fd);
	it = timod_mkctl(sizeof(struct T_ok_ack));
	if (!it)
		return;

	ok = (struct T_ok_ack *)&it->type;
	ok->PRIM_type = T_OK_ACK;
	ok->CORRECT_prim = prim;

	it->pri = MSG_HIPRI;
	it->length = sizeof(struct T_ok_ack);
	it->next = Priv(fp)->pfirst;

	Priv(fp)->pfirst = it;
	if (!Priv(fp)->plast)
		Priv(fp)->plast = it;
	timod_socket_wakeup(fp);
}
Esempio n. 6
0
static XLIST_PAGE_T *xlist_newchild(XLIST_T *Me, PAGECHECK fcheck)
{
    if(Me==NULL) return NULL;
    XLIST_PAGE_T *pg = NULL;
    LONG_T i;
    if(fcheck == NULL)
    {
        if(Me->PageCount==0 || Me->Pages==NULL)
        {
            pg = xlist_newpage(Me);
        }
        else
        {
            pg = xlist_page_appendchild(Me->Pages[Me->PageCount-1]);
        }
    }
    else
    {
        for(i=0; i<Me->PageCount; i++)
        {
            if(fcheck(Me->Pages[i]))
            {
                pg = xlist_page_appendchild(Me->Pages[i]);
                break;
            }
        }
    }
    return pg;
}
Esempio n. 7
0
asmlinkage int solaris_putmsg(unsigned int fd, u32 arg1, u32 arg2, u32 arg3)
{
	struct file *filp;
	struct inode *ino;
	struct strbuf *ctlptr, *datptr;
	struct strbuf ctl, dat;
	int flags = (int) arg3;
	int error = -EBADF;

	SOLD("entry");
	lock_kernel();
	if(fd >= NR_OPEN) goto out;

	read_lock(&current->files->file_lock);
	filp = fcheck(fd);
	read_unlock(&current->files->file_lock);
	if(!filp) goto out;

	ino = filp->f_dentry->d_inode;
	if (!ino) goto out;

	if (!ino->i_sock &&
		(MAJOR(ino->i_rdev) != 30 || MINOR(ino->i_rdev) != 1))
		goto out;

	ctlptr = (struct strbuf *)A(arg1);
	datptr = (struct strbuf *)A(arg2);

	error = -EFAULT;

	if (ctlptr) {
		if (copy_from_user(&ctl,ctlptr,sizeof(ctl)))
			goto out;
		if (ctl.len < 0 && flags) {
			error = -EINVAL;
			goto out;
		}
	} else {
		ctl.len = 0;
		ctl.buf = 0;
	}

	if (datptr) {
		if (copy_from_user(&dat,datptr,sizeof(dat)))
			goto out;
	} else {
		dat.len = 0;
		dat.buf = 0;
	}

	error = timod_putmsg(fd,(char*)A(ctl.buf),ctl.len,
				(char*)A(dat.buf),dat.len,flags);
out:
	unlock_kernel();
	SOLD("done");
	return error;
}
Esempio n. 8
0
/*
 * descriptor table is not shared, so files can't change or go away.
 */
static struct spu_context *coredump_next_context(int *fd)
{
	struct file *file;
	int n = iterate_fd(current->files, *fd, match_context, NULL);
	if (!n)
		return NULL;
	*fd = n - 1;
	file = fcheck(*fd);
	return SPUFS_I(file->f_dentry->d_inode)->i_ctx;
}
asmlinkage int px_sys_mmap2(
		unsigned long addr, unsigned long len,
		unsigned long prot, unsigned long flgs,
		unsigned long fd, unsigned long pgoff
/*		unsigned long lRegSP*/
		)
{
	int ret = 0;
	int saved_r5;
	unsigned long lsc;
	struct file *file;

	INIT_STACK_FRAME; 

	// here we must save r5 since it will be used by the OS sys_mmap2 code
	__asm__("str r5, %0\n\t":"=m"(saved_r5):);

	APPEND_STACK_FRAME;

	lsc = get_sample_count();

	// restore r5 
	__asm__("ldr r5, %0\n\t"::"m"(saved_r5):"r5");

	ret = px_original_sys_mmap2( addr, len, prot, flgs, fd, pgoff);

	CUTTAIL_STACK_FRAME;

	if (gb_enable_os_hooks && !IS_ERR((void *)ret) && (prot & PROT_EXEC) && !(flgs & MAP_ANONYMOUS))
	{
		//rcu_read_lock();

		if ((file = fcheck(fd))!= NULL)
		{
			char *pname;
			
			memset(name, 0, PATH_MAX * sizeof(char));
			pname = px_d_path(file, name, PATH_MAX);
			
			if (pname)
			{
				unsigned long name_offset;

				name_offset = get_filename_offset(pname);

				module_load_notif(pname, name_offset, current->tgid,
						          ret, len, 0, lsc);
			}
			
		}
		//rcu_read_unlock();
	}
	
	return ret;
}
Esempio n. 10
0
struct file *e_fget_light(unsigned int fd, int *fput_needed)
{
    struct file *file;
    struct files_struct *files = current->files;

    *fput_needed = 0;
    if (likely((atomic_read(&files->count) == 1))) {
        file = fcheck(fd);
    } else {
        spin_lock(&files->file_lock);
        file = fcheck(fd);
        if (file) {
            get_file(file);
            *fput_needed = 1;
        }
        spin_unlock(&files->file_lock);
    }
    return file;

} /*********** fin get_light **********/
asmlinkage int px_sys_mmap(struct mmap_arg_struct *arg)
{
	int ret = 0;
	struct mmap_arg_struct tmp;
	struct file *file;
	unsigned long long lsc;
	char * name = NULL;

	lsc = get_sample_count();

	if (copy_from_user(&tmp, arg, sizeof(tmp)) != 0)
	{
		return -EFAULT;
	}

 	ret = px_original_sys_mmap(arg);

	if (gb_enable_os_hooks && (!IS_ERR((void*)ret)) && (tmp.prot & PROT_EXEC) && !(tmp.flags & MAP_ANONYMOUS))
	{
		//rcu_read_lock();
		if ((file = fcheck(tmp.fd)) != NULL)
		{
			char *filename;
			//memset(name, 0, PATH_MAX * sizeof(char));
			name = kzalloc(PATH_MAX, GFP_ATOMIC);

			if (name == NULL)
			{
				return ret;
			}

			filename = px_d_path(file, name, PATH_MAX);
			if (filename)
			{
				unsigned long name_offset;

				name_offset = get_filename_offset(filename);

				module_load_notif(filename, name_offset, current->tgid,
					              ret, tmp.len,
					              0, lsc);
			}

			kfree(name);
		}

		//rcu_read_unlock();
	}

	return ret;
}
Esempio n. 12
0
static struct tty_struct *get_tty(int fd)
{
	struct file *filp;
	struct tty_struct *ttyp = NULL;

	spin_lock(&current->files->file_lock);
	filp = fcheck(fd);
	if(filp && filp->private_data) {
		ttyp = (struct tty_struct *) filp->private_data;

		if(ttyp->magic != TTY_MAGIC)
			ttyp =NULL;
	}
	spin_unlock(&current->files->file_lock);
	return ttyp;
}
Esempio n. 13
0
static struct tty_struct *get_tty(int fd)
{
	struct file *filp;
	struct tty_struct *ttyp = NULL;

	rcu_read_lock();
	filp = fcheck(fd);
	if(filp && filp->private_data) {
		ttyp = (struct tty_struct *) filp->private_data;

		if(ttyp->magic != TTY_MAGIC)
			ttyp =NULL;
	}
	rcu_read_unlock();
	return ttyp;
}
Esempio n. 14
0
int		fcorr(int fd, va_list p, char f)
{
  int		i;
  static t_form	formats[] = {{'d', &my_fdeci},
			     {'x', &my_flhex},
			     {'i', &my_fdeci},
			     {'X', &my_fLhex},
			     {'p', &my_fhexp},
			     {'s', &my_fstrp},
			     {'u', &my_funsigned},
			     {'o', &my_foctal},
			     {'S', &my_fspec},
			     {'c', &my_fchar},
			     {'b', &my_fbin},
			     {0, NULL}};

  i = fcheck(fd, p, formats, f);
  return (i);
}
Esempio n. 15
0
/*
 * The additional architecture-specific notes for Cell are various
 * context files in the spu context.
 *
 * This function iterates over all open file descriptors and sees
 * if they are a directory in spufs.  In that case we use spufs
 * internal functionality to dump them without needing to actually
 * open the files.
 */
static struct spu_context *coredump_next_context(int *fd)
{
	struct fdtable *fdt = files_fdtable(current->files);
	struct file *file;
	struct spu_context *ctx = NULL;

	for (; *fd < fdt->max_fds; (*fd)++) {
		if (!fd_is_open(*fd, fdt))
			continue;

		file = fcheck(*fd);

		if (!file || file->f_op != &spufs_context_fops)
			continue;

		ctx = SPUFS_I(file->f_dentry->d_inode)->i_ctx;
		if (ctx->flags & SPU_CREATE_NOSCHED)
			continue;

		break;
	}

	return ctx;
}
Esempio n. 16
0
/*
 * XXX: this function is a _horrible_ mess.
 */
static int
timod_optmgmt(int fd, struct pt_regs * regs, int flag,
	      char * opt_buf, int opt_len, int do_ret)
{
	struct file * fp = fcheck(fd);
	char *ret_buf, *ret_base;
	u_int old_esp, *tsp;
	int is_tli, error, failed;
	int ret_len, ret_space;
error=0;
	if (opt_buf && opt_len > 0) {
		if (!access_ok(VERIFY_READ, opt_buf, opt_len))
			return -EFAULT;
	}

	/*
	 * FIXME:
	 *   We should be able to detect the difference between
	 *   TLI and XTI requests at run time?
	 */
#ifdef CONFIG_ABI_TLI_OPTMGMT
	is_tli = 1;
#else
	is_tli = 0;
#endif

	if (!do_ret && (!opt_buf || opt_len <= 0))
		return 0;

	/*
	 * Grab some space on the user stack to work with. We need 6 longs
	 * to build an argument frame for [gs]etsockopt calls. We also
	 * need space to build the return buffer. This will be at least
	 * as big as the given options buffer but the given options
	 * buffer may not include space for option values so we allow two
	 * longs for each option multiple of the option header size
	 * and hope that big options will not exhaust our space and
	 * trash the stack.
	 */
	ret_space = 1024 + opt_len
		+ 2*sizeof(long)*(opt_len / (is_tli ? sizeof(struct opthdr) : sizeof(struct t_opthdr)));
	ret_buf = ret_base = (char *)(_SP(regs) - ret_space);
	ret_len = 0;

	old_esp = _SP(regs);
	_SP(regs) -= ret_space + 6*sizeof(long);
	tsp = (unsigned int *)_SP(regs);
	if (!access_ok(VERIFY_WRITE, tsp, 6*sizeof(long))) {
		_SP(regs) = old_esp;
		return -EFAULT;
	}

	failed = 0;

#ifndef CONFIG_ABI_TLI_OPTMGMT
	if (is_tli) {
		printk(KERN_WARNING
			"%d iBCS: TLI optmgmt requested but not supported\n",
			current->pid);
	}
#else
	if (is_tli)
		while (opt_len >= sizeof(struct opthdr)) {
		struct opthdr opt;

#if defined(CONFIG_ABI_TRACE)
		abi_trace(ABI_TRACE_STREAMS, "TLI optmgmt opt_len=%d, "
				"ret_buf=0x%08lx, ret_len=%d, ret_space=%d\n",
				opt_len, (unsigned long)ret_buf,
				ret_len, ret_space);
#endif

		if (copy_from_user(&opt, opt_buf, sizeof(struct opthdr)))
			return -EFAULT;

		/* Idiot check... */
		if (opt.len > opt_len) {
			failed = TBADOPT;
			break;
		}

#if defined(CONFIG_ABI_TRACE)
		if (abi_traced(ABI_TRACE_STREAMS)) {
			unsigned long v;
			get_user(v, (unsigned long *)(opt_buf+sizeof(struct opthdr)));
			__abi_trace("TLI optmgmt fd=%d, level=%ld, "
					"name=%ld, value=%ld\n",
					fd, opt.level, opt.name, v);
		}
#endif
		/* Check writable space in the return buffer. */
		if (!access_ok(VERIFY_WRITE, ret_buf, sizeof(struct opthdr))) {
			failed = TSYSERR;
			break;
		}

		/* Flag values:
		 * T_NEGOTIATE means try and set it.
		 * T_DEFAULT means get the default value.
		 *           (return the current for now)
		 * T_CHECK means get the current value.
		 */
		error = 0;
		if (flag == T_NEGOTIATE) {
			put_user(fd, tsp);
			put_user(opt.level, tsp+1);
			put_user(opt.name, tsp+2);
			put_user((long)opt_buf+sizeof(struct opthdr), tsp+3);
			put_user(opt.len, tsp+4);
			error = abi_do_setsockopt(tsp);

			if (error) {
#if defined(CONFIG_ABI_TRACE)
				abi_trace(ABI_TRACE_STREAMS,
					"setsockopt failed: %d\n", error);
#endif
				failed = TBADOPT;
				break;
			}
		}
		if (!error) {
			int len;

			put_user(fd, tsp);
			put_user(opt.level, tsp+1);
			put_user(opt.name, tsp+2);
			put_user((long)ret_buf+sizeof(struct opthdr), tsp+3);
			put_user((long)(tsp+5), tsp+4);
			put_user(ret_space, tsp+5);
			error = abi_do_getsockopt(tsp);

			if (error) {
#if defined(CONFIG_ABI_TRACE)
				abi_trace(ABI_TRACE_STREAMS,
					"getsockopt failed: %d\n", error);
#endif
				failed = TBADOPT;
				break;
			}

			get_user(len, tsp+5);
			if (copy_to_user(ret_buf, &opt, sizeof(opt)))
				return -EFAULT;
			put_user(len,
				&((struct opthdr *)opt_buf)->len);
			ret_space -= sizeof(struct opthdr) + len;
			ret_len += sizeof(struct opthdr) + len;
			ret_buf += sizeof(struct opthdr) + len;
		}

		opt_len -= sizeof(struct opthdr) + opt.len;
		opt_buf += sizeof(struct opthdr) + opt.len;
	}
#endif /* CONFIG_ABI_TLI_OPTMGMT */
#ifndef CONFIG_ABI_XTI_OPTMGMT
	else {
		printk(KERN_WARNING
			"%d iBCS: XTI optmgmt requested but not supported\n",
			current->pid);
	}
#else
	else while (opt_len >= sizeof(struct t_opthdr)) {
Esempio n. 17
0
int timod_getmsg(unsigned int fd, char *ctl_buf, int ctl_maxlen, s32 *ctl_len,
			char *data_buf, int data_maxlen, s32 *data_len, int *flags_p)
{
	int error;
	int oldflags;
	struct file *filp;
	struct inode *ino;
	struct sol_socket_struct *sock;
	struct T_unitdata_ind udi;
	mm_segment_t old_fs = get_fs();
	long args[6];
	char *tmpbuf;
	int tmplen;
	int (*sys_socketcall)(int, unsigned long *) =
		(int (*)(int, unsigned long *))SYS(socketcall);
	int (*sys_recvfrom)(int, void *, size_t, unsigned, struct sockaddr *, int *);
	
	SOLD("entry");
	SOLDD(("%u %p %d %p %p %d %p %d\n", fd, ctl_buf, ctl_maxlen, ctl_len, data_buf, data_maxlen, data_len, *flags_p));
	read_lock(&current->files->file_lock);
	filp = fcheck(fd);
	read_unlock(&current->files->file_lock);
	if (!filp)
		return -EBADF;
	ino = filp->f_dentry->d_inode;
	sock = (struct sol_socket_struct *)filp->private_data;
	SOLDD(("%p %p\n", sock->pfirst, sock->pfirst ? sock->pfirst->next : NULL));
	if ( ctl_maxlen > 0 && !sock->pfirst && ino->u.socket_i.type == SOCK_STREAM
		&& sock->state == TS_IDLE) {
		SOLD("calling LISTEN");
		args[0] = fd;
		args[1] = -1;
		set_fs(KERNEL_DS);
		sys_socketcall(SYS_LISTEN, args);
		set_fs(old_fs);
		SOLD("LISTEN done");
	}
	if (!(filp->f_flags & O_NONBLOCK)) {
		poll_table wait_table, *wait;

		poll_initwait(&wait_table);
		wait = &wait_table;
		for(;;) {
			SOLD("loop");
			set_current_state(TASK_INTERRUPTIBLE);
			/* ! ( l<0 || ( l>=0 && ( ! pfirst || (flags == HIPRI && pri != HIPRI) ) ) ) */ 
			/* ( ! l<0 && ! ( l>=0 && ( ! pfirst || (flags == HIPRI && pri != HIPRI) ) ) ) */ 
			/* ( l>=0 && ( ! l>=0 || ! ( ! pfirst || (flags == HIPRI && pri != HIPRI) ) ) ) */ 
			/* ( l>=0 && ( l<0 || ( pfirst && ! (flags == HIPRI && pri != HIPRI) ) ) ) */ 
			/* ( l>=0 && ( l<0 || ( pfirst && (flags != HIPRI || pri == HIPRI) ) ) ) */ 
			/* ( l>=0 && ( pfirst && (flags != HIPRI || pri == HIPRI) ) ) */ 
			if (ctl_maxlen >= 0 && sock->pfirst && (*flags_p != MSG_HIPRI || sock->pfirst->pri == MSG_HIPRI))
				break;
			SOLD("cond 1 passed");
			if (
			#if 1
				*flags_p != MSG_HIPRI &&
			#endif
				((filp->f_op->poll(filp, wait) & POLLIN) ||
				(filp->f_op->poll(filp, NULL) & POLLIN) ||
				signal_pending(current))
			) {
				break;
			}
			if( *flags_p == MSG_HIPRI ) {
				SOLD("avoiding lockup");
				break ;
			}
			if(wait_table.error) {
				SOLD("wait-table error");
				poll_freewait(&wait_table);
				return wait_table.error;
			}
			SOLD("scheduling");
			schedule();
		}
		SOLD("loop done");
		current->state = TASK_RUNNING;
		poll_freewait(&wait_table);
		if (signal_pending(current)) {
			SOLD("signal pending");
			return -EINTR;
		}
	}
	if (ctl_maxlen >= 0 && sock->pfirst) {
		struct T_primsg *it = sock->pfirst;
		int l = min_t(int, ctl_maxlen, it->length);
		SCHECK_MAGIC((char*)((u64)(((char *)&it->type)+sock->offset+it->length+7)&~7),MKCTL_MAGIC);
		SOLD("purting ctl data");
		if(copy_to_user(ctl_buf,
			(char*)&it->type + sock->offset, l))
			return -EFAULT;
		SOLD("pur it");
		if(put_user(l, ctl_len))
			return -EFAULT;
		SOLD("set ctl_len");
		*flags_p = it->pri;
		it->length -= l;
		if (it->length) {
			SOLD("more ctl");
			sock->offset += l;
			return MORECTL;
		} else {
			SOLD("removing message");
			sock->pfirst = it->next;
			if (!sock->pfirst)
				sock->plast = NULL;
			SOLDD(("getmsg kfree %016lx->%016lx\n", it, sock->pfirst));
			mykfree(it);
			sock->offset = 0;
			SOLD("ctl done");
			return 0;
		}
	}
	*flags_p = 0;
	if (ctl_maxlen >= 0) {
		SOLD("ACCEPT perhaps?");
		if (ino->u.socket_i.type == SOCK_STREAM && sock->state == TS_IDLE) {
			struct T_conn_ind ind;
			char *buf = getpage();
			int len = BUF_SIZE;

			SOLD("trying ACCEPT");
			if (put_user(ctl_maxlen - sizeof(ind), ctl_len))
				return -EFAULT;
			args[0] = fd;
			args[1] = (long)buf;
			args[2] = (long)&len;
			oldflags = filp->f_flags;
			filp->f_flags |= O_NONBLOCK;
			SOLD("calling ACCEPT");
			set_fs(KERNEL_DS);
			error = sys_socketcall(SYS_ACCEPT, args);
			set_fs(old_fs);
			filp->f_flags = oldflags;
			if (error < 0) {
				SOLD("some error");
				putpage(buf);
				return error;
			}
			if (error) {
				SOLD("connect");
				putpage(buf);
				if (sizeof(ind) > ctl_maxlen) {
					SOLD("generating CONN_IND");
					ind.PRIM_type = T_CONN_IND;
					ind.SRC_length = len;
					ind.SRC_offset = sizeof(ind);
					ind.OPT_length = ind.OPT_offset = 0;
					ind.SEQ_number = error;
					if(copy_to_user(ctl_buf, &ind, sizeof(ind))||
					   put_user(sizeof(ind)+ind.SRC_length,ctl_len))
						return -EFAULT;
					SOLD("CONN_IND created");
				}
				if (data_maxlen >= 0)
					put_user(0, data_len);
				SOLD("CONN_IND done");
				return 0;
			}
			if (len>ctl_maxlen) {
				SOLD("data don't fit");
				putpage(buf);
				return -EFAULT;		/* XXX - is this ok ? */
			}
			if(copy_to_user(ctl_buf,buf,len) || put_user(len,ctl_len)){
				SOLD("can't copy data");
				putpage(buf);
				return -EFAULT;
			}
			SOLD("ACCEPT done");
			putpage(buf);
		}
	}
	SOLD("checking data req");
	if (data_maxlen <= 0) {
		if (data_maxlen == 0)
			put_user(0, data_len);
		if (ctl_maxlen >= 0)
			put_user(0, ctl_len);
		return -EAGAIN;
	}
	SOLD("wants data");
	if (ctl_maxlen > sizeof(udi) && sock->state == TS_IDLE) {
		SOLD("udi fits");
		tmpbuf = ctl_buf + sizeof(udi);
		tmplen = ctl_maxlen - sizeof(udi);
	} else {
		SOLD("udi does not fit");
		tmpbuf = NULL;
		tmplen = 0;
	}
	if (put_user(tmplen, ctl_len))
		return -EFAULT;
	SOLD("set ctl_len");
	oldflags = filp->f_flags;
	filp->f_flags |= O_NONBLOCK;
	SOLD("calling recvfrom");
	sys_recvfrom = (int (*)(int, void *, size_t, unsigned, struct sockaddr *, int *))SYS(recvfrom);
	error = sys_recvfrom(fd, data_buf, data_maxlen, 0, (struct sockaddr*)tmpbuf, ctl_len);
	filp->f_flags = oldflags;
	if (error < 0)
		return error;
	SOLD("error >= 0" ) ;
	if (error && ctl_maxlen > sizeof(udi) && sock->state == TS_IDLE) {
		SOLD("generating udi");
		udi.PRIM_type = T_UNITDATA_IND;
		get_user(udi.SRC_length, ctl_len);
		udi.SRC_offset = sizeof(udi);
		udi.OPT_length = udi.OPT_offset = 0;
		copy_to_user(ctl_buf, &udi, sizeof(udi));
		put_user(sizeof(udi)+udi.SRC_length, ctl_len);
		SOLD("udi done");
	} else
		put_user(0, ctl_len);
	put_user(error, data_len);
	SOLD("done");
	return 0;
}
Esempio n. 18
0
asmlinkage int solaris_getmsg(unsigned int fd, u32 arg1, u32 arg2, u32 arg3)
{
	struct file *filp;
	struct inode *ino;
	struct strbuf *ctlptr, *datptr;
	struct strbuf ctl, dat;
	int *flgptr;
	int flags;
	int error = -EBADF;

	SOLD("entry");
	lock_kernel();
	if(fd >= NR_OPEN) goto out;

	read_lock(&current->files->file_lock);
	filp = fcheck(fd);
	read_unlock(&current->files->file_lock);
	if(!filp) goto out;

	ino = filp->f_dentry->d_inode;
	if (!ino) goto out;

	if (!ino->i_sock)
		goto out;

	ctlptr = (struct strbuf *)A(arg1);
	datptr = (struct strbuf *)A(arg2);
	flgptr = (int *)A(arg3);

	error = -EFAULT;

	if (ctlptr) {
		if (copy_from_user(&ctl,ctlptr,sizeof(struct strbuf)) || 
		    put_user(-1,&ctlptr->len))
			goto out;
	} else
		ctl.maxlen = -1;

	if (datptr) {
		if (copy_from_user(&dat,datptr,sizeof(struct strbuf)) || 
		    put_user(-1,&datptr->len))
			goto out;
	} else
		dat.maxlen = -1;

	if (get_user(flags,flgptr))
		goto out;

	switch (flags) {
	case 0:
	case MSG_HIPRI:
	case MSG_ANY:
	case MSG_BAND:
		break;
	default:
		error = -EINVAL;
		goto out;
	}

	error = timod_getmsg(fd,(char*)A(ctl.buf),ctl.maxlen,&ctlptr->len,
				(char*)A(dat.buf),dat.maxlen,&datptr->len,&flags);

	if (!error && put_user(flags,flgptr))
		error = -EFAULT;
out:
	unlock_kernel();
	SOLD("done");
	return error;
}
Esempio n. 19
0
asmlinkage int sunos_ioctl (int fd, unsigned long cmd, unsigned long arg)
{
	int ret = -EBADF;

	if (fd >= SUNOS_NR_OPEN || !fcheck(fd))
		goto out;

	/* First handle an easy compat. case for tty ldisc. */
	if (cmd == TIOCSETD) {
		int __user *p;
		int ntty = N_TTY, tmp;
		mm_segment_t oldfs;

		p = (int __user *) arg;
		ret = -EFAULT;
		if (get_user(tmp, p))
			goto out;
		if (tmp == 2) {
			oldfs = get_fs();
			set_fs(KERNEL_DS);
			ret = sys_ioctl(fd, cmd, (unsigned long) &ntty);
			set_fs(oldfs);
			ret = (ret == -EINVAL ? -EOPNOTSUPP : ret);
			goto out;
		}
	}

	/* Binary compatibility is good American knowhow f****n' up. */
	if (cmd == TIOCNOTTY) {
		ret = sys_setsid();
		goto out;
	}

	/* SunOS networking ioctls. */
	switch (cmd) {
	case _IOW('r', 10, struct rtentry):
		ret = sys_ioctl(fd, SIOCADDRT, arg);
		goto out;
	case _IOW('r', 11, struct rtentry):
		ret = sys_ioctl(fd, SIOCDELRT, arg);
		goto out;
	case _IOW('i', 12, struct ifreq):
		ret = sys_ioctl(fd, SIOCSIFADDR, arg);
		goto out;
	case _IOWR('i', 13, struct ifreq):
		ret = sys_ioctl(fd, SIOCGIFADDR, arg);
		goto out;
	case _IOW('i', 14, struct ifreq):
		ret = sys_ioctl(fd, SIOCSIFDSTADDR, arg);
		goto out;
	case _IOWR('i', 15, struct ifreq):
		ret = sys_ioctl(fd, SIOCGIFDSTADDR, arg);
		goto out;
	case _IOW('i', 16, struct ifreq):
		ret = sys_ioctl(fd, SIOCSIFFLAGS, arg);
		goto out;
	case _IOWR('i', 17, struct ifreq):
		ret = sys_ioctl(fd, SIOCGIFFLAGS, arg);
		goto out;
	case _IOW('i', 18, struct ifreq):
		ret = sys_ioctl(fd, SIOCSIFMEM, arg);
		goto out;
	case _IOWR('i', 19, struct ifreq):
		ret = sys_ioctl(fd, SIOCGIFMEM, arg);
		goto out;
	case _IOWR('i', 20, struct ifconf):
		ret = sys_ioctl(fd, SIOCGIFCONF, arg);
		goto out;
	case _IOW('i', 21, struct ifreq): /* SIOCSIFMTU */
		ret = sys_ioctl(fd, SIOCSIFMTU, arg);
		goto out;
	case _IOWR('i', 22, struct ifreq): /* SIOCGIFMTU */
		ret = sys_ioctl(fd, SIOCGIFMTU, arg);
		goto out;

	case _IOWR('i', 23, struct ifreq):
		ret = sys_ioctl(fd, SIOCGIFBRDADDR, arg);
		goto out;
	case _IOW('i', 24, struct ifreq):
		ret = sys_ioctl(fd, SIOCSIFBRDADDR, arg);
		goto out;
	case _IOWR('i', 25, struct ifreq):
		ret = sys_ioctl(fd, SIOCGIFNETMASK, arg);
		goto out;
	case _IOW('i', 26, struct ifreq):
		ret = sys_ioctl(fd, SIOCSIFNETMASK, arg);
		goto out;
	case _IOWR('i', 27, struct ifreq):
		ret = sys_ioctl(fd, SIOCGIFMETRIC, arg);
		goto out;
	case _IOW('i', 28, struct ifreq):
		ret = sys_ioctl(fd, SIOCSIFMETRIC, arg);
		goto out;

	case _IOW('i', 30, struct arpreq):
		ret = sys_ioctl(fd, SIOCSARP, arg);
		goto out;
	case _IOWR('i', 31, struct arpreq):
		ret = sys_ioctl(fd, SIOCGARP, arg);
		goto out;
	case _IOW('i', 32, struct arpreq):
		ret = sys_ioctl(fd, SIOCDARP, arg);
		goto out;

	case _IOW('i', 40, struct ifreq): /* SIOCUPPER */
	case _IOW('i', 41, struct ifreq): /* SIOCLOWER */
	case _IOW('i', 44, struct ifreq): /* SIOCSETSYNC */
	case _IOW('i', 45, struct ifreq): /* SIOCGETSYNC */
	case _IOW('i', 46, struct ifreq): /* SIOCSSDSTATS */
	case _IOW('i', 47, struct ifreq): /* SIOCSSESTATS */
	case _IOW('i', 48, struct ifreq): /* SIOCSPROMISC */
		ret = -EOPNOTSUPP;
		goto out;

	case _IOW('i', 49, struct ifreq):
		ret = sys_ioctl(fd, SIOCADDMULTI, arg);
		goto out;
	case _IOW('i', 50, struct ifreq):
		ret = sys_ioctl(fd, SIOCDELMULTI, arg);
		goto out;

	/* FDDI interface ioctls, unsupported. */
		
	case _IOW('i', 51, struct ifreq): /* SIOCFDRESET */
	case _IOW('i', 52, struct ifreq): /* SIOCFDSLEEP */
	case _IOW('i', 53, struct ifreq): /* SIOCSTRTFMWAR */
	case _IOW('i', 54, struct ifreq): /* SIOCLDNSTRTFW */
	case _IOW('i', 55, struct ifreq): /* SIOCGETFDSTAT */
	case _IOW('i', 56, struct ifreq): /* SIOCFDNMIINT */
	case _IOW('i', 57, struct ifreq): /* SIOCFDEXUSER */
	case _IOW('i', 58, struct ifreq): /* SIOCFDGNETMAP */
	case _IOW('i', 59, struct ifreq): /* SIOCFDGIOCTL */
		printk("FDDI ioctl, returning EOPNOTSUPP\n");
		ret = -EOPNOTSUPP;
		goto out;

	case _IOW('t', 125, int):
		/* More stupid tty sunos ioctls, just
		 * say it worked.
		 */
		ret = 0;
		goto out;
	/* Non posix grp */
	case _IOW('t', 118, int): {
		int oldval, newval, __user *ptr;

		cmd = TIOCSPGRP;
		ptr = (int __user *) arg;
		ret = -EFAULT;
		if (get_user(oldval, ptr))
			goto out;
		ret = sys_ioctl(fd, cmd, arg);
		__get_user(newval, ptr);
		if (newval == -1) {
			__put_user(oldval, ptr);
			ret = -EIO;
		}
		if (ret == -ENOTTY)
			ret = -EIO;
		goto out;
	}

	case _IOR('t', 119, int): {
		int oldval, newval, __user *ptr;

		cmd = TIOCGPGRP;
		ptr = (int __user *) arg;
		ret = -EFAULT;
		if (get_user(oldval, ptr))
			goto out;
		ret = sys_ioctl(fd, cmd, arg);
		__get_user(newval, ptr);
		if (newval == -1) {
			__put_user(oldval, ptr);
			ret = -EIO;
		}
		if (ret == -ENOTTY)
			ret = -EIO;
		goto out;
	}
	}

#if 0
	if ((cmd & 0xff00) == ('k' << 8)) {
		printk ("[[KBIO: %8.8x\n", (unsigned int) cmd);
	}
#endif

	ret = sys_ioctl(fd, cmd, arg);
	/* so stupid... */
	ret = (ret == -EINVAL ? -EOPNOTSUPP : ret);
out:
	return ret;
}
Esempio n. 20
0
int fcntl_dirnotify(int fd, struct file *filp, unsigned long arg)
{
	struct dnotify_struct *dn;
	struct dnotify_struct *odn;
	struct dnotify_struct **prev;
	struct inode *inode;
	fl_owner_t id = current->files;
	struct file *f;
	int error = 0;

	if ((arg & ~DN_MULTISHOT) == 0) {
		dnotify_flush(filp, id);
		return 0;
	}
	if (!dir_notify_enable)
		return -EINVAL;
	inode = filp->f_dentry->d_inode;
	if (!S_ISDIR(inode->i_mode))
		return -ENOTDIR;
	dn = kmem_cache_alloc(dn_cache, SLAB_KERNEL);
	if (dn == NULL)
		return -ENOMEM;
	spin_lock(&inode->i_lock);
	prev = &inode->i_dnotify;
	while ((odn = *prev) != NULL) {
		if ((odn->dn_owner == id) && (odn->dn_filp == filp)) {
			odn->dn_fd = fd;
			odn->dn_mask |= arg;
			inode->i_dnotify_mask |= arg & ~DN_MULTISHOT;
			goto out_free;
		}
		prev = &odn->dn_next;
	}

	rcu_read_lock();
	f = fcheck(fd);
	rcu_read_unlock();
	/* we'd lost the race with close(), sod off silently */
	/* note that inode->i_lock prevents reordering problems
	 * between accesses to descriptor table and ->i_dnotify */
	if (f != filp)
		goto out_free;

	error = f_setown(filp, current->pid, 0);
	if (error)
		goto out_free;

	dn->dn_mask = arg;
	dn->dn_fd = fd;
	dn->dn_filp = filp;
	dn->dn_owner = id;
	inode->i_dnotify_mask |= arg & ~DN_MULTISHOT;
	dn->dn_next = inode->i_dnotify;
	inode->i_dnotify = dn;
	spin_unlock(&inode->i_lock);

	if (filp->f_op && filp->f_op->dir_notify)
		return filp->f_op->dir_notify(filp, arg);
	return 0;

out_free:
	spin_unlock(&inode->i_lock);
	kmem_cache_free(dn_cache, dn);
	return error;
}
Esempio n. 21
0
int timod_putmsg(unsigned int fd, char *ctl_buf, int ctl_len,
			char *data_buf, int data_len, int flags)
{
	int ret, error, terror;
	char *buf;
	struct file *filp;
	struct inode *ino;
	struct sol_socket_struct *sock;
	mm_segment_t old_fs = get_fs();
	long args[6];
	int (*sys_socketcall)(int, unsigned long *) =
		(int (*)(int, unsigned long *))SYS(socketcall);
	int (*sys_sendto)(int, void *, size_t, unsigned, struct sockaddr *, int) =
		(int (*)(int, void *, size_t, unsigned, struct sockaddr *, int))SYS(sendto);
	read_lock(&current->files->file_lock);
	filp = fcheck(fd);
	read_unlock(&current->files->file_lock);
	if (!filp)
		return -EBADF;
	ino = filp->f_dentry->d_inode;
	sock = (struct sol_socket_struct *)filp->private_data;
	SOLD("entry");
	if (get_user(ret, (int *)A(ctl_buf)))
		return -EFAULT;
	switch (ret) {
	case T_BIND_REQ:
	{
		struct T_bind_req req;
		
		SOLDD(("bind %016lx(%016lx)\n", sock, filp));
		SOLD("T_BIND_REQ");
		if (sock->state != TS_UNBND) {
			timod_error(fd, T_BIND_REQ, TOUTSTATE, 0);
			return 0;
		}
		SOLD("state ok");
		if (copy_from_user(&req, ctl_buf, sizeof(req))) {
			timod_error(fd, T_BIND_REQ, TSYSERR, EFAULT);
			return 0;
		}
		SOLD("got ctl req");
		if (req.ADDR_offset && req.ADDR_length) {
			if (req.ADDR_length > BUF_SIZE) {
				timod_error(fd, T_BIND_REQ, TSYSERR, EFAULT);
				return 0;
			}
			SOLD("req size ok");
			buf = getpage();
			if (copy_from_user(buf, ctl_buf + req.ADDR_offset, req.ADDR_length)) {
				timod_error(fd, T_BIND_REQ, TSYSERR, EFAULT);
				putpage(buf);
				return 0;
			}
			SOLD("got ctl data");
			args[0] = fd;
			args[1] = (long)buf;
			args[2] = req.ADDR_length;
			SOLD("calling BIND");
			set_fs(KERNEL_DS);
			error = sys_socketcall(SYS_BIND, args);
			set_fs(old_fs);
			putpage(buf);
			SOLD("BIND returned");
		} else 
			error = 0;
		if (!error) {
			struct T_primsg *it;
			if (req.CONIND_number) {
	  			args[0] = fd;
  				args[1] = req.CONIND_number;
  				SOLD("calling LISTEN");
  				set_fs(KERNEL_DS);
	  			error = sys_socketcall(SYS_LISTEN, args);
  				set_fs(old_fs);
  				SOLD("LISTEN done");
  			}
			it = timod_mkctl(sizeof(struct T_bind_ack)+sizeof(struct sockaddr));
			if (it) {
				struct T_bind_ack *ack;

				ack = (struct T_bind_ack *)&it->type;
				ack->PRIM_type = T_BIND_ACK;
				ack->ADDR_offset = sizeof(*ack);
				ack->ADDR_length = sizeof(struct sockaddr);
				ack->CONIND_number = req.CONIND_number;
				args[0] = fd;
				args[1] = (long)(ack+sizeof(*ack));
				args[2] = (long)&ack->ADDR_length;
				set_fs(KERNEL_DS);
				sys_socketcall(SYS_GETSOCKNAME,args);
				set_fs(old_fs);
				sock->state = TS_IDLE;
				timod_ok(fd, T_BIND_REQ);
				timod_queue_end(fd, it);
				SOLD("BIND done");
				return 0;
			}
		}
		SOLD("some error");
		switch (error) {
			case -EINVAL:
				terror = TOUTSTATE;
				error = 0;
				break;
			case -EACCES:
				terror = TACCES;
				error = 0;
				break;
			case -EADDRNOTAVAIL:
			case -EADDRINUSE:
				terror = TNOADDR;
				error = 0;
				break;
			default:
				terror = TSYSERR;
				break;
		}
		timod_error(fd, T_BIND_REQ, terror, -error);
		SOLD("BIND done");
		return 0;
	}
	case T_CONN_REQ:
	{
		struct T_conn_req req;
		unsigned short oldflags;
		struct T_primsg *it;
		SOLD("T_CONN_REQ");
		if (sock->state != TS_UNBND && sock->state != TS_IDLE) {
			timod_error(fd, T_CONN_REQ, TOUTSTATE, 0);
			return 0;
		}
		SOLD("state ok");
		if (copy_from_user(&req, ctl_buf, sizeof(req))) {
			timod_error(fd, T_CONN_REQ, TSYSERR, EFAULT);
			return 0;
		}
		SOLD("got ctl req");
		if (ctl_len > BUF_SIZE) {
			timod_error(fd, T_CONN_REQ, TSYSERR, EFAULT);
			return 0;
		}
		SOLD("req size ok");
		buf = getpage();
		if (copy_from_user(buf, ctl_buf, ctl_len)) {
			timod_error(fd, T_CONN_REQ, TSYSERR, EFAULT);
			putpage(buf);
			return 0;
		}
#ifdef DEBUG_SOLARIS		
		{
			char * ptr = buf;
			int len = ctl_len;
			printk("returned data (%d bytes): ",len);
			while( len-- ) {
				if (!(len & 7))
					printk(" ");
				printk("%02x",(unsigned char)*ptr++);
			}
			printk("\n");
		}
#endif
		SOLD("got ctl data");
		args[0] = fd;
		args[1] = (long)buf+req.DEST_offset;
		args[2] = req.DEST_length;
		oldflags = filp->f_flags;
		filp->f_flags &= ~O_NONBLOCK;
		SOLD("calling CONNECT");
		set_fs(KERNEL_DS);
		error = sys_socketcall(SYS_CONNECT, args);
		set_fs(old_fs);
		filp->f_flags = oldflags;
		SOLD("CONNECT done");
		if (!error) {
			struct T_conn_con *con;
			SOLD("no error");
			it = timod_mkctl(ctl_len);
			if (!it) {
				putpage(buf);
				return -ENOMEM;
			}
			con = (struct T_conn_con *)&it->type;
#ifdef DEBUG_SOLARIS			
			{
				char * ptr = buf;
				int len = ctl_len;
				printk("returned data (%d bytes): ",len);
				while( len-- ) {
					if (!(len & 7))
						printk(" ");
					printk("%02x",(unsigned char)*ptr++);
				}
				printk("\n");
			}
#endif
			memcpy(con, buf, ctl_len);
			SOLD("copied ctl_buf");
			con->PRIM_type = T_CONN_CON;
			sock->state = TS_DATA_XFER;
		} else {
			struct T_discon_ind *dis;
			SOLD("some error");
			it = timod_mkctl(sizeof(*dis));
			if (!it) {
				putpage(buf);
				return -ENOMEM;
			}
			SOLD("got primsg");
			dis = (struct T_discon_ind *)&it->type;
			dis->PRIM_type = T_DISCON_IND;
			dis->DISCON_reason = -error;	/* FIXME: convert this as in iABI_errors() */
			dis->SEQ_number = 0;
		}
		putpage(buf);
		timod_ok(fd, T_CONN_REQ);
		it->pri = 0;
		timod_queue_end(fd, it);
		SOLD("CONNECT done");
		return 0;
	}
	case T_OPTMGMT_REQ:
	{
		struct T_optmgmt_req req;
		SOLD("OPTMGMT_REQ");
		if (copy_from_user(&req, ctl_buf, sizeof(req)))
			return -EFAULT;
		SOLD("got req");
		return timod_optmgmt(fd, req.MGMT_flags,
				req.OPT_offset > 0 ? ctl_buf + req.OPT_offset : NULL,
				req.OPT_length, 1);
	}
	case T_UNITDATA_REQ:
	{
		struct T_unitdata_req req;
		
		int err;
		SOLD("T_UNITDATA_REQ");
		if (sock->state != TS_IDLE && sock->state != TS_DATA_XFER) {
			timod_error(fd, T_CONN_REQ, TOUTSTATE, 0);
			return 0;
		}
		SOLD("state ok");
		if (copy_from_user(&req, ctl_buf, sizeof(req))) {
			timod_error(fd, T_CONN_REQ, TSYSERR, EFAULT);
			return 0;
		}
		SOLD("got ctl req");
#ifdef DEBUG_SOLARIS		
		{
			char * ptr = ctl_buf+req.DEST_offset;
			int len = req.DEST_length;
			printk("socket address (%d bytes): ",len);
			while( len-- ) {
				char c;
				if (get_user(c,ptr))
					printk("??");
				else
					printk("%02x",(unsigned char)c);
				ptr++;
			}
			printk("\n");
		}
#endif		
		err = sys_sendto(fd, data_buf, data_len, 0, req.DEST_length > 0 ? (struct sockaddr*)(ctl_buf+req.DEST_offset) : NULL, req.DEST_length);
		if (err == data_len)
			return 0;
		if(err >= 0) {
			printk("timod: sendto failed to send all the data\n");
			return 0;
		}
		timod_error(fd, T_CONN_REQ, TSYSERR, -err);
		return 0;
	}
	default:
		printk(KERN_INFO "timod_putmsg: unsupported command %u.\n", ret);
		break;
	}
	return -EINVAL;
}
Esempio n. 22
0
asmlinkage int sunos_ioctl (int fd, u32 cmd, u32 arg)
{
	int ret = -EBADF;

	if(fd >= SUNOS_NR_OPEN)
		goto out;
	if(!fcheck(fd))
		goto out;

	if(cmd == TIOCSETD) {
		mm_segment_t old_fs = get_fs();
		int __user *p;
		int ntty = N_TTY;
		int tmp;

		p = (int __user *) (unsigned long) arg;
		ret = -EFAULT;
		if(get_user(tmp, p))
			goto out;
		if(tmp == 2) {
			set_fs(KERNEL_DS);
			ret = sys_ioctl(fd, cmd, (unsigned long) &ntty);
			set_fs(old_fs);
			ret = (ret == -EINVAL ? -EOPNOTSUPP : ret);
			goto out;
		}
	}
	if(cmd == TIOCNOTTY) {
		ret = sys_setsid();
		goto out;
	}
	switch(cmd) {
	case _IOW('r', 10, struct rtentry32):
		ret = compat_sys_ioctl(fd, SIOCADDRT, arg);
		goto out;
	case _IOW('r', 11, struct rtentry32):
		ret = compat_sys_ioctl(fd, SIOCDELRT, arg);
		goto out;

	case _IOW('i', 12, struct ifreq32):
		ret = compat_sys_ioctl(fd, SIOCSIFADDR, arg);
		goto out;
	case _IOWR('i', 13, struct ifreq32):
		ret = compat_sys_ioctl(fd, SIOCGIFADDR, arg);
		goto out;
	case _IOW('i', 14, struct ifreq32):
		ret = compat_sys_ioctl(fd, SIOCSIFDSTADDR, arg);
		goto out;
	case _IOWR('i', 15, struct ifreq32):
		ret = compat_sys_ioctl(fd, SIOCGIFDSTADDR, arg);
		goto out;
	case _IOW('i', 16, struct ifreq32):
		ret = compat_sys_ioctl(fd, SIOCSIFFLAGS, arg);
		goto out;
	case _IOWR('i', 17, struct ifreq32):
		ret = compat_sys_ioctl(fd, SIOCGIFFLAGS, arg);
		goto out;
	case _IOW('i', 18, struct ifreq32):
		ret = compat_sys_ioctl(fd, SIOCSIFMEM, arg);
		goto out;
	case _IOWR('i', 19, struct ifreq32):
		ret = compat_sys_ioctl(fd, SIOCGIFMEM, arg);
		goto out;

	case _IOWR('i', 20, struct ifconf32):
		ret = compat_sys_ioctl(fd, SIOCGIFCONF, arg);
		goto out;

	case _IOW('i', 21, struct ifreq32):
		ret = compat_sys_ioctl(fd, SIOCSIFMTU, arg);
		goto out;

	case _IOWR('i', 22, struct ifreq32):
		ret = compat_sys_ioctl(fd, SIOCGIFMTU, arg);
		goto out;

	case _IOWR('i', 23, struct ifreq32):
		ret = compat_sys_ioctl(fd, SIOCGIFBRDADDR, arg);
		goto out;
	case _IOW('i', 24, struct ifreq32):
		ret = compat_sys_ioctl(fd, SIOCSIFBRDADDR, arg);
		goto out;
	case _IOWR('i', 25, struct ifreq32):
		ret = compat_sys_ioctl(fd, SIOCGIFNETMASK, arg);
		goto out;
	case _IOW('i', 26, struct ifreq32):
		ret = compat_sys_ioctl(fd, SIOCSIFNETMASK, arg);
		goto out;
	case _IOWR('i', 27, struct ifreq32):
		ret = compat_sys_ioctl(fd, SIOCGIFMETRIC, arg);
		goto out;
	case _IOW('i', 28, struct ifreq32):
		ret = compat_sys_ioctl(fd, SIOCSIFMETRIC, arg);
		goto out;

	case _IOW('i', 30, struct arpreq):
		ret = compat_sys_ioctl(fd, SIOCSARP, arg);
		goto out;
	case _IOWR('i', 31, struct arpreq):
		ret = compat_sys_ioctl(fd, SIOCGARP, arg);
		goto out;
	case _IOW('i', 32, struct arpreq):
		ret = compat_sys_ioctl(fd, SIOCDARP, arg);
		goto out;

	case _IOW('i', 40, struct ifreq32): /* SIOCUPPER */
	case _IOW('i', 41, struct ifreq32): /* SIOCLOWER */
	case _IOW('i', 44, struct ifreq32): /* SIOCSETSYNC */
	case _IOW('i', 45, struct ifreq32): /* SIOCGETSYNC */
	case _IOW('i', 46, struct ifreq32): /* SIOCSSDSTATS */
	case _IOW('i', 47, struct ifreq32): /* SIOCSSESTATS */
	case _IOW('i', 48, struct ifreq32): /* SIOCSPROMISC */
		ret = -EOPNOTSUPP;
		goto out;

	case _IOW('i', 49, struct ifreq32):
		ret = compat_sys_ioctl(fd, SIOCADDMULTI, arg);
		goto out;
	case _IOW('i', 50, struct ifreq32):
		ret = compat_sys_ioctl(fd, SIOCDELMULTI, arg);
		goto out;

	/* FDDI interface ioctls, unsupported. */
		
	case _IOW('i', 51, struct ifreq32): /* SIOCFDRESET */
	case _IOW('i', 52, struct ifreq32): /* SIOCFDSLEEP */
	case _IOW('i', 53, struct ifreq32): /* SIOCSTRTFMWAR */
	case _IOW('i', 54, struct ifreq32): /* SIOCLDNSTRTFW */
	case _IOW('i', 55, struct ifreq32): /* SIOCGETFDSTAT */
	case _IOW('i', 56, struct ifreq32): /* SIOCFDNMIINT */
	case _IOW('i', 57, struct ifreq32): /* SIOCFDEXUSER */
	case _IOW('i', 58, struct ifreq32): /* SIOCFDGNETMAP */
	case _IOW('i', 59, struct ifreq32): /* SIOCFDGIOCTL */
		printk("FDDI ioctl, returning EOPNOTSUPP\n");
		ret = -EOPNOTSUPP;
		goto out;

	case _IOW('t', 125, int):
		/* More stupid tty sunos ioctls, just
		 * say it worked.
		 */
		ret = 0;
		goto out;

	/* Non posix grp */
	case _IOW('t', 118, int): {
		int oldval, newval, __user *ptr;

		cmd = TIOCSPGRP;
		ptr = (int __user *) (unsigned long) arg;
		ret = -EFAULT;
		if(get_user(oldval, ptr))
			goto out;
		ret = compat_sys_ioctl(fd, cmd, arg);
		__get_user(newval, ptr);
		if(newval == -1) {
			__put_user(oldval, ptr);
			ret = -EIO;
		}
		if(ret == -ENOTTY)
			ret = -EIO;
		goto out;
	}

	case _IOR('t', 119, int): {
		int oldval, newval, __user *ptr;

		cmd = TIOCGPGRP;
		ptr = (int __user *) (unsigned long) arg;
		ret = -EFAULT;
		if(get_user(oldval, ptr))
			goto out;
		ret = compat_sys_ioctl(fd, cmd, arg);
		__get_user(newval, ptr);
		if(newval == -1) {
			__put_user(oldval, ptr);
			ret = -EIO;
		}
		if(ret == -ENOTTY)
			ret = -EIO;
		goto out;
	}
	};

	ret = compat_sys_ioctl(fd, cmd, arg);
	/* so stupid... */
	ret = (ret == -EINVAL ? -EOPNOTSUPP : ret);
out:
	return ret;
}
Esempio n. 23
0
int
main(int argc, char **argv)
{
     int i, retval = SUCCESS;
#if defined (HAVE_WORKING_FORK)
     pid_t cpid;
     FILE *fscore;
#endif

#if defined (HAVE_ASSERT_H) && defined (SHORT_PASSWORDS)
     assert(MAX_PLAIN_SIZE < 16);
#endif

     /* set the default values for `usr_opt' */
     memset(&usr_opt, 0, sizeof(usr_opt));
     usr_opt.verbose = 1;
#if defined (DEV_RANDOM_SUPPORT)
     usr_opt.cryptopt.get_entropy = get_dev_entropy;
#elif defined (EGD_SUPPORT)
     usr_opt.cryptopt.get_entropy = get_egd_entropy;
#else
     usr_opt.cryptopt.get_entropy = get_sys_entropy;
#endif

     opt_parse(argc, argv, &usr_opt);

#if defined (HAVE_UMASK)
     /* set umask for security reasons */
     umask(0077);
#endif

     switch (usr_opt.action) {
     case crypt_ios:
     case crypt_pix:
          if (argc != optind + 1)
               tty_error(ERR_USAGE, "no string to crypt");
          usr_opt.cryptopt.plain = (u_char *) str_alloc_copy(argv[optind]);

          retval = (usr_opt.action == crypt_ios) ?
                    crypt_ios_fe(usr_opt.cryptopt.plain,
                                 usr_opt.cryptopt.salt) :
                    crypt_pix_fe(usr_opt.cryptopt.plain);
          break;
     case decrypt_bf:
     case decrypt_wl:
          if (argc != optind + 1)
               tty_error(ERR_USAGE, "no password to decrypt");
          usr_opt.decryptopt.cipher = (u_char *) str_alloc_copy(argv[optind]);
          /* no break here! */
     case resume:
          /* if `decrypt_bf', `decrypt_wl', `resume_bf', `resume_wl',
           * create the restore file in case of an abort event
           */
          save_session_if_signal_abort = true;

          if (usr_opt.action == resume) {
               if (argc != optind)
                    tty_error(ERR_USAGE,
                              "bad argument found `%s'", argv[optind]);

               session_load(usr_opt.decryptopt.restore_file);

               /* `usr_opt.decryptopt.regexpr' can be NULL,
                *  so we must check `usr_opt.decryptopt.wordlist' */
               usr_opt.action =
                    usr_opt.decryptopt.wordlist ? resume_wl: resume_bf;
          }

#if defined (HAVE_WORKING_FORK)
          if (usr_opt.daemonize) {
               cpid = fork();
               if (cpid == (pid_t) 0) {   /* child process */
                    /* checks the SCORE_FILE format */
                    fcheck(SCORE_FILE, HEAD_SCORE_TEXT);

                    /* add the line `HEAD_SCORE_TEXT"\n"' at the begin,
                     * if the file do not exists */
                    if (!(fscore = fopen(SCORE_FILE, "r"))) {
                         fscore = fopen(SCORE_FILE, "w");
                         fprintf(fscore, HEAD_SCORE_TEXT"\n");
                    }
                    fclose(fscore);
                    tty_message
                        ("%s -- running in daemon mode"
#if defined (HAVE_GETPID)
                         " [pid: %d]"
#endif
                         "...\n** WARNING: "
                         "sensible data could be written in the file `%s'!\n",
                         *argv,
#if defined (HAVE_GETPID)
                         (int) getpid(),
#endif
                         SCORE_FILE);
                    /* point stdin/stdout/stderr to /dev/null */
                    for (i = 0; i < 3; i++)
                         close(i);
                    i = open(NULL_DEV, O_RDWR);
                    if (i >= 0) {
                         dup2(i, 0);
                         dup2(i, 1);
                         dup2(i, 2);
                         if (i > 2)
                              close(i);
                    }
                    retval = cisco_decrypt();
                    return retval;
               } else if (cpid < (pid_t) 0)
                    tty_error(ERR_FORKING,
                              "cannot run in daemon mode : %s",
                              strerror(errno));
               else
                    return SUCCESS;     /* parent process */
          } else
#endif
               retval = cisco_decrypt();
          break;
     default:                  /* not enought paramethers entered */
          tty_error(ERR_USAGE, "nothing to do (?)");
     }

     mem_free_all();
     return retval;
}