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/fs/nwfs/nwfs_subr.c

Version: -  FREEBSD  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-2  -  FREEBSD-11-1  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-4  -  FREEBSD-10-3  -  FREEBSD-10-2  -  FREEBSD-10-1  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-3  -  FREEBSD-9-2  -  FREEBSD-9-1  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-4  -  FREEBSD-8-3  -  FREEBSD-8-2  -  FREEBSD-8-1  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-4  -  FREEBSD-7-3  -  FREEBSD-7-2  -  FREEBSD-7-1  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-4  -  FREEBSD-6-3  -  FREEBSD-6-2  -  FREEBSD-6-1  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-5  -  FREEBSD-5-4  -  FREEBSD-5-3  -  FREEBSD-5-2  -  FREEBSD-5-1  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  linux-2.6  -  linux-2.4.22  -  MK83  -  MK84  -  PLAN9  -  DFBSD  -  NETBSD  -  NETBSD5  -  NETBSD4  -  NETBSD3  -  NETBSD20  -  OPENBSD  -  xnu-517  -  xnu-792  -  xnu-792.6.70  -  xnu-1228  -  xnu-1456.1.26  -  xnu-1699.24.8  -  xnu-2050.18.24  -  OPENSOLARIS  -  minix-3-1-1 
SearchContext: -  none  -  3  -  10 

    1 /*-
    2  * Copyright (c) 1999, 2001 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/systm.h>
   36 #include <sys/kernel.h>
   37 #include <sys/clock.h>
   38 #include <sys/lock.h>
   39 #include <sys/lockmgr.h>
   40 #include <sys/malloc.h>
   41 #include <sys/clock.h>
   42 #include <sys/time.h>
   43 
   44 #include <netncp/ncp.h>
   45 #include <netncp/ncp_conn.h>
   46 #include <netncp/ncp_ncp.h>
   47 #include <netncp/ncp_subr.h>
   48 #include <netncp/ncp_rq.h>
   49 #include <netncp/nwerror.h>
   50 
   51 #include <fs/nwfs/nwfs.h>
   52 #include <fs/nwfs/nwfs_node.h>
   53 #include <fs/nwfs/nwfs_subr.h>
   54 
   55 #define NCP_INFOSZ      (sizeof(struct nw_entry_info) - 257)
   56 
   57 MALLOC_DEFINE(M_NWFSDATA, "nwfs_data", "NWFS private data");
   58 
   59 static int
   60 ncp_extract_file_info(struct nwmount *nmp, struct ncp_rq *rqp,
   61         struct nw_entry_info *target, int withname)
   62 {
   63         u_int8_t name_len;
   64 
   65         md_get_mem(&rqp->rp, (caddr_t)target, NCP_INFOSZ, MB_MSYSTEM);
   66         if (!withname)
   67                 return 0;
   68         md_get_uint8(&rqp->rp, &name_len);
   69         target->nameLen = name_len;
   70         md_get_mem(&rqp->rp, (caddr_t)target->entryName, name_len, MB_MSYSTEM);
   71         target->entryName[name_len] = '\0';
   72         ncp_path2unix(target->entryName, target->entryName, name_len, &nmp->m.nls);
   73         return 0;
   74 }
   75 
   76 int
   77 ncp_initsearch(struct vnode *dvp, struct thread *td, struct ucred *cred)
   78 {
   79         struct nwmount *nmp = VTONWFS(dvp);
   80         struct ncp_conn *conn = NWFSTOCONN(nmp);
   81         struct nwnode *np = VTONW(dvp);
   82         struct ncp_rq *rqp;
   83         u_int8_t volnum = nmp->n_volume;
   84         u_int32_t dirent = np->n_fid.f_id;
   85         int error;
   86 
   87         NCPNDEBUG("vol=%d,dir=%d\n", volnum, dirent);
   88         error = ncp_rq_alloc(87, conn, td, cred, &rqp);
   89         if (error)
   90                 return error;
   91         mb_put_uint8(&rqp->rq, 2);              /* subfunction */
   92         mb_put_uint8(&rqp->rq, nmp->name_space);
   93         mb_put_uint8(&rqp->rq, 0);              /* reserved */
   94         ncp_rq_dbase_path(rqp, volnum, dirent, 0, NULL, NULL);
   95         rqp->nr_minrplen = sizeof(np->n_seq);
   96         error = ncp_request(rqp);
   97         if (error)
   98                 return error;
   99         md_get_mem(&rqp->rp, (caddr_t)&np->n_seq, sizeof(np->n_seq), MB_MSYSTEM);
  100         ncp_rq_done(rqp);
  101         return 0;
  102 }
  103 
  104 int 
  105 ncp_search_for_file_or_subdir(struct nwmount *nmp,
  106                               struct nw_search_seq *seq,
  107                               struct nw_entry_info *target,
  108                               struct thread *td,struct ucred *cred)
  109 {
  110         struct ncp_conn *conn = NWFSTOCONN(nmp);
  111         struct ncp_rq *rqp;
  112         int error;
  113 
  114         error = ncp_rq_alloc(87, conn, td, cred, &rqp);
  115         if (error)
  116                 return error;
  117         mb_put_uint8(&rqp->rq, 3);              /* subfunction */
  118         mb_put_uint8(&rqp->rq, nmp->name_space);
  119         mb_put_uint8(&rqp->rq, 0);              /* data stream */
  120         mb_put_uint16le(&rqp->rq, 0xffff);      /* Search attribs */
  121         mb_put_uint32le(&rqp->rq, IM_ALL);      /* return info mask */
  122         mb_put_mem(&rqp->rq, (caddr_t)seq, 9, MB_MSYSTEM);
  123         mb_put_uint8(&rqp->rq, 2);              /* 2 byte pattern */
  124         mb_put_uint8(&rqp->rq, 0xff);           /* following is a wildcard */
  125         mb_put_uint8(&rqp->rq, '*');
  126         rqp->nr_minrplen = sizeof(*seq) +  1 + NCP_INFOSZ + 1;
  127         error = ncp_request(rqp);
  128         if (error)
  129                 return error;
  130         md_get_mem(&rqp->rp, (caddr_t)seq, sizeof(*seq), MB_MSYSTEM);
  131         md_get_uint8(&rqp->rp, NULL);           /* skip */
  132         error = ncp_extract_file_info(nmp, rqp, target, 1);
  133         ncp_rq_done(rqp);
  134         return error;
  135 }
  136 
  137 /*
  138  * Returns information for a (one-component) name relative to the specified
  139  * directory.
  140  */
  141 int 
  142 ncp_obtain_info(struct nwmount *nmp,  u_int32_t dirent,
  143                 int namelen, char *path, struct nw_entry_info *target,
  144                 struct thread *td,struct ucred *cred)
  145 {
  146         struct ncp_conn *conn=NWFSTOCONN(nmp);
  147         struct ncp_rq *rqp;
  148         int error;
  149         u_char volnum = nmp->n_volume, ns;
  150 
  151         if (target == NULL) {
  152                 NCPFATAL("target == NULL\n");
  153                 return EINVAL;
  154         }
  155         ns = (path == NULL || path[0] == 0) ? NW_NS_DOS : nmp->name_space;
  156         error = ncp_rq_alloc(87, conn, td, cred, &rqp);
  157         if (error)
  158                 return error;
  159         mb_put_uint8(&rqp->rq, 6);      /* subfunction */
  160         mb_put_uint8(&rqp->rq, ns);
  161         mb_put_uint8(&rqp->rq, ns);     /* DestNameSpace */
  162         mb_put_uint16le(&rqp->rq, 0xff);        /* get all */
  163         mb_put_uint32le(&rqp->rq, IM_ALL);
  164         ncp_rq_dbase_path(rqp, volnum, dirent, namelen, path, &nmp->m.nls);
  165         error = ncp_request(rqp);
  166         if (error)
  167                 return error;
  168         error = ncp_extract_file_info(nmp, rqp, target, path != NULL);
  169         ncp_rq_done(rqp);
  170         return error;
  171 }
  172 /* 
  173  * lookup name pointed by cnp in directory dvp and return file info in np.
  174  * May be I should create a little cache, but another way is to minimize
  175  * number of calls, on other hand, in multiprocess environment ...
  176  */
  177 int
  178 ncp_lookup(struct vnode *dvp, int len, char *name, struct nw_entry_info *fap,
  179                 struct thread *td,struct ucred *cred)
  180 {
  181         struct nwmount *nmp;
  182         struct nwnode *dnp;
  183         struct ncp_conn *conn;
  184         int error;
  185 
  186         if (!dvp || dvp->v_type != VDIR) {
  187                 nwfs_printf("dvp is NULL or not a directory.\n");
  188                 return (ENOENT);
  189         }
  190         dnp = VTONW(dvp);
  191         nmp = VTONWFS(dvp);
  192         conn = NWFSTOCONN(nmp);
  193 
  194         if (len == 1 && name[0] == '.') {
  195                 if (dnp->n_flag & NVOLUME) {
  196                         error = ncp_obtain_info(nmp, dnp->n_fid.f_id, 0, NULL,
  197                                 fap, td, cred);
  198                 } else {
  199                         error = ncp_obtain_info(nmp, dnp->n_fid.f_parent, 
  200                                 dnp->n_nmlen, dnp->n_name, fap, td, cred);
  201                 }
  202                 return error;
  203         } else if (len == 2 && name[0] == '.' && name[1] == '.') {
  204                 printf("%s: knows NOTHING about '..'\n", __func__);
  205                 return EIO;
  206         } else {
  207                 error = ncp_obtain_info(nmp, dnp->n_fid.f_id, 
  208                         len, name, fap, td, cred);
  209         }
  210         return error;
  211 }
  212 
  213 static void ConvertToNWfromDWORD(u_int32_t sfd, ncp_fh *fh);
  214 static void 
  215 ConvertToNWfromDWORD(u_int32_t sfd, ncp_fh *fh) {
  216         fh->val1 = (fh->val.val32 = sfd);
  217         return;
  218 }
  219 
  220 /*
  221  * If both dir and name are NULL, then in target there's already a looked-up
  222  * entry that wants to be opened.
  223  */
  224 int 
  225 ncp_open_create_file_or_subdir(struct nwmount *nmp,struct vnode *dvp,int namelen,
  226             char *name, int open_create_mode, u_int32_t create_attributes,
  227             int desired_acc_rights, struct ncp_open_info *nop,
  228             struct thread *td,struct ucred *cred)
  229 {
  230         
  231         struct ncp_conn *conn=NWFSTOCONN(nmp);
  232         struct ncp_rq *rqp;
  233         u_int16_t search_attribs = SA_ALL & (~SA_SUBDIR_FILES);
  234         u_int8_t volnum;
  235         u_int32_t dirent;
  236         int error;
  237 
  238         error = ncp_rq_alloc(87, conn, td, cred, &rqp);
  239         if (error)
  240                 return error;
  241         volnum = nmp->n_volume;
  242         dirent = VTONW(dvp)->n_fid.f_id;
  243         if ((create_attributes & aDIR) != 0) {
  244                 search_attribs |= SA_SUBDIR_FILES;
  245         }
  246         mb_put_uint8(&rqp->rq, 1);/* subfunction */
  247         mb_put_uint8(&rqp->rq, nmp->name_space);
  248         mb_put_uint8(&rqp->rq, open_create_mode);
  249         mb_put_uint16le(&rqp->rq, search_attribs);
  250         mb_put_uint32le(&rqp->rq, IM_ALL);
  251         mb_put_uint32le(&rqp->rq, create_attributes);
  252         /*
  253          * The desired acc rights seem to be the inherited rights mask for
  254          * directories
  255          */
  256         mb_put_uint16le(&rqp->rq, desired_acc_rights);
  257         ncp_rq_dbase_path(rqp, volnum, dirent, namelen, name, &nmp->m.nls);
  258         error = ncp_request(rqp);
  259         if (error) {
  260                 if (error == NWE_FILE_NO_CREATE_PRIV)
  261                         error = EACCES;
  262                 return error;
  263         }
  264         md_get_uint32le(&rqp->rp, &nop->origfh);
  265         md_get_uint8(&rqp->rp, &nop->action);
  266         md_get_uint8(&rqp->rp, NULL);   /* skip */
  267         error = ncp_extract_file_info(nmp, rqp, &nop->fattr, 1);
  268         ncp_rq_done(rqp);
  269         ConvertToNWfromDWORD(nop->origfh, &nop->fh);
  270         return error;
  271 }
  272 
  273 int
  274 ncp_close_file(struct ncp_conn *conn, ncp_fh *fh,struct thread *td,struct ucred *cred)
  275 {
  276         struct ncp_rq *rqp;
  277         int error;
  278 
  279         error = ncp_rq_alloc(66, conn, td, cred, &rqp);
  280         if (error)
  281                 return error;
  282         mb_put_uint8(&rqp->rq, 0);
  283         mb_put_mem(&rqp->rq, (caddr_t)fh, 6, MB_MSYSTEM);
  284         error = ncp_request(rqp);
  285         if (error)
  286                 return error;
  287         ncp_rq_done(rqp);
  288         return error;
  289 }
  290 
  291 int
  292 ncp_DeleteNSEntry(struct nwmount *nmp, u_int32_t dirent,
  293         int namelen,char *name,struct thread *td,struct ucred *cred)
  294 {
  295         struct ncp_rq *rqp;
  296         int error;
  297         struct ncp_conn *conn=NWFSTOCONN(nmp);
  298 
  299         error = ncp_rq_alloc(87, conn, td, cred, &rqp);
  300         if (error)
  301                 return error;
  302         mb_put_uint8(&rqp->rq, 8);              /* subfunction */
  303         mb_put_uint8(&rqp->rq, nmp->name_space);
  304         mb_put_uint8(&rqp->rq, 0);              /* reserved */
  305         mb_put_uint16le(&rqp->rq, SA_ALL);      /* search attribs: all */
  306         ncp_rq_dbase_path(rqp, nmp->n_volume, dirent, namelen, name, &nmp->m.nls);
  307         error = ncp_request(rqp);
  308         if (!error)
  309                 ncp_rq_done(rqp);
  310         return error;
  311 }
  312 
  313 int 
  314 ncp_nsrename(struct ncp_conn *conn, int volume, int ns, int oldtype, 
  315         struct ncp_nlstables *nt,
  316         nwdirent fdir, char *old_name, int oldlen,
  317         nwdirent tdir, char *new_name, int newlen,
  318         struct thread *td, struct ucred *cred)
  319 {
  320         struct ncp_rq *rqp;
  321         int error;
  322 
  323         error = ncp_rq_alloc(87, conn, td, cred, &rqp);
  324         if (error)
  325                 return error;
  326         mb_put_uint8(&rqp->rq, 4);
  327         mb_put_uint8(&rqp->rq, ns);
  328         mb_put_uint8(&rqp->rq, 1);      /* RRenameToMySelf */
  329         mb_put_uint16le(&rqp->rq, oldtype);
  330         /* source Handle Path */
  331         mb_put_uint8(&rqp->rq, volume);
  332         mb_put_mem(&rqp->rq, (c_caddr_t)&fdir, sizeof(fdir), MB_MSYSTEM);
  333         mb_put_uint8(&rqp->rq, 1);
  334         mb_put_uint8(&rqp->rq, 1);      /* 1 source component */
  335         /* dest Handle Path */
  336         mb_put_uint8(&rqp->rq, volume);
  337         mb_put_mem(&rqp->rq, (c_caddr_t)&tdir, sizeof(tdir), MB_MSYSTEM);
  338         mb_put_uint8(&rqp->rq, 1);
  339         mb_put_uint8(&rqp->rq, 1);      /* 1 destination component */
  340         ncp_rq_pathstring(rqp, oldlen, old_name, nt);
  341         ncp_rq_pathstring(rqp, newlen, new_name, nt);
  342         error = ncp_request(rqp);
  343         if (!error)
  344                 ncp_rq_done(rqp);
  345         return error;
  346 }
  347 
  348 int
  349 ncp_modify_file_or_subdir_dos_info(struct nwmount *nmp, struct vnode *vp, 
  350                                 u_int32_t info_mask,
  351                                 struct nw_modify_dos_info *info,
  352                                 struct thread *td,struct ucred *cred)
  353 {
  354         struct nwnode *np=VTONW(vp);
  355         struct ncp_rq *rqp;
  356         u_int8_t volnum = nmp->n_volume;
  357         u_int32_t dirent = np->n_fid.f_id;
  358         struct ncp_conn *conn=NWFSTOCONN(nmp);
  359         int             error;
  360 
  361         error = ncp_rq_alloc(87, conn, td, cred, &rqp);
  362         if (error)
  363                 return error;
  364         mb_put_uint8(&rqp->rq, 7);      /* subfunction */
  365         mb_put_uint8(&rqp->rq, nmp->name_space);
  366         mb_put_uint8(&rqp->rq, 0);      /* reserved */
  367         mb_put_uint16le(&rqp->rq, SA_ALL);      /* search attribs: all */
  368         mb_put_uint32le(&rqp->rq, info_mask);
  369         mb_put_mem(&rqp->rq, (caddr_t)info, sizeof(*info), MB_MSYSTEM);
  370         ncp_rq_dbase_path(rqp, volnum, dirent, 0, NULL, NULL);
  371         error = ncp_request(rqp);
  372         if (!error)
  373                 ncp_rq_done(rqp);
  374         return error;
  375 }
  376 
  377 int
  378 ncp_setattr(vp, vap, cred, td)
  379         struct vnode *vp;
  380         struct vattr *vap;
  381         struct ucred *cred;
  382         struct thread *td;
  383 {
  384         struct nwmount *nmp=VTONWFS(vp);
  385         struct nwnode *np=VTONW(vp);
  386         struct ncp_open_info nwn;
  387         struct ncp_conn *conn=NWFSTOCONN(nmp);
  388         struct nw_modify_dos_info info;
  389         struct ncp_rq *rqp;
  390         int error = 0, info_mask;
  391 
  392         if (vap->va_size != VNOVAL) {
  393                 error = ncp_open_create_file_or_subdir(nmp, vp, 0, NULL, OC_MODE_OPEN, 0,
  394                                                    AR_WRITE | AR_READ, &nwn,td,cred);
  395                 if (error)
  396                         return error;
  397                 error = ncp_rq_alloc(73, conn, td, cred, &rqp);
  398                 if (error) {
  399                         ncp_close_file(conn, &nwn.fh, td, cred);
  400                         return error;
  401                 }
  402                 mb_put_uint8(&rqp->rq, 0);
  403                 mb_put_mem(&rqp->rq, (caddr_t)&nwn.fh, 6, MB_MSYSTEM);
  404                 mb_put_uint32be(&rqp->rq, vap->va_size);
  405                 mb_put_uint16be(&rqp->rq, 0);
  406                 error = ncp_request(rqp);
  407                 np->n_vattr.va_size = np->n_size = vap->va_size;
  408                 if (!error)
  409                         ncp_rq_done(rqp);
  410                 ncp_close_file(conn, &nwn.fh, td, cred);
  411                 if (error)
  412                         return error;
  413         }
  414         info_mask = 0;
  415         bzero(&info, sizeof(info));
  416 
  417         if (vap->va_mtime.tv_sec != VNOVAL) {
  418                 info_mask |= (DM_MODIFY_TIME | DM_MODIFY_DATE);
  419                 ncp_unix2dostime(&vap->va_mtime, nmp->m.tz, &info.modifyDate, &info.modifyTime, NULL);
  420         }
  421         if (vap->va_atime.tv_sec != VNOVAL) {
  422                 info_mask |= (DM_LAST_ACCESS_DATE);
  423                 ncp_unix2dostime(&vap->va_atime, nmp->m.tz, &info.lastAccessDate, NULL, NULL);
  424         }
  425         if (info_mask) {
  426                 error = ncp_modify_file_or_subdir_dos_info(nmp, vp, info_mask, &info,td,cred);
  427         }
  428         return (error);
  429 }
  430 
  431 int
  432 ncp_get_volume_info_with_number(struct ncp_conn *conn, 
  433         int n, struct ncp_volume_info *target,
  434         struct thread *td,struct ucred *cred)
  435 {
  436         struct ncp_rq *rqp;
  437         u_int32_t tmp32;
  438         u_int8_t len;
  439         int error;
  440 
  441         error = ncp_rq_alloc_subfn(22, 44, conn, td, cred, &rqp);
  442         if (error)
  443                 return error;
  444         mb_put_uint8(&rqp->rq,n);
  445         error = ncp_request(rqp);
  446         if (error)
  447                 return error;
  448         md_get_uint32le(&rqp->rp, &target->total_blocks);
  449         md_get_uint32le(&rqp->rp, &target->free_blocks);
  450         md_get_uint32le(&rqp->rp, &target->purgeable_blocks);
  451         md_get_uint32le(&rqp->rp, &target->not_yet_purgeable_blocks);
  452         md_get_uint32le(&rqp->rp, &target->total_dir_entries);
  453         md_get_uint32le(&rqp->rp, &target->available_dir_entries);
  454         md_get_uint32le(&rqp->rp, &tmp32);
  455         md_get_uint8(&rqp->rp, &target->sectors_per_block);
  456         bzero(&target->volume_name, sizeof(target->volume_name));
  457         md_get_uint8(&rqp->rp, &len);
  458         if (len > NCP_VOLNAME_LEN) {
  459                 error = ENAMETOOLONG;
  460         } else {
  461                 md_get_mem(&rqp->rp, (caddr_t)&target->volume_name, len, MB_MSYSTEM);
  462         }
  463         ncp_rq_done(rqp);
  464         return error;
  465 }
  466 
  467 int
  468 ncp_get_namespaces(struct ncp_conn *conn, u_int32_t volume, int *nsf,
  469         struct thread *td,struct ucred *cred)
  470 {
  471         struct ncp_rq *rqp;
  472         int error;
  473         u_int8_t ns;
  474         u_int16_t nscnt;
  475 
  476         error = ncp_rq_alloc(87, conn, td, cred, &rqp);
  477         if (error)
  478                 return error;
  479         mb_put_uint8(&rqp->rq, 24);     /* Subfunction: Get Loaded Name Spaces */
  480         mb_put_uint16le(&rqp->rq, 0);   /* reserved */
  481         mb_put_uint8(&rqp->rq, volume);
  482         error = ncp_request(rqp);
  483         if (error)
  484                 return error;
  485         md_get_uint16le(&rqp->rp, &nscnt);
  486         *nsf = 0;
  487         while (nscnt-- > 0) {
  488                 md_get_uint8(&rqp->rp, &ns);
  489                 *nsf |= 1 << ns;
  490         }
  491         ncp_rq_done(rqp);
  492         return error;
  493 }
  494 
  495 int
  496 ncp_lookup_volume(struct ncp_conn *conn, char *volname, 
  497                 u_char *volNum, u_int32_t *dirEnt,
  498                 struct thread *td,struct ucred *cred)
  499 {
  500         struct ncp_rq *rqp;
  501         u_int32_t tmp32;
  502         int error;
  503 
  504         NCPNDEBUG("looking up vol %s\n", volname);
  505         error = ncp_rq_alloc(87, conn, td, cred, &rqp);
  506         if (error)
  507                 return error;
  508         mb_put_uint8(&rqp->rq, 22);     /* Subfunction: Generate dir handle */
  509         mb_put_uint8(&rqp->rq, 0);      /* src name space */
  510         mb_put_uint8(&rqp->rq, 0);      /* dst name space, always zero */
  511         mb_put_uint16le(&rqp->rq, 0);   /* dstNSIndicator (Jn) */
  512 
  513         mb_put_uint8(&rqp->rq, 0);      /* faked volume number */
  514         mb_put_uint32be(&rqp->rq, 0);   /* faked dir_base */
  515         mb_put_uint8(&rqp->rq, 0xff);   /* Don't have a dir_base */
  516         mb_put_uint8(&rqp->rq, 1);      /* 1 path component */
  517         ncp_rq_pstring(rqp, volname);
  518         error = ncp_request(rqp);
  519         if (error)
  520                 return error;
  521         md_get_uint32le(&rqp->rp, &tmp32);
  522         md_get_uint32le(&rqp->rp, dirEnt);
  523         md_get_uint8(&rqp->rp, volNum);
  524         ncp_rq_done(rqp);
  525         return error;
  526 }
  527 
  528 /*
  529  * XXX: I think the timezone in struct nwfs_args is truly bogus, especially
  530  * XXX: considering that nwfs_mount(8) picks this up from the kernel in
  531  * XXX: the first place.  Since I can't test this, I won't attempt to fix it.
  532  * XXX: /phk
  533  */
  534 
  535 void
  536 ncp_unix2dostime(tsp, tzoff, ddp, dtp, dhp)
  537         struct timespec *tsp;
  538         int tzoff;
  539         u_int16_t *ddp;
  540         u_int16_t *dtp;
  541         u_int8_t *dhp;
  542 {
  543         struct timespec t;
  544 
  545         t = *tsp;
  546         
  547         t.tv_sec = - tzoff * 60 - utc_offset();
  548         timespec2fattime(&t, 1, ddp, dtp, dhp);
  549 }
  550 
  551 void
  552 ncp_dos2unixtime(dd, dt, dh, tzoff, tsp)
  553         u_int dd;
  554         u_int dt;
  555         u_int dh;
  556         int tzoff;
  557         struct timespec *tsp;
  558 {
  559 
  560         fattime2timespec(dd, dt, dh, 1, tsp);
  561         tsp->tv_sec += tzoff * 60 + utc_offset();
  562 }

Cache object: 8cf69453a298d96ac045dd8a24c6d2dd


[ 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.