/* * Returns information for a (one-component) name relative to the specified * directory. */ int ncp_obtain_info(struct nwmount *nmp, u_int32_t dirent, int namelen, char *path, struct nw_entry_info *target, struct thread *td,struct ucred *cred) { struct ncp_conn *conn=NWFSTOCONN(nmp); struct ncp_rq *rqp; int error; u_char volnum = nmp->n_volume, ns; if (target == NULL) { NCPFATAL("target == NULL\n"); return EINVAL; } ns = (path == NULL || path[0] == 0) ? NW_NS_DOS : nmp->name_space; error = ncp_rq_alloc(87, conn, td, cred, &rqp); if (error) return error; mb_put_uint8(&rqp->rq, 6); /* subfunction */ mb_put_uint8(&rqp->rq, ns); mb_put_uint8(&rqp->rq, ns); /* DestNameSpace */ mb_put_uint16le(&rqp->rq, 0xff); /* get all */ mb_put_uint32le(&rqp->rq, IM_ALL); ncp_rq_dbase_path(rqp, volnum, dirent, namelen, path, &nmp->m.nls); error = ncp_request(rqp); if (error) return error; error = ncp_extract_file_info(nmp, rqp, target, path != NULL); ncp_rq_done(rqp); return error; }
int ncp_init(void) { ncp_conn_init(); if (at_exit(ncp_at_exit)) { NCPFATAL("can't register at_exit handler\n"); return ENOMEM; } ncp_timer_handle = timeout(ncp_timer,NULL,NCP_TIMER_TICK); return 0; }
void ncp_done(void) { struct ncp_conn *ncp, *nncp; struct proc *p = curproc; untimeout(ncp_timer,NULL,ncp_timer_handle); rm_at_exit(ncp_at_exit); ncp_conn_locklist(LK_EXCLUSIVE, p); for (ncp = conn_list.slh_first; ncp; ncp = nncp) { nncp = ncp->nc_next.sle_next; ncp->ref_cnt = 0; if (ncp_conn_lock(ncp, p, p->p_ucred,NCPM_READ|NCPM_EXECUTE|NCPM_WRITE)) { NCPFATAL("Can't lock connection !\n"); continue; } if (ncp_disconnect(ncp) != 0) ncp_conn_unlock(ncp,p); } ncp_conn_unlocklist(p); }
/* Return locked vnode to root of a filesystem */ static int nwfs_root(struct mount *mp, struct vnode **vpp) { struct vnode *vp; struct nwmount *nmp; struct nwnode *np; struct ncp_conn *conn; struct nw_entry_info fattr; struct thread *td = curthread; /* XXX */ struct ucred *cred; int error, nsf, opt; u_char vol; KKASSERT(td->td_proc); cred = td->td_proc->p_ucred; nmp = VFSTONWFS(mp); conn = NWFSTOCONN(nmp); if (nmp->n_root) { *vpp = NWTOV(nmp->n_root); while (vget(*vpp, LK_EXCLUSIVE) != 0) /* XXX */ ; return 0; } error = ncp_lookup_volume(conn, nmp->m.mounted_vol, &vol, &nmp->n_rootent.f_id, td, cred); if (error) return ENOENT; nmp->n_volume = vol; error = ncp_get_namespaces(conn, vol, &nsf, td, cred); if (error) return ENOENT; if (nsf & NW_NSB_OS2) { NCPVODEBUG("volume %s has os2 namespace\n",nmp->m.mounted_vol); if ((nmp->m.flags & NWFS_MOUNT_NO_OS2) == 0) { nmp->name_space = NW_NS_OS2; nmp->m.nls.opt &= ~NWHP_DOS; } } opt = nmp->m.nls.opt; nsf = opt & (NWHP_UPPER | NWHP_LOWER); if (opt & NWHP_DOS) { if (nsf == (NWHP_UPPER | NWHP_LOWER)) { nmp->m.nls.opt &= ~(NWHP_LOWER | NWHP_UPPER); } else if (nsf == 0) { nmp->m.nls.opt |= NWHP_LOWER; } } else { if (nsf == (NWHP_UPPER | NWHP_LOWER)) { nmp->m.nls.opt &= ~(NWHP_LOWER | NWHP_UPPER); } } if (nmp->m.root_path[0]) { nmp->m.root_path[0]--; error = ncp_obtain_info(nmp, nmp->n_rootent.f_id, -nmp->m.root_path[0], nmp->m.root_path, &fattr, td, cred); if (error) { NCPFATAL("Invalid root path specified\n"); return ENOENT; } nmp->n_rootent.f_parent = fattr.dirEntNum; nmp->m.root_path[0]++; error = ncp_obtain_info(nmp, nmp->n_rootent.f_id, -nmp->m.root_path[0], nmp->m.root_path, &fattr, td, cred); if (error) { NCPFATAL("Invalid root path specified\n"); return ENOENT; } nmp->n_rootent.f_id = fattr.dirEntNum; } else { error = ncp_obtain_info(nmp, nmp->n_rootent.f_id, 0, NULL, &fattr, td, cred); if (error) { NCPFATAL("Can't obtain volume info\n"); return ENOENT; } fattr.nameLen = strlen(strcpy(fattr.entryName, NWFS_ROOTVOL)); nmp->n_rootent.f_parent = nmp->n_rootent.f_id; } error = nwfs_nget(mp, nmp->n_rootent, &fattr, NULL, &vp); if (error) return (error); vsetflags(vp, VROOT); np = VTONW(vp); if (nmp->m.root_path[0] == 0) np->n_flag |= NVOLUME; nmp->n_root = np; /* error = VOP_GETATTR(vp, &vattr); if (error) { vput(vp); NCPFATAL("Can't get root directory entry\n"); return error; }*/ *vpp = vp; return (0); }
/* ARGSUSED */ static int nwfs_open(struct vop_open_args *ap) { thread_t td = curthread; /* XXX */ struct vnode *vp = ap->a_vp; int mode = ap->a_mode; struct nwnode *np = VTONW(vp); struct ncp_open_info no; struct nwmount *nmp = VTONWFS(vp); struct vattr vattr; int error, nwm; NCPVNDEBUG("%s,%d\n",np->n_name, np->opened); if (vp->v_type != VREG && vp->v_type != VDIR) { NCPFATAL("open vtype = %d\n", vp->v_type); return (EACCES); } if (vp->v_type == VDIR) return 0; /* nothing to do now */ if (np->n_flag & NMODIFIED) { if ((error = nwfs_vinvalbuf(vp, V_SAVE, 1)) == EINTR) return (error); np->n_atime = 0; error = VOP_GETATTR(vp, &vattr); if (error) return (error); np->n_mtime = vattr.va_mtime.tv_sec; } else { error = VOP_GETATTR(vp, &vattr); if (error) return (error); if (np->n_mtime != vattr.va_mtime.tv_sec) { if ((error = nwfs_vinvalbuf(vp, V_SAVE, 1)) == EINTR) return (error); np->n_mtime = vattr.va_mtime.tv_sec; } } if (np->opened) { np->opened++; return (vop_stdopen(ap)); } nwm = AR_READ; if ((vp->v_mount->mnt_flag & MNT_RDONLY) == 0) nwm |= AR_WRITE; error = ncp_open_create_file_or_subdir(nmp, vp, 0, NULL, OC_MODE_OPEN, 0, nwm, &no, td, ap->a_cred); if (error) { if (mode & FWRITE) return EACCES; nwm = AR_READ; error = ncp_open_create_file_or_subdir(nmp, vp, 0, NULL, OC_MODE_OPEN, 0, nwm, &no, td, ap->a_cred); } np->n_atime = 0; if (error == 0) { np->opened++; np->n_fh = no.fh; np->n_origfh = no.origfh; error = vop_stdopen(ap); } return (error); }