home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / misc / volume28 / advise / part01 / advisemod.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-02-23  |  7.3 KB  |  376 lines

  1. /* Copyright (C) 1990 Keith Gabryelski (ag@amix.commodore.com)
  2.  
  3. This file is part of advise.
  4.  
  5. advise is distributed in the hope that it will be useful,
  6. but WITHOUT ANY WARRANTY.  No author or distributor
  7. accepts responsibility to anyone for the consequences of using it
  8. or for whether it serves any particular purpose or works at all,
  9. unless he says so in writing.  Refer to the advise General Public
  10. License for full details.
  11.  
  12. Everyone is granted permission to copy, modify and redistribute
  13. advise, but only under the conditions described in the
  14. advise General Public License.   A copy of this license is
  15. supposed to have been given to you along with advise so you
  16. can know your rights and responsibilities.  It should be in a
  17. file named COPYING.  Among other things, the copyright notice
  18. and this notice must be preserved on all copies.  */
  19.  
  20. /*
  21. ** Author:    Keith Gabryelski    (ag@amix.commodore.com)
  22. */
  23.  
  24. #ifndef sun
  25. #include <sys/types.h>
  26. #include <sys/param.h>
  27. #include <sys/signal.h>
  28. #include <sys/file.h>
  29. #include <sys/user.h>
  30. #include <sys/proc.h>
  31. #include <sys/termios.h>
  32. #include <sys/ttold.h>
  33. #include <sys/cmn_err.h>
  34. #include <sys/stream.h>
  35. #include <sys/stropts.h>
  36. #include <sys/errno.h>
  37. #include <sys/debug.h>
  38. #include "advise.h"
  39. #include <sys/inline.h>
  40. #endif /* sun */
  41.  
  42. #ifdef i386
  43. #include <sys/ddi.h>
  44.  
  45. int advmoddevflag = 0;    /* Used by the Kernel */
  46. #endif /* i386 */
  47.  
  48. int advisemopen(), advisemclose(), advisemput();
  49.  
  50. static struct module_info advisemiinfo =
  51. {
  52.     0, ADVMODNAME, 0, INFPSZ, 2048, 128,
  53. };
  54.  
  55. static struct qinit advisemrinit =
  56. {
  57.     advisemput, NULL, advisemopen, advisemclose, NULL, &advisemiinfo, NULL
  58. };
  59.  
  60. static struct module_info advisemoinfo =
  61. {
  62.     42, ADVMODNAME, 0, INFPSZ, 300, 200,
  63. };
  64.  
  65. static struct qinit advisemwinit =
  66. {
  67.     advisemput, NULL, NULL, NULL, NULL, &advisemoinfo, NULL
  68. };
  69.  
  70. #ifdef sun
  71. static
  72. #endif /* sun */
  73. struct streamtab advmodinfo =
  74. {
  75.     &advisemrinit, &advisemwinit, NULL, NULL,
  76. };
  77.  
  78. #ifdef sun
  79. static
  80. #endif /* sun */
  81. struct advise_state advise_table;
  82.  
  83.  
  84. /*ARGSUSED*/
  85. static int
  86. advisemopen(q, dev, flag, sflag
  87. #ifndef sun
  88.     , credp
  89. #endif /* !sun */
  90. )
  91. register queue_t *q;
  92. #ifdef sun
  93. #define DEVP    dev
  94. #else
  95. #define DEVP    *dev
  96. dev_t DEVP;
  97. cred_t *credp;
  98. #endif /* !sun */
  99. {
  100.     register struct advise_state *sp;
  101.     register mblk_t *bp;
  102.     struct advise_state *llist = &advise_table;
  103.     int s;
  104.  
  105.     if (sflag != MODOPEN)
  106.     return EINVAL;
  107.  
  108.     if ((bp = allocb((int)sizeof(struct advise_state), BPRI_MED)) == NULL)
  109.     {
  110.     return ENOMEM;
  111.     }
  112.  
  113.     bp->b_wptr += sizeof(struct advise_state);
  114.     sp = (struct advise_state *)bp->b_rptr;
  115.     sp->savbp = bp;
  116.  
  117.     sp->dev = DEVP;
  118.     sp->status = 0;        /* Deny access by default */
  119.     sp->next = NULL;
  120.     sp->q_wlist = sp->q_rlist = NULL;
  121.     sp->q = q;
  122.  
  123.     s=spladvise();
  124.     while (llist->next != NULL)
  125.     {
  126.     if (llist->next->dev == DEVP)
  127.     {
  128.         /*
  129.         ** We are already pushed on this stream.
  130.         */
  131.         freeb(bp);
  132.  
  133.         sp = llist->next;
  134.  
  135.         break;
  136.     }
  137.  
  138.     llist = llist->next;
  139.     }
  140.  
  141.     llist->next = sp;
  142.     splx(s);
  143.  
  144.     q->q_ptr = (caddr_t)sp;
  145.     WR(q)->q_ptr = (caddr_t)sp;
  146.  
  147.     return 0;
  148. }
  149.  
  150. static
  151. advisemclose(q)
  152. register queue_t *q;
  153. {
  154.     register struct advise_state *sp = (struct advise_state *)q->q_ptr;
  155.     struct advise_state *llist = &advise_table;
  156.     struct advise_queue_list *qp;
  157.     int s;
  158.  
  159.     sp->status = 0;
  160.  
  161.     s = spladvise();
  162.  
  163.     /* unlink us from the state table */
  164.  
  165.     while (llist->next != sp)
  166.     llist = llist->next;
  167.  
  168.     llist->next = llist->next->next;
  169.  
  170.     /* tell each advisor that we're shutting down */
  171.     for (qp = sp->q_rlist; qp != NULL; qp = qp->next)
  172.     {
  173.     flushq(qp->q, FLUSHDATA);
  174.     putctl(qp->q->q_next, M_HANGUP);
  175.     }
  176.     for (qp = sp->q_wlist; qp != NULL; qp = qp->next)
  177.     {
  178.     flushq(qp->q, FLUSHDATA);
  179.     putctl(qp->q->q_next, M_HANGUP);
  180.     }
  181.     splx(s);
  182.  
  183.     freeb(sp->savbp);
  184.  
  185.     q->q_ptr = NULL;
  186.     WR(q)->q_ptr = NULL;
  187. }
  188.  
  189. static int
  190. advisemput(q, mp)
  191. register queue_t *q;
  192. register mblk_t *mp;
  193. {
  194.     struct advise_state *sp = (struct advise_state *)q->q_ptr;
  195.     register struct advise_queue_list *qp;
  196.     int s;
  197.  
  198.     if(q==sp->q) { /* called as read-side put proc */
  199.     if(mp->b_datap->db_type==M_DATA) {
  200.         /*
  201.         ** Write data to advisors.
  202.         */
  203.         s = spladvise();
  204.         for (qp = sp->q_rlist; qp != NULL; qp = qp->next) {
  205.         mblk_t *mp1 = copymsg(mp);
  206.  
  207.         if (mp1 != NULL) putnext(qp->q, mp1);
  208.         }
  209.         splx(s);
  210.     }
  211.  
  212.     }
  213.     else switch (mp->b_datap->db_type) /* called as write-side put proc */
  214.     {
  215.     case M_DATA:
  216.     /*
  217.     ** Write data to advisors.
  218.     */
  219.     s = spladvise();
  220.     for (qp = sp->q_wlist; qp != NULL; qp = qp->next)
  221.     {
  222.         mblk_t *mp1 = copymsg(mp);
  223.  
  224.         if (mp1 != NULL)
  225.         putnext(qp->q, mp1);
  226.     }
  227.  
  228.     splx(s);
  229.     break;
  230.  
  231. #ifdef M_COPYOUT
  232.     case M_IOCDATA:
  233. #endif /* !M_COPYOUT */
  234.     case M_IOCTL:
  235.     if (advisemsrvioc(q, mp)) /* handled? */
  236.         return 0;
  237.     break;
  238.     }
  239.  
  240.     putnext(q, mp);
  241.  
  242.     return 0;
  243. }
  244.  
  245. static int
  246. advisemsrvioc(q, mp)
  247. queue_t *q;
  248. mblk_t *mp;
  249. {
  250.     mblk_t *mp1;
  251.     struct iocblk *iocbp = (struct iocblk *)mp->b_rptr;
  252.     struct advise_state *sp = (struct advise_state *)q->q_ptr;
  253.  
  254. #ifdef M_COPYOUT
  255.     if (mp->b_datap->db_type == M_IOCDATA)
  256.     {
  257.     struct copyresp *csp = (struct copyresp *)mp->b_rptr;
  258.  
  259.     switch(csp->cp_cmd)
  260.     {
  261.     case ADVISE_STATUS:
  262.     case ADVISE_ALLOW:
  263.     case ADVISE_DENY:
  264.         /* For copyin/copyout failures, just free message. */
  265.  
  266.         if (csp->cp_rval)
  267.         freemsg(mp);
  268.         else if (!csp->cp_private)
  269.         {
  270.         mp->b_datap->db_type = M_IOCACK;
  271.         freemsg(unlinkb(mp));
  272.         iocbp->ioc_count = 0;
  273.         iocbp->ioc_rval = 0;
  274.         iocbp->ioc_error = 0;
  275.         putnext(RD(q), mp);
  276.         }
  277.  
  278.         return 1;
  279.         }
  280.     }
  281. #endif /* M_COPYOUT */
  282.  
  283.     switch (iocbp->ioc_cmd)
  284.     {
  285. #if defined(M_COPYOUT) || defined(sun)
  286.     case ADVISE_STATUS:
  287.         {
  288.         int *status;
  289. #ifdef M_COPYOUT
  290.         caddr_t arg = *(caddr_t *)mp->b_cont->b_rptr;
  291.  
  292.         freemsg(mp->b_cont);
  293. #endif /* M_COPYOUT */
  294.  
  295.         mp->b_cont = allocb(sizeof(int), BPRI_MED);
  296.         if (!mp->b_cont)
  297.         {
  298.         mp->b_datap->db_type = M_IOCNAK;
  299.         freemsg(unlinkb(mp));
  300.         iocbp->ioc_count = 0;
  301.         iocbp->ioc_rval = 0;
  302.         iocbp->ioc_error = ENOMEM;
  303.         putnext(RD(q), mp);
  304.         return 1;
  305.         }
  306.  
  307.         status = (int *)mp->b_cont->b_rptr;
  308.         mp->b_cont->b_wptr += sizeof(int);
  309.  
  310.         *status = sp->status;
  311.  
  312. #ifdef M_COPYOUT
  313.         if (mp->b_datap->db_type == M_IOCTL &&
  314.         iocbp->ioc_count == TRANSPARENT)
  315.         {
  316.         struct copyreq *creq = (struct copyreq *)mp->b_rptr;
  317.         mp->b_datap->db_type = M_COPYOUT;
  318.         creq->cq_addr = arg;
  319.         mp->b_wptr = mp->b_rptr + sizeof *creq;
  320.         mp->b_cont->b_wptr = mp->b_cont->b_rptr + sizeof(int);
  321.         creq->cq_size = sizeof(int);
  322.         creq->cq_flag = 0;
  323.         creq->cq_private = (mblk_t *)NULL;
  324.         putnext(RD(q), mp);
  325.         return 1;
  326.         }
  327. #else /* !M_COPYOUT */
  328.         mp->b_datap->db_type = M_IOCACK;
  329.         iocbp->ioc_count = sizeof(int);
  330.         putnext(RD(q), mp);
  331. #endif /* M_COPYOUT */
  332.     }
  333.  
  334.     break;
  335.  
  336. #else /* !M_COPYOUT && !sun */
  337.  
  338.     case ADVISE_STATUS:
  339.     mp->b_datap->db_type = M_IOCACK;
  340.     mp1 = unlinkb(mp);
  341.     if (mp1)
  342.         freeb(mp1);
  343.     iocbp->ioc_count = 0;
  344.     putnext(RD(q), mp);
  345.     break;
  346. #endif /* M_COPYOUT || sun */
  347.  
  348.     case ADVISE_ALLOW:
  349.     sp->status |= ALLOW_ADVICE;
  350.  
  351.     mp->b_datap->db_type = M_IOCACK;
  352.     mp1 = unlinkb(mp);
  353.     if (mp1)
  354.         freeb(mp1);
  355.     iocbp->ioc_count = 0;
  356.     putnext(RD(q), mp);
  357.     break;
  358.  
  359.     case ADVISE_DENY:
  360.     sp->status &= ~(ALLOW_ADVICE);
  361.  
  362.     mp->b_datap->db_type = M_IOCACK;
  363.     mp1 = unlinkb(mp);
  364.     if (mp1)
  365.         freeb(mp1);
  366.     iocbp->ioc_count = 0;
  367.     putnext(RD(q), mp);
  368.     break;
  369.  
  370.     default:
  371.     return 0;
  372.     }
  373.  
  374.     return 1;
  375. }
  376.