home *** CD-ROM | disk | FTP | other *** search
- /* Copyright (C) 1990 Keith Gabryelski (ag@amix.commodore.com)
-
- This file is part of advise.
-
- advise is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY. No author or distributor
- accepts responsibility to anyone for the consequences of using it
- or for whether it serves any particular purpose or works at all,
- unless he says so in writing. Refer to the advise General Public
- License for full details.
-
- Everyone is granted permission to copy, modify and redistribute
- advise, but only under the conditions described in the
- advise General Public License. A copy of this license is
- supposed to have been given to you along with advise so you
- can know your rights and responsibilities. It should be in a
- file named COPYING. Among other things, the copyright notice
- and this notice must be preserved on all copies. */
-
- /*
- ** Author: Keith Gabryelski (ag@amix.commodore.com)
- */
-
- #ifndef sun
- #include <sys/types.h>
- #include <sys/param.h>
- #include <sys/signal.h>
- #include <sys/file.h>
- #include <sys/user.h>
- #include <sys/proc.h>
- #include <sys/termios.h>
- #include <sys/ttold.h>
- #include <sys/cmn_err.h>
- #include <sys/stream.h>
- #include <sys/stropts.h>
- #include <sys/errno.h>
- #include <sys/debug.h>
- #include "advise.h"
- #include <sys/inline.h>
- #endif /* sun */
-
- #ifdef i386
- #include <sys/ddi.h>
-
- int advmoddevflag = 0; /* Used by the Kernel */
- #endif /* i386 */
-
- int advisemopen(), advisemclose(), advisemput();
-
- static struct module_info advisemiinfo =
- {
- 0, ADVMODNAME, 0, INFPSZ, 2048, 128,
- };
-
- static struct qinit advisemrinit =
- {
- advisemput, NULL, advisemopen, advisemclose, NULL, &advisemiinfo, NULL
- };
-
- static struct module_info advisemoinfo =
- {
- 42, ADVMODNAME, 0, INFPSZ, 300, 200,
- };
-
- static struct qinit advisemwinit =
- {
- advisemput, NULL, NULL, NULL, NULL, &advisemoinfo, NULL
- };
-
- #ifdef sun
- static
- #endif /* sun */
- struct streamtab advmodinfo =
- {
- &advisemrinit, &advisemwinit, NULL, NULL,
- };
-
- #ifdef sun
- static
- #endif /* sun */
- struct advise_state advise_table;
-
-
- /*ARGSUSED*/
- static int
- advisemopen(q, dev, flag, sflag
- #ifndef sun
- , credp
- #endif /* !sun */
- )
- register queue_t *q;
- #ifdef sun
- #define DEVP dev
- #else
- #define DEVP *dev
- dev_t DEVP;
- cred_t *credp;
- #endif /* !sun */
- {
- register struct advise_state *sp;
- register mblk_t *bp;
- struct advise_state *llist = &advise_table;
- int s;
-
- if (sflag != MODOPEN)
- return EINVAL;
-
- if ((bp = allocb((int)sizeof(struct advise_state), BPRI_MED)) == NULL)
- {
- return ENOMEM;
- }
-
- bp->b_wptr += sizeof(struct advise_state);
- sp = (struct advise_state *)bp->b_rptr;
- sp->savbp = bp;
-
- sp->dev = DEVP;
- sp->status = 0; /* Deny access by default */
- sp->next = NULL;
- sp->q_wlist = sp->q_rlist = NULL;
- sp->q = q;
-
- s=spladvise();
- while (llist->next != NULL)
- {
- if (llist->next->dev == DEVP)
- {
- /*
- ** We are already pushed on this stream.
- */
- freeb(bp);
-
- sp = llist->next;
-
- break;
- }
-
- llist = llist->next;
- }
-
- llist->next = sp;
- splx(s);
-
- q->q_ptr = (caddr_t)sp;
- WR(q)->q_ptr = (caddr_t)sp;
-
- return 0;
- }
-
- static
- advisemclose(q)
- register queue_t *q;
- {
- register struct advise_state *sp = (struct advise_state *)q->q_ptr;
- struct advise_state *llist = &advise_table;
- struct advise_queue_list *qp;
- int s;
-
- sp->status = 0;
-
- s = spladvise();
-
- /* unlink us from the state table */
-
- while (llist->next != sp)
- llist = llist->next;
-
- llist->next = llist->next->next;
-
- /* tell each advisor that we're shutting down */
- for (qp = sp->q_rlist; qp != NULL; qp = qp->next)
- {
- flushq(qp->q, FLUSHDATA);
- putctl(qp->q->q_next, M_HANGUP);
- }
- for (qp = sp->q_wlist; qp != NULL; qp = qp->next)
- {
- flushq(qp->q, FLUSHDATA);
- putctl(qp->q->q_next, M_HANGUP);
- }
- splx(s);
-
- freeb(sp->savbp);
-
- q->q_ptr = NULL;
- WR(q)->q_ptr = NULL;
- }
-
- static int
- advisemput(q, mp)
- register queue_t *q;
- register mblk_t *mp;
- {
- struct advise_state *sp = (struct advise_state *)q->q_ptr;
- register struct advise_queue_list *qp;
- int s;
-
- if(q==sp->q) { /* called as read-side put proc */
- if(mp->b_datap->db_type==M_DATA) {
- /*
- ** Write data to advisors.
- */
- s = spladvise();
- for (qp = sp->q_rlist; qp != NULL; qp = qp->next) {
- mblk_t *mp1 = copymsg(mp);
-
- if (mp1 != NULL) putnext(qp->q, mp1);
- }
- splx(s);
- }
-
- }
- else switch (mp->b_datap->db_type) /* called as write-side put proc */
- {
- case M_DATA:
- /*
- ** Write data to advisors.
- */
- s = spladvise();
- for (qp = sp->q_wlist; qp != NULL; qp = qp->next)
- {
- mblk_t *mp1 = copymsg(mp);
-
- if (mp1 != NULL)
- putnext(qp->q, mp1);
- }
-
- splx(s);
- break;
-
- #ifdef M_COPYOUT
- case M_IOCDATA:
- #endif /* !M_COPYOUT */
- case M_IOCTL:
- if (advisemsrvioc(q, mp)) /* handled? */
- return 0;
- break;
- }
-
- putnext(q, mp);
-
- return 0;
- }
-
- static int
- advisemsrvioc(q, mp)
- queue_t *q;
- mblk_t *mp;
- {
- mblk_t *mp1;
- struct iocblk *iocbp = (struct iocblk *)mp->b_rptr;
- struct advise_state *sp = (struct advise_state *)q->q_ptr;
-
- #ifdef M_COPYOUT
- if (mp->b_datap->db_type == M_IOCDATA)
- {
- struct copyresp *csp = (struct copyresp *)mp->b_rptr;
-
- switch(csp->cp_cmd)
- {
- case ADVISE_STATUS:
- case ADVISE_ALLOW:
- case ADVISE_DENY:
- /* For copyin/copyout failures, just free message. */
-
- if (csp->cp_rval)
- freemsg(mp);
- else if (!csp->cp_private)
- {
- mp->b_datap->db_type = M_IOCACK;
- freemsg(unlinkb(mp));
- iocbp->ioc_count = 0;
- iocbp->ioc_rval = 0;
- iocbp->ioc_error = 0;
- putnext(RD(q), mp);
- }
-
- return 1;
- }
- }
- #endif /* M_COPYOUT */
-
- switch (iocbp->ioc_cmd)
- {
- #if defined(M_COPYOUT) || defined(sun)
- case ADVISE_STATUS:
- {
- int *status;
- #ifdef M_COPYOUT
- caddr_t arg = *(caddr_t *)mp->b_cont->b_rptr;
-
- freemsg(mp->b_cont);
- #endif /* M_COPYOUT */
-
- mp->b_cont = allocb(sizeof(int), BPRI_MED);
- if (!mp->b_cont)
- {
- mp->b_datap->db_type = M_IOCNAK;
- freemsg(unlinkb(mp));
- iocbp->ioc_count = 0;
- iocbp->ioc_rval = 0;
- iocbp->ioc_error = ENOMEM;
- putnext(RD(q), mp);
- return 1;
- }
-
- status = (int *)mp->b_cont->b_rptr;
- mp->b_cont->b_wptr += sizeof(int);
-
- *status = sp->status;
-
- #ifdef M_COPYOUT
- if (mp->b_datap->db_type == M_IOCTL &&
- iocbp->ioc_count == TRANSPARENT)
- {
- struct copyreq *creq = (struct copyreq *)mp->b_rptr;
- mp->b_datap->db_type = M_COPYOUT;
- creq->cq_addr = arg;
- mp->b_wptr = mp->b_rptr + sizeof *creq;
- mp->b_cont->b_wptr = mp->b_cont->b_rptr + sizeof(int);
- creq->cq_size = sizeof(int);
- creq->cq_flag = 0;
- creq->cq_private = (mblk_t *)NULL;
- putnext(RD(q), mp);
- return 1;
- }
- #else /* !M_COPYOUT */
- mp->b_datap->db_type = M_IOCACK;
- iocbp->ioc_count = sizeof(int);
- putnext(RD(q), mp);
- #endif /* M_COPYOUT */
- }
-
- break;
-
- #else /* !M_COPYOUT && !sun */
-
- case ADVISE_STATUS:
- mp->b_datap->db_type = M_IOCACK;
- mp1 = unlinkb(mp);
- if (mp1)
- freeb(mp1);
- iocbp->ioc_count = 0;
- putnext(RD(q), mp);
- break;
- #endif /* M_COPYOUT || sun */
-
- case ADVISE_ALLOW:
- sp->status |= ALLOW_ADVICE;
-
- mp->b_datap->db_type = M_IOCACK;
- mp1 = unlinkb(mp);
- if (mp1)
- freeb(mp1);
- iocbp->ioc_count = 0;
- putnext(RD(q), mp);
- break;
-
- case ADVISE_DENY:
- sp->status &= ~(ALLOW_ADVICE);
-
- mp->b_datap->db_type = M_IOCACK;
- mp1 = unlinkb(mp);
- if (mp1)
- freeb(mp1);
- iocbp->ioc_count = 0;
- putnext(RD(q), mp);
- break;
-
- default:
- return 0;
- }
-
- return 1;
- }
-