예제 #1
0
/*
 * 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;
}
예제 #2
0
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;
}
예제 #3
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);
}
예제 #4
0
/*  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);
}
예제 #5
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);
}