Catch up with KSE changes.
Reviewed by: tjr
This commit is contained in:
parent
f0bc886975
commit
c7eeea06ec
@ -61,7 +61,7 @@ static int ncp_next_handle = 1;
|
||||
static struct lock lhlock;
|
||||
|
||||
static int ncp_sysctl_connstat(SYSCTL_HANDLER_ARGS);
|
||||
static int ncp_conn_lock_any(struct ncp_conn *conn, struct proc *p,
|
||||
static int ncp_conn_lock_any(struct ncp_conn *conn, struct thread *td,
|
||||
struct ucred *cred);
|
||||
|
||||
SYSCTL_DECL(_net_ncp);
|
||||
@ -93,15 +93,15 @@ ncp_conn_destroy(void)
|
||||
}
|
||||
|
||||
int
|
||||
ncp_conn_locklist(int flags, struct proc *p)
|
||||
ncp_conn_locklist(int flags, struct thread *td)
|
||||
{
|
||||
return lockmgr(&listlock, flags | LK_CANRECURSE, 0, p);
|
||||
return lockmgr(&listlock, flags | LK_CANRECURSE, 0, td);
|
||||
}
|
||||
|
||||
void
|
||||
ncp_conn_unlocklist(struct proc *p)
|
||||
ncp_conn_unlocklist(struct thread *td)
|
||||
{
|
||||
lockmgr(&listlock, LK_RELEASE, 0, p);
|
||||
lockmgr(&listlock, LK_RELEASE, 0, td);
|
||||
}
|
||||
|
||||
int
|
||||
@ -120,55 +120,55 @@ ncp_conn_access(struct ncp_conn *conn, struct ucred *cred, mode_t mode)
|
||||
}
|
||||
|
||||
int
|
||||
ncp_conn_lock_any(struct ncp_conn *conn, struct proc *p, struct ucred *cred)
|
||||
ncp_conn_lock_any(struct ncp_conn *conn, struct thread *td, struct ucred *cred)
|
||||
{
|
||||
int error;
|
||||
|
||||
if (conn->nc_id == 0) return EACCES;
|
||||
error = lockmgr(&conn->nc_lock, LK_EXCLUSIVE | LK_CANRECURSE, 0, p);
|
||||
error = lockmgr(&conn->nc_lock, LK_EXCLUSIVE | LK_CANRECURSE, 0, td);
|
||||
if (error == ERESTART)
|
||||
return EINTR;
|
||||
error = ncp_chkintr(conn, p);
|
||||
error = ncp_chkintr(conn, td);
|
||||
if (error) {
|
||||
lockmgr(&conn->nc_lock, LK_RELEASE, 0, p);
|
||||
lockmgr(&conn->nc_lock, LK_RELEASE, 0, td);
|
||||
return error;
|
||||
}
|
||||
|
||||
if (conn->nc_id == 0) {
|
||||
lockmgr(&conn->nc_lock, LK_RELEASE, 0, p);
|
||||
lockmgr(&conn->nc_lock, LK_RELEASE, 0, td);
|
||||
return EACCES;
|
||||
}
|
||||
conn->procp = p; /* who currently operates */
|
||||
conn->td = td; /* who currently operates */
|
||||
conn->ucred = cred;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
ncp_conn_lock(struct ncp_conn *conn, struct proc *p, struct ucred *cred, int mode)
|
||||
ncp_conn_lock(struct ncp_conn *conn, struct thread *td, struct ucred *cred, int mode)
|
||||
{
|
||||
int error;
|
||||
|
||||
error = ncp_conn_access(conn,cred,mode);
|
||||
error = ncp_conn_access(conn, cred, mode);
|
||||
if (error) return error;
|
||||
return ncp_conn_lock_any(conn, p, cred);
|
||||
return ncp_conn_lock_any(conn, td, cred);
|
||||
}
|
||||
|
||||
/*
|
||||
* Lock conn but unlock connlist
|
||||
*/
|
||||
static int
|
||||
ncp_conn_lock2(struct ncp_conn *conn, struct proc *p, struct ucred *cred, int mode)
|
||||
ncp_conn_lock2(struct ncp_conn *conn, struct thread *td, struct ucred *cred, int mode)
|
||||
{
|
||||
int error;
|
||||
|
||||
error = ncp_conn_access(conn,cred,mode);
|
||||
error = ncp_conn_access(conn, cred, mode);
|
||||
if (error) {
|
||||
ncp_conn_unlocklist(p);
|
||||
ncp_conn_unlocklist(td);
|
||||
return error;
|
||||
}
|
||||
conn->nc_lwant++;
|
||||
ncp_conn_unlocklist(p);
|
||||
error = ncp_conn_lock_any(conn,p,cred);
|
||||
ncp_conn_unlocklist(td);
|
||||
error = ncp_conn_lock_any(conn, td, cred);
|
||||
conn->nc_lwant--;
|
||||
if (conn->nc_lwant == 0) {
|
||||
wakeup(&conn->nc_lwant);
|
||||
@ -177,17 +177,18 @@ ncp_conn_lock2(struct ncp_conn *conn, struct proc *p, struct ucred *cred, int mo
|
||||
}
|
||||
|
||||
void
|
||||
ncp_conn_unlock(struct ncp_conn *conn, struct proc *p)
|
||||
ncp_conn_unlock(struct ncp_conn *conn, struct thread *td)
|
||||
{
|
||||
/*
|
||||
* note, that LK_RELASE will do wakeup() instead of wakeup_one().
|
||||
* this will do a little overhead
|
||||
*/
|
||||
lockmgr(&conn->nc_lock, LK_RELEASE, 0, p);
|
||||
lockmgr(&conn->nc_lock, LK_RELEASE, 0, td);
|
||||
}
|
||||
|
||||
int
|
||||
ncp_conn_assert_locked(struct ncp_conn *conn,char *checker, struct proc *p){
|
||||
int
|
||||
ncp_conn_assert_locked(struct ncp_conn *conn, const char *checker, struct thread *td)
|
||||
{
|
||||
if (conn->nc_lock.lk_flags & LK_HAVE_EXCL) return 0;
|
||||
printf("%s: connection isn't locked!\n", checker);
|
||||
return EIO;
|
||||
@ -205,11 +206,11 @@ ncp_conn_invalid(struct ncp_conn *ncp)
|
||||
return ncp->flags & NCPFL_INVALID;
|
||||
}
|
||||
|
||||
/*
|
||||
/*
|
||||
* create, fill with defaults and return in locked state
|
||||
*/
|
||||
int
|
||||
ncp_conn_alloc(struct ncp_conn_args *cap, struct proc *p, struct ucred *cred,
|
||||
ncp_conn_alloc(struct ncp_conn_args *cap, struct thread *td, struct ucred *cred,
|
||||
struct ncp_conn **conn)
|
||||
{
|
||||
struct ncp_conn *ncp;
|
||||
@ -242,18 +243,18 @@ ncp_conn_alloc(struct ncp_conn_args *cap, struct proc *p, struct ucred *cred,
|
||||
ncp->seq = 0;
|
||||
ncp->connid = 0xFFFF;
|
||||
ncp->li = *cap;
|
||||
ncp->nc_group = (cap->group != NCP_DEFAULT_GROUP) ?
|
||||
ncp->nc_group = (cap->group != NCP_DEFAULT_GROUP) ?
|
||||
cap->group : cred->cr_groups[0];
|
||||
|
||||
if (cap->retry_count == 0)
|
||||
ncp->li.retry_count = NCP_RETRY_COUNT;
|
||||
if (cap->timeout == 0)
|
||||
ncp->li.timeout = NCP_RETRY_TIMEOUT;
|
||||
ncp_conn_lock_any(ncp, p, ncp->nc_owner);
|
||||
ncp_conn_lock_any(ncp, td, ncp->nc_owner);
|
||||
*conn = ncp;
|
||||
ncp_conn_locklist(LK_EXCLUSIVE, p);
|
||||
ncp_conn_locklist(LK_EXCLUSIVE, td);
|
||||
SLIST_INSERT_HEAD(&conn_list,ncp,nc_next);
|
||||
ncp_conn_unlocklist(p);
|
||||
ncp_conn_unlocklist(td);
|
||||
return (error);
|
||||
}
|
||||
|
||||
@ -263,7 +264,7 @@ ncp_conn_alloc(struct ncp_conn_args *cap, struct proc *p, struct ucred *cred,
|
||||
int
|
||||
ncp_conn_free(struct ncp_conn *ncp)
|
||||
{
|
||||
struct proc *p;
|
||||
struct thread *td;
|
||||
int error;
|
||||
|
||||
if (ncp == NULL) {
|
||||
@ -274,8 +275,8 @@ ncp_conn_free(struct ncp_conn *ncp)
|
||||
NCPERROR("nc_id == 0\n");
|
||||
return EACCES;
|
||||
}
|
||||
p = ncp->procp;
|
||||
error = ncp_conn_assert_locked(ncp, __func__, p);
|
||||
td = ncp->td;
|
||||
error = ncp_conn_assert_locked(ncp, __func__, td);
|
||||
if (error)
|
||||
return error;
|
||||
if (ncp->ref_cnt != 0 || (ncp->flags & NCPFL_PERMANENT))
|
||||
@ -291,20 +292,20 @@ ncp_conn_free(struct ncp_conn *ncp)
|
||||
* Mark conn as dead and wait for other process
|
||||
*/
|
||||
ncp->nc_id = 0;
|
||||
ncp_conn_unlock(ncp, p);
|
||||
ncp_conn_unlock(ncp, td);
|
||||
/*
|
||||
* if signal is raised - how I do react ?
|
||||
*/
|
||||
lockmgr(&ncp->nc_lock, LK_DRAIN, 0, p);
|
||||
lockmgr(&ncp->nc_lock, LK_DRAIN, 0, td);
|
||||
lockdestroy(&ncp->nc_lock);
|
||||
while (ncp->nc_lwant) {
|
||||
printf("lwant = %d\n", ncp->nc_lwant);
|
||||
tsleep(&ncp->nc_lwant, PZERO,"ncpdr",2*hz);
|
||||
}
|
||||
ncp_conn_locklist(LK_EXCLUSIVE, p);
|
||||
ncp_conn_locklist(LK_EXCLUSIVE, td);
|
||||
SLIST_REMOVE(&conn_list, ncp, ncp_conn, nc_next);
|
||||
ncp_conn_cnt--;
|
||||
ncp_conn_unlocklist(p);
|
||||
ncp_conn_unlocklist(td);
|
||||
if (ncp->li.user)
|
||||
free(ncp->li.user, M_NCPDATA);
|
||||
if (ncp->li.password)
|
||||
@ -349,7 +350,7 @@ ncp_conn_reconnect(struct ncp_conn *ncp)
|
||||
}
|
||||
|
||||
int
|
||||
ncp_conn_login(struct ncp_conn *conn, struct proc *p, struct ucred *cred)
|
||||
ncp_conn_login(struct ncp_conn *conn, struct thread *td, struct ucred *cred)
|
||||
{
|
||||
struct ncp_bindery_object user;
|
||||
u_char ncp_key[8];
|
||||
@ -359,36 +360,38 @@ ncp_conn_login(struct ncp_conn *conn, struct proc *p, struct ucred *cred)
|
||||
if (error) {
|
||||
printf("%s: Warning: use unencrypted login\n", __func__);
|
||||
error = ncp_login_unencrypted(conn, conn->li.objtype,
|
||||
conn->li.user, conn->li.password, p, cred);
|
||||
conn->li.user, conn->li.password, td, cred);
|
||||
} else {
|
||||
error = ncp_get_bindery_object_id(conn, conn->li.objtype,
|
||||
conn->li.user, &user, p, cred);
|
||||
conn->li.user, &user, td, cred);
|
||||
if (error)
|
||||
return error;
|
||||
error = ncp_login_encrypted(conn, &user, ncp_key,
|
||||
conn->li.password, p, cred);
|
||||
conn->li.password, td, cred);
|
||||
}
|
||||
if (!error)
|
||||
conn->flags |= NCPFL_LOGGED | NCPFL_WASLOGGED;
|
||||
return error;
|
||||
}
|
||||
|
||||
/*
|
||||
* Lookup connection by handle, return a locked conn descriptor
|
||||
/*
|
||||
* Lookup connection by handle, return a locked conn descriptor
|
||||
*/
|
||||
int
|
||||
ncp_conn_getbyref(int ref,struct proc *p,struct ucred *cred, int mode, struct ncp_conn **connpp){
|
||||
ncp_conn_getbyref(int ref, struct thread *td, struct ucred *cred, int mode,
|
||||
struct ncp_conn **connpp)
|
||||
{
|
||||
struct ncp_conn *ncp;
|
||||
int error=0;
|
||||
int error = 0;
|
||||
|
||||
ncp_conn_locklist(LK_SHARED, p);
|
||||
ncp_conn_locklist(LK_SHARED, td);
|
||||
SLIST_FOREACH(ncp, &conn_list, nc_next)
|
||||
if (ncp->nc_id == ref) break;
|
||||
if (ncp == NULL) {
|
||||
ncp_conn_unlocklist(p);
|
||||
ncp_conn_unlocklist(td);
|
||||
return(EBADF);
|
||||
}
|
||||
error = ncp_conn_lock2(ncp, p, cred, mode);
|
||||
error = ncp_conn_lock2(ncp, td, cred, mode);
|
||||
if (!error)
|
||||
*connpp = ncp;
|
||||
return (error);
|
||||
@ -397,18 +400,20 @@ ncp_conn_getbyref(int ref,struct proc *p,struct ucred *cred, int mode, struct nc
|
||||
* find attached, but not logged in connection to specified server
|
||||
*/
|
||||
int
|
||||
ncp_conn_getattached(struct ncp_conn_args *li,struct proc *p,struct ucred *cred,int mode, struct ncp_conn **connpp){
|
||||
struct ncp_conn *ncp, *ncp2=NULL;
|
||||
ncp_conn_getattached(struct ncp_conn_args *li, struct thread *td,
|
||||
struct ucred *cred, int mode, struct ncp_conn **connpp)
|
||||
{
|
||||
struct ncp_conn *ncp, *ncp2 = NULL;
|
||||
int error = 0;
|
||||
|
||||
ncp_conn_locklist(LK_SHARED, p);
|
||||
ncp_conn_locklist(LK_SHARED, td);
|
||||
SLIST_FOREACH(ncp, &conn_list, nc_next) {
|
||||
if ((ncp->flags & NCPFL_LOGGED) != 0 ||
|
||||
strcmp(ncp->li.server,li->server) != 0 ||
|
||||
strcmp(ncp->li.server,li->server) != 0 ||
|
||||
ncp->li.saddr.sa_len != li->saddr.sa_len ||
|
||||
bcmp(&ncp->li.saddr,&ncp->li.saddr,li->saddr.sa_len) != 0)
|
||||
continue;
|
||||
if (ncp_suser(cred) == 0 ||
|
||||
if (ncp_suser(cred) == 0 ||
|
||||
cred->cr_uid == ncp->nc_owner->cr_uid)
|
||||
break;
|
||||
error = ncp_conn_access(ncp,cred,mode);
|
||||
@ -417,18 +422,18 @@ ncp_conn_getattached(struct ncp_conn_args *li,struct proc *p,struct ucred *cred,
|
||||
}
|
||||
if (ncp == NULL) ncp = ncp2;
|
||||
if (ncp == NULL) {
|
||||
ncp_conn_unlocklist(p);
|
||||
ncp_conn_unlocklist(td);
|
||||
return(EBADF);
|
||||
}
|
||||
error = ncp_conn_lock2(ncp,p,cred,mode);
|
||||
error = ncp_conn_lock2(ncp, td, cred, mode);
|
||||
if (!error)
|
||||
*connpp=ncp;
|
||||
return (error);
|
||||
}
|
||||
|
||||
/*
|
||||
/*
|
||||
* Lookup connection by server/user pair, return a locked conn descriptor.
|
||||
* if li is NULL or server/user pair incomplete, try to select best connection
|
||||
* if li is NULL or server/user pair incomplete, try to select best connection
|
||||
* based on owner.
|
||||
* Connection selected in next order:
|
||||
* 1. Try to search conn with ucred owner, if li is NULL also find a primary
|
||||
@ -437,13 +442,15 @@ ncp_conn_getattached(struct ncp_conn_args *li,struct proc *p,struct ucred *cred,
|
||||
*/
|
||||
|
||||
int
|
||||
ncp_conn_getbyli(struct ncp_conn_args *li,struct proc *p,struct ucred *cred,int mode, struct ncp_conn **connpp){
|
||||
struct ncp_conn *ncp, *ncp2=NULL;
|
||||
int error=0, partial, haveserv;
|
||||
ncp_conn_getbyli(struct ncp_conn_args *li, struct thread *td,
|
||||
struct ucred *cred, int mode, struct ncp_conn **connpp)
|
||||
{
|
||||
struct ncp_conn *ncp, *ncp2 = NULL;
|
||||
int error = 0, partial, haveserv;
|
||||
|
||||
partial = (li == NULL || li->server[0] == 0 || li->user == NULL);
|
||||
haveserv = (li && li->server[0]);
|
||||
ncp_conn_locklist(LK_SHARED, p);
|
||||
ncp_conn_locklist(LK_SHARED, td);
|
||||
SLIST_FOREACH(ncp, &conn_list, nc_next) {
|
||||
if (partial) {
|
||||
if (cred->cr_uid == ncp->nc_owner->cr_uid) {
|
||||
@ -473,10 +480,10 @@ ncp_conn_getbyli(struct ncp_conn_args *li,struct proc *p,struct ucred *cred,int
|
||||
}
|
||||
if (ncp == NULL) ncp = ncp2;
|
||||
if (ncp == NULL) {
|
||||
ncp_conn_unlocklist(p);
|
||||
ncp_conn_unlocklist(td);
|
||||
return(EBADF);
|
||||
}
|
||||
error = ncp_conn_lock2(ncp,p,cred,mode);
|
||||
error = ncp_conn_lock2(ncp, td, cred,mode);
|
||||
if (!error)
|
||||
*connpp=ncp;
|
||||
return (error);
|
||||
@ -488,59 +495,62 @@ ncp_conn_getbyli(struct ncp_conn_args *li,struct proc *p,struct ucred *cred,int
|
||||
* connection expected to be locked.
|
||||
*/
|
||||
int
|
||||
ncp_conn_setprimary(struct ncp_conn *conn, int on){
|
||||
ncp_conn_setprimary(struct ncp_conn *conn, int on)
|
||||
{
|
||||
struct ncp_conn *ncp=NULL;
|
||||
|
||||
if (conn->ucred->cr_uid != conn->nc_owner->cr_uid)
|
||||
return EACCES;
|
||||
ncp_conn_locklist(LK_SHARED, conn->procp);
|
||||
ncp_conn_locklist(LK_SHARED, conn->td);
|
||||
SLIST_FOREACH(ncp, &conn_list, nc_next) {
|
||||
if (conn->ucred->cr_uid == ncp->nc_owner->cr_uid)
|
||||
ncp->flags &= ~NCPFL_PRIMARY;
|
||||
}
|
||||
ncp_conn_unlocklist(conn->procp);
|
||||
ncp_conn_unlocklist(conn->td);
|
||||
if (on)
|
||||
conn->flags |= NCPFL_PRIMARY;
|
||||
return 0;
|
||||
}
|
||||
/*
|
||||
/*
|
||||
* Lease conn to given proc, returning unique handle
|
||||
* problem: how locks should be applied ?
|
||||
*/
|
||||
int
|
||||
ncp_conn_gethandle(struct ncp_conn *conn, struct proc *p, struct ncp_handle **handle){
|
||||
ncp_conn_gethandle(struct ncp_conn *conn, struct thread *td, struct ncp_handle **handle)
|
||||
{
|
||||
struct ncp_handle *refp;
|
||||
|
||||
lockmgr(&lhlock, LK_EXCLUSIVE, 0, p);
|
||||
lockmgr(&lhlock, LK_EXCLUSIVE, 0, td);
|
||||
SLIST_FOREACH(refp, &lhlist, nh_next)
|
||||
if (refp->nh_conn == conn && p == refp->nh_proc) break;
|
||||
if (refp->nh_conn == conn && td == refp->nh_td) break;
|
||||
if (refp) {
|
||||
conn->ref_cnt++;
|
||||
refp->nh_ref++;
|
||||
*handle = refp;
|
||||
lockmgr(&lhlock, LK_RELEASE, 0, p);
|
||||
lockmgr(&lhlock, LK_RELEASE, 0, td);
|
||||
return 0;
|
||||
}
|
||||
MALLOC(refp,struct ncp_handle *,sizeof(struct ncp_handle),M_NCPDATA,
|
||||
M_WAITOK | M_ZERO);
|
||||
SLIST_INSERT_HEAD(&lhlist,refp,nh_next);
|
||||
refp->nh_ref++;
|
||||
refp->nh_proc = p;
|
||||
refp->nh_td = td;
|
||||
refp->nh_conn = conn;
|
||||
refp->nh_id = ncp_next_handle++;
|
||||
*handle = refp;
|
||||
conn->ref_cnt++;
|
||||
lockmgr(&lhlock, LK_RELEASE, 0, p);
|
||||
lockmgr(&lhlock, LK_RELEASE, 0, td);
|
||||
return 0;
|
||||
}
|
||||
/*
|
||||
* release reference, if force - ignore refcount
|
||||
*/
|
||||
int
|
||||
ncp_conn_puthandle(struct ncp_handle *handle, struct proc *p, int force) {
|
||||
ncp_conn_puthandle(struct ncp_handle *handle, struct thread *td, int force)
|
||||
{
|
||||
struct ncp_handle *refp = handle;
|
||||
|
||||
lockmgr(&lhlock, LK_EXCLUSIVE, 0, p);
|
||||
lockmgr(&lhlock, LK_EXCLUSIVE, 0, td);
|
||||
refp->nh_ref--;
|
||||
refp->nh_conn->ref_cnt--;
|
||||
if (force) {
|
||||
@ -551,20 +561,20 @@ ncp_conn_puthandle(struct ncp_handle *handle, struct proc *p, int force) {
|
||||
SLIST_REMOVE(&lhlist, refp, ncp_handle, nh_next);
|
||||
FREE(refp, M_NCPDATA);
|
||||
}
|
||||
lockmgr(&lhlock, LK_RELEASE, 0, p);
|
||||
lockmgr(&lhlock, LK_RELEASE, 0, td);
|
||||
return 0;
|
||||
}
|
||||
/*
|
||||
* find a connHandle
|
||||
*/
|
||||
int
|
||||
ncp_conn_findhandle(int connHandle, struct proc *p, struct ncp_handle **handle) {
|
||||
ncp_conn_findhandle(int connHandle, struct thread *td, struct ncp_handle **handle) {
|
||||
struct ncp_handle *refp;
|
||||
|
||||
lockmgr(&lhlock, LK_SHARED, 0, p);
|
||||
lockmgr(&lhlock, LK_SHARED, 0, td);
|
||||
SLIST_FOREACH(refp, &lhlist, nh_next)
|
||||
if (refp->nh_proc == p && refp->nh_id == connHandle) break;
|
||||
lockmgr(&lhlock, LK_RELEASE, 0, p);
|
||||
if (refp->nh_td == td && refp->nh_id == connHandle) break;
|
||||
lockmgr(&lhlock, LK_RELEASE, 0, td);
|
||||
if (refp == NULL) {
|
||||
return EBADF;
|
||||
}
|
||||
@ -575,20 +585,21 @@ ncp_conn_findhandle(int connHandle, struct proc *p, struct ncp_handle **handle)
|
||||
* Clear handles associated with specified process
|
||||
*/
|
||||
int
|
||||
ncp_conn_putprochandles(struct proc *p) {
|
||||
ncp_conn_putprochandles(struct thread *td)
|
||||
{
|
||||
struct ncp_handle *hp, *nhp;
|
||||
int haveone = 0;
|
||||
|
||||
lockmgr(&lhlock, LK_EXCLUSIVE, 0, p);
|
||||
lockmgr(&lhlock, LK_EXCLUSIVE, 0, td);
|
||||
for (hp = SLIST_FIRST(&lhlist); hp; hp = nhp) {
|
||||
nhp = SLIST_NEXT(hp, nh_next);
|
||||
if (hp->nh_proc != p) continue;
|
||||
if (hp->nh_td != td) continue;
|
||||
haveone = 1;
|
||||
hp->nh_conn->ref_cnt -= hp->nh_ref;
|
||||
SLIST_REMOVE(&lhlist, hp, ncp_handle, nh_next);
|
||||
FREE(hp, M_NCPDATA);
|
||||
}
|
||||
lockmgr(&lhlock, LK_RELEASE, 0, p);
|
||||
lockmgr(&lhlock, LK_RELEASE, 0, td);
|
||||
return haveone;
|
||||
}
|
||||
/*
|
||||
@ -626,7 +637,8 @@ ncp_conn_getinfo(struct ncp_conn *ncp, struct ncp_conn_stat *ncs) {
|
||||
}
|
||||
|
||||
static int
|
||||
ncp_sysctl_connstat(SYSCTL_HANDLER_ARGS) {
|
||||
ncp_sysctl_connstat(SYSCTL_HANDLER_ARGS)
|
||||
{
|
||||
int error;
|
||||
struct ncp_conn_stat ncs;
|
||||
struct ncp_conn *ncp;
|
||||
@ -634,7 +646,7 @@ ncp_sysctl_connstat(SYSCTL_HANDLER_ARGS) {
|
||||
|
||||
error = 0;
|
||||
sysctl_wire_old_buffer(req, 0);
|
||||
ncp_conn_locklist(LK_SHARED, req->p);
|
||||
ncp_conn_locklist(LK_SHARED, req->td);
|
||||
error = SYSCTL_OUT(req, &ncp_conn_cnt, sizeof(ncp_conn_cnt));
|
||||
SLIST_FOREACH(ncp, &conn_list, nc_next) {
|
||||
if (error) break;
|
||||
@ -650,6 +662,6 @@ ncp_sysctl_connstat(SYSCTL_HANDLER_ARGS) {
|
||||
ncp->nc_lwant--;
|
||||
error = SYSCTL_OUT(req, &ncs, sizeof(ncs));
|
||||
}
|
||||
ncp_conn_unlocklist(req->p);
|
||||
ncp_conn_unlocklist(req->td);
|
||||
return(error);
|
||||
}
|
||||
|
@ -132,7 +132,7 @@ struct ncp_conn_stat {
|
||||
#ifdef _KERNEL
|
||||
|
||||
#ifndef LK_SHARED
|
||||
#include <sys/lock.h>
|
||||
#include <sys/lockmgr.h>
|
||||
#endif
|
||||
|
||||
struct socket;
|
||||
@ -151,7 +151,7 @@ struct ncp_handle {
|
||||
SLIST_ENTRY(ncp_handle) nh_next;
|
||||
int nh_id; /* handle id */
|
||||
struct ncp_conn*nh_conn; /* which conn we are refernce */
|
||||
struct proc * nh_proc; /* who owns the handle */
|
||||
struct thread * nh_td; /* who owns the handle */
|
||||
int nh_ref; /* one process can asquire many handles, but we return the one */
|
||||
};
|
||||
|
||||
@ -173,7 +173,7 @@ struct ncp_conn {
|
||||
SLIST_HEAD(ncp_ref_hd,ncp_ref) ref_list;/* list of handles */
|
||||
struct lock nc_lock; /* excl locks */
|
||||
int nc_lwant; /* number of wanted locks */
|
||||
struct proc *procp; /* pid currently operates */
|
||||
struct thread *td; /* pid currently operates */
|
||||
struct ucred *ucred; /* usr currently operates */
|
||||
/* Fields used to process ncp requests */
|
||||
int connid; /* assigned by server */
|
||||
@ -200,7 +200,7 @@ int ncp_conn_free(struct ncp_conn *conn);
|
||||
int ncp_conn_access(struct ncp_conn *conn,struct ucred *cred,mode_t mode);
|
||||
int ncp_conn_lock(struct ncp_conn *conn,struct thread *td, struct ucred *cred,int mode);
|
||||
void ncp_conn_unlock(struct ncp_conn *conn,struct thread *td);
|
||||
int ncp_conn_assert_locked(struct ncp_conn *conn,char *checker,struct thread *td);
|
||||
int ncp_conn_assert_locked(struct ncp_conn *conn,const char *checker,struct thread *td);
|
||||
void ncp_conn_invalidate(struct ncp_conn *ncp);
|
||||
int ncp_conn_invalid(struct ncp_conn *ncp);
|
||||
/*int ncp_conn_ref(struct ncp_conn *conn, pid_t pid);
|
||||
|
@ -37,6 +37,7 @@
|
||||
#include <sys/sysent.h>
|
||||
#include <sys/proc.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/syscall.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/uio.h>
|
||||
@ -61,7 +62,8 @@ MODULE_VERSION(ncp, 1);
|
||||
MODULE_DEPEND(ncp, libmchain, 1, 1, 1);
|
||||
|
||||
static int
|
||||
ncp_conn_frag_rq(struct ncp_conn *conn, struct proc *p, struct ncp_conn_frag *nfp);
|
||||
ncp_conn_frag_rq(struct ncp_conn *conn, struct thread *td,
|
||||
struct ncp_conn_frag *nfp);
|
||||
|
||||
/*
|
||||
* Attach to NCP server
|
||||
@ -71,8 +73,8 @@ struct sncp_connect_args {
|
||||
int *connHandle;
|
||||
};
|
||||
|
||||
static int
|
||||
sncp_connect(struct proc *p, struct sncp_connect_args *uap)
|
||||
static int
|
||||
sncp_connect(struct thread *td, struct sncp_connect_args *uap)
|
||||
{
|
||||
int connHandle = 0, error;
|
||||
struct ncp_conn *conn;
|
||||
@ -82,9 +84,9 @@ sncp_connect(struct proc *p, struct sncp_connect_args *uap)
|
||||
checkbad(copyin(uap->li,&li,sizeof(li)));
|
||||
checkbad(copyout(&connHandle,uap->connHandle,sizeof(connHandle))); /* check before */
|
||||
li.password = li.user = NULL;
|
||||
error = ncp_conn_getattached(&li, p, p->p_ucred, NCPM_WRITE | NCPM_EXECUTE, &conn);
|
||||
error = ncp_conn_getattached(&li, td, td->td_ucred, NCPM_WRITE | NCPM_EXECUTE, &conn);
|
||||
if (error) {
|
||||
error = ncp_conn_alloc(&li, p, p->p_ucred, &conn);
|
||||
error = ncp_conn_alloc(&li, td, td->td_ucred, &conn);
|
||||
if (error)
|
||||
goto bad;
|
||||
error = ncp_conn_reconnect(conn);
|
||||
@ -92,12 +94,12 @@ sncp_connect(struct proc *p, struct sncp_connect_args *uap)
|
||||
ncp_conn_free(conn);
|
||||
}
|
||||
if (!error) {
|
||||
error = ncp_conn_gethandle(conn, p, &handle);
|
||||
error = ncp_conn_gethandle(conn, td, &handle);
|
||||
copyout(&handle->nh_id, uap->connHandle, sizeof(uap->connHandle));
|
||||
ncp_conn_unlock(conn,p);
|
||||
ncp_conn_unlock(conn,td);
|
||||
}
|
||||
bad:
|
||||
p->p_retval[0]=error;
|
||||
td->td_retval[0]=error;
|
||||
return error;
|
||||
}
|
||||
|
||||
@ -107,27 +109,27 @@ struct sncp_request_args {
|
||||
struct ncp_buf *ncpbuf;
|
||||
};
|
||||
|
||||
static int ncp_conn_handler(struct proc *p, struct sncp_request_args *uap,
|
||||
static int ncp_conn_handler(struct thread *td, struct sncp_request_args *uap,
|
||||
struct ncp_conn *conn, struct ncp_handle *handle);
|
||||
|
||||
static int
|
||||
sncp_request(struct proc *p, struct sncp_request_args *uap)
|
||||
sncp_request(struct thread *td, struct sncp_request_args *uap)
|
||||
{
|
||||
struct ncp_rq *rqp;
|
||||
struct ncp_conn *conn;
|
||||
struct ncp_handle *handle;
|
||||
int error = 0, rqsize;
|
||||
|
||||
error = ncp_conn_findhandle(uap->connHandle,p,&handle);
|
||||
error = ncp_conn_findhandle(uap->connHandle, td, &handle);
|
||||
if (error)
|
||||
return error;
|
||||
conn = handle->nh_conn;
|
||||
if (uap->fn == NCP_CONN)
|
||||
return ncp_conn_handler(p, uap, conn, handle);
|
||||
return ncp_conn_handler(td, uap, conn, handle);
|
||||
error = copyin(&uap->ncpbuf->rqsize, &rqsize, sizeof(int));
|
||||
if (error)
|
||||
return(error);
|
||||
error = ncp_rq_alloc(uap->fn, conn, p, p->p_ucred, &rqp);
|
||||
error = ncp_rq_alloc(uap->fn, conn, td, td->td_ucred, &rqp);
|
||||
if (error)
|
||||
return error;
|
||||
if (rqsize) {
|
||||
@ -151,7 +153,7 @@ sncp_request(struct proc *p, struct sncp_request_args *uap)
|
||||
|
||||
static int
|
||||
ncp_mod_login(struct ncp_conn *conn, char *user, int objtype, char *password,
|
||||
struct proc *p, struct ucred *cred)
|
||||
struct thread *td, struct ucred *cred)
|
||||
{
|
||||
int error;
|
||||
|
||||
@ -169,7 +171,7 @@ ncp_mod_login(struct ncp_conn *conn, char *user, int objtype, char *password,
|
||||
if ((conn->li.opt & NCP_OPT_NOUPCASEPASS) == 0)
|
||||
ncp_str_upper(conn->li.password);
|
||||
conn->li.objtype = objtype;
|
||||
error = ncp_conn_login(conn, p, cred);
|
||||
error = ncp_conn_login(conn, td, cred);
|
||||
return error;
|
||||
bad:
|
||||
if (conn->li.user) {
|
||||
@ -184,17 +186,18 @@ ncp_mod_login(struct ncp_conn *conn, char *user, int objtype, char *password,
|
||||
}
|
||||
|
||||
static int
|
||||
ncp_conn_handler(struct proc *p, struct sncp_request_args *uap,
|
||||
ncp_conn_handler(struct thread *td, struct sncp_request_args *uap,
|
||||
struct ncp_conn *conn, struct ncp_handle *hp)
|
||||
{
|
||||
int error=0, rqsize, subfn;
|
||||
int error = 0, rqsize, subfn;
|
||||
struct ucred *cred;
|
||||
|
||||
|
||||
char *pdata;
|
||||
|
||||
cred = p->p_ucred;
|
||||
cred = td->td_ucred;
|
||||
error = copyin(&uap->ncpbuf->rqsize, &rqsize, sizeof(int));
|
||||
if (error) return(error);
|
||||
if (error)
|
||||
return(error);
|
||||
error = 0;
|
||||
pdata = uap->ncpbuf->packet;
|
||||
subfn = *(pdata++) & 0xff;
|
||||
@ -204,10 +207,12 @@ ncp_conn_handler(struct proc *p, struct sncp_request_args *uap,
|
||||
struct ncp_rw rwrq;
|
||||
struct uio auio;
|
||||
struct iovec iov;
|
||||
|
||||
if (rqsize != sizeof(rwrq)) return (EBADRPC);
|
||||
|
||||
if (rqsize != sizeof(rwrq))
|
||||
return (EBADRPC);
|
||||
error = copyin(pdata,&rwrq,rqsize);
|
||||
if (error) return (error);
|
||||
if (error)
|
||||
return (error);
|
||||
iov.iov_base = rwrq.nrw_base;
|
||||
iov.iov_len = rwrq.nrw_cnt;
|
||||
auio.uio_iov = &iov;
|
||||
@ -216,25 +221,28 @@ ncp_conn_handler(struct proc *p, struct sncp_request_args *uap,
|
||||
auio.uio_resid = rwrq.nrw_cnt;
|
||||
auio.uio_segflg = UIO_USERSPACE;
|
||||
auio.uio_rw = (subfn == NCP_CONN_READ) ? UIO_READ : UIO_WRITE;
|
||||
auio.uio_procp = p;
|
||||
auio.uio_td = td;
|
||||
if (subfn == NCP_CONN_READ)
|
||||
error = ncp_read(conn, &rwrq.nrw_fh, &auio, cred);
|
||||
else
|
||||
error = ncp_write(conn, &rwrq.nrw_fh, &auio, cred);
|
||||
rwrq.nrw_cnt -= auio.uio_resid;
|
||||
p->p_retval[0] = rwrq.nrw_cnt;
|
||||
td->td_retval[0] = rwrq.nrw_cnt;
|
||||
break;
|
||||
} /* case int_read/write */
|
||||
case NCP_CONN_SETFLAGS: {
|
||||
u_int16_t mask, flags;
|
||||
|
||||
error = copyin(pdata,&mask, sizeof(mask));
|
||||
if (error) return error;
|
||||
if (error)
|
||||
return error;
|
||||
pdata += sizeof(mask);
|
||||
error = copyin(pdata,&flags,sizeof(flags));
|
||||
if (error) return error;
|
||||
error = ncp_conn_lock(conn,p,cred,NCPM_WRITE);
|
||||
if (error) return error;
|
||||
if (error)
|
||||
return error;
|
||||
error = ncp_conn_lock(conn, td, cred, NCPM_WRITE);
|
||||
if (error)
|
||||
return error;
|
||||
if (mask & NCPFL_PERMANENT) {
|
||||
conn->flags &= ~NCPFL_PERMANENT;
|
||||
conn->flags |= (flags & NCPFL_PERMANENT);
|
||||
@ -242,11 +250,11 @@ ncp_conn_handler(struct proc *p, struct sncp_request_args *uap,
|
||||
if (mask & NCPFL_PRIMARY) {
|
||||
error = ncp_conn_setprimary(conn, flags & NCPFL_PRIMARY);
|
||||
if (error) {
|
||||
ncp_conn_unlock(conn,p);
|
||||
ncp_conn_unlock(conn, td);
|
||||
break;
|
||||
}
|
||||
}
|
||||
ncp_conn_unlock(conn,p);
|
||||
ncp_conn_unlock(conn, td);
|
||||
break;
|
||||
}
|
||||
case NCP_CONN_LOGIN: {
|
||||
@ -258,83 +266,90 @@ ncp_conn_handler(struct proc *p, struct sncp_request_args *uap,
|
||||
return EALREADY;
|
||||
if ((error = copyin(pdata,&la,rqsize)) != 0)
|
||||
break;
|
||||
error = ncp_conn_lock(conn, p, cred, NCPM_EXECUTE | NCPM_WRITE);
|
||||
if (error) return error;
|
||||
error = ncp_mod_login(conn, la.username, la.objtype, la.password, p, p->p_ucred);
|
||||
ncp_conn_unlock(conn, p);
|
||||
p->p_retval[0] = error;
|
||||
error = ncp_conn_lock(conn, td, cred, NCPM_EXECUTE | NCPM_WRITE);
|
||||
if (error)
|
||||
return error;
|
||||
error = ncp_mod_login(conn, la.username, la.objtype,
|
||||
la.password, td, td->td_ucred);
|
||||
ncp_conn_unlock(conn, td);
|
||||
td->td_retval[0] = error;
|
||||
break;
|
||||
}
|
||||
case NCP_CONN_GETINFO: {
|
||||
struct ncp_conn_stat ncs;
|
||||
int len = sizeof(ncs);
|
||||
|
||||
error = ncp_conn_lock(conn, p, p->p_ucred, NCPM_READ);
|
||||
if (error) return error;
|
||||
error = ncp_conn_lock(conn, td, td->td_ucred, NCPM_READ);
|
||||
if (error)
|
||||
return error;
|
||||
ncp_conn_getinfo(conn, &ncs);
|
||||
copyout(&len, &uap->ncpbuf->rpsize, sizeof(int));
|
||||
error = copyout(&ncs, &uap->ncpbuf->packet, len);
|
||||
ncp_conn_unlock(conn, p);
|
||||
ncp_conn_unlock(conn, td);
|
||||
break;
|
||||
}
|
||||
case NCP_CONN_GETUSER: {
|
||||
int len;
|
||||
|
||||
error = ncp_conn_lock(conn, p, p->p_ucred, NCPM_READ);
|
||||
if (error) return error;
|
||||
error = ncp_conn_lock(conn, td, td->td_ucred, NCPM_READ);
|
||||
if (error)
|
||||
return error;
|
||||
len = (conn->li.user) ? strlen(conn->li.user) + 1 : 0;
|
||||
copyout(&len, &uap->ncpbuf->rpsize, sizeof(int));
|
||||
if (len) {
|
||||
error = copyout(conn->li.user, &uap->ncpbuf->packet, len);
|
||||
}
|
||||
ncp_conn_unlock(conn, p);
|
||||
ncp_conn_unlock(conn, td);
|
||||
break;
|
||||
}
|
||||
case NCP_CONN_CONN2REF: {
|
||||
int len = sizeof(int);
|
||||
|
||||
error = ncp_conn_lock(conn, p, p->p_ucred, NCPM_READ);
|
||||
if (error) return error;
|
||||
error = ncp_conn_lock(conn, td, td->td_ucred, NCPM_READ);
|
||||
if (error)
|
||||
return error;
|
||||
copyout(&len, &uap->ncpbuf->rpsize, sizeof(int));
|
||||
if (len) {
|
||||
error = copyout(&conn->nc_id, &uap->ncpbuf->packet, len);
|
||||
}
|
||||
ncp_conn_unlock(conn, p);
|
||||
ncp_conn_unlock(conn, td);
|
||||
break;
|
||||
}
|
||||
case NCP_CONN_FRAG: {
|
||||
struct ncp_conn_frag nf;
|
||||
|
||||
if (rqsize != sizeof(nf)) return (EBADRPC);
|
||||
if (rqsize != sizeof(nf))
|
||||
return (EBADRPC);
|
||||
if ((error = copyin(pdata, &nf, rqsize)) != 0) break;
|
||||
error = ncp_conn_lock(conn, p, cred, NCPM_EXECUTE);
|
||||
if (error) return error;
|
||||
error = ncp_conn_frag_rq(conn, p, &nf);
|
||||
ncp_conn_unlock(conn, p);
|
||||
error = ncp_conn_lock(conn, td, cred, NCPM_EXECUTE);
|
||||
if (error)
|
||||
return error;
|
||||
error = ncp_conn_frag_rq(conn, td, &nf);
|
||||
ncp_conn_unlock(conn, td);
|
||||
copyout(&nf, &pdata, sizeof(nf));
|
||||
p->p_retval[0] = error;
|
||||
td->td_retval[0] = error;
|
||||
break;
|
||||
}
|
||||
case NCP_CONN_DUP: {
|
||||
struct ncp_handle *newhp;
|
||||
int len = sizeof(NWCONN_HANDLE);
|
||||
|
||||
error = ncp_conn_lock(conn, p, cred, NCPM_READ);
|
||||
error = ncp_conn_lock(conn, td, cred, NCPM_READ);
|
||||
if (error) break;
|
||||
copyout(&len, &uap->ncpbuf->rpsize, len);
|
||||
error = ncp_conn_gethandle(conn, p, &newhp);
|
||||
error = ncp_conn_gethandle(conn, td, &newhp);
|
||||
if (!error)
|
||||
error = copyout(&newhp->nh_id, uap->ncpbuf->packet, len);
|
||||
ncp_conn_unlock(conn,p);
|
||||
ncp_conn_unlock(conn, td);
|
||||
break;
|
||||
}
|
||||
case NCP_CONN_CONNCLOSE: {
|
||||
error = ncp_conn_lock(conn, p, cred, NCPM_EXECUTE);
|
||||
error = ncp_conn_lock(conn, td, cred, NCPM_EXECUTE);
|
||||
if (error) break;
|
||||
ncp_conn_puthandle(hp, p, 0);
|
||||
ncp_conn_puthandle(hp, td, 0);
|
||||
error = ncp_conn_free(conn);
|
||||
if (error)
|
||||
ncp_conn_unlock(conn, p);
|
||||
ncp_conn_unlock(conn, td);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@ -348,8 +363,8 @@ struct sncp_conn_scan_args {
|
||||
int *connHandle;
|
||||
};
|
||||
|
||||
static int
|
||||
sncp_conn_scan(struct proc *p, struct sncp_conn_scan_args *uap)
|
||||
static int
|
||||
sncp_conn_scan(struct thread *td, struct sncp_conn_scan_args *uap)
|
||||
{
|
||||
int connHandle = 0, error;
|
||||
struct ncp_conn_args li, *lip;
|
||||
@ -358,7 +373,8 @@ sncp_conn_scan(struct proc *p, struct sncp_conn_scan_args *uap)
|
||||
char *user = NULL, *password = NULL;
|
||||
|
||||
if (uap->li) {
|
||||
if (copyin(uap->li,&li,sizeof(li))) return EFAULT;
|
||||
if (copyin(uap->li, &li, sizeof(li)))
|
||||
return EFAULT;
|
||||
lip = &li;
|
||||
} else {
|
||||
lip = NULL;
|
||||
@ -369,7 +385,8 @@ sncp_conn_scan(struct proc *p, struct sncp_conn_scan_args *uap)
|
||||
ncp_str_upper(lip->server);
|
||||
if (lip->user) {
|
||||
user = ncp_str_dup(lip->user);
|
||||
if (user == NULL) return EINVAL;
|
||||
if (user == NULL)
|
||||
return EINVAL;
|
||||
ncp_str_upper(user);
|
||||
}
|
||||
if (lip->password) {
|
||||
@ -384,29 +401,32 @@ sncp_conn_scan(struct proc *p, struct sncp_conn_scan_args *uap)
|
||||
lip->user = user;
|
||||
lip->password = password;
|
||||
}
|
||||
error = ncp_conn_getbyli(lip,p,p->p_ucred,NCPM_EXECUTE,&conn);
|
||||
if (!error) { /* already have this login */
|
||||
ncp_conn_gethandle(conn, p, &hp);
|
||||
error = ncp_conn_getbyli(lip, td, td->td_ucred, NCPM_EXECUTE, &conn);
|
||||
if (!error) { /* already have this login */
|
||||
ncp_conn_gethandle(conn, td, &hp);
|
||||
connHandle = hp->nh_id;
|
||||
ncp_conn_unlock(conn,p);
|
||||
copyout(&connHandle,uap->connHandle,sizeof(connHandle));
|
||||
ncp_conn_unlock(conn, td);
|
||||
copyout(&connHandle, uap->connHandle, sizeof(connHandle));
|
||||
}
|
||||
if (user) free(user, M_NCPDATA);
|
||||
if (password) free(password, M_NCPDATA);
|
||||
p->p_retval[0] = error;
|
||||
if (user)
|
||||
free(user, M_NCPDATA);
|
||||
if (password)
|
||||
free(password, M_NCPDATA);
|
||||
td->td_retval[0] = error;
|
||||
return error;
|
||||
|
||||
}
|
||||
|
||||
int
|
||||
ncp_conn_frag_rq(struct ncp_conn *conn, struct proc *p, struct ncp_conn_frag *nfp)
|
||||
ncp_conn_frag_rq(struct ncp_conn *conn, struct thread *td,
|
||||
struct ncp_conn_frag *nfp)
|
||||
{
|
||||
NW_FRAGMENT *fp;
|
||||
struct ncp_rq *rqp;
|
||||
u_int32_t fsize;
|
||||
int error, i, rpsize;
|
||||
|
||||
error = ncp_rq_alloc(nfp->fn, conn, p, p->p_ucred, &rqp);
|
||||
error = ncp_rq_alloc(nfp->fn, conn, td, td->td_ucred, &rqp);
|
||||
if (error)
|
||||
return error;
|
||||
for(fp = nfp->rqf, i = 0; i < nfp->rqfcnt; i++, fp++) {
|
||||
@ -456,17 +476,19 @@ sncp_intfn(struct proc *p, struct sncp_intfn_args *uap)
|
||||
{
|
||||
return ENOSYS;
|
||||
}
|
||||
|
||||
/*
|
||||
* define our new system calls
|
||||
*/
|
||||
static struct sysent newent[] = {
|
||||
{2, (sy_call_t*)sncp_conn_scan},
|
||||
{2, (sy_call_t*)sncp_conn_scan},
|
||||
{2, (sy_call_t*)sncp_connect},
|
||||
{2, (sy_call_t*)sncp_intfn},
|
||||
{3, (sy_call_t*)sncp_request}
|
||||
};
|
||||
|
||||
#define SC_SIZE sizeof(newent)/sizeof(struct sysent)
|
||||
|
||||
/*
|
||||
* Miscellaneous modules must have their own save areas...
|
||||
*/
|
||||
@ -475,44 +497,47 @@ static struct sysent oldent[SC_SIZE]; /* save are for old callslot entry*/
|
||||
/*
|
||||
* Number of syscall entries for a.out executables
|
||||
*/
|
||||
/*#define nsysent SYS_MAXSYSCALL*/
|
||||
#define nsysent (aout_sysvec.sv_size)
|
||||
#define nsysent SYS_MAXSYSCALL
|
||||
/* #define nsysent (elf_sysvec.sv_size) */
|
||||
|
||||
|
||||
static int
|
||||
ncp_load(void) {
|
||||
int i, ff, scnt, err=0;
|
||||
ncp_load(void)
|
||||
{
|
||||
int i, ff, scnt, err = 0;
|
||||
|
||||
while(1) {
|
||||
while (1) {
|
||||
/* Search the table looking for an enough number of slots... */
|
||||
for (scnt=0, ff = -1, i = 0; i < nsysent; i++) {
|
||||
for (scnt = 0, ff = -1, i = 0; i < nsysent; i++) {
|
||||
if (sysent[i].sy_call == (sy_call_t *)lkmnosys) {
|
||||
if (ff == -1) {
|
||||
ff = i;
|
||||
scnt = 1;
|
||||
ff = i;
|
||||
scnt = 1;
|
||||
} else {
|
||||
scnt++;
|
||||
if (scnt == SC_SIZE) break;
|
||||
scnt++;
|
||||
if (scnt == SC_SIZE)
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
ff = -1;
|
||||
}
|
||||
}
|
||||
/* out of allocable slots?*/
|
||||
if(i == nsysent || ff == -1) {
|
||||
if (i == nsysent || ff == -1) {
|
||||
err = ENFILE;
|
||||
break;
|
||||
}
|
||||
err = ncp_init();
|
||||
if (err) break;
|
||||
bcopy(&sysent[ff], &oldent, sizeof(struct sysent)*SC_SIZE);
|
||||
bcopy(&newent, &sysent[ff], sizeof(struct sysent)*SC_SIZE);
|
||||
if (err)
|
||||
break;
|
||||
bcopy(&sysent[ff], &oldent, sizeof(struct sysent) * SC_SIZE);
|
||||
bcopy(&newent, &sysent[ff], sizeof(struct sysent) * SC_SIZE);
|
||||
ncp_sysent = ff; /* slot in sysent[]*/
|
||||
printf("ncp_load: [%d-%d]\n",ff,i);
|
||||
printf("ncp_load: [%d-%d]\n", ff, i);
|
||||
break;
|
||||
}
|
||||
|
||||
return( err);
|
||||
return (err);
|
||||
}
|
||||
|
||||
static int
|
||||
@ -534,18 +559,18 @@ ncp_mod_handler(module_t mod, int type, void *data)
|
||||
int error;
|
||||
|
||||
switch (type) {
|
||||
case MOD_LOAD:
|
||||
case MOD_LOAD:
|
||||
error = ncp_load();
|
||||
break;
|
||||
case MOD_UNLOAD:
|
||||
case MOD_UNLOAD:
|
||||
error = ncp_unload();
|
||||
break;
|
||||
default:
|
||||
default:
|
||||
error = EINVAL;
|
||||
}
|
||||
return error;
|
||||
}
|
||||
\
|
||||
|
||||
static moduledata_t ncp_mod = {
|
||||
"ncp",
|
||||
ncp_mod_handler,
|
||||
|
@ -41,6 +41,8 @@
|
||||
#include <sys/signalvar.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <sys/mbuf.h>
|
||||
#include <sys/lock.h>
|
||||
#include <sys/mutex.h>
|
||||
#include <sys/uio.h>
|
||||
|
||||
#include <netipx/ipx.h>
|
||||
@ -74,12 +76,14 @@ void m_dumpm(struct mbuf *m) {
|
||||
#endif /* NCP_DATA_DEBUG */
|
||||
|
||||
int
|
||||
ncp_chkintr(struct ncp_conn *conn, struct proc *p)
|
||||
ncp_chkintr(struct ncp_conn *conn, struct thread *td)
|
||||
{
|
||||
struct proc *p;
|
||||
sigset_t tmpset;
|
||||
|
||||
if (p == NULL)
|
||||
if (td == NULL)
|
||||
return 0;
|
||||
p = td->td_proc;
|
||||
PROC_LOCK(p);
|
||||
tmpset = p->p_siglist;
|
||||
SIGSETNAND(tmpset, p->p_sigmask);
|
||||
@ -103,8 +107,8 @@ ncp_ncp_connect(struct ncp_conn *conn)
|
||||
struct ncp_rq *rqp;
|
||||
struct ncp_rphdr *rp;
|
||||
int error;
|
||||
|
||||
error = ncp_rq_alloc_any(NCP_ALLOC_SLOT, 0, conn, conn->procp, conn->ucred, &rqp);
|
||||
|
||||
error = ncp_rq_alloc_any(NCP_ALLOC_SLOT, 0, conn, conn->td, conn->ucred, &rqp);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
@ -134,7 +138,7 @@ ncp_ncp_disconnect(struct ncp_conn *conn)
|
||||
ncp_burst_disconnect(conn);
|
||||
#endif
|
||||
if (conn->flags & NCPFL_ATTACHED) {
|
||||
error = ncp_rq_alloc_any(NCP_FREE_SLOT, 0, conn, conn->procp, conn->ucred, &rqp);
|
||||
error = ncp_rq_alloc_any(NCP_FREE_SLOT, 0, conn, conn->td, conn->ucred, &rqp);
|
||||
if (!error) {
|
||||
ncp_request_int(rqp);
|
||||
ncp_rq_done(rqp);
|
||||
@ -156,7 +160,7 @@ ncp_negotiate_buffersize(struct ncp_conn *conn, int size, int *target)
|
||||
u_int16_t bsize;
|
||||
int error;
|
||||
|
||||
error = ncp_rq_alloc(0x21, conn, conn->procp, conn->ucred, &rqp);
|
||||
error = ncp_rq_alloc(0x21, conn, conn->td, conn->ucred, &rqp);
|
||||
if (error)
|
||||
return error;
|
||||
mb_put_uint16be(&rqp->rq, size);
|
||||
@ -170,14 +174,14 @@ ncp_negotiate_buffersize(struct ncp_conn *conn, int size, int *target)
|
||||
}
|
||||
|
||||
static int
|
||||
ncp_negotiate_size_and_options(struct ncp_conn *conn, int size, int options,
|
||||
ncp_negotiate_size_and_options(struct ncp_conn *conn, int size, int options,
|
||||
int *ret_size, u_int8_t *ret_options)
|
||||
{
|
||||
struct ncp_rq *rqp;
|
||||
u_int16_t rs;
|
||||
int error;
|
||||
|
||||
error = ncp_rq_alloc(0x61, conn, conn->procp, conn->ucred, &rqp);
|
||||
error = ncp_rq_alloc(0x61, conn, conn->td, conn->ucred, &rqp);
|
||||
if (error)
|
||||
return error;
|
||||
mb_put_uint16be(&rqp->rq, size);
|
||||
@ -205,14 +209,14 @@ ncp_renegotiate_connparam(struct ncp_conn *conn, int buffsize, u_int8_t in_optio
|
||||
in_options |= NCP_SECURITY_LEVEL_SIGN_HEADERS;
|
||||
if (conn->li.saddr.sa_family == AF_IPX) {
|
||||
ilen = sizeof(ckslevel);
|
||||
error = kernel_sysctlbyname(curproc, "net.ipx.ipx.checksum",
|
||||
error = kernel_sysctlbyname(curthread, "net.ipx.ipx.checksum",
|
||||
&ckslevel, &ilen, NULL, 0, NULL);
|
||||
if (error)
|
||||
return error;
|
||||
if (ckslevel == 2)
|
||||
in_options |= NCP_IPX_CHECKSUM;
|
||||
}
|
||||
error = ncp_negotiate_size_and_options(conn, buffsize, in_options,
|
||||
error = ncp_negotiate_size_and_options(conn, buffsize, in_options,
|
||||
&neg_buffsize, &options);
|
||||
if (!error) {
|
||||
if (conn->li.saddr.sa_family == AF_IPX &&
|
||||
@ -256,26 +260,27 @@ ncp_renegotiate_connparam(struct ncp_conn *conn, int buffsize, u_int8_t in_optio
|
||||
}
|
||||
|
||||
void
|
||||
ncp_check_rq(struct ncp_conn *conn){
|
||||
ncp_check_rq(struct ncp_conn *conn)
|
||||
{
|
||||
return;
|
||||
if (conn->flags & NCPFL_INTR) return;
|
||||
if (conn->flags & NCPFL_INTR)
|
||||
return;
|
||||
/* first, check for signals */
|
||||
if (ncp_chkintr(conn,conn->procp)) {
|
||||
if (ncp_chkintr(conn, conn->td))
|
||||
conn->flags |= NCPFL_INTR;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
int
|
||||
ncp_get_bindery_object_id(struct ncp_conn *conn,
|
||||
u_int16_t object_type, char *object_name,
|
||||
ncp_get_bindery_object_id(struct ncp_conn *conn,
|
||||
u_int16_t object_type, char *object_name,
|
||||
struct ncp_bindery_object *target,
|
||||
struct proc *p,struct ucred *cred)
|
||||
struct thread *td, struct ucred *cred)
|
||||
{
|
||||
struct ncp_rq *rqp;
|
||||
int error;
|
||||
|
||||
error = ncp_rq_alloc_subfn(23, 53, conn, conn->procp, conn->ucred, &rqp);
|
||||
error = ncp_rq_alloc_subfn(23, 53, conn, conn->td, conn->ucred, &rqp);
|
||||
mb_put_uint16be(&rqp->rq, object_type);
|
||||
ncp_rq_pstring(rqp, object_name);
|
||||
rqp->nr_minrplen = 54;
|
||||
@ -298,7 +303,7 @@ ncp_get_encryption_key(struct ncp_conn *conn, char *target)
|
||||
struct ncp_rq *rqp;
|
||||
int error;
|
||||
|
||||
error = ncp_rq_alloc_subfn(23, 23, conn, conn->procp, conn->ucred, &rqp);
|
||||
error = ncp_rq_alloc_subfn(23, 23, conn, conn->td, conn->ucred, &rqp);
|
||||
if (error)
|
||||
return error;
|
||||
rqp->nr_minrplen = 8;
|
||||
@ -340,7 +345,7 @@ ncp_sign_start(struct ncp_conn *conn, char *logindata)
|
||||
int
|
||||
ncp_login_encrypted(struct ncp_conn *conn, struct ncp_bindery_object *object,
|
||||
const u_char *key, const u_char *passwd,
|
||||
struct proc *p, struct ucred *cred)
|
||||
struct thread *td, struct ucred *cred)
|
||||
{
|
||||
struct ncp_rq *rqp;
|
||||
struct mbchain *mbp;
|
||||
@ -352,7 +357,7 @@ ncp_login_encrypted(struct ncp_conn *conn, struct ncp_bindery_object *object,
|
||||
nw_keyhash((u_char*)&tmpID, passwd, strlen(passwd), buf);
|
||||
nw_encrypt(key, buf, encrypted);
|
||||
|
||||
error = ncp_rq_alloc_subfn(23, 24, conn, p, cred, &rqp);
|
||||
error = ncp_rq_alloc_subfn(23, 24, conn, td, cred, &rqp);
|
||||
if (error)
|
||||
return error;
|
||||
mbp = &rqp->rq;
|
||||
@ -371,14 +376,14 @@ ncp_login_encrypted(struct ncp_conn *conn, struct ncp_bindery_object *object,
|
||||
}
|
||||
|
||||
int
|
||||
ncp_login_unencrypted(struct ncp_conn *conn, u_int16_t object_type,
|
||||
ncp_login_unencrypted(struct ncp_conn *conn, u_int16_t object_type,
|
||||
const char *object_name, const u_char *passwd,
|
||||
struct proc *p, struct ucred *cred)
|
||||
struct thread *td, struct ucred *cred)
|
||||
{
|
||||
struct ncp_rq *rqp;
|
||||
int error;
|
||||
|
||||
error = ncp_rq_alloc_subfn(23, 20, conn, p, cred, &rqp);
|
||||
error = ncp_rq_alloc_subfn(23, 20, conn, td, cred, &rqp);
|
||||
if (error)
|
||||
return error;
|
||||
mb_put_uint16be(&rqp->rq, object_type);
|
||||
@ -409,7 +414,7 @@ ncp_read(struct ncp_conn *conn, ncp_fh *file, struct uio *uiop, struct ucred *cr
|
||||
if (!burstio) {
|
||||
len = min(4096 - (uiop->uio_offset % 4096), tsiz);
|
||||
len = min(len, conn->buffer_size);
|
||||
error = ncp_rq_alloc(72, conn, uiop->uio_procp, cred, &rqp);
|
||||
error = ncp_rq_alloc(72, conn, uiop->uio_td, cred, &rqp);
|
||||
if (error)
|
||||
break;
|
||||
mbp = &rqp->rq;
|
||||
@ -459,7 +464,7 @@ ncp_write(struct ncp_conn *conn, ncp_fh *file, struct uio *uiop, struct ucred *c
|
||||
printf("gotcha!\n");
|
||||
}
|
||||
/* rq head */
|
||||
error = ncp_rq_alloc(73, conn, uiop->uio_procp, cred, &rqp);
|
||||
error = ncp_rq_alloc(73, conn, uiop->uio_td, cred, &rqp);
|
||||
if (error)
|
||||
break;
|
||||
mbp = &rqp->rq;
|
||||
|
@ -108,7 +108,6 @@ struct ncp_bursthdr {
|
||||
struct ncp_conn;
|
||||
struct ncp_conn_args;
|
||||
struct ncp_rq;
|
||||
struct proc;
|
||||
struct ucred;
|
||||
|
||||
int ncp_ncp_connect(struct ncp_conn *conn);
|
||||
@ -119,15 +118,15 @@ int ncp_renegotiate_connparam(struct ncp_conn *conn, int buffsize,
|
||||
int ncp_get_bindery_object_id(struct ncp_conn *conn,
|
||||
u_int16_t object_type, char *object_name,
|
||||
struct ncp_bindery_object *target,
|
||||
struct proc *p,struct ucred *cred);
|
||||
struct thread *td,struct ucred *cred);
|
||||
int ncp_get_encryption_key(struct ncp_conn *conn, char *target);
|
||||
int ncp_login_encrypted(struct ncp_conn *conn,
|
||||
struct ncp_bindery_object *object,
|
||||
const u_char *key, const u_char *passwd,
|
||||
struct proc *p, struct ucred *cred);
|
||||
struct thread *td, struct ucred *cred);
|
||||
int ncp_login_unencrypted(struct ncp_conn *conn, u_int16_t object_type,
|
||||
const char *object_name, const u_char *passwd,
|
||||
struct proc *p, struct ucred *cred);
|
||||
struct thread *td, struct ucred *cred);
|
||||
int ncp_read(struct ncp_conn *conn, ncp_fh *file, struct uio *uiop, struct ucred *cred);
|
||||
int ncp_write(struct ncp_conn *conn, ncp_fh *file, struct uio *uiop, struct ucred *cred);
|
||||
|
||||
|
@ -57,14 +57,14 @@ static int ncp_sign_packet(struct ncp_conn *conn, struct ncp_rq *rqp, int *size)
|
||||
|
||||
int
|
||||
ncp_rq_alloc_any(u_int32_t ptype, u_int8_t fn, struct ncp_conn *ncp,
|
||||
struct proc *p, struct ucred *cred,
|
||||
struct thread *td, struct ucred *cred,
|
||||
struct ncp_rq **rqpp)
|
||||
{
|
||||
struct ncp_rq *rqp;
|
||||
int error;
|
||||
|
||||
MALLOC(rqp, struct ncp_rq *, sizeof(*rqp), M_NCPRQ, M_WAITOK);
|
||||
error = ncp_rq_init_any(rqp, ptype, fn, ncp, p, cred);
|
||||
error = ncp_rq_init_any(rqp, ptype, fn, ncp, td, cred);
|
||||
rqp->nr_flags |= NCPR_ALLOCED;
|
||||
if (error) {
|
||||
ncp_rq_done(rqp);
|
||||
@ -76,19 +76,19 @@ ncp_rq_alloc_any(u_int32_t ptype, u_int8_t fn, struct ncp_conn *ncp,
|
||||
|
||||
int
|
||||
ncp_rq_alloc(u_int8_t fn, struct ncp_conn *ncp,
|
||||
struct proc *p, struct ucred *cred, struct ncp_rq **rqpp)
|
||||
struct thread *td, struct ucred *cred, struct ncp_rq **rqpp)
|
||||
{
|
||||
return ncp_rq_alloc_any(NCP_REQUEST, fn, ncp, p, cred, rqpp);
|
||||
return ncp_rq_alloc_any(NCP_REQUEST, fn, ncp, td, cred, rqpp);
|
||||
}
|
||||
|
||||
int
|
||||
ncp_rq_alloc_subfn(u_int8_t fn, u_int8_t subfn, struct ncp_conn *ncp,
|
||||
struct proc *p, struct ucred *cred, struct ncp_rq **rqpp)
|
||||
struct thread *td, struct ucred *cred, struct ncp_rq **rqpp)
|
||||
{
|
||||
struct ncp_rq *rqp;
|
||||
int error;
|
||||
|
||||
error = ncp_rq_alloc_any(NCP_REQUEST, fn, ncp, p, cred, &rqp);
|
||||
error = ncp_rq_alloc_any(NCP_REQUEST, fn, ncp, td, cred, &rqp);
|
||||
if (error)
|
||||
return error;
|
||||
mb_reserve(&rqp->rq, 2);
|
||||
@ -100,7 +100,7 @@ ncp_rq_alloc_subfn(u_int8_t fn, u_int8_t subfn, struct ncp_conn *ncp,
|
||||
int
|
||||
ncp_rq_init_any(struct ncp_rq *rqp, u_int32_t ptype, u_int8_t fn,
|
||||
struct ncp_conn *ncp,
|
||||
struct proc *p, struct ucred *cred)
|
||||
struct thread *td, struct ucred *cred)
|
||||
{
|
||||
struct ncp_rqhdr *rq;
|
||||
struct ncp_bursthdr *brq;
|
||||
@ -111,7 +111,7 @@ ncp_rq_init_any(struct ncp_rq *rqp, u_int32_t ptype, u_int8_t fn,
|
||||
error = ncp_conn_access(ncp, cred, NCPM_EXECUTE);
|
||||
if (error)
|
||||
return error;
|
||||
rqp->nr_p = p;
|
||||
rqp->nr_td = td;
|
||||
rqp->nr_cred = cred;
|
||||
rqp->nr_conn = ncp;
|
||||
mbp = &rqp->rq;
|
||||
@ -239,11 +239,11 @@ ncp_sign_packet(struct ncp_conn *conn, struct ncp_rq *rqp, int *size)
|
||||
* Low level send rpc, here we do not attempt to restore any connection,
|
||||
* Connection expected to be locked
|
||||
*/
|
||||
int
|
||||
int
|
||||
ncp_request_int(struct ncp_rq *rqp)
|
||||
{
|
||||
struct ncp_conn *conn = rqp->nr_conn;
|
||||
struct proc *p = conn->procp;
|
||||
struct thread *td = conn->td;
|
||||
struct socket *so = conn->ncp_so;
|
||||
struct ncp_rqhdr *rq;
|
||||
struct ncp_rphdr *rp=NULL;
|
||||
@ -257,8 +257,8 @@ ncp_request_int(struct ncp_rq *rqp)
|
||||
ncp_conn_invalidate(conn);
|
||||
return ENOTCONN;
|
||||
}
|
||||
if (p == NULL)
|
||||
p = curproc; /* XXX maybe procpage ? */
|
||||
if (td == NULL)
|
||||
td = curthread; /* XXX maybe procpage ? */
|
||||
/*
|
||||
* Flush out replies on previous reqs
|
||||
*/
|
||||
@ -307,10 +307,10 @@ ncp_request_int(struct ncp_rq *rqp)
|
||||
}
|
||||
tv.tv_sec = conn->li.timeout;
|
||||
tv.tv_usec = 0;
|
||||
error = ncp_sock_rselect(so, p, &tv, POLLIN);
|
||||
error = ncp_sock_rselect(so, td, &tv, POLLIN);
|
||||
if (error == EWOULDBLOCK ) /* timeout expired */
|
||||
continue;
|
||||
error = ncp_chkintr(conn, p);
|
||||
error = ncp_chkintr(conn, td);
|
||||
if (error)
|
||||
break;
|
||||
/*
|
||||
@ -422,7 +422,7 @@ ncp_restore_login(struct ncp_conn *conn)
|
||||
conn->flags |= NCPFL_RESTORING;
|
||||
error = ncp_conn_reconnect(conn);
|
||||
if (!error && (conn->flags & NCPFL_WASLOGGED))
|
||||
error = ncp_conn_login(conn, conn->procp, conn->ucred);
|
||||
error = ncp_conn_login(conn, conn->td, conn->ucred);
|
||||
if (error)
|
||||
ncp_ncp_disconnect(conn);
|
||||
conn->flags &= ~NCPFL_RESTORING;
|
||||
@ -435,7 +435,7 @@ ncp_request(struct ncp_rq *rqp)
|
||||
struct ncp_conn *ncp = rqp->nr_conn;
|
||||
int error, rcnt;
|
||||
|
||||
error = ncp_conn_lock(ncp, rqp->nr_p, rqp->nr_cred, NCPM_EXECUTE);
|
||||
error = ncp_conn_lock(ncp, rqp->nr_td, rqp->nr_cred, NCPM_EXECUTE);
|
||||
if (error)
|
||||
goto out;
|
||||
rcnt = NCP_RESTORE_COUNT;
|
||||
@ -460,7 +460,7 @@ ncp_request(struct ncp_rq *rqp)
|
||||
if (error)
|
||||
continue;
|
||||
}
|
||||
ncp_conn_unlock(ncp, rqp->nr_p);
|
||||
ncp_conn_unlock(ncp, rqp->nr_td);
|
||||
out:
|
||||
if (error && (rqp->nr_flags & NCPR_DONTFREEONERR) == 0)
|
||||
ncp_rq_done(rqp);
|
||||
|
@ -52,11 +52,6 @@
|
||||
#define setdle(buf,ofs,val) getdle(buf,ofs)=val
|
||||
#define setdbe(buf,ofs,val) getdle(buf,ofs)=htonl(val)
|
||||
|
||||
#define htoles(x) ((u_int16_t)(x))
|
||||
#define letohs(x) ((u_int16_t)(x))
|
||||
#define htolel(x) ((u_int32_t)(x))
|
||||
#define letohl(x) ((u_int32_t)(x))
|
||||
|
||||
#else
|
||||
#error "Macros for Big-Endians are incomplete"
|
||||
#define getwle(buf,ofs) ((u_int16_t)(getb(buf, ofs) | (getb(buf, ofs + 1) << 8)))
|
||||
|
@ -66,17 +66,19 @@
|
||||
|
||||
/*int ncp_poll(struct socket *so, int events);*/
|
||||
/*static int ncp_getsockname(struct socket *so, caddr_t asa, int *alen);*/
|
||||
static int ncp_soconnect(struct socket *so,struct sockaddr *target, struct proc *p);
|
||||
static int ncp_soconnect(struct socket *so, struct sockaddr *target,
|
||||
struct thread *td);
|
||||
|
||||
|
||||
/* This will need only if native IP used, or (unlikely) NCP will be
|
||||
* implemented on the socket level
|
||||
*/
|
||||
static int
|
||||
ncp_soconnect(struct socket *so,struct sockaddr *target, struct proc *p) {
|
||||
int error,s;
|
||||
ncp_soconnect(struct socket *so, struct sockaddr *target, struct thread *td)
|
||||
{
|
||||
int error, s;
|
||||
|
||||
error = soconnect(so, (struct sockaddr*)target, p);
|
||||
error = soconnect(so, (struct sockaddr*)target, td);
|
||||
if (error)
|
||||
return error;
|
||||
/*
|
||||
@ -129,11 +131,11 @@ ncp_getsockname(struct socket *so, caddr_t asa, int *alen) {
|
||||
int ncp_sock_recv(struct socket *so, struct mbuf **mp, int *rlen)
|
||||
{
|
||||
struct uio auio;
|
||||
struct proc *p=curproc; /* XXX */
|
||||
struct thread *td = curthread; /* XXX */
|
||||
int error,flags,len;
|
||||
|
||||
|
||||
auio.uio_resid = len = 1000000;
|
||||
auio.uio_procp = p;
|
||||
auio.uio_td = td;
|
||||
flags = MSG_DONTWAIT;
|
||||
|
||||
/* error = so->so_proto->pr_usrreqs->pru_soreceive(so, 0, &auio,
|
||||
@ -155,23 +157,23 @@ int ncp_sock_recv(struct socket *so, struct mbuf **mp, int *rlen)
|
||||
int
|
||||
ncp_sock_send(struct socket *so, struct mbuf *top, struct ncp_rq *rqp)
|
||||
{
|
||||
struct proc *p = curproc; /* XXX */
|
||||
struct thread *td = curthread; /* XXX */
|
||||
struct sockaddr *to = 0;
|
||||
struct ncp_conn *conn = rqp->nr_conn;
|
||||
struct mbuf *m;
|
||||
int error, flags=0;
|
||||
int sendwait;
|
||||
|
||||
for(;;) {
|
||||
for (;;) {
|
||||
m = m_copym(top, 0, M_COPYALL, M_TRYWAIT);
|
||||
/* NCPDDEBUG(m);*/
|
||||
error = so->so_proto->pr_usrreqs->pru_sosend(so, to, 0, m, 0, flags, p);
|
||||
error = so->so_proto->pr_usrreqs->pru_sosend(so, to, 0, m, 0, flags, td);
|
||||
if (error == 0 || error == EINTR || error == ENETDOWN)
|
||||
break;
|
||||
if (rqp->rexmit == 0) break;
|
||||
rqp->rexmit--;
|
||||
tsleep(&sendwait, PWAIT, "ncprsn", conn->li.timeout * hz);
|
||||
error = ncp_chkintr(conn, p);
|
||||
error = ncp_chkintr(conn, td);
|
||||
if (error == EINTR) break;
|
||||
}
|
||||
if (error) {
|
||||
@ -181,20 +183,23 @@ ncp_sock_send(struct socket *so, struct mbuf *top, struct ncp_rq *rqp)
|
||||
}
|
||||
|
||||
int
|
||||
ncp_poll(struct socket *so, int events){
|
||||
struct proc *p = curproc;
|
||||
struct ucred *cred=NULL;
|
||||
return so->so_proto->pr_usrreqs->pru_sopoll(so, events, cred, p);
|
||||
ncp_poll(struct socket *so, int events)
|
||||
{
|
||||
struct thread *td = curthread;
|
||||
struct ucred *cred = NULL;
|
||||
|
||||
return so->so_proto->pr_usrreqs->pru_sopoll(so, events, cred, td);
|
||||
}
|
||||
|
||||
int
|
||||
ncp_sock_rselect(struct socket *so,struct proc *p, struct timeval *tv, int events)
|
||||
ncp_sock_rselect(struct socket *so, struct thread *td, struct timeval *tv,
|
||||
int events)
|
||||
{
|
||||
struct timeval atv,rtv,ttv;
|
||||
int timo,error=0;
|
||||
struct timeval atv, rtv, ttv;
|
||||
int ncoll, timo, error = 0;
|
||||
|
||||
if (tv) {
|
||||
atv=*tv;
|
||||
atv = *tv;
|
||||
if (itimerfix(&atv)) {
|
||||
error = EINVAL;
|
||||
goto done_noproclock;
|
||||
@ -203,56 +208,65 @@ ncp_sock_rselect(struct socket *so,struct proc *p, struct timeval *tv, int event
|
||||
timevaladd(&atv, &rtv);
|
||||
}
|
||||
timo = 0;
|
||||
PROC_LOCK(p);
|
||||
p->p_flag |= P_SELECT;
|
||||
PROC_UNLOCK(p);
|
||||
mtx_lock(&sellock);
|
||||
|
||||
retry:
|
||||
ncoll = nselcoll;
|
||||
mtx_lock_spin(&sched_lock);
|
||||
td->td_flags |= TDF_SELECT;
|
||||
mtx_unlock_spin(&sched_lock);
|
||||
mtx_unlock(&sellock);
|
||||
|
||||
TAILQ_INIT(&td->td_selq);
|
||||
error = ncp_poll(so, events);
|
||||
PROC_LOCK(p);
|
||||
mtx_lock(&sellock);
|
||||
if (error) {
|
||||
error = 0;
|
||||
goto done;
|
||||
}
|
||||
if (tv) {
|
||||
getmicrouptime(&rtv);
|
||||
if (timevalcmp(&rtv, &atv, >=)) {
|
||||
/*
|
||||
* An event of our interest may occur during locking a process.
|
||||
* In order to avoid missing the event that occured during locking
|
||||
* the process, test P_SELECT and rescan file descriptors if
|
||||
* necessary.
|
||||
*/
|
||||
if ((p->p_flag & P_SELECT) == 0) {
|
||||
p->p_flag |= P_SELECT;
|
||||
PROC_UNLOCK(p);
|
||||
error = ncp_poll(so, events);
|
||||
PROC_LOCK(p);
|
||||
}
|
||||
if (timevalcmp(&rtv, &atv, >=))
|
||||
goto done;
|
||||
}
|
||||
ttv=atv;
|
||||
ttv = atv;
|
||||
timevalsub(&ttv, &rtv);
|
||||
timo = tvtohz(&ttv);
|
||||
}
|
||||
p->p_flag &= ~P_SELECT;
|
||||
/*
|
||||
* An event of our interest may occur during locking a thread.
|
||||
* In order to avoid missing the event that occurred during locking
|
||||
* the process, test TDF_SELECT and rescan file descriptors if
|
||||
* necessary.
|
||||
*/
|
||||
mtx_lock_spin(&sched_lock);
|
||||
if ((td->td_flags & TDF_SELECT) == 0 || nselcoll != ncoll) {
|
||||
mtx_unlock_spin(&sched_lock);
|
||||
goto retry;
|
||||
}
|
||||
mtx_unlock_spin(&sched_lock);
|
||||
|
||||
if (timo > 0)
|
||||
error = cv_timedwait(&selwait, &p->p_mtx, timo);
|
||||
error = cv_timedwait(&selwait, &sellock, timo);
|
||||
else {
|
||||
cv_wait(&selwait, &p->p_mtx);
|
||||
cv_wait(&selwait, &sellock);
|
||||
error = 0;
|
||||
}
|
||||
|
||||
done:
|
||||
p->p_flag &= ~P_SELECT;
|
||||
PROC_UNLOCK(p);
|
||||
clear_selinfo_list(td);
|
||||
|
||||
mtx_lock_spin(&sched_lock);
|
||||
td->td_flags &= ~TDF_SELECT;
|
||||
mtx_unlock_spin(&sched_lock);
|
||||
mtx_unlock(&sellock);
|
||||
|
||||
done_noproclock:
|
||||
if (error == ERESTART) {
|
||||
/* printf("Signal: %x", cursig(p));*/
|
||||
if (error == ERESTART)
|
||||
error = 0;
|
||||
}
|
||||
return (error);
|
||||
}
|
||||
|
||||
/*
|
||||
/*
|
||||
* Connect to specified server via IPX
|
||||
*/
|
||||
static int
|
||||
@ -260,7 +274,7 @@ ncp_sock_connect_ipx(struct ncp_conn *conn)
|
||||
{
|
||||
struct sockaddr_ipx sipx;
|
||||
struct ipxpcb *npcb;
|
||||
struct proc *p = conn->procp;
|
||||
struct thread *td = conn->td;
|
||||
int addrlen, error, count;
|
||||
|
||||
sipx.sipx_port = htons(0);
|
||||
@ -271,15 +285,15 @@ ncp_sock_connect_ipx(struct ncp_conn *conn)
|
||||
goto bad;
|
||||
}
|
||||
conn->ncp_so = conn->wdg_so = NULL;
|
||||
checkbad(socreate(AF_IPX, &conn->ncp_so, SOCK_DGRAM, 0, p));
|
||||
checkbad(socreate(AF_IPX, &conn->ncp_so, SOCK_DGRAM, 0, td->td_ucred, td));
|
||||
if (conn->li.opt & NCP_OPT_WDOG)
|
||||
checkbad(socreate(AF_IPX, &conn->wdg_so, SOCK_DGRAM,0,p));
|
||||
checkbad(socreate(AF_IPX, &conn->wdg_so, SOCK_DGRAM, 0, td->td_ucred, td));
|
||||
addrlen = sizeof(sipx);
|
||||
sipx.sipx_family = AF_IPX;
|
||||
ipx_setnullnet(sipx.sipx_addr);
|
||||
ipx_setnullhost(sipx.sipx_addr);
|
||||
sipx.sipx_len = addrlen;
|
||||
error = sobind(conn->ncp_so, (struct sockaddr *)&sipx, p);
|
||||
error = sobind(conn->ncp_so, (struct sockaddr *)&sipx, td);
|
||||
if (error == 0) {
|
||||
if ((conn->li.opt & NCP_OPT_WDOG) == 0)
|
||||
break;
|
||||
@ -287,7 +301,7 @@ ncp_sock_connect_ipx(struct ncp_conn *conn)
|
||||
sipx.sipx_port = htons(ntohs(sipx.sipx_port) + 1);
|
||||
ipx_setnullnet(sipx.sipx_addr);
|
||||
ipx_setnullhost(sipx.sipx_addr);
|
||||
error = sobind(conn->wdg_so, (struct sockaddr *)&sipx, p);
|
||||
error = sobind(conn->wdg_so, (struct sockaddr *)&sipx, td);
|
||||
}
|
||||
if (!error) break;
|
||||
if (error != EADDRINUSE) goto bad;
|
||||
@ -300,7 +314,7 @@ ncp_sock_connect_ipx(struct ncp_conn *conn)
|
||||
npcb->ipxp_dpt = IPXPROTO_NCP;
|
||||
/* IPXrouted must be running, i.e. route must be presented */
|
||||
conn->li.ipxaddr.sipx_len = sizeof(struct sockaddr_ipx);
|
||||
checkbad(ncp_soconnect(conn->ncp_so, &conn->li.saddr, p));
|
||||
checkbad(ncp_soconnect(conn->ncp_so, &conn->li.saddr, td));
|
||||
if (conn->wdg_so) {
|
||||
sotoipxpcb(conn->wdg_so)->ipxp_laddr.x_net = npcb->ipxp_laddr.x_net;
|
||||
sotoipxpcb(conn->wdg_so)->ipxp_laddr.x_host= npcb->ipxp_laddr.x_host;
|
||||
@ -310,11 +324,11 @@ ncp_sock_connect_ipx(struct ncp_conn *conn)
|
||||
}
|
||||
#ifdef NCPBURST
|
||||
if (ncp_burst_enabled) {
|
||||
checkbad(socreate(AF_IPX, &conn->bc_so, SOCK_DGRAM, 0, p));
|
||||
checkbad(socreate(AF_IPX, &conn->bc_so, SOCK_DGRAM, 0, td));
|
||||
bzero(&sipx, sizeof(sipx));
|
||||
sipx.sipx_len = sizeof(sipx);
|
||||
checkbad(sobind(conn->bc_so, (struct sockaddr *)&sipx, p));
|
||||
checkbad(ncp_soconnect(conn->bc_so, &conn->li.saddr, p));
|
||||
checkbad(sobind(conn->bc_so, (struct sockaddr *)&sipx, td));
|
||||
checkbad(ncp_soconnect(conn->bc_so, &conn->li.saddr, td));
|
||||
}
|
||||
#endif
|
||||
if (!error) {
|
||||
@ -339,24 +353,24 @@ ncp_sock_checksum(struct ncp_conn *conn, int enable)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
/*
|
||||
* Connect to specified server via IP
|
||||
*/
|
||||
static int
|
||||
ncp_sock_connect_in(struct ncp_conn *conn)
|
||||
{
|
||||
struct sockaddr_in sin;
|
||||
struct proc *p=conn->procp;
|
||||
int addrlen=sizeof(sin), error;
|
||||
struct thread *td = conn->td;
|
||||
int addrlen = sizeof(sin), error;
|
||||
|
||||
conn->flags = 0;
|
||||
bzero(&sin,addrlen);
|
||||
conn->ncp_so = conn->wdg_so = NULL;
|
||||
checkbad(socreate(AF_INET, &conn->ncp_so, SOCK_DGRAM, IPPROTO_UDP, p));
|
||||
checkbad(socreate(AF_INET, &conn->ncp_so, SOCK_DGRAM, IPPROTO_UDP, td->td_ucred, td));
|
||||
sin.sin_family = AF_INET;
|
||||
sin.sin_len = addrlen;
|
||||
checkbad(sobind(conn->ncp_so, (struct sockaddr *)&sin, p));
|
||||
checkbad(ncp_soconnect(conn->ncp_so,(struct sockaddr*)&conn->li.addr, p));
|
||||
checkbad(sobind(conn->ncp_so, (struct sockaddr *)&sin, td));
|
||||
checkbad(ncp_soconnect(conn->ncp_so,(struct sockaddr*)&conn->li.addr, td));
|
||||
if (!error)
|
||||
conn->flags |= NCPFL_SOCONN;
|
||||
return error;
|
||||
@ -426,9 +440,9 @@ ncp_watchdog(struct ncp_conn *conn) {
|
||||
while (conn->wdg_so) { /* not a loop */
|
||||
so = conn->wdg_so;
|
||||
auio.uio_resid = len = 1000000;
|
||||
auio.uio_procp = curproc;
|
||||
auio.uio_td = curthread;
|
||||
flags = MSG_DONTWAIT;
|
||||
error = so->so_proto->pr_usrreqs->pru_soreceive(so,
|
||||
error = so->so_proto->pr_usrreqs->pru_soreceive(so,
|
||||
(struct sockaddr**)&sa, &auio, &m, (struct mbuf**)0, &flags);
|
||||
if (error) break;
|
||||
len -= auio.uio_resid;
|
||||
@ -437,7 +451,7 @@ ncp_watchdog(struct ncp_conn *conn) {
|
||||
buf = mtod(m, char*);
|
||||
if (buf[1] != '?') break;
|
||||
buf[1] = 'Y';
|
||||
error = so->so_proto->pr_usrreqs->pru_sosend(so, (struct sockaddr*)sa, 0, m, 0, 0, curproc);
|
||||
error = so->so_proto->pr_usrreqs->pru_sosend(so, (struct sockaddr*)sa, 0, m, 0, 0, curthread);
|
||||
NCPSDEBUG("send watch dog %d\n",error);
|
||||
break;
|
||||
}
|
||||
|
@ -46,7 +46,8 @@ int ncp_sock_recv(struct socket *so, struct mbuf **mp, int *rlen);
|
||||
int ncp_sock_send(struct socket *so, struct mbuf *data, struct ncp_rq *rqp);
|
||||
int ncp_sock_disconnect(struct ncp_conn *conn);
|
||||
int ncp_poll(struct socket *so, int events);
|
||||
int ncp_sock_rselect(struct socket *so,struct proc *p, struct timeval *tv,int events);
|
||||
int ncp_sock_rselect(struct socket *so, struct thread *td, struct timeval *tv,
|
||||
int events);
|
||||
int ncp_sock_checksum(struct ncp_conn *conn, int enable);
|
||||
|
||||
void ncp_check_rq(struct ncp_conn *conn);
|
||||
|
@ -79,19 +79,23 @@ void
|
||||
ncp_at_exit(struct proc *p)
|
||||
{
|
||||
struct ncp_conn *ncp, *nncp;
|
||||
struct thread *td;
|
||||
|
||||
if (ncp_conn_putprochandles(p) == 0) return;
|
||||
|
||||
ncp_conn_locklist(LK_EXCLUSIVE, p);
|
||||
for (ncp = SLIST_FIRST(&conn_list); ncp; ncp = nncp) {
|
||||
nncp = SLIST_NEXT(ncp, nc_next);
|
||||
if (ncp_conn_lock(ncp, p, p->p_ucred,NCPM_READ|NCPM_EXECUTE|NCPM_WRITE))
|
||||
FOREACH_THREAD_IN_PROC(p, td) {
|
||||
if (ncp_conn_putprochandles(td) == 0)
|
||||
continue;
|
||||
if (ncp_conn_free(ncp) != 0)
|
||||
ncp_conn_unlock(ncp,p);
|
||||
|
||||
ncp_conn_locklist(LK_EXCLUSIVE, td);
|
||||
for (ncp = SLIST_FIRST(&conn_list); ncp; ncp = nncp) {
|
||||
nncp = SLIST_NEXT(ncp, nc_next);
|
||||
if (ncp_conn_lock(ncp, td, td->td_ucred,
|
||||
NCPM_READ | NCPM_EXECUTE | NCPM_WRITE))
|
||||
continue;
|
||||
if (ncp_conn_free(ncp) != 0)
|
||||
ncp_conn_unlock(ncp, td);
|
||||
}
|
||||
ncp_conn_unlocklist(td);
|
||||
}
|
||||
ncp_conn_unlocklist(p);
|
||||
return;
|
||||
}
|
||||
|
||||
int
|
||||
@ -102,7 +106,7 @@ ncp_init(void)
|
||||
NCPFATAL("can't register at_exit handler\n");
|
||||
return ENOMEM;
|
||||
}
|
||||
ncp_timer_handle = timeout(ncp_timer,NULL,NCP_TIMER_TICK);
|
||||
ncp_timer_handle = timeout(ncp_timer, NULL, NCP_TIMER_TICK);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -114,7 +118,7 @@ ncp_done(void)
|
||||
error = ncp_conn_destroy();
|
||||
if (error)
|
||||
return error;
|
||||
untimeout(ncp_timer,NULL,ncp_timer_handle);
|
||||
untimeout(ncp_timer, NULL, ncp_timer_handle);
|
||||
rm_at_exit(ncp_at_exit);
|
||||
return 0;
|
||||
}
|
||||
@ -131,5 +135,5 @@ ncp_timer(void *arg)
|
||||
ncp_check_conn(conn);
|
||||
ncp_conn_unlocklist(NULL);
|
||||
}
|
||||
ncp_timer_handle = timeout(ncp_timer,NULL,NCP_TIMER_TICK);
|
||||
ncp_timer_handle = timeout(ncp_timer, NULL, NCP_TIMER_TICK);
|
||||
}
|
||||
|
@ -111,7 +111,7 @@ struct ucred;
|
||||
|
||||
int ncp_init(void);
|
||||
int ncp_done(void);
|
||||
int ncp_chkintr(struct ncp_conn *conn, struct proc *p);
|
||||
int ncp_chkintr(struct ncp_conn *conn, struct thread *td);
|
||||
char*ncp_str_dup(char *s);
|
||||
|
||||
/* ncp_crypt.c */
|
||||
|
Loading…
Reference in New Issue
Block a user