#include <sys/errno.h>
#include <sys/types.h>
#include <sys/param.h>
#include <machine/spl.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/proc_internal.h>
#include <sys/filedesc.h>
#include <sys/fcntl.h>
#include <sys/mbuf.h>
#include <sys/malloc.h>
#include <sys/file_internal.h>
#include <sys/socket.h>
#include <sys/socketvar.h>
#include <sys/sysproto.h>
#include <sys/kdebug.h>
#include <net/if_var.h>
#include <netat/sysglue.h>
#include <netat/appletalk.h>
#include <netat/at_pcb.h>
#include <netat/at_var.h>
#include <netat/debug.h>
int falloc_locked(proc_t, struct fileproc **, int *, vfs_context_t, int);
extern at_ifaddr_t *ifID_home;
extern lck_mtx_t * atalk_mutex;
#define f_flag f_fglob->fg_flag
#define f_type f_fglob->fg_type
#define f_msgcount f_fglob->fg_msgcount
#define f_cred f_fglob->fg_cred
#define f_ops f_fglob->fg_ops
#define f_offset f_fglob->fg_offset
#define f_data f_fglob->fg_data
int _ATkqfilter(struct fileproc *, struct knote *, vfs_context_t);
int _ATselect(struct fileproc *, int, void *, vfs_context_t);
int _ATioctl(struct fileproc *, u_long, caddr_t, vfs_context_t);
int _ATwrite(struct fileproc *, struct uio *, int, vfs_context_t);
int _ATread(struct fileproc *, struct uio *, int, vfs_context_t);
int _ATclose(struct fileglob *, vfs_context_t);
int ATsocket(proc, uap, retval)
struct proc *proc;
struct ATsocket_args *uap;
int *retval;
{
int err;
atalk_lock();
if (1 ) {
if (!(at_state.flags & AT_ST_STARTED) || !ifID_home) {
*retval = -1;
err = ENOTREADY;
} else {
*retval = _ATsocket((int)uap->proto, (int *)&err, (void *)proc);
}
} else {
*retval = -1;
err = ENXIO;
}
atalk_unlock();
return err;
}
int ATgetmsg(proc, uap, retval)
struct proc *proc;
struct ATgetmsg_args *uap;
int *retval;
{
int err;
atalk_lock();
if (1 ) {
if (!(at_state.flags & AT_ST_STARTED) || !ifID_home) {
*retval = -1;
err = ENOTREADY;
} else {
*retval =
(*_ATgetmsg)(uap->fd, uap->ctlptr, uap->datptr,
uap->flags, &err, proc);
}
} else {
*retval = -1;
err = ENXIO;
}
atalk_unlock();
return err;
}
int ATputmsg(proc, uap, retval)
struct proc *proc;
struct ATputmsg_args *uap;
int *retval;
{
int err;
atalk_lock();
if (1 ) {
if (!(at_state.flags & AT_ST_STARTED) || !ifID_home) {
*retval = -1;
err = ENOTREADY;
} else {
*retval =
_ATputmsg(uap->fd, uap->ctlptr, uap->datptr,
uap->flags, &err, proc);
}
} else {
*retval = -1;
err = ENXIO;
}
atalk_unlock();
return err;
}
int ATPsndreq(proc, uap, retval)
struct proc *proc;
struct ATPsndreq_args *uap;
int *retval;
{
int err;
atalk_lock();
if (1 ) {
if (!(at_state.flags & AT_ST_STARTED) || !ifID_home) {
*retval = -1;
err = ENOTREADY;
} else {
*retval =
_ATPsndreq(uap->fd, uap->buf, uap->len,
uap->nowait, &err, proc);
}
} else {
*retval = -1;
err= ENXIO;
}
atalk_unlock();
return err;
}
int ATPsndrsp(proc, uap, retval)
struct proc *proc;
struct ATPsndrsp_args *uap;
int *retval;
{
int err;
atalk_lock();
if (1 ) {
if (!(at_state.flags & AT_ST_STARTED) || !ifID_home) {
*retval = -1;
err = ENOTREADY;
} else {
*retval =
_ATPsndrsp(uap->fd, uap->respbuff,
uap->resplen, uap->datalen, &err, proc);
}
} else {
*retval = -1;
err = ENXIO;
}
atalk_unlock();
return err;
}
int ATPgetreq(proc, uap, retval)
struct proc *proc;
struct ATPgetreq_args *uap;
int *retval;
{
int err;
atalk_lock();
if (1 ) {
if (!(at_state.flags & AT_ST_STARTED) || !ifID_home) {
*retval = -1;
err = ENOTREADY;
} else {
*retval =
_ATPgetreq(uap->fd, uap->buf, uap->buflen,
&err, proc);
}
} else {
*retval = -1;
err = ENXIO;
}
atalk_unlock();
return err;
}
int ATPgetrsp(proc, uap, retval)
struct proc *proc;
struct ATPgetrsp_args *uap;
int *retval;
{
int err = 0;
atalk_lock();
if (1 ) {
if (!(at_state.flags & AT_ST_STARTED) || !ifID_home) {
*retval = -1;
err = ENOTREADY;
} else {
*retval =
_ATPgetrsp(uap->fd, (struct atpBDS *)uap->bdsp, &err, proc);
}
} else {
*retval = -1;
err = ENXIO;
}
atalk_unlock();
return err;
}
int atalk_closeref(fg, grefp)
struct fileglob *fg;
gref_t **grefp;
{
if ((*grefp = (gref_t *)fg->fg_data)) {
fg->fg_data = 0;
return(0);
}
return(EBADF);
}
int atalk_openref(gref, retfd, proc)
gref_t *gref;
int *retfd;
struct proc *proc;
{
static struct fileops fileops =
{_ATread, _ATwrite, _ATioctl, _ATselect, _ATclose, _ATkqfilter, 0};
int err, fd;
struct fileproc *fp;
lck_mtx_assert(atalk_mutex, LCK_MTX_ASSERT_OWNED);
proc_fdlock(proc);
if ((err = falloc_locked(proc, &fp, &fd, vfs_context_current(), 1)) != 0) {
proc_fdunlock(proc);
return err;
}
fp->f_flag = FREAD|FWRITE;
fp->f_type = DTYPE_ATALK+1;
fp->f_ops = &fileops;
fp->f_data = (void *)gref;
procfdtbl_releasefd(proc, fd, NULL);
*retfd = fd;
fp_drop(proc, fd, fp, 1);
proc_fdunlock(proc);
return 0;
}
int atalk_getref(fp, fd, grefp, proc, droponerr)
struct fileproc *fp;
int fd;
gref_t **grefp;
struct proc *proc;
int droponerr;
{
int error;
proc_fdlock(proc);
error = atalk_getref_locked(fp, fd, grefp, proc, droponerr);
proc_fdunlock(proc);
return error;
}
int atalk_getref_locked(fp, fd, grefp, proc, droponerr)
struct fileproc *fp;
int fd;
gref_t **grefp;
struct proc *proc;
int droponerr;
{
lck_mtx_assert(atalk_mutex, LCK_MTX_ASSERT_OWNED);
if (fp == 0) {
int error = fp_lookup(proc, fd, &fp, 1);
if (error) {
*grefp = (gref_t *) 0;
return EBADF;
}
}
*grefp = (gref_t *)fp->f_data;
if (fp->f_type != (DTYPE_ATALK+1) || *grefp == 0 || *grefp == (gref_t *)(-1)) {
if (droponerr)
fp_drop(proc, fd, fp, 1);
printf("atalk_getref_locked EBADF f_data: %p\n", fp->f_data);
return EBADF;
}
if ((*grefp)->errno) {
if (droponerr)
fp_drop(proc, fd, fp, 1);
return (int)(*grefp)->errno;
}
return 0;
}