The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/netncp/ncp_subr.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*
    2  * Copyright (c) 1999, Boris Popov
    3  * All rights reserved.
    4  *
    5  * Redistribution and use in source and binary forms, with or without
    6  * modification, are permitted provided that the following conditions
    7  * are met:
    8  * 1. Redistributions of source code must retain the above copyright
    9  *    notice, this list of conditions and the following disclaimer.
   10  * 2. Redistributions in binary form must reproduce the above copyright
   11  *    notice, this list of conditions and the following disclaimer in the
   12  *    documentation and/or other materials provided with the distribution.
   13  * 3. All advertising materials mentioning features or use of this software
   14  *    must display the following acknowledgement:
   15  *    This product includes software developed by Boris Popov.
   16  * 4. Neither the name of the author nor the names of any co-contributors
   17  *    may be used to endorse or promote products derived from this software
   18  *    without specific prior written permission.
   19  *
   20  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   21  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   22  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   23  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   24  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   25  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   26  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   27  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   28  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   29  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   30  * SUCH DAMAGE.
   31  *
   32  * $FreeBSD$
   33  */
   34 #include <sys/param.h>
   35 #include <sys/errno.h>
   36 #include <sys/proc.h>
   37 #include <sys/systm.h>
   38 #include <sys/kernel.h>
   39 #include <sys/malloc.h>
   40 #include <sys/time.h>
   41 #include <sys/uio.h>
   42 #include <sys/mbuf.h>
   43 
   44 #include <netncp/ncp.h>
   45 #include <netncp/ncp_conn.h>
   46 #include <netncp/ncp_sock.h>
   47 #include <netncp/ncp_subr.h>
   48 #include <netncp/ncp_rq.h>
   49 #include <netncp/ncp_ncp.h>
   50 #include <netncp/nwerror.h>
   51 
   52 int ncp_debuglevel = 0;
   53 
   54 struct callout_handle ncp_timer_handle;
   55 
   56 static void ncp_at_exit(struct proc *p);
   57 static void ncp_timer(void *arg);
   58 
   59 /*
   60  * duplicate string from user space. It should be very-very slow.
   61  */
   62 char *
   63 ncp_str_dup(char *s) {
   64         char *p, bt;
   65         int len = 0;
   66 
   67         for (p = s;;p++) {
   68                 if (copyin(p, &bt, 1)) return NULL;
   69                 len++;
   70                 if (bt == 0) break;
   71         }
   72         MALLOC(p, char*, len, M_NCPDATA, M_WAITOK);
   73         copyin(s, p, len);
   74         return p;
   75 }
   76 
   77 
   78 void
   79 ncp_at_exit(struct proc *p) {
   80         struct ncp_conn *ncp, *nncp;
   81 
   82         if (ncp_conn_putprochandles(p) == 0) return;
   83 
   84         ncp_conn_locklist(LK_EXCLUSIVE, p);
   85         for (ncp = SLIST_FIRST(&conn_list); ncp; ncp = nncp) {
   86                 nncp = SLIST_NEXT(ncp, nc_next);
   87                 if (ncp->ref_cnt != 0) continue;
   88                 if (ncp_conn_lock(ncp, p, p->p_ucred,NCPM_READ|NCPM_EXECUTE|NCPM_WRITE))
   89                         continue;
   90                 if (ncp_disconnect(ncp) != 0)
   91                         ncp_conn_unlock(ncp,p);
   92         }
   93         ncp_conn_unlocklist(p);
   94         return;
   95 }
   96 
   97 int
   98 ncp_init(void) {
   99         ncp_conn_init();
  100         if (at_exit(ncp_at_exit)) {
  101                 NCPFATAL("can't register at_exit handler\n");
  102                 return ENOMEM;
  103         }
  104         ncp_timer_handle = timeout(ncp_timer,NULL,NCP_TIMER_TICK);
  105         return 0;
  106 }
  107 
  108 void
  109 ncp_done(void) {
  110         struct ncp_conn *ncp, *nncp;
  111         struct proc *p = curproc;
  112         
  113         untimeout(ncp_timer,NULL,ncp_timer_handle);
  114         rm_at_exit(ncp_at_exit);
  115         ncp_conn_locklist(LK_EXCLUSIVE, p);
  116         for (ncp = SLIST_FIRST(&conn_list); ncp; ncp = nncp) {
  117                 nncp = SLIST_NEXT(ncp, nc_next);
  118                 ncp->ref_cnt = 0;
  119                 if (ncp_conn_lock(ncp, p, p->p_ucred,NCPM_READ|NCPM_EXECUTE|NCPM_WRITE)) {
  120                         NCPFATAL("Can't lock connection !\n");
  121                         continue;
  122                 }
  123                 if (ncp_disconnect(ncp) != 0)
  124                         ncp_conn_unlock(ncp,p);
  125         }
  126         ncp_conn_unlocklist(p);
  127 }
  128 
  129 
  130 /* tick every second and check for watch dog packets and lost connections */
  131 static void
  132 ncp_timer(void *arg){
  133         struct ncp_conn *conn;
  134 
  135         if(ncp_conn_locklist(LK_SHARED | LK_NOWAIT, NULL) == 0) {
  136                 SLIST_FOREACH(conn, &conn_list, nc_next)
  137                         ncp_check_conn(conn);
  138                 ncp_conn_unlocklist(NULL);
  139         }
  140         ncp_timer_handle = timeout(ncp_timer,NULL,NCP_TIMER_TICK);
  141 }
  142 
  143 int
  144 ncp_get_bindery_object_id(struct ncp_conn *conn, 
  145                 u_int16_t object_type, char *object_name, 
  146                 struct ncp_bindery_object *target,
  147                 struct proc *p,struct ucred *cred)
  148 {
  149         int error;
  150         DECLARE_RQ;
  151 
  152         NCP_RQ_HEAD_S(23,53,p,cred);
  153         ncp_rq_word_hl(rqp, object_type);
  154         ncp_rq_pstring(rqp, object_name);
  155         checkbad(ncp_request(conn,rqp));
  156         if (rqp->rpsize < 54) {
  157                 printf("ncp_rp_size %d < 54\n", rqp->rpsize);
  158                 error = EINVAL;
  159                 goto bad;
  160         }
  161         target->object_id = ncp_rp_dword_hl(rqp);
  162         target->object_type = ncp_rp_word_hl(rqp);
  163         ncp_rp_mem(rqp,(caddr_t)target->object_name, 48);
  164         NCP_RQ_EXIT;
  165         return error;
  166 }
  167 
  168 int
  169 ncp_read(struct ncp_conn *conn, ncp_fh *file, struct uio *uiop, struct ucred *cred) {
  170         int error = 0, len = 0, retlen=0, tsiz, burstio;
  171         DECLARE_RQ;
  172 
  173         tsiz = uiop->uio_resid;
  174 #ifdef NCPBURST
  175         burstio = (ncp_burst_enabled && tsiz > conn->buffer_size);
  176 #else
  177         burstio = 0;
  178 #endif
  179 
  180         while (tsiz > 0) {
  181                 if (!burstio) {
  182                         len = min(4096 - (uiop->uio_offset % 4096), tsiz);
  183                         len = min(len, conn->buffer_size);
  184                         NCP_RQ_HEAD(72,uiop->uio_procp,cred);
  185                         ncp_rq_byte(rqp, 0);
  186                         ncp_rq_mem(rqp, (caddr_t)file, 6);
  187                         ncp_rq_dword(rqp, htonl(uiop->uio_offset));
  188                         ncp_rq_word(rqp, htons(len));
  189                         checkbad(ncp_request(conn,rqp));
  190                         retlen = ncp_rp_word_hl(rqp);
  191                         if (uiop->uio_offset & 1)
  192                                 ncp_rp_byte(rqp);
  193                         error = nwfs_mbuftouio(&rqp->mrp,uiop,retlen,&rqp->bpos);
  194                         NCP_RQ_EXIT;
  195                 } else {
  196 #ifdef NCPBURST
  197                         error = ncp_burst_read(conn, file, tsiz, &len, &retlen, uiop, cred);
  198 #endif
  199                 }
  200                 if (error) break;
  201                 tsiz -= retlen;
  202                 if (retlen < len)
  203                         break;
  204         }
  205         return (error);
  206 }
  207 
  208 int
  209 ncp_write(struct ncp_conn *conn, ncp_fh *file, struct uio *uiop, struct ucred *cred)
  210 {
  211         int error = 0, len, tsiz, backup;
  212         DECLARE_RQ;
  213 
  214         if (uiop->uio_iovcnt != 1) {
  215                 printf("%s: can't handle iovcnt>1 !!!\n", __FUNCTION__);
  216                 return EIO;
  217         }
  218         tsiz = uiop->uio_resid;
  219         while (tsiz > 0) {
  220                 len = min(4096 - (uiop->uio_offset % 4096), tsiz);
  221                 len = min(len, conn->buffer_size);
  222                 if (len == 0) {
  223                         printf("gotcha!\n");
  224                 }
  225                 /* rq head */
  226                 NCP_RQ_HEAD(73,uiop->uio_procp,cred);
  227                 ncp_rq_byte(rqp, 0);
  228                 ncp_rq_mem(rqp, (caddr_t)file, 6);
  229                 ncp_rq_dword(rqp, htonl(uiop->uio_offset));
  230                 ncp_rq_word_hl(rqp, len);
  231                 nwfs_uiotombuf(uiop,&rqp->mrq,len,&rqp->bpos);
  232                 checkbad(ncp_request(conn,rqp));
  233                 if (len == 0)
  234                         break;
  235                 NCP_RQ_EXIT;
  236                 if (error) {
  237                         backup = len;
  238                         uiop->uio_iov->iov_base -= backup;
  239                         uiop->uio_iov->iov_len += backup;
  240                         uiop->uio_offset -= backup;
  241                         uiop->uio_resid += backup;
  242                         break;
  243                 }
  244                 tsiz -= len;
  245         }
  246         if (error)
  247                 uiop->uio_resid = tsiz;
  248         switch (error) {
  249             case NWE_INSUFFICIENT_SPACE:
  250                 error = ENOSPC;
  251                 break;
  252         }
  253         return (error);
  254 }

Cache object: 4d52be7f85dab3bb454b7cf7e095ba47


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.