Garbage collect NWFS and NCP bits which are now completely disconnected
from the tree since few months. This patch is not targeted for MFC.
This commit is contained in:
parent
7a61281f22
commit
a92189b377
@ -38,6 +38,43 @@
|
||||
# xargs -n1 | sort | uniq -d;
|
||||
# done
|
||||
|
||||
# 20130902: NWFS and NCP supports removed
|
||||
OLD_FILES+=usr/bin/ncplist
|
||||
OLD_FILES+=usr/bin/ncplogin
|
||||
OLD_FILES+=usr/bin/ncplogout
|
||||
OLD_FILES+=usr/include/fs/nwfs/nwfs.h
|
||||
OLD_FILES+=usr/include/fs/nwfs/nwfs_mount.h
|
||||
OLD_FILES+=usr/include/fs/nwfs/nwfs_node.h
|
||||
OLD_FILES+=usr/include/fs/nwfs/nwfs_subr.h
|
||||
OLD_DIRS+=usr/include/fs/nwfs
|
||||
OLD_FILES+=usr/include/netncp/ncp.h
|
||||
OLD_FILES+=usr/include/netncp/ncp_cfg.h
|
||||
OLD_FILES+=usr/include/netncp/ncp_conn.h
|
||||
OLD_FILES+=usr/include/netncp/ncp_file.h
|
||||
OLD_FILES+=usr/include/netncp/ncp_lib.h
|
||||
OLD_FILES+=usr/include/netncp/ncp_ncp.h
|
||||
OLD_FILES+=usr/include/netncp/ncp_nls.h
|
||||
OLD_FILES+=usr/include/netncp/ncp_rcfile.h
|
||||
OLD_FILES+=usr/include/netncp/ncp_rq.h
|
||||
OLD_FILES+=usr/include/netncp/ncp_sock.h
|
||||
OLD_FILES+=usr/include/netncp/ncp_subr.h
|
||||
OLD_FILES+=usr/include/netncp/ncp_user.h
|
||||
OLD_FILES+=usr/include/netncp/ncpio.h
|
||||
OLD_FILES+=usr/include/netncp/nwerror.h
|
||||
OLD_DIRS+=usr/include/netncp
|
||||
OLD_FILES+=usr/lib/libncp.a
|
||||
OLD_FILES+=usr/lib/libncp.so
|
||||
OLD_LIBS+=usr/lib/libncp.so.4
|
||||
OLD_FILES+=usr/lib/libncp_p.a
|
||||
OLD_FILES+=usr/lib32/libncp.a
|
||||
OLD_FILES+=usr/lib32/libncp.so
|
||||
OLD_LIBS+=usr/lib32/libncp.so.4
|
||||
OLD_FILES+=usr/lib32/libncp_p.a
|
||||
OLD_FILES+=usr/sbin/mount_nwfs
|
||||
OLD_FILES+=usr/share/man/man1/ncplist.1.gz
|
||||
OLD_FILES+=usr/share/man/man1/ncplogin.1.gz
|
||||
OLD_FILES+=usr/share/man/man1/ncplogout.1.gz
|
||||
OLD_FILES+=usr/share/man/man8/mount_nwfs.8.gz
|
||||
# 20130302: NTFS support removed
|
||||
OLD_FILES+=rescue/mount_ntfs
|
||||
OLD_FILES+=sbin/mount_ntfs
|
||||
|
@ -1,27 +0,0 @@
|
||||
# $FreeBSD$
|
||||
|
||||
In the development of NetWare client for FreeBSD next sources was used:
|
||||
|
||||
ncpfs for Linux - written by Volker Lendecke (lendecke@math.uni-goettingen.de),
|
||||
thanks to him for giving a permission to publish his code under BSD-style
|
||||
license.
|
||||
|
||||
"Interrupt List" from Ralf Brown,
|
||||
|
||||
Many files from the /sys directory.
|
||||
|
||||
NDK documentation from Novell Inc.
|
||||
|
||||
|
||||
Also thanks to thouse who gets time to testing, reporting problems and give
|
||||
a good suggestions (in alphabet order):
|
||||
|
||||
Anatoly A. Orehovsky
|
||||
Andrew Petrenko
|
||||
Jesus Rodriguez
|
||||
Matthew N. Dodd
|
||||
Mike Pitt
|
||||
Vadim Mikhailov
|
||||
|
||||
|
||||
Author - Boris Popov <bp@butya.kz>, <bp@freebsd.org>
|
@ -1,16 +0,0 @@
|
||||
# $FreeBSD$
|
||||
|
||||
LIB= ncp
|
||||
|
||||
SHLIB_MAJOR= 4
|
||||
|
||||
DPADD= ${LIBIPX}
|
||||
LDADD= -lipx
|
||||
|
||||
SRCS= ncpl_subr.c ncpl_bind.c ncpl_queue.c ncpl_file.c ncpl_misc.c \
|
||||
ncpl_net.c ncpl_rcfile.c ncpl_conn.c ncpl_nls.c ncpl_msg.c \
|
||||
ncpl_rpc.c ncpl_crypt.c ipx.c sap.c
|
||||
|
||||
WARNS?= 0
|
||||
|
||||
.include <bsd.lib.mk>
|
352
lib/libncp/ipx.c
352
lib/libncp/ipx.c
@ -1,352 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 1999, Boris Popov
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the author nor the names of any co-contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#include <arpa/inet.h>
|
||||
#include <net/if.h>
|
||||
#include <net/if_var.h>
|
||||
#include <net/if_dl.h>
|
||||
#include <net/if_types.h>
|
||||
#include <net/route.h>
|
||||
|
||||
/* IPX */
|
||||
#include <netipx/ipx.h>
|
||||
#include <netipx/ipx_if.h>
|
||||
|
||||
#include <ctype.h>
|
||||
#include <err.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <netncp/ncp_lib.h>
|
||||
|
||||
#define IPX_NODE_LEN 6
|
||||
|
||||
typedef u_long IPXNet;
|
||||
typedef u_short IPXPort;
|
||||
typedef union ipx_host IPXNode;
|
||||
|
||||
|
||||
void
|
||||
ipx_fprint_node(FILE * file, IPXNode node){
|
||||
fprintf(file, "%02X%02X%02X%02X%02X%02X",
|
||||
(unsigned char) node.c_host[0],
|
||||
(unsigned char) node.c_host[1],
|
||||
(unsigned char) node.c_host[2],
|
||||
(unsigned char) node.c_host[3],
|
||||
(unsigned char) node.c_host[4],
|
||||
(unsigned char) node.c_host[5]
|
||||
);
|
||||
}
|
||||
|
||||
void
|
||||
ipx_fprint_network(FILE * file, const IPXNet net){
|
||||
fprintf(file, "%08X", (u_int32_t)ntohl(net));
|
||||
}
|
||||
|
||||
void
|
||||
ipx_fprint_port(FILE * file, IPXPort port)
|
||||
{
|
||||
fprintf(file, "%04X", ntohs(port));
|
||||
}
|
||||
|
||||
void
|
||||
ipx_fprint_addr(FILE * file, struct ipx_addr *ipx)
|
||||
{
|
||||
ipx_fprint_network(file, ipx_netlong(*ipx));
|
||||
fprintf(file, ":");
|
||||
ipx_fprint_node(file, ipx->x_host);
|
||||
fprintf(file, ":");
|
||||
ipx_fprint_port(file, ipx->x_port);
|
||||
}
|
||||
|
||||
void
|
||||
ipx_print_node(IPXNode node)
|
||||
{
|
||||
ipx_fprint_node(stdout, node);
|
||||
}
|
||||
|
||||
void
|
||||
ipx_print_network(IPXNet net)
|
||||
{
|
||||
ipx_fprint_network(stdout, net);
|
||||
}
|
||||
|
||||
void
|
||||
ipx_print_port(IPXPort port)
|
||||
{
|
||||
ipx_fprint_port(stdout, port);
|
||||
}
|
||||
|
||||
void
|
||||
ipx_print_addr(struct ipx_addr *ipx)
|
||||
{
|
||||
ipx_fprint_addr(stdout, ipx);
|
||||
}
|
||||
|
||||
int
|
||||
ipx_sscanf_node(char *buf, unsigned char node[6])
|
||||
{
|
||||
int i;
|
||||
int n[6];
|
||||
|
||||
if ((i = sscanf(buf, "%2x%2x%2x%2x%2x%2x",
|
||||
&(n[0]), &(n[1]), &(n[2]),
|
||||
&(n[3]), &(n[4]), &(n[5]))) != 6)
|
||||
{
|
||||
return i;
|
||||
}
|
||||
for (i = 0; i < 6; i++)
|
||||
{
|
||||
node[i] = n[i];
|
||||
}
|
||||
return 6;
|
||||
}
|
||||
|
||||
int
|
||||
ipx_sscanf_saddr(char *buf, struct sockaddr_ipx *target)
|
||||
{
|
||||
char *p;
|
||||
struct sockaddr_ipx addr;
|
||||
unsigned long sipx_net;
|
||||
|
||||
addr.sipx_family = AF_IPX;
|
||||
/*!! addr.sipx_type = NCP_PTYPE;*/
|
||||
|
||||
if (sscanf(buf, "%lx", &sipx_net) != 1)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
((union ipx_net_u*)(&addr.sipx_addr.x_net))->long_e = htonl(sipx_net);
|
||||
if ((p = strchr(buf, ':')) == NULL){
|
||||
return 1;
|
||||
}
|
||||
p += 1;
|
||||
if (ipx_sscanf_node(p, addr.sipx_node) != 6)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
if ((p = strchr(p, ':')) == NULL)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
p += 1;
|
||||
if (sscanf(p, "%hx", &addr.sipx_port) != 1)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
addr.sipx_port = htons(addr.sipx_port);
|
||||
*target = addr;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void ipx_assign_node(IPXNode *dest, IPXNode *src) {
|
||||
memcpy(dest, src, IPX_NODE_LEN);
|
||||
}
|
||||
|
||||
|
||||
static void rt_xaddrs(caddr_t, caddr_t, struct rt_addrinfo *);
|
||||
static int if_ipxscan(int addrcount, struct sockaddr_dl *sdl,
|
||||
struct if_msghdr *ifm, struct ifa_msghdr *ifam,
|
||||
struct ipx_addr *addr);
|
||||
|
||||
/*
|
||||
* Find an IPX interface.
|
||||
* ifname specifies interface name, if NULL search for all interfaces
|
||||
* if ifname[0]='0', also all interfaces, but return its name
|
||||
* addr on input preferred net address can be specified or 0 for any,
|
||||
* on return contains full address (except port)
|
||||
* returns 0 if interface was found
|
||||
*/
|
||||
int
|
||||
ipx_iffind(char *ifname,struct ipx_addr *addr){
|
||||
char name[32];
|
||||
int all=0, flags, foundit = 0, addrcount;
|
||||
struct if_msghdr *ifm, *nextifm;
|
||||
struct ifa_msghdr *ifam;
|
||||
struct sockaddr_dl *sdl;
|
||||
char *buf, *lim, *next;
|
||||
size_t needed;
|
||||
int mib[6];
|
||||
|
||||
if( ifname!=NULL ) {
|
||||
strncpy(name,ifname,sizeof(name)-1);
|
||||
if( name[0]==0 )
|
||||
all=1;
|
||||
} else
|
||||
all = 1;
|
||||
|
||||
mib[0] = CTL_NET;
|
||||
mib[1] = PF_ROUTE;
|
||||
mib[2] = 0;
|
||||
mib[3] = AF_IPX;
|
||||
mib[4] = NET_RT_IFLIST;
|
||||
mib[5] = 0;
|
||||
|
||||
if (sysctl(mib, 6, NULL, &needed, NULL, 0) < 0)
|
||||
return(1);
|
||||
if ((buf = malloc(needed)) == NULL)
|
||||
return(1);
|
||||
if (sysctl(mib, 6, buf, &needed, NULL, 0) < 0) {
|
||||
free(buf);
|
||||
return(1);
|
||||
}
|
||||
lim = buf + needed;
|
||||
|
||||
next = buf;
|
||||
while (next < lim) {
|
||||
ifm = (struct if_msghdr *)next;
|
||||
if (ifm->ifm_type == RTM_IFINFO) {
|
||||
sdl = (struct sockaddr_dl *)(ifm + 1);
|
||||
flags = ifm->ifm_flags;
|
||||
} else {
|
||||
fprintf(stderr, "if_ipxfind: out of sync parsing NET_RT_IFLIST\n");
|
||||
fprintf(stderr, "expected %d, got %d\n", RTM_IFINFO, ifm->ifm_type);
|
||||
fprintf(stderr, "msglen = %d\n", ifm->ifm_msglen);
|
||||
fprintf(stderr, "buf:%p, next:%p, lim:%p\n", buf, next, lim);
|
||||
free(buf);
|
||||
return(1);
|
||||
}
|
||||
|
||||
next += ifm->ifm_msglen;
|
||||
ifam = NULL;
|
||||
addrcount = 0;
|
||||
while (next < lim) {
|
||||
nextifm = (struct if_msghdr *)next;
|
||||
if (nextifm->ifm_type != RTM_NEWADDR)
|
||||
break;
|
||||
if (ifam == NULL)
|
||||
ifam = (struct ifa_msghdr *)nextifm;
|
||||
addrcount++;
|
||||
next += nextifm->ifm_msglen;
|
||||
}
|
||||
|
||||
if (all) {
|
||||
if ((flags & IFF_UP) == 0)
|
||||
continue; /* not up */
|
||||
strncpy(name, sdl->sdl_data, sdl->sdl_nlen);
|
||||
name[sdl->sdl_nlen] = '\0';
|
||||
} else {
|
||||
if (strlen(name) != sdl->sdl_nlen)
|
||||
continue; /* not same len */
|
||||
if (strncmp(name, sdl->sdl_data, sdl->sdl_nlen) != 0)
|
||||
continue; /* not same name */
|
||||
}
|
||||
|
||||
foundit=if_ipxscan(addrcount, sdl, ifm, ifam, addr);
|
||||
if( foundit ) {
|
||||
if( ifname!=NULL && ifname[0]==0) {
|
||||
strncpy(ifname,sdl->sdl_data, sdl->sdl_nlen);
|
||||
ifname[sdl->sdl_nlen]=0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
free(buf);
|
||||
|
||||
return foundit ? 0:1;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
if_ipxscan(addrcount, sdl, ifm, ifam, addr)
|
||||
int addrcount;
|
||||
struct sockaddr_dl *sdl;
|
||||
struct if_msghdr *ifm;
|
||||
struct ifa_msghdr *ifam;
|
||||
struct ipx_addr *addr;
|
||||
{
|
||||
struct rt_addrinfo info;
|
||||
struct sockaddr_ipx *sipx;
|
||||
int s;
|
||||
|
||||
if ((s = socket(AF_IPX, SOCK_DGRAM, 0)) < 0) {
|
||||
perror("ifconfig: socket");
|
||||
return 0;
|
||||
}
|
||||
|
||||
while (addrcount > 0) {
|
||||
info.rti_addrs = ifam->ifam_addrs;
|
||||
/* Expand the compacted addresses */
|
||||
rt_xaddrs((char *)(ifam + 1), ifam->ifam_msglen + (char *)ifam, &info);
|
||||
addrcount--;
|
||||
ifam = (struct ifa_msghdr *)((char *)ifam + ifam->ifam_msglen);
|
||||
if (info.rti_info[RTAX_IFA]->sa_family == AF_IPX) {
|
||||
sipx = (struct sockaddr_ipx *)info.rti_info[RTAX_IFA];
|
||||
if( ipx_nullnet(sipx->sipx_addr) ) continue;
|
||||
if( ipx_nullnet(*addr) ||
|
||||
ipx_neteq(sipx->sipx_addr,*addr) ) {
|
||||
*addr=sipx->sipx_addr;
|
||||
close(s);
|
||||
return(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
close(s);
|
||||
return(0);
|
||||
}
|
||||
/*
|
||||
* Expand the compacted form of addresses as returned via the
|
||||
* configuration read via sysctl().
|
||||
*/
|
||||
|
||||
#define ROUNDUP(a) \
|
||||
((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long))
|
||||
#define ADVANCE(x, n) (x += ROUNDUP((n)->sa_len))
|
||||
|
||||
static void
|
||||
rt_xaddrs(cp, cplim, rtinfo)
|
||||
caddr_t cp, cplim;
|
||||
struct rt_addrinfo *rtinfo;
|
||||
{
|
||||
struct sockaddr *sa;
|
||||
int i;
|
||||
|
||||
memset(rtinfo->rti_info, 0, sizeof(rtinfo->rti_info));
|
||||
for (i = 0; (i < RTAX_MAX) && (cp < cplim); i++) {
|
||||
if ((rtinfo->rti_addrs & (1 << i)) == 0)
|
||||
continue;
|
||||
rtinfo->rti_info[i] = sa = (struct sockaddr *)cp;
|
||||
ADVANCE(cp, sa);
|
||||
}
|
||||
}
|
||||
|
@ -1,92 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 1999, Boris Popov
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the author nor the names of any co-contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
#ifndef _IPXSAP_H_
|
||||
#define _IPXSAP_H_
|
||||
|
||||
#define IPX_SAP_GENERAL_QUERY 1
|
||||
#define IPX_SAP_GENERAL_RESPONSE 2
|
||||
#define IPX_SAP_NEAREST_QUERY 3
|
||||
#define IPX_SAP_NEAREST_RESPONSE 4
|
||||
|
||||
|
||||
#define IPX_SAP_MAX_ENTRIES 7
|
||||
#define IPX_SAP_SERVER_DOWN 16
|
||||
#define IPX_SAP_SERVER_NAME_LEN 48
|
||||
#define IPX_SAP_REQUEST_LEN 4
|
||||
|
||||
/* Values for server_type */
|
||||
#define IPX_SAP_FILE_SERVER 4
|
||||
|
||||
struct sap_query {
|
||||
u_short query_type; /* net order */
|
||||
u_short server_type; /* net order */
|
||||
} __packed;
|
||||
|
||||
struct sap_entry {
|
||||
u_short server_type;
|
||||
u_char server_name[IPX_SAP_SERVER_NAME_LEN];
|
||||
struct ipx_addr ipx;
|
||||
u_short hops;
|
||||
} __packed;
|
||||
|
||||
struct sap_packet {
|
||||
u_short operation;
|
||||
struct sap_entry sap_entries[1];
|
||||
} __packed;
|
||||
|
||||
struct sap_rq {
|
||||
struct sockaddr_ipx dest_addr;
|
||||
int sock;
|
||||
int entries;
|
||||
struct sap_packet* buffer;
|
||||
};
|
||||
/*
|
||||
#define sap_name_equal(n1,n2) (strncmp(n1,n2,IPX_SAP_SERVER_NAME_LEN) == 0);
|
||||
#define sap_type_equal(t1,t2) (t1==IPX_SAP_GENERAL_RQ || t2==IPX_SAP_GENERAL_RQ || t1==t2);
|
||||
*/
|
||||
void sap_copy_name(char *dest,char *src);
|
||||
int sap_getsock(int *rsock);
|
||||
|
||||
|
||||
int sap_rq_init(struct sap_rq* out,int sock);
|
||||
int sap_rq_flush(struct sap_rq* out);
|
||||
void sap_rq_general(struct sap_rq* out,u_short ser_type);
|
||||
void sap_rq_gns_request(struct sap_rq* out,u_short ser_type);
|
||||
void sap_rq_response(struct sap_rq* out,u_short type,char *name,struct sockaddr_ipx* addr,u_short hops,int down_allow);
|
||||
void sap_rq_gns_response(struct sap_rq* out,u_short type,char * name,struct sockaddr_ipx* addr,u_short hops);
|
||||
void sap_rq_set_destination(struct sap_rq* out,struct ipx_addr *dest);
|
||||
|
||||
int sap_find_nearest(int server_type, struct sockaddr_ipx *result,char *server_name);
|
||||
|
||||
extern int (*sap_sendto_func)(void* buffer,int size,struct sockaddr_ipx* daddr,int sock);
|
||||
int ipx_iffind(char *ifname, struct ipx_addr *addr);
|
||||
|
||||
#endif /* !_IPXSAP_H_ */
|
@ -1,267 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 1999, Boris Popov
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the author nor the names of any co-contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <netncp/ncp_lib.h>
|
||||
|
||||
static void nw_passencrypt(char *old, char *new, char *out);
|
||||
|
||||
int
|
||||
ncp_get_bindery_object_id(NWCONN_HANDLE connid, u_int16_t object_type,
|
||||
const char *object_name, struct ncp_bindery_object *target)
|
||||
{
|
||||
int error;
|
||||
DECLARE_RQ;
|
||||
|
||||
ncp_init_request_s(conn, 53);
|
||||
ncp_add_word_hl(conn, object_type);
|
||||
ncp_add_pstring(conn, object_name);
|
||||
|
||||
if ((error = ncp_request(connid, 23, conn)) != 0) {
|
||||
return error;
|
||||
}
|
||||
if (conn->rpsize < 54) {
|
||||
return EACCES;
|
||||
}
|
||||
target->object_id = ncp_reply_dword_hl(conn, 0);
|
||||
target->object_type = ncp_reply_word_hl(conn, 4);
|
||||
memcpy(target->object_name, ncp_reply_data(conn, 6), 48);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
ncp_read_property_value(NWCONN_HANDLE connid, int object_type,
|
||||
const char *object_name, int segment, const char *prop_name,
|
||||
struct nw_property *target)
|
||||
{
|
||||
int error;
|
||||
struct ncp_buf conn;
|
||||
ncp_init_request_s(&conn, 61);
|
||||
ncp_add_word_hl(&conn, object_type);
|
||||
ncp_add_pstring(&conn, object_name);
|
||||
ncp_add_byte(&conn, segment);
|
||||
ncp_add_pstring(&conn, prop_name);
|
||||
|
||||
if ((error = ncp_request(connid,23,&conn)) != 0) {
|
||||
return error;
|
||||
}
|
||||
memcpy(&(target->value), ncp_reply_data(&conn, 0), 128);
|
||||
target->more_flag = ncp_reply_byte(&conn, 128);
|
||||
target->property_flag = ncp_reply_byte(&conn, 129);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
ncp_scan_bindery_object(NWCONN_HANDLE connid, u_int32_t last_id,
|
||||
u_int16_t object_type, const char *search_string,
|
||||
struct ncp_bindery_object *target)
|
||||
{
|
||||
int error;
|
||||
DECLARE_RQ;
|
||||
|
||||
ncp_init_request_s(conn, 55);
|
||||
ncp_add_dword_hl(conn, last_id);
|
||||
ncp_add_word_hl(conn, object_type);
|
||||
ncp_add_pstring(conn, search_string);
|
||||
error = ncp_request(connid, 23, conn);
|
||||
if (error) return error;
|
||||
target->object_id = ncp_reply_dword_hl(conn, 0);
|
||||
target->object_type = ncp_reply_word_hl(conn, 4);
|
||||
memcpy(target->object_name, ncp_reply_data(conn, 6),NCP_BINDERY_NAME_LEN);
|
||||
target->object_flags = ncp_reply_byte(conn, 54);
|
||||
target->object_security = ncp_reply_byte(conn, 55);
|
||||
target->object_has_prop = ncp_reply_byte(conn, 56);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
ncp_get_bindery_object_name(NWCONN_HANDLE connid, u_int32_t object_id,
|
||||
struct ncp_bindery_object *target)
|
||||
{
|
||||
int error;
|
||||
DECLARE_RQ;
|
||||
|
||||
ncp_init_request_s(conn, 54);
|
||||
ncp_add_dword_hl(conn, object_id);
|
||||
if ((error = ncp_request(connid, 23, conn)) != 0)
|
||||
return error;
|
||||
target->object_id = ncp_reply_dword_hl(conn, 0);
|
||||
target->object_type = ncp_reply_word_hl(conn, 4);
|
||||
memcpy(target->object_name, ncp_reply_data(conn, 6), 48);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
ncp_change_obj_passwd(NWCONN_HANDLE connid,
|
||||
const struct ncp_bindery_object *object,
|
||||
const u_char *key,
|
||||
const u_char *oldpasswd,
|
||||
const u_char *newpasswd)
|
||||
{
|
||||
long id = htonl(object->object_id);
|
||||
u_char cryptkey[8];
|
||||
u_char newpwd[16]; /* new passwd as stored by server */
|
||||
u_char oldpwd[16]; /* old passwd as stored by server */
|
||||
u_char len;
|
||||
DECLARE_RQ;
|
||||
|
||||
memcpy(cryptkey, key, 8);
|
||||
nw_keyhash((u_char *)&id, oldpasswd, strlen(oldpasswd), oldpwd);
|
||||
nw_keyhash((u_char *)&id, newpasswd, strlen(newpasswd), newpwd);
|
||||
nw_encrypt(cryptkey, oldpwd, cryptkey);
|
||||
nw_passencrypt(oldpwd, newpwd, newpwd);
|
||||
nw_passencrypt(oldpwd + 8, newpwd + 8, newpwd + 8);
|
||||
if ((len = strlen(newpasswd)) > 63) {
|
||||
len = 63;
|
||||
}
|
||||
len = ((len ^ oldpwd[0] ^ oldpwd[1]) & 0x7f) | 0x40;
|
||||
|
||||
ncp_init_request_s(conn, 75);
|
||||
ncp_add_mem(conn, cryptkey, 8);
|
||||
ncp_add_word_hl(conn, object->object_type);
|
||||
ncp_add_pstring(conn, object->object_name);
|
||||
ncp_add_byte(conn, len);
|
||||
ncp_add_mem(conn, newpwd, 16);
|
||||
return ncp_request(connid, 23, conn);
|
||||
}
|
||||
|
||||
/*
|
||||
* target is a 8-byte buffer
|
||||
*/
|
||||
int
|
||||
ncp_get_encryption_key(NWCONN_HANDLE cH, char *target) {
|
||||
int error;
|
||||
DECLARE_RQ;
|
||||
|
||||
ncp_init_request_s(conn, 23);
|
||||
|
||||
error = ncp_request(cH, 23, conn);
|
||||
if (error)
|
||||
return error;
|
||||
if (conn->rpsize < 8)
|
||||
return EACCES;
|
||||
memcpy(target, ncp_reply_data(conn, 0), 8);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
ncp_keyed_verify_password(NWCONN_HANDLE cH, char *key, char *passwd,
|
||||
struct ncp_bindery_object *objinfo)
|
||||
{
|
||||
u_long id = htonl(objinfo->object_id);
|
||||
u_char cryptkey[8];
|
||||
u_char buf[128];
|
||||
DECLARE_RQ;
|
||||
|
||||
nw_keyhash((u_char *)&id, passwd, strlen(passwd), buf);
|
||||
nw_encrypt(key, buf, cryptkey);
|
||||
|
||||
ncp_init_request_s(conn, 74);
|
||||
ncp_add_mem(conn, cryptkey, sizeof(cryptkey));
|
||||
ncp_add_word_hl(conn, objinfo->object_type);
|
||||
ncp_add_pstring(conn, objinfo->object_name);
|
||||
|
||||
return ncp_request(cH, 23, conn);
|
||||
}
|
||||
|
||||
static char passkeys[256 + 16] = {
|
||||
0x0f, 0x08, 0x05, 0x07, 0x0c, 0x02, 0x0e, 0x09,
|
||||
0x00, 0x01, 0x06, 0x0d, 0x03, 0x04, 0x0b, 0x0a,
|
||||
0x02, 0x0c, 0x0e, 0x06, 0x0f, 0x00, 0x01, 0x08,
|
||||
0x0d, 0x03, 0x0a, 0x04, 0x09, 0x0b, 0x05, 0x07,
|
||||
0x05, 0x02, 0x09, 0x0f, 0x0c, 0x04, 0x0d, 0x00,
|
||||
0x0e, 0x0a, 0x06, 0x08, 0x0b, 0x01, 0x03, 0x07,
|
||||
0x0f, 0x0d, 0x02, 0x06, 0x07, 0x08, 0x05, 0x09,
|
||||
0x00, 0x04, 0x0c, 0x03, 0x01, 0x0a, 0x0b, 0x0e,
|
||||
0x05, 0x0e, 0x02, 0x0b, 0x0d, 0x0a, 0x07, 0x00,
|
||||
0x08, 0x06, 0x04, 0x01, 0x0f, 0x0c, 0x03, 0x09,
|
||||
0x08, 0x02, 0x0f, 0x0a, 0x05, 0x09, 0x06, 0x0c,
|
||||
0x00, 0x0b, 0x01, 0x0d, 0x07, 0x03, 0x04, 0x0e,
|
||||
0x0e, 0x08, 0x00, 0x09, 0x04, 0x0b, 0x02, 0x07,
|
||||
0x0c, 0x03, 0x0a, 0x05, 0x0d, 0x01, 0x06, 0x0f,
|
||||
0x01, 0x04, 0x08, 0x0a, 0x0d, 0x0b, 0x07, 0x0e,
|
||||
0x05, 0x0f, 0x03, 0x09, 0x00, 0x02, 0x06, 0x0c,
|
||||
0x05, 0x03, 0x0c, 0x08, 0x0b, 0x02, 0x0e, 0x0a,
|
||||
0x04, 0x01, 0x0d, 0x00, 0x06, 0x07, 0x0f, 0x09,
|
||||
0x06, 0x00, 0x0b, 0x0e, 0x0d, 0x04, 0x0c, 0x0f,
|
||||
0x07, 0x02, 0x08, 0x0a, 0x01, 0x05, 0x03, 0x09,
|
||||
0x0b, 0x05, 0x0a, 0x0e, 0x0f, 0x01, 0x0c, 0x00,
|
||||
0x06, 0x04, 0x02, 0x09, 0x03, 0x0d, 0x07, 0x08,
|
||||
0x07, 0x02, 0x0a, 0x00, 0x0e, 0x08, 0x0f, 0x04,
|
||||
0x0c, 0x0b, 0x09, 0x01, 0x05, 0x0d, 0x03, 0x06,
|
||||
0x07, 0x04, 0x0f, 0x09, 0x05, 0x01, 0x0c, 0x0b,
|
||||
0x00, 0x03, 0x08, 0x0e, 0x02, 0x0a, 0x06, 0x0d,
|
||||
0x09, 0x04, 0x08, 0x00, 0x0a, 0x03, 0x01, 0x0c,
|
||||
0x05, 0x0f, 0x07, 0x02, 0x0b, 0x0e, 0x06, 0x0d,
|
||||
0x09, 0x05, 0x04, 0x07, 0x0e, 0x08, 0x03, 0x01,
|
||||
0x0d, 0x0b, 0x0c, 0x02, 0x00, 0x0f, 0x06, 0x0a,
|
||||
0x09, 0x0a, 0x0b, 0x0d, 0x05, 0x03, 0x0f, 0x00,
|
||||
0x01, 0x0c, 0x08, 0x07, 0x06, 0x04, 0x0e, 0x02,
|
||||
0x03, 0x0e, 0x0f, 0x02, 0x0d, 0x0c, 0x04, 0x05,
|
||||
0x09, 0x06, 0x00, 0x01, 0x0b, 0x07, 0x0a, 0x08
|
||||
};
|
||||
|
||||
static void
|
||||
nw_passencrypt(char *old, char *new, char *out)
|
||||
{
|
||||
char *p, v;
|
||||
char copy[8];
|
||||
int i, di, ax;
|
||||
|
||||
#define HIGH(x) (((x) >> 4) & 0xf)
|
||||
#define LOW(x) ((x) & 0xf)
|
||||
memcpy(copy, new, 8);
|
||||
|
||||
for (i = 0; i < 16; i++) {
|
||||
for (di = 0, ax = 0, p = old; di < 8; di++, ax += 0x20, p++) {
|
||||
v = copy[di] ^ *p;
|
||||
copy[di] = (passkeys[HIGH(v) + ax + 0x10] << 4) |
|
||||
passkeys[LOW(v) + ax];
|
||||
}
|
||||
v = old[7];
|
||||
for (p = old + 7; p > old; p--) {
|
||||
*p = HIGH(p[-1]) | ((*p) << 4);
|
||||
}
|
||||
*old = HIGH(v) | (*old) << 4;
|
||||
bzero(out, 8);
|
||||
|
||||
for (di = 0; di < 16; di++) {
|
||||
v = passkeys[di + 0x100];
|
||||
v = (v & 1) ? HIGH(copy[v / 2]) : LOW(copy[v / 2]);
|
||||
out[di / 2] |= ((di & 1) ? v << 4 : v);
|
||||
}
|
||||
memcpy(copy, out, 8);
|
||||
}
|
||||
}
|
@ -1,511 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 1999, Boris Popov
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the author nor the names of any co-contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
/*
|
||||
*
|
||||
* Current scheme to create/open connection:
|
||||
* 1. ncp_li_init() - lookup -S [-U] options in command line
|
||||
* 2. ncp_li_init() - try to find existing connection
|
||||
* 3. ncp_li_init() - if no server name and no accessible connections - bail out
|
||||
* 4. This is connection candidate, read .rc file, override with command line
|
||||
* and go ahead
|
||||
* Note: connection referenced only via ncp_login() call. Although it is
|
||||
* possible to get connection handle in other way, it will be unwise to use
|
||||
* it, since conn can be destroyed at any time.
|
||||
*
|
||||
*/
|
||||
#include <sys/param.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/mount.h>
|
||||
#include <fcntl.h>
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <pwd.h>
|
||||
#include <grp.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <netncp/ncp_lib.h>
|
||||
#include <netncp/ncp_rcfile.h>
|
||||
#include <fs/nwfs/nwfs.h>
|
||||
|
||||
static char *server_name; /* need a better way ! */
|
||||
|
||||
|
||||
|
||||
int
|
||||
ncp_li_setserver(struct ncp_conn_loginfo *li, const char *arg) {
|
||||
if (strlen(arg) >= NCP_BINDERY_NAME_LEN) {
|
||||
ncp_error("server name '%s' too long", 0, arg);
|
||||
return ENAMETOOLONG;
|
||||
}
|
||||
ncp_str_upper(strcpy(li->server, arg));
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
ncp_li_setuser(struct ncp_conn_loginfo *li, char *arg) {
|
||||
if (arg && strlen(arg) >= NCP_BINDERY_NAME_LEN) {
|
||||
ncp_error("user name '%s' too long", 0, arg);
|
||||
return ENAMETOOLONG;
|
||||
}
|
||||
if (li->user)
|
||||
free(li->user);
|
||||
if (arg) {
|
||||
li->user = strdup(arg);
|
||||
if (li->user == NULL)
|
||||
return ENOMEM;
|
||||
ncp_str_upper(li->user);
|
||||
} else
|
||||
li->user = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
ncp_li_setpassword(struct ncp_conn_loginfo *li, const char *passwd) {
|
||||
if (passwd && strlen(passwd) >= 127) {
|
||||
ncp_error("password too long", 0);
|
||||
return ENAMETOOLONG;
|
||||
}
|
||||
if (li->password) {
|
||||
bzero(li->password, strlen(li->password));
|
||||
free(li->password);
|
||||
}
|
||||
if (passwd) {
|
||||
li->password = strdup(passwd);
|
||||
if (li->password == NULL)
|
||||
return ENOMEM;
|
||||
} else
|
||||
li->password = NULL;
|
||||
return 0;
|
||||
}
|
||||
/*
|
||||
* Prescan command line for [-S server] [-U user] arguments
|
||||
* and fill li structure with defaults
|
||||
*/
|
||||
int
|
||||
ncp_li_init(struct ncp_conn_loginfo *li, int argc, char *argv[]) {
|
||||
int opt, error = 0;
|
||||
char *arg;
|
||||
|
||||
bzero(li,sizeof(*li));
|
||||
li->timeout = 15; /* these values should be large enough to handle */
|
||||
li->retry_count = 4; /* slow servers, even on ethernet */
|
||||
li->access_mode = 0;
|
||||
li->password = NULL;
|
||||
li->sig_level = 1;
|
||||
li->objtype = NCP_BINDERY_USER;
|
||||
li->owner = NCP_DEFAULT_OWNER;
|
||||
li->group = NCP_DEFAULT_GROUP;
|
||||
server_name = NULL;
|
||||
if (argv == NULL) return 0;
|
||||
while (error == 0 && (opt = ncp_getopt(argc, argv, ":S:U:")) != -1) {
|
||||
arg = ncp_optarg;
|
||||
switch (opt) {
|
||||
case 'S':
|
||||
error = ncp_li_setserver(li, arg);
|
||||
break;
|
||||
case 'U':
|
||||
error = ncp_li_setuser(li, arg);
|
||||
break;
|
||||
}
|
||||
}
|
||||
ncp_optind = ncp_optreset = 1;
|
||||
return error;
|
||||
}
|
||||
|
||||
void
|
||||
ncp_li_done(struct ncp_conn_loginfo *li) {
|
||||
if (li->user)
|
||||
free(li->user);
|
||||
if (li->password)
|
||||
free(li->password);
|
||||
}
|
||||
|
||||
/*
|
||||
* Lookup existing connection based on li structure, if connection
|
||||
* found, it will be referenced. Otherwise full login sequence performed.
|
||||
*/
|
||||
int
|
||||
ncp_li_login(struct ncp_conn_loginfo *li, int *aconnid) {
|
||||
int connHandle, error;
|
||||
|
||||
if ((error = ncp_conn_scan(li, &connHandle)) == 0) {
|
||||
*aconnid = connHandle;
|
||||
return 0;
|
||||
}
|
||||
error = ncp_connect(li, &connHandle);
|
||||
if (error) return errno;
|
||||
error = ncp_login(connHandle, li->user, li->objtype, li->password);
|
||||
if (error) {
|
||||
ncp_disconnect(connHandle);
|
||||
} else
|
||||
*aconnid = connHandle;
|
||||
return error;
|
||||
}
|
||||
|
||||
/*
|
||||
* read rc file as follows:
|
||||
* 1. read [server] section
|
||||
* 2. override with [server:user] section
|
||||
* Since abcence of rcfile is not a bug, silently ignore that fact.
|
||||
* rcfile never closed to reduce number of open/close operations.
|
||||
*/
|
||||
int
|
||||
ncp_li_readrc(struct ncp_conn_loginfo *li) {
|
||||
int i, val, error;
|
||||
char uname[NCP_BINDERY_NAME_LEN*2+1];
|
||||
char *sect = NULL, *p;
|
||||
|
||||
/*
|
||||
* if info from cmd line incomplete, try to find existing
|
||||
* connection and fill server/user from it.
|
||||
*/
|
||||
if (li->server[0] == 0 || li->user == NULL) {
|
||||
int connHandle;
|
||||
struct ncp_conn_stat cs;
|
||||
|
||||
if ((error = ncp_conn_scan(li, &connHandle)) != 0) {
|
||||
ncp_error("no default connection found", errno);
|
||||
return error;
|
||||
}
|
||||
ncp_conn_getinfo(connHandle, &cs);
|
||||
ncp_li_setserver(li, cs.li.server);
|
||||
ncp_li_setuser(li, cs.user);
|
||||
ncp_li_setpassword(li, "");
|
||||
ncp_disconnect(connHandle);
|
||||
}
|
||||
if (ncp_open_rcfile()) return 0;
|
||||
|
||||
for (i = 0; i < 2; i++) {
|
||||
switch (i) {
|
||||
case 0:
|
||||
sect = li->server;
|
||||
break;
|
||||
case 1:
|
||||
strcat(strcat(strcpy(uname,li->server),":"),li->user ? li->user : "default");
|
||||
sect = uname;
|
||||
break;
|
||||
}
|
||||
rc_getstringptr(ncp_rc, sect, "password", &p);
|
||||
if (p)
|
||||
ncp_li_setpassword(li, p);
|
||||
rc_getint(ncp_rc,sect, "timeout", &li->timeout);
|
||||
rc_getint(ncp_rc,sect, "retry_count", &li->retry_count);
|
||||
rc_getint(ncp_rc,sect, "sig_level", &li->sig_level);
|
||||
if (rc_getint(ncp_rc,sect,"access_mode",&val) == 0)
|
||||
li->access_mode = val;
|
||||
if(rc_getbool(ncp_rc,sect,"bindery",&val) == 0 && val) {
|
||||
li->opt |= NCP_OPT_BIND;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* check for all uncompleted fields
|
||||
*/
|
||||
int
|
||||
ncp_li_check(struct ncp_conn_loginfo *li) {
|
||||
int error = 0;
|
||||
char *p;
|
||||
|
||||
do {
|
||||
if (li->server[0] == 0) {
|
||||
ncp_error("no server name specified", 0);
|
||||
error = 1;
|
||||
break;
|
||||
}
|
||||
error = ncp_find_fileserver(li,
|
||||
(server_name==NULL) ? AF_IPX : AF_INET, server_name);
|
||||
if (error) {
|
||||
ncp_error("can't find server %s", error, li->server);
|
||||
break;
|
||||
}
|
||||
if (li->user == NULL || li->user[0] == 0) {
|
||||
ncp_error("no user name specified for server %s",
|
||||
0, li->server);
|
||||
error = 1;
|
||||
break;
|
||||
}
|
||||
if (li->password == NULL) {
|
||||
p = getpass("Netware password:");
|
||||
error = ncp_li_setpassword(li, p) ? 1 : 0;
|
||||
}
|
||||
} while (0);
|
||||
return error;
|
||||
}
|
||||
|
||||
int
|
||||
ncp_conn_cnt(void) {
|
||||
int error, cnt = 0;
|
||||
size_t len = sizeof(cnt);
|
||||
|
||||
error = sysctlbyname("net.ncp.conn_cnt", &cnt, &len, NULL, 0);
|
||||
if (error) cnt = 0;
|
||||
return cnt;
|
||||
}
|
||||
|
||||
/*
|
||||
* Find an existing connection and reference it
|
||||
*/
|
||||
int
|
||||
ncp_conn_find(char *server,char *user) {
|
||||
struct ncp_conn_args ca;
|
||||
int connid, error;
|
||||
|
||||
if (server == NULL && user == NULL) {
|
||||
error = ncp_conn_scan(NULL,&connid);
|
||||
if (error) return -2;
|
||||
return connid;
|
||||
}
|
||||
if (server == NULL)
|
||||
return -2;
|
||||
ncp_str_upper(server);
|
||||
if (user) ncp_str_upper(user);
|
||||
bzero(&ca, sizeof(ca));
|
||||
ncp_li_setserver(&ca, server);
|
||||
ncp_li_setuser(&ca, user);
|
||||
error = ncp_conn_scan(&ca,&connid);
|
||||
if (error)
|
||||
connid = -1;
|
||||
return connid;
|
||||
}
|
||||
|
||||
int
|
||||
ncp_li_arg(struct ncp_conn_loginfo *li, int opt, char *arg) {
|
||||
int error = 0, sig_level;
|
||||
char *p, *cp;
|
||||
struct group *gr;
|
||||
struct passwd *pw;
|
||||
|
||||
switch(opt) {
|
||||
case 'S': /* we already fill server/[user] pair */
|
||||
case 'U':
|
||||
break;
|
||||
case 'A':
|
||||
server_name = arg;
|
||||
break;
|
||||
case 'B':
|
||||
li->opt |= NCP_OPT_BIND;
|
||||
break;
|
||||
case 'C':
|
||||
li->opt |= NCP_OPT_NOUPCASEPASS;
|
||||
break;
|
||||
case 'I':
|
||||
sig_level = atoi(arg);
|
||||
if (sig_level < 0 || sig_level > 3) {
|
||||
ncp_error("invalid NCP signature level option `%s'\
|
||||
(must be a number between 0 and 3)", 0, arg);
|
||||
error = 1;
|
||||
}
|
||||
li->sig_level = sig_level;
|
||||
if (sig_level > 1) li->opt |= NCP_OPT_SIGN;
|
||||
break;
|
||||
case 'M':
|
||||
li->access_mode = strtol(arg, NULL, 8);
|
||||
break;
|
||||
case 'N':
|
||||
ncp_li_setpassword(li, "");
|
||||
break;
|
||||
case 'O':
|
||||
p = strdup(arg);
|
||||
cp = strchr(p, ':');
|
||||
if (cp) {
|
||||
*cp++ = '\0';
|
||||
if (*cp) {
|
||||
gr = getgrnam(cp);
|
||||
if (gr) {
|
||||
li->group = gr->gr_gid;
|
||||
} else
|
||||
ncp_error("invalid group name %s, ignored",
|
||||
0, cp);
|
||||
}
|
||||
}
|
||||
if (*p) {
|
||||
pw = getpwnam(p);
|
||||
if (pw) {
|
||||
li->owner = pw->pw_uid;
|
||||
} else
|
||||
ncp_error("invalid user name %s, ignored", 0, p);
|
||||
}
|
||||
endpwent();
|
||||
free(p);
|
||||
break;
|
||||
case 'P':
|
||||
li->opt |= NCP_OPT_PERMANENT;
|
||||
break;
|
||||
case 'R':
|
||||
li->retry_count = atoi(arg);
|
||||
break;
|
||||
case 'W':
|
||||
li->timeout = atoi(arg);
|
||||
break;
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
void *
|
||||
ncp_conn_list(void) {
|
||||
int error, cnt = 0;
|
||||
size_t len;
|
||||
void *p;
|
||||
|
||||
cnt = ncp_conn_cnt();
|
||||
if (cnt == 0) return NULL;
|
||||
len = cnt*(sizeof(struct ncp_conn_stat))+sizeof(int);
|
||||
p = malloc(len);
|
||||
if (p == NULL) return NULL;
|
||||
error = sysctlbyname("net.ncp.conn_stat", p, &len, NULL, 0);
|
||||
if (error) {
|
||||
free(p);
|
||||
p = NULL;
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
ncp_conn_setflags(int connid, u_int16_t mask, u_int16_t flags) {
|
||||
int error;
|
||||
DECLARE_RQ;
|
||||
|
||||
ncp_init_request(conn);
|
||||
ncp_add_byte(conn, NCP_CONN_SETFLAGS);
|
||||
ncp_add_word_lh(conn, mask);
|
||||
ncp_add_word_lh(conn, flags);
|
||||
if ((error = ncp_conn_request(connid, conn)) < 0)
|
||||
return -1;
|
||||
return error;
|
||||
}
|
||||
|
||||
int
|
||||
ncp_login(int connHandle, const char *user, int objtype, const char *password) {
|
||||
int error;
|
||||
struct ncp_conn_login *p;
|
||||
DECLARE_RQ;
|
||||
|
||||
ncp_init_request(conn);
|
||||
ncp_add_byte(conn, NCP_CONN_LOGIN);
|
||||
p = (struct ncp_conn_login *)&conn->packet[conn->rqsize];
|
||||
p->username = (char *)user;
|
||||
p->objtype = objtype;
|
||||
p->password = (char *)password;
|
||||
conn->rqsize += sizeof(*p);
|
||||
if ((error = ncp_conn_request(connHandle, conn)) < 0)
|
||||
return -1;
|
||||
return error;
|
||||
}
|
||||
|
||||
int
|
||||
ncp_connect_addr(struct sockaddr *sa, NWCONN_HANDLE *chp) {
|
||||
int error;
|
||||
struct ncp_conn_args li;
|
||||
|
||||
bzero(&li, sizeof(li));
|
||||
bcopy(sa, &li.addr, sa->sa_len);
|
||||
/*
|
||||
* XXX Temporary !!!. server will be filled in kernel !!!
|
||||
*/
|
||||
strcpy(li.server,ipx_ntoa(li.ipxaddr.sipx_addr));
|
||||
error = ncp_connect(&li, chp);
|
||||
return error;
|
||||
}
|
||||
|
||||
int
|
||||
ncp_conn_getinfo(int connHandle, struct ncp_conn_stat *ps) {
|
||||
int error;
|
||||
DECLARE_RQ;
|
||||
|
||||
ncp_init_request(conn);
|
||||
ncp_add_byte(conn, NCP_CONN_GETINFO);
|
||||
if ((error = ncp_conn_request(connHandle, conn)) < 0)
|
||||
return -1;
|
||||
memcpy(ps, ncp_reply_data(conn,0), sizeof(*ps));
|
||||
return error;
|
||||
}
|
||||
|
||||
int
|
||||
ncp_conn_getuser(int connHandle, char **user) {
|
||||
int error;
|
||||
DECLARE_RQ;
|
||||
|
||||
ncp_init_request(conn);
|
||||
ncp_add_byte(conn, NCP_CONN_GETUSER);
|
||||
if ((error = ncp_conn_request(connHandle, conn)) < 0)
|
||||
return -1;
|
||||
*user = strdup(ncp_reply_data(conn,0));
|
||||
return error;
|
||||
}
|
||||
|
||||
int
|
||||
ncp_conn2ref(int connHandle, int *connRef) {
|
||||
int error;
|
||||
DECLARE_RQ;
|
||||
|
||||
ncp_init_request(conn);
|
||||
ncp_add_byte(conn, NCP_CONN_CONN2REF);
|
||||
if ((error = ncp_conn_request(connHandle, conn)) < 0)
|
||||
return -1;
|
||||
*connRef = *((int*)ncp_reply_data(conn,0));
|
||||
return error;
|
||||
}
|
||||
|
||||
int
|
||||
ncp_path2conn(char *path, int *connHandle) {
|
||||
struct statfs st;
|
||||
int d, error;
|
||||
|
||||
if ((error = statfs(path, &st)) != 0) return errno;
|
||||
if (strcmp(st.f_fstypename,"nwfs") != 0) return EINVAL;
|
||||
if ((d = open(path, O_RDONLY)) < 0) return errno;
|
||||
if ((error = ioctl(d,NWFSIOC_GETCONN, connHandle)) != 0) return errno;
|
||||
close(d);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
ncp_conn_dup(NWCONN_HANDLE org, NWCONN_HANDLE *res) {
|
||||
int error;
|
||||
DECLARE_RQ;
|
||||
|
||||
ncp_init_request(conn);
|
||||
ncp_add_byte(conn, NCP_CONN_DUP);
|
||||
if ((error = ncp_conn_request(org, conn)) < 0)
|
||||
return errno;
|
||||
*res = *((int*)ncp_reply_data(conn, 0));
|
||||
return 0;
|
||||
}
|
@ -1,139 +0,0 @@
|
||||
/*
|
||||
* Routines in this file based on the work of Volker Lendecke,
|
||||
* Adapted for ncplib by Boris Popov
|
||||
* Please note that ncpl_crypt.c file should be indentical to this one
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/errno.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <string.h>
|
||||
|
||||
/*$*********************************************************
|
||||
$*
|
||||
$* This code has been taken from DDJ 11/93, from an
|
||||
$* article by Pawel Szczerbina.
|
||||
$*
|
||||
$* Password encryption routines follow.
|
||||
$* Converted to C from Barry Nance's Pascal
|
||||
$* prog published in the March -93 issue of Byte.
|
||||
$*
|
||||
$* Adapted to be useable for ncpfs by
|
||||
$* Volker Lendecke <lendecke@namu01.gwdg.de> in
|
||||
$* October 1995.
|
||||
$*
|
||||
$********************************************************* */
|
||||
|
||||
|
||||
|
||||
typedef unsigned char buf32[32];
|
||||
|
||||
static unsigned char encrypttable[256] = {
|
||||
0x7, 0x8, 0x0, 0x8, 0x6, 0x4, 0xE, 0x4, 0x5, 0xC, 0x1, 0x7, 0xB, 0xF, 0xA, 0x8,
|
||||
0xF, 0x8, 0xC, 0xC, 0x9, 0x4, 0x1, 0xE, 0x4, 0x6, 0x2, 0x4, 0x0, 0xA, 0xB, 0x9,
|
||||
0x2, 0xF, 0xB, 0x1, 0xD, 0x2, 0x1, 0x9, 0x5, 0xE, 0x7, 0x0, 0x0, 0x2, 0x6, 0x6,
|
||||
0x0, 0x7, 0x3, 0x8, 0x2, 0x9, 0x3, 0xF, 0x7, 0xF, 0xC, 0xF, 0x6, 0x4, 0xA, 0x0,
|
||||
0x2, 0x3, 0xA, 0xB, 0xD, 0x8, 0x3, 0xA, 0x1, 0x7, 0xC, 0xF, 0x1, 0x8, 0x9, 0xD,
|
||||
0x9, 0x1, 0x9, 0x4, 0xE, 0x4, 0xC, 0x5, 0x5, 0xC, 0x8, 0xB, 0x2, 0x3, 0x9, 0xE,
|
||||
0x7, 0x7, 0x6, 0x9, 0xE, 0xF, 0xC, 0x8, 0xD, 0x1, 0xA, 0x6, 0xE, 0xD, 0x0, 0x7,
|
||||
0x7, 0xA, 0x0, 0x1, 0xF, 0x5, 0x4, 0xB, 0x7, 0xB, 0xE, 0xC, 0x9, 0x5, 0xD, 0x1,
|
||||
0xB, 0xD, 0x1, 0x3, 0x5, 0xD, 0xE, 0x6, 0x3, 0x0, 0xB, 0xB, 0xF, 0x3, 0x6, 0x4,
|
||||
0x9, 0xD, 0xA, 0x3, 0x1, 0x4, 0x9, 0x4, 0x8, 0x3, 0xB, 0xE, 0x5, 0x0, 0x5, 0x2,
|
||||
0xC, 0xB, 0xD, 0x5, 0xD, 0x5, 0xD, 0x2, 0xD, 0x9, 0xA, 0xC, 0xA, 0x0, 0xB, 0x3,
|
||||
0x5, 0x3, 0x6, 0x9, 0x5, 0x1, 0xE, 0xE, 0x0, 0xE, 0x8, 0x2, 0xD, 0x2, 0x2, 0x0,
|
||||
0x4, 0xF, 0x8, 0x5, 0x9, 0x6, 0x8, 0x6, 0xB, 0xA, 0xB, 0xF, 0x0, 0x7, 0x2, 0x8,
|
||||
0xC, 0x7, 0x3, 0xA, 0x1, 0x4, 0x2, 0x5, 0xF, 0x7, 0xA, 0xC, 0xE, 0x5, 0x9, 0x3,
|
||||
0xE, 0x7, 0x1, 0x2, 0xE, 0x1, 0xF, 0x4, 0xA, 0x6, 0xC, 0x6, 0xF, 0x4, 0x3, 0x0,
|
||||
0xC, 0x0, 0x3, 0x6, 0xF, 0x8, 0x7, 0xB, 0x2, 0xD, 0xC, 0x6, 0xA, 0xA, 0x8, 0xD
|
||||
};
|
||||
|
||||
static buf32 encryptkeys = {
|
||||
0x48, 0x93, 0x46, 0x67, 0x98, 0x3D, 0xE6, 0x8D,
|
||||
0xB7, 0x10, 0x7A, 0x26, 0x5A, 0xB9, 0xB1, 0x35,
|
||||
0x6B, 0x0F, 0xD5, 0x70, 0xAE, 0xFB, 0xAD, 0x11,
|
||||
0xF4, 0x47, 0xDC, 0xA7, 0xEC, 0xCF, 0x50, 0xC0
|
||||
};
|
||||
|
||||
/*
|
||||
* Create table-based 16-bytes hash from a 32-bytes array
|
||||
*/
|
||||
static void
|
||||
nw_hash(buf32 temp, unsigned char *target) {
|
||||
short sum;
|
||||
unsigned char b3;
|
||||
int s, b2, i;
|
||||
|
||||
sum = 0;
|
||||
|
||||
for (b2 = 0; b2 <= 1; ++b2) {
|
||||
for (s = 0; s <= 31; ++s) {
|
||||
b3 = (temp[s] + sum) ^ (temp[(s + sum) & 31] - encryptkeys[s]);
|
||||
sum += b3;
|
||||
temp[s] = b3;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i <= 15; ++i) {
|
||||
target[i] = encrypttable[temp[2 * i]]
|
||||
| (encrypttable[temp[2 * i + 1]] << 4);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Create a 16-bytes pattern from given buffer based on a four bytes key
|
||||
*/
|
||||
void
|
||||
nw_keyhash(const u_char *key, const u_char *buf, int buflen, u_char *target) {
|
||||
int b2, d, s;
|
||||
buf32 temp;
|
||||
|
||||
while (buflen > 0 && buf[buflen - 1] == 0)
|
||||
buflen--;
|
||||
|
||||
bzero(temp, sizeof(temp));
|
||||
|
||||
d = 0;
|
||||
while (buflen >= 32) {
|
||||
for (s = 0; s <= 31; ++s)
|
||||
temp[s] ^= buf[d++];
|
||||
buflen -= 32;
|
||||
}
|
||||
b2 = d;
|
||||
if (buflen > 0) {
|
||||
for (s = 0; s <= 31; ++s) {
|
||||
if (d + buflen == b2) {
|
||||
temp[s] ^= encryptkeys[s];
|
||||
b2 = d;
|
||||
} else
|
||||
temp[s] ^= buf[b2++];
|
||||
}
|
||||
}
|
||||
for (s = 0; s <= 31; ++s)
|
||||
temp[s] ^= key[s & 3];
|
||||
|
||||
nw_hash(temp, target);
|
||||
}
|
||||
|
||||
/*
|
||||
* Create an 8-bytes pattern from an 8-bytes key and 16-bytes of data
|
||||
*/
|
||||
void
|
||||
nw_encrypt(const u_char *fra, const u_char *buf, u_char *target) {
|
||||
buf32 k;
|
||||
int s;
|
||||
|
||||
nw_keyhash(fra, buf, 16, k);
|
||||
nw_keyhash(fra + 4, buf, 16, k + 16);
|
||||
|
||||
for (s = 0; s < 16; s++)
|
||||
k[s] ^= k[31 - s];
|
||||
|
||||
for (s = 0; s < 8; s++)
|
||||
*target++ = k[s] ^ k[15 - s];
|
||||
}
|
||||
|
||||
|
@ -1,263 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 1999, Boris Popov
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the author nor the names of any co-contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <netncp/ncp_lib.h>
|
||||
#include <netncp/ncp_file.h>
|
||||
#include <fs/nwfs/nwfs.h>
|
||||
|
||||
int
|
||||
ncp_read(NWCONN_HANDLE connid, ncp_fh *fh, off_t offset, size_t count, char *target) {
|
||||
int result;
|
||||
struct ncp_rw rwrq;
|
||||
DECLARE_RQ;
|
||||
|
||||
ncp_init_request(conn);
|
||||
ncp_add_byte(conn, NCP_CONN_READ);
|
||||
rwrq.nrw_fh = *fh;
|
||||
rwrq.nrw_base = target;
|
||||
rwrq.nrw_cnt = count;
|
||||
rwrq.nrw_offset = offset;
|
||||
ncp_add_mem(conn, &rwrq, sizeof(rwrq));
|
||||
if ((result = ncp_conn_request(connid, conn)) < 0)
|
||||
return -1;
|
||||
return result;
|
||||
}
|
||||
|
||||
int
|
||||
ncp_write(NWCONN_HANDLE connid, ncp_fh *fh, off_t offset, size_t count, char *source)
|
||||
{
|
||||
int result;
|
||||
struct ncp_rw rwrq;
|
||||
DECLARE_RQ;
|
||||
|
||||
ncp_init_request(conn);
|
||||
ncp_add_byte(conn, NCP_CONN_WRITE);
|
||||
rwrq.nrw_fh = *fh;
|
||||
rwrq.nrw_base = source;
|
||||
rwrq.nrw_cnt = count;
|
||||
rwrq.nrw_offset = offset;
|
||||
ncp_add_mem(conn, &rwrq, sizeof(rwrq));
|
||||
|
||||
if ((result = ncp_conn_request(connid, conn)) < 0)
|
||||
return -1;
|
||||
return result;
|
||||
}
|
||||
|
||||
int
|
||||
ncp_geteinfo(char *path, struct nw_entry_info *fi) {
|
||||
int d, error;
|
||||
|
||||
if ((d = open(path, O_RDONLY)) < 0) return errno;
|
||||
if ((error = ioctl(d, NWFSIOC_GETEINFO, fi)) != 0) return errno;
|
||||
close(d);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
ncp_AllocTempDirHandle(char *path, NWDIR_HANDLE *pdh) {
|
||||
int d;
|
||||
|
||||
if ((d = open(path, O_RDONLY)) < 0) return errno;
|
||||
*pdh = d;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
ncp_DeallocateDirHandle(NWDIR_HANDLE dh) {
|
||||
close(dh);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
ncp_GetNSEntryInfo(NWDIR_HANDLE dh, struct nw_entry_info *fi, int *ns) {
|
||||
int error;
|
||||
|
||||
if ((error = ioctl(dh, NWFSIOC_GETEINFO, fi)) != 0) return errno;
|
||||
if ((error = ioctl(dh, NWFSIOC_GETNS, ns)) != 0) return errno;
|
||||
return 0;
|
||||
}
|
||||
|
||||
NWCCODE
|
||||
ncp_ScanForDeletedFiles(NWCONN_HANDLE cH, pnuint32 iterHandle,
|
||||
pnuint32 volNum, pnuint32 dirBase, nuint8 ns,
|
||||
NWDELETED_INFO *entryInfo)
|
||||
{
|
||||
int error;
|
||||
struct nw_entry_info *pfi;
|
||||
DECLARE_RQ;
|
||||
#define UNITEDT(d,t) (((d) << 16) | (t))
|
||||
|
||||
bzero(entryInfo, sizeof(NWDELETED_INFO));
|
||||
ncp_init_request(conn);
|
||||
ncp_add_byte(conn, 16);
|
||||
ncp_add_byte(conn, ns);
|
||||
ncp_add_byte(conn, 0); /* data stream */
|
||||
ncp_add_dword_lh(conn, IM_ALL & ~(IM_SPACE_ALLOCATED | IM_TOTAL_SIZE | IM_EA | IM_DIRECTORY));
|
||||
ncp_add_dword_lh(conn, *iterHandle);
|
||||
|
||||
ncp_add_byte(conn, *volNum);
|
||||
ncp_add_dword_lh(conn, *dirBase);
|
||||
ncp_add_byte(conn, NCP_HF_DIRBASE); /* dirBase */
|
||||
ncp_add_byte(conn, 0); /* no component */
|
||||
if ((error = ncp_request(cH, 87, conn)) != 0) {
|
||||
return error;
|
||||
}
|
||||
if (conn->rpsize < 0x61) {
|
||||
return EBADRPC; /* EACCES ? */
|
||||
}
|
||||
*iterHandle = entryInfo->sequence = ncp_reply_dword_lh(conn, 0x00);
|
||||
entryInfo->deletedTime = ncp_reply_word_lh(conn, 0x04);
|
||||
entryInfo->deletedDateAndTime = UNITEDT(ncp_reply_word_lh(conn, 0x06), entryInfo->deletedTime);
|
||||
entryInfo->deletorID = ncp_reply_dword_hl(conn, 0x08);
|
||||
*volNum = ncp_reply_dword_lh(conn, 0x0C);
|
||||
*dirBase = ncp_reply_dword_lh(conn, 0x10);
|
||||
entryInfo->parent = ncp_reply_dword_lh(conn, 0x10);
|
||||
pfi = (struct nw_entry_info*) ncp_reply_data(conn, 0x14);
|
||||
entryInfo->nameLength = pfi->nameLen;
|
||||
memcpy(entryInfo->name, pfi->entryName, pfi->nameLen);
|
||||
return error;
|
||||
}
|
||||
|
||||
NWCCODE
|
||||
ncp_PurgeDeletedFile(NWCONN_HANDLE cH, nuint32 iterHandle,
|
||||
nuint32 volNum, nuint32 dirBase, nuint8 ns)
|
||||
{
|
||||
DECLARE_RQ;
|
||||
|
||||
ncp_init_request(conn);
|
||||
ncp_add_byte(conn, 18);
|
||||
ncp_add_byte(conn, ns);
|
||||
ncp_add_byte(conn, 0); /* reserved */
|
||||
ncp_add_dword_lh(conn, iterHandle);
|
||||
ncp_add_dword_lh(conn, volNum);
|
||||
ncp_add_dword_lh(conn, dirBase);
|
||||
return ncp_request(cH, 87, conn);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ncp_extract_entryInfo(char *data, NW_ENTRY_INFO *entry) {
|
||||
u_char l;
|
||||
const int info_struct_size = sizeof(NW_ENTRY_INFO) - 257;
|
||||
|
||||
memcpy(entry, data, info_struct_size);
|
||||
data += info_struct_size;
|
||||
l = *data++;
|
||||
entry->nameLen = l;
|
||||
memcpy(entry->entryName, data, l);
|
||||
entry->entryName[l] = '\0';
|
||||
return;
|
||||
}
|
||||
|
||||
NWCCODE
|
||||
ncp_ScanNSEntryInfo(NWCONN_HANDLE cH,
|
||||
nuint8 namSpc, nuint16 attrs, SEARCH_SEQUENCE *seq,
|
||||
pnstr8 searchPattern, nuint32 retInfoMask, NW_ENTRY_INFO *entryInfo)
|
||||
{
|
||||
int error, l;
|
||||
DECLARE_RQ;
|
||||
|
||||
if (seq->searchDirNumber == -1) {
|
||||
seq->searchDirNumber = 0;
|
||||
ncp_init_request(conn);
|
||||
ncp_add_byte(conn, 2);
|
||||
ncp_add_byte(conn, namSpc);
|
||||
ncp_add_byte(conn, 0);
|
||||
ncp_add_handle_path(conn, seq->volNumber, seq->dirNumber,
|
||||
NCP_HF_DIRBASE, NULL);
|
||||
error = ncp_request(cH, 87, conn);
|
||||
if (error) return error;
|
||||
memcpy(seq, ncp_reply_data(conn, 0), 9);
|
||||
}
|
||||
ncp_init_request(conn);
|
||||
ncp_add_byte(conn, 3);
|
||||
ncp_add_byte(conn, namSpc);
|
||||
ncp_add_byte(conn, 0); /* dataStream */
|
||||
ncp_add_word_lh(conn, attrs); /* SearchAttributes */
|
||||
ncp_add_dword_lh(conn, retInfoMask);
|
||||
ncp_add_mem(conn, seq, sizeof(*seq));
|
||||
l = strlen(searchPattern);
|
||||
ncp_add_byte(conn, l);
|
||||
ncp_add_mem(conn, searchPattern, l);
|
||||
error = ncp_request(cH, 87, conn);
|
||||
if (error) return error;
|
||||
memcpy(seq, ncp_reply_data(conn, 0), sizeof(*seq));
|
||||
ncp_extract_entryInfo(ncp_reply_data(conn, 10), entryInfo);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
ncp_NSEntryInfo(NWCONN_HANDLE cH, nuint8 ns, nuint8 vol, nuint32 dirent,
|
||||
NW_ENTRY_INFO *entryInfo)
|
||||
{
|
||||
DECLARE_RQ;
|
||||
int error;
|
||||
|
||||
ncp_init_request(conn);
|
||||
ncp_add_byte(conn, 6);
|
||||
ncp_add_byte(conn, ns);
|
||||
ncp_add_byte(conn, ns); /* DestNameSpace */
|
||||
ncp_add_word_lh(conn, htons(0xff00)); /* get all */
|
||||
ncp_add_dword_lh(conn, IM_ALL);
|
||||
ncp_add_handle_path(conn, vol, dirent, NCP_HF_DIRBASE, NULL);
|
||||
error = ncp_request(cH, 87, conn);
|
||||
if (error) return error;
|
||||
ncp_extract_entryInfo(ncp_reply_data(conn, 0), entryInfo);
|
||||
return 0;
|
||||
}
|
||||
|
||||
NWCCODE
|
||||
NWGetVolumeName(NWCONN_HANDLE cH, u_char volume, char *name) {
|
||||
int error, len;
|
||||
DECLARE_RQ;
|
||||
|
||||
ncp_init_request_s(conn, 44);
|
||||
ncp_add_byte(conn, volume);
|
||||
error = ncp_request(cH, 22, conn);
|
||||
if (error) return error;
|
||||
len = ncp_reply_byte(conn, 29);
|
||||
if (len == 0)
|
||||
return ENOENT;
|
||||
bcopy(ncp_reply_data(conn, 30), name, len);
|
||||
name[len] = 0;
|
||||
return 0;
|
||||
}
|
@ -1,294 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 1999, Boris Popov
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the author nor the names of any co-contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* calls that don't fit to any other category
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/time.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <strings.h>
|
||||
|
||||
#include <netncp/ncp_lib.h>
|
||||
|
||||
static time_t
|
||||
ncp_nw_to_ctime(struct nw_time_buffer *source) {
|
||||
struct tm u_time;
|
||||
|
||||
bzero(&u_time,sizeof(struct tm));
|
||||
/*
|
||||
* XXX: NW 4.x tracks daylight automatically
|
||||
*/
|
||||
u_time.tm_isdst = -1;
|
||||
u_time.tm_sec = source->second;
|
||||
u_time.tm_min = source->minute;
|
||||
u_time.tm_hour = source->hour;
|
||||
u_time.tm_mday = source->day;
|
||||
u_time.tm_mon = source->month - 1;
|
||||
u_time.tm_year = source->year;
|
||||
|
||||
if (u_time.tm_year < 80) {
|
||||
u_time.tm_year += 100;
|
||||
}
|
||||
return mktime(&u_time);
|
||||
}
|
||||
|
||||
int
|
||||
ncp_get_file_server_information(NWCONN_HANDLE connid,
|
||||
struct ncp_file_server_info *target)
|
||||
{
|
||||
int error;
|
||||
DECLARE_RQ;
|
||||
|
||||
ncp_init_request_s(conn, 17);
|
||||
if ((error = ncp_request(connid, 23, conn)) != 0)
|
||||
return error;
|
||||
memcpy(target, ncp_reply_data(conn, 0), sizeof(*target));
|
||||
target->MaximumServiceConnections
|
||||
= htons(target->MaximumServiceConnections);
|
||||
target->ConnectionsInUse
|
||||
= htons(target->ConnectionsInUse);
|
||||
target->MaxConnectionsEverUsed
|
||||
= htons(target->MaxConnectionsEverUsed);
|
||||
target->NumberMountedVolumes
|
||||
= htons(target->NumberMountedVolumes);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
ncp_get_stations_logged_info(NWCONN_HANDLE connid, u_int32_t connection,
|
||||
struct ncp_bindery_object *target, time_t *login_time)
|
||||
{
|
||||
int error;
|
||||
DECLARE_RQ;
|
||||
|
||||
ncp_init_request_s(conn, 28);
|
||||
ncp_add_dword_lh(conn, connection);
|
||||
|
||||
if ((error = ncp_request(connid, 23, conn)) != 0)
|
||||
return error;
|
||||
bzero(target, sizeof(*target));
|
||||
target->object_id = ncp_reply_dword_hl(conn, 0);
|
||||
target->object_type = ncp_reply_word_hl(conn, 4);
|
||||
memcpy(target->object_name, ncp_reply_data(conn, 6),
|
||||
sizeof(target->object_name));
|
||||
*login_time = ncp_nw_to_ctime((struct nw_time_buffer *)ncp_reply_data(conn, 54));
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
ncp_get_internet_address(NWCONN_HANDLE connid, u_int32_t connection,
|
||||
struct ipx_addr *target, u_int8_t * conn_type)
|
||||
{
|
||||
int error;
|
||||
DECLARE_RQ;
|
||||
|
||||
ncp_init_request_s(conn, 26);
|
||||
ncp_add_dword_lh(conn, connection);
|
||||
error = ncp_request(connid, 23, conn);
|
||||
if (error) return error;
|
||||
bzero(target, sizeof(*target));
|
||||
ipx_netlong(*target) = ncp_reply_dword_lh(conn, 0);
|
||||
memcpy(&(target->x_host), ncp_reply_data(conn, 4), 6);
|
||||
target->x_port = ncp_reply_word_lh(conn, 10);
|
||||
*conn_type = ncp_reply_byte(conn, 12);
|
||||
return 0;
|
||||
}
|
||||
|
||||
NWCCODE
|
||||
NWGetObjectConnectionNumbers(NWCONN_HANDLE connHandle,
|
||||
pnstr8 pObjName, nuint16 objType,
|
||||
pnuint16 pNumConns, pnuint16 pConnHandleList,
|
||||
nuint16 maxConns)
|
||||
{
|
||||
int error, i, n;
|
||||
nuint32 lastconn;
|
||||
DECLARE_RQ;
|
||||
|
||||
lastconn = 0;
|
||||
ncp_init_request_s(conn, 27);
|
||||
ncp_add_dword_lh(conn, lastconn);
|
||||
ncp_add_word_hl(conn, objType);
|
||||
ncp_add_pstring(conn, pObjName);
|
||||
if ((error = ncp_request(connHandle, 23, conn)) != 0) return error;
|
||||
n = min(ncp_reply_byte(conn, 0), maxConns);
|
||||
*pNumConns = n;
|
||||
for (i = 0; i < n ; i++) {
|
||||
*pConnHandleList++ = ncp_reply_dword_lh(conn, i * 4 + 1);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
NWUnpackDateTime(nuint32 dateTime, NW_DATE *sDate, NW_TIME *sTime) {
|
||||
NWUnpackDate(dateTime >> 16, sDate);
|
||||
NWUnpackTime(dateTime & 0xffff, sTime);
|
||||
}
|
||||
|
||||
void
|
||||
NWUnpackDate(nuint16 date, NW_DATE *sDate) {
|
||||
sDate->day = date & 0x1f;
|
||||
sDate->month = (date >> 5) & 0xf;
|
||||
sDate->year = ((date >> 9) & 0x7f) + 1980;
|
||||
}
|
||||
|
||||
void
|
||||
NWUnpackTime(nuint16 time, NW_TIME *sTime) {
|
||||
sTime->seconds = time & 0x1f;
|
||||
sTime->minutes = (time >> 5) & 0x3f;
|
||||
sTime->hours = (time >> 11) & 0x1f;
|
||||
}
|
||||
|
||||
nuint32
|
||||
NWPackDateTime(NW_DATE *sDate, NW_TIME *sTime) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
nuint16
|
||||
NWPackDate(NW_DATE *sDate) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
nuint16
|
||||
NWPackTime(NW_TIME *sTime) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
time_t
|
||||
ncp_UnpackDateTime(nuint32 dateTime) {
|
||||
struct tm u_time;
|
||||
NW_DATE d;
|
||||
NW_TIME t;
|
||||
|
||||
NWUnpackDateTime(dateTime, &d, &t);
|
||||
bzero(&u_time,sizeof(struct tm));
|
||||
u_time.tm_isdst = -1;
|
||||
u_time.tm_sec = t.seconds;
|
||||
u_time.tm_min = t.minutes;
|
||||
u_time.tm_hour = t.hours;
|
||||
u_time.tm_mday = d.day;
|
||||
u_time.tm_mon = d.month - 1;
|
||||
u_time.tm_year = d.year - 1900;
|
||||
|
||||
return mktime(&u_time);
|
||||
}
|
||||
|
||||
int
|
||||
ncp_GetFileServerDateAndTime(NWCONN_HANDLE cH, time_t *target) {
|
||||
int error;
|
||||
DECLARE_RQ;
|
||||
|
||||
ncp_init_request(conn);
|
||||
if ((error = ncp_request(cH, 20, conn)) != 0)
|
||||
return error;
|
||||
*target = ncp_nw_to_ctime((struct nw_time_buffer *) ncp_reply_data(conn, 0));
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
ncp_SetFileServerDateAndTime(NWCONN_HANDLE cH, time_t * source) {
|
||||
int year;
|
||||
struct tm *utime = localtime(source);
|
||||
DECLARE_RQ;
|
||||
|
||||
year = utime->tm_year;
|
||||
if (year > 99) {
|
||||
year -= 100;
|
||||
}
|
||||
ncp_init_request_s(conn, 202);
|
||||
ncp_add_byte(conn, year);
|
||||
ncp_add_byte(conn, utime->tm_mon + 1);
|
||||
ncp_add_byte(conn, utime->tm_mday);
|
||||
ncp_add_byte(conn, utime->tm_hour);
|
||||
ncp_add_byte(conn, utime->tm_min);
|
||||
ncp_add_byte(conn, utime->tm_sec);
|
||||
return ncp_request(cH, 23, conn);
|
||||
}
|
||||
|
||||
NWCCODE
|
||||
NWDownFileServer(NWCONN_HANDLE cH, int force) {
|
||||
DECLARE_RQ;
|
||||
|
||||
ncp_init_request_s(conn, 211);
|
||||
ncp_add_byte(conn, force ? 0 : 0xff);
|
||||
return ncp_request(cH, 23, conn);
|
||||
}
|
||||
|
||||
NWCCODE
|
||||
NWCloseBindery(NWCONN_HANDLE cH) {
|
||||
DECLARE_RQ;
|
||||
|
||||
ncp_init_request_s(conn, 68);
|
||||
return ncp_request(cH, 23, conn);
|
||||
}
|
||||
|
||||
NWCCODE
|
||||
NWOpenBindery(NWCONN_HANDLE cH) {
|
||||
DECLARE_RQ;
|
||||
|
||||
ncp_init_request_s(conn, 69);
|
||||
return ncp_request(cH, 23, conn);
|
||||
}
|
||||
|
||||
NWCCODE
|
||||
NWDisableTTS(NWCONN_HANDLE cH) {
|
||||
DECLARE_RQ;
|
||||
|
||||
ncp_init_request_s(conn, 207);
|
||||
return ncp_request(cH, 23, conn);
|
||||
}
|
||||
|
||||
NWCCODE
|
||||
NWEnableTTS(NWCONN_HANDLE cH) {
|
||||
DECLARE_RQ;
|
||||
|
||||
ncp_init_request_s(conn, 208);
|
||||
return ncp_request(cH, 23, conn);
|
||||
}
|
||||
|
||||
NWCCODE
|
||||
NWDisableFileServerLogin(NWCONN_HANDLE cH) {
|
||||
DECLARE_RQ;
|
||||
|
||||
ncp_init_request_s(conn, 203);
|
||||
return ncp_request(cH, 23, conn);
|
||||
}
|
||||
|
||||
NWCCODE
|
||||
NWEnableFileServerLogin(NWCONN_HANDLE cH) {
|
||||
DECLARE_RQ;
|
||||
|
||||
ncp_init_request_s(conn, 204);
|
||||
return ncp_request(cH, 23, conn);
|
||||
}
|
@ -1,130 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 1999, Boris Popov
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the author nor the names of any co-contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <netncp/ncp_lib.h>
|
||||
#include <netncp/ncp_nls.h>
|
||||
|
||||
NWCCODE
|
||||
NWDisableBroadcasts(NWCONN_HANDLE connHandle) {
|
||||
DECLARE_RQ;
|
||||
|
||||
ncp_init_request_s(conn, 2);
|
||||
return ncp_request(connHandle, 21, conn);
|
||||
}
|
||||
|
||||
NWCCODE
|
||||
NWEnableBroadcasts(NWCONN_HANDLE connHandle) {
|
||||
DECLARE_RQ;
|
||||
|
||||
ncp_init_request_s(conn, 3);
|
||||
return ncp_request(connHandle, 21, conn);
|
||||
}
|
||||
|
||||
NWCCODE
|
||||
NWBroadcastToConsole(NWCONN_HANDLE connHandle, pnstr8 message) {
|
||||
int l, error;
|
||||
DECLARE_RQ;
|
||||
|
||||
l = strlen(message);
|
||||
if (l > 60) return EMSGSIZE;
|
||||
ncp_init_request_s(conn, 9);
|
||||
ncp_add_byte(conn, l);
|
||||
ncp_add_mem_nls(conn, message, l);
|
||||
error = ncp_request(connHandle, 21, conn);
|
||||
return error;
|
||||
}
|
||||
|
||||
NWCCODE
|
||||
NWSendBroadcastMessage(NWCONN_HANDLE connHandle, pnstr8 message,
|
||||
nuint16 connCount, pnuint16 connList, pnuint8 resultList)
|
||||
{
|
||||
int l, i, error;
|
||||
DECLARE_RQ;
|
||||
|
||||
l = strlen(message);
|
||||
if (l > 255) return EMSGSIZE;
|
||||
if (connCount > 350) return EINVAL;
|
||||
|
||||
ncp_init_request_s(conn, 0x0A);
|
||||
ncp_add_word_lh(conn, connCount);
|
||||
for (i = 0; i < connCount; i++)
|
||||
ncp_add_dword_lh(conn, connList[i]);
|
||||
ncp_add_byte(conn, l);
|
||||
ncp_add_mem_nls(conn, message, l);
|
||||
error = ncp_request(connHandle, 0x15, conn);
|
||||
if (!error) {
|
||||
l = ncp_reply_word_lh(conn, 0);
|
||||
for (i = 0; i < l; i++)
|
||||
resultList[i] = ncp_reply_dword_lh(conn, (i)*4 + 2);
|
||||
return 0;
|
||||
}
|
||||
if (error != 0xfb) return error;
|
||||
if (l > 58) return EMSGSIZE;
|
||||
ncp_init_request_s(conn, 0);
|
||||
ncp_add_byte(conn, connCount);
|
||||
for (i = 0; i < connCount; i++)
|
||||
ncp_add_byte(conn, connList[i]);
|
||||
ncp_add_byte(conn, l);
|
||||
ncp_add_mem_nls(conn, message, l);
|
||||
error = ncp_request(connHandle, 0x15, conn);
|
||||
if (error) return error;
|
||||
i = ncp_reply_byte(conn, 0);
|
||||
memcpy(resultList, ncp_reply_data(conn, 1), i);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
NWCCODE
|
||||
NWGetBroadcastMessage(NWCONN_HANDLE connHandle, pnstr8 message) {
|
||||
int i, error;
|
||||
DECLARE_RQ;
|
||||
|
||||
ncp_init_request_s(conn, 0x0B);
|
||||
error = ncp_request(connHandle, 0x15, conn);
|
||||
if (error) {
|
||||
if (error != 0x89fb) return error;
|
||||
ncp_init_request_s(conn, 0x01);
|
||||
if ((error = ncp_request(connHandle, 0x15, conn)) != 0)
|
||||
return error;
|
||||
}
|
||||
i = ncp_reply_byte(conn, 0);
|
||||
if (i == 0) return ENOENT;
|
||||
memcpy(message, ncp_reply_data(conn, 1), i);
|
||||
message[i] = 0;
|
||||
ncp_nls_str_n2u(message, message);
|
||||
return 0;
|
||||
}
|
@ -1,147 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 1999, Boris Popov
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the author nor the names of any co-contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/errno.h>
|
||||
#include <sys/syscall.h>
|
||||
#include <ctype.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netipx/ipx.h>
|
||||
#include <netdb.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "ipxsap.h"
|
||||
#include <netncp/ncp_lib.h>
|
||||
|
||||
static int ncp_find_server_in(struct ncp_conn_loginfo *li, int type, char *server_name);
|
||||
|
||||
static int
|
||||
ncp_find_server_ipx(struct ncp_conn_loginfo *li, int type) {
|
||||
char server[NCP_BINDERY_NAME_LEN + 1];
|
||||
int error;
|
||||
char nearest[NCP_BINDERY_NAME_LEN + 1];
|
||||
struct nw_property prop;
|
||||
struct ipx_addr *n_addr = (struct ipx_addr *) ∝
|
||||
/* struct ncp_conn_loginfo ltmp;*/
|
||||
int connid;
|
||||
|
||||
bzero(server, sizeof(server));
|
||||
bzero(nearest, sizeof(nearest));
|
||||
|
||||
strcpy(server, li->server);
|
||||
ncp_str_upper(server);
|
||||
|
||||
if ((error = sap_find_nearest(type, &li->ipxaddr, nearest)) != 0) {
|
||||
return error;
|
||||
}
|
||||
/* if no server specified return info about nearest */
|
||||
if (!li->server[0]) {
|
||||
strcpy(li->server, nearest);
|
||||
return 0;
|
||||
}
|
||||
/* printf("%s\n",ipx_ntoa(li->ipxaddr.sipx_addr));*/
|
||||
if (strcmp(server, nearest) == 0) {
|
||||
return 0;
|
||||
}
|
||||
/* We have to ask the nearest server for our wanted server */
|
||||
li->opt=0;
|
||||
if ((error = ncp_connect(li, &connid)) != 0) {
|
||||
return error;
|
||||
}
|
||||
if (ncp_read_property_value(connid, type, server, 1, "NET_ADDRESS", &prop) != 0) {
|
||||
ncp_disconnect(connid);
|
||||
return EHOSTUNREACH;
|
||||
}
|
||||
if ((error = ncp_disconnect(connid)) != 0) {
|
||||
return error;
|
||||
}
|
||||
li->ipxaddr.sipx_family = AF_IPX;
|
||||
li->ipxaddr.sipx_addr.x_net = n_addr->x_net;
|
||||
li->ipxaddr.sipx_port = n_addr->x_port;
|
||||
li->ipxaddr.sipx_addr.x_host = n_addr->x_host;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
ncp_find_server_in(struct ncp_conn_loginfo *li, int type, char *server_name) {
|
||||
struct hostent* h;
|
||||
int l;
|
||||
|
||||
h = gethostbyname(server_name);
|
||||
if (!h) {
|
||||
fprintf(stderr, "Get host address `%s': ", server_name);
|
||||
herror(NULL);
|
||||
return 1;
|
||||
}
|
||||
if (h->h_addrtype != AF_INET) {
|
||||
fprintf(stderr, "Get host address `%s': Not AF_INET\n", server_name);
|
||||
return 1;
|
||||
}
|
||||
if (h->h_length != 4) {
|
||||
fprintf(stderr, "Get host address `%s': Bad address length\n", server_name);
|
||||
return 1;
|
||||
}
|
||||
l = sizeof(struct sockaddr_in);
|
||||
bzero(&li->inaddr, l);
|
||||
li->inaddr.sin_len = l;
|
||||
li->inaddr.sin_family = h->h_addrtype;
|
||||
memcpy(&li->inaddr.sin_addr.s_addr, h->h_addr, 4);
|
||||
li->inaddr.sin_port = htons(524); /* ncp */
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
ncp_find_server(struct ncp_conn_loginfo *li, int type, int af, char *name) {
|
||||
int error = EHOSTUNREACH;
|
||||
|
||||
switch(af) {
|
||||
case AF_IPX:
|
||||
error = ncp_find_server_ipx(li, type);
|
||||
break;
|
||||
case AF_INET:
|
||||
if (name)
|
||||
error = ncp_find_server_in(li, type, name);
|
||||
break;
|
||||
default:
|
||||
error = EPROTONOSUPPORT;
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
int
|
||||
ncp_find_fileserver(struct ncp_conn_loginfo *li, int af, char *name) {
|
||||
return ncp_find_server(li, NCP_BINDERY_FSERVER, af, name);
|
||||
}
|
@ -1,423 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 1999-2002, Boris Popov
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the author nor the names of any co-contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
/*
|
||||
* Languages support. Currently is very primitive.
|
||||
*/
|
||||
#include <sys/types.h>
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <locale.h>
|
||||
|
||||
#include <netncp/ncp_lib.h>
|
||||
#include <netncp/ncp_cfg.h>
|
||||
#include <netncp/ncp_nls.h>
|
||||
|
||||
#ifndef NCP_NLS_DEFAULT
|
||||
#define NCP_NLS_DEFAULT NCP_NLS_AS_IS
|
||||
#endif
|
||||
|
||||
/*
|
||||
* TODO: Make all tables dynamically loadable.
|
||||
*/
|
||||
#ifdef NCP_NLS_KOI2CP866
|
||||
/* Russian tables from easy-cyrillic:
|
||||
* Copyright (C) 1993-1994 by Andrey A. Chernov, Moscow, Russia
|
||||
*/
|
||||
static u_int8_t alt2koi8[] = {
|
||||
0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, /* 0x00 */
|
||||
0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f,
|
||||
0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, /* 0x10 */
|
||||
0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f,
|
||||
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, /* 0x20 */
|
||||
0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
|
||||
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, /* 0x30 */
|
||||
0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x5f,
|
||||
0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* 0x40 */
|
||||
0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
|
||||
0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, /* 0x50 */
|
||||
0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
|
||||
0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, /* 0x60 */
|
||||
0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
|
||||
0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, /* 0x70 */
|
||||
0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
|
||||
0xe1, 0xe2, 0xf7, 0xe7, 0xe4, 0xe5, 0xf6, 0xfa,
|
||||
0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, 0xf0,
|
||||
0xf2, 0xf3, 0xf4, 0xf5, 0xe6, 0xe8, 0xe3, 0xfe,
|
||||
0xfb, 0xfd, 0xff, 0xf9, 0xf8, 0xfc, 0xe0, 0xf1,
|
||||
0xc1, 0xc2, 0xd7, 0xc7, 0xc4, 0xc5, 0xd6, 0xda,
|
||||
0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 0xd0,
|
||||
0x90, 0x91, 0x92, 0x81, 0x87, 0xb2, 0xb4, 0xa7,
|
||||
0xa6, 0xb5, 0xa1, 0xa8, 0xae, 0xad, 0xac, 0x83,
|
||||
0x84, 0x89, 0x88, 0x86, 0x80, 0x8a, 0xaf, 0xb0,
|
||||
0xab, 0xa5, 0xbb, 0xb8, 0xb1, 0xa0, 0xbe, 0xb9,
|
||||
0xba, 0xb6, 0xb7, 0xaa, 0xa9, 0xa2, 0xa4, 0xbd,
|
||||
0xbc, 0x85, 0x82, 0x8d, 0x8c, 0x8e, 0x8f, 0x8b,
|
||||
0xd2, 0xd3, 0xd4, 0xd5, 0xc6, 0xc8, 0xc3, 0xde,
|
||||
0xdb, 0xdd, 0xdf, 0xd9, 0xd8, 0xdc, 0xc0, 0xd1,
|
||||
0xb3, 0xa3, 0x99, 0x98, 0x93, 0x9b, 0x9f, 0x97,
|
||||
0x9c, 0x95, 0x9e, 0x96, 0xbf, 0x9d, 0x94, 0x9a
|
||||
};
|
||||
|
||||
static u_int8_t koi82alt[] = {
|
||||
0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, /* 0x00 */
|
||||
0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f,
|
||||
0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, /* 0x10 */
|
||||
0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f,
|
||||
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, /* 0x20 */
|
||||
0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
|
||||
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, /* 0x30 */
|
||||
0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x5f,
|
||||
0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* 0x40 */
|
||||
0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
|
||||
0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, /* 0x50 */
|
||||
0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
|
||||
0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, /* 0x60 */
|
||||
0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
|
||||
0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, /* 0x70 */
|
||||
0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
|
||||
0xc4, 0xb3, 0xda, 0xbf, 0xc0, 0xd9, 0xc3, 0xb4, /* 0x80 */
|
||||
0xc2, 0xc1, 0xc5, 0xdf, 0xdc, 0xdb, 0xdd, 0xde,
|
||||
0xb0, 0xb1, 0xb2, 0xf4, 0xfe, 0xf9, 0xfb, 0xf7,
|
||||
0xf3, 0xf2, 0xff, 0xf5, 0xf8, 0xfd, 0xfa, 0xf6,
|
||||
0xcd, 0xba, 0xd5, 0xf1, 0xd6, 0xc9, 0xb8, 0xb7,
|
||||
0xbb, 0xd4, 0xd3, 0xc8, 0xbe, 0xbd, 0xbc, 0xc6,
|
||||
0xc7, 0xcc, 0xb5, 0xf0, 0xb6, 0xb9, 0xd1, 0xd2,
|
||||
0xcb, 0xcf, 0xd0, 0xca, 0xd8, 0xd7, 0xce, 0xfc,
|
||||
0xee, 0xa0, 0xa1, 0xe6, 0xa4, 0xa5, 0xe4, 0xa3,
|
||||
0xe5, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae,
|
||||
0xaf, 0xef, 0xe0, 0xe1, 0xe2, 0xe3, 0xa6, 0xa2,
|
||||
0xec, 0xeb, 0xa7, 0xe8, 0xed, 0xe9, 0xe7, 0xea,
|
||||
0x9e, 0x80, 0x81, 0x96, 0x84, 0x85, 0x94, 0x83,
|
||||
0x95, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e,
|
||||
0x8f, 0x9f, 0x90, 0x91, 0x92, 0x93, 0x86, 0x82, /* 0xf0 */
|
||||
0x9c, 0x9b, 0x87, 0x98, 0x9d, 0x99, 0x97, 0x9a
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Characters mapping for codepages used in Sweden.
|
||||
*/
|
||||
static u_int8_t se_nw2unix[] = {
|
||||
0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, /* 0x00 */
|
||||
0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f,
|
||||
0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, /* 0x10 */
|
||||
0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f,
|
||||
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, /* 0x20 */
|
||||
0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
|
||||
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, /* 0x30 */
|
||||
0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x5f,
|
||||
0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* 0x40 */
|
||||
0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
|
||||
0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, /* 0x50 */
|
||||
0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
|
||||
0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, /* 0x60 */
|
||||
0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
|
||||
0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, /* 0x70 */
|
||||
0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
|
||||
0xe1, 0xe2, 0xf7, 0xe7, 0xE4, 0xc4, 0xE5, 0xfa, /* 0x80 */
|
||||
0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xC4, 0xC5,
|
||||
0xf2, 0xf3, 0xf4, 0xf5, 0xF6, 0xe8, 0xe3, 0xfe, /* 0x90 */
|
||||
0xfb, 0xD6, 0xff, 0xf9, 0xf8, 0xfc, 0xe0, 0xf1,
|
||||
0xc1, 0xc2, 0xd7, 0xc7, 0xc4, 0xc5, 0xd6, 0xda, /* 0xA0 */
|
||||
0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 0xd0,
|
||||
0x90, 0x91, 0x92, 0x81, 0x87, 0xb2, 0xb4, 0xa7, /* 0xB0 */
|
||||
0xa6, 0xb5, 0xa1, 0xa8, 0xae, 0xad, 0xac, 0x83,
|
||||
0x84, 0x89, 0x88, 0x86, 0x80, 0x8a, 0xaf, 0xb0, /* 0xC0 */
|
||||
0xab, 0xa5, 0xbb, 0xb8, 0xb1, 0xa0, 0xbe, 0xb9,
|
||||
0xba, 0xb6, 0xb7, 0xaa, 0xa9, 0xa2, 0xa4, 0xbd, /* 0xD0 */
|
||||
0xbc, 0x85, 0x82, 0x8d, 0x8c, 0x8e, 0x8f, 0x8b,
|
||||
0xd2, 0xd3, 0xd4, 0xd5, 0xc6, 0xc8, 0xc3, 0xde, /* 0xE0 */
|
||||
0xdb, 0xdd, 0xdf, 0xd9, 0xd8, 0xdc, 0xc0, 0xd1,
|
||||
0xb3, 0xa3, 0x99, 0x98, 0x93, 0x9b, 0x9f, 0x97, /* 0xF0 */
|
||||
0x9c, 0x95, 0x9e, 0x96, 0xbf, 0x9d, 0x94, 0x9a
|
||||
};
|
||||
|
||||
static u_int8_t se_unix2nw[] = {
|
||||
0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, /* 0x00 */
|
||||
0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f,
|
||||
0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, /* 0x10 */
|
||||
0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f,
|
||||
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, /* 0x20 */
|
||||
0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
|
||||
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, /* 0x30 */
|
||||
0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x5f,
|
||||
0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* 0x40 */
|
||||
0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
|
||||
0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, /* 0x50 */
|
||||
0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
|
||||
0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, /* 0x60 */
|
||||
0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
|
||||
0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, /* 0x70 */
|
||||
0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
|
||||
0xc4, 0xb3, 0xda, 0xbf, 0xc0, 0xd9, 0xc3, 0xb4, /* 0x80 */
|
||||
0xc2, 0xc1, 0xc5, 0xdf, 0xdc, 0xdb, 0xdd, 0xde,
|
||||
0xb0, 0xb1, 0xb2, 0xf4, 0xfe, 0xf9, 0xfb, 0xf7, /* 0x90 */
|
||||
0xf3, 0xf2, 0xff, 0xf5, 0xf8, 0xfd, 0xfa, 0xf6,
|
||||
0xcd, 0xba, 0xd5, 0xf1, 0xd6, 0xc9, 0xb8, 0xb7, /* 0xA0 */
|
||||
0xbb, 0xd4, 0xd3, 0xc8, 0xbe, 0xbd, 0xbc, 0xc6,
|
||||
0xc7, 0xcc, 0xb5, 0xf0, 0xb6, 0xb9, 0xd1, 0xd2, /* 0xB0 */
|
||||
0xcb, 0xcf, 0xd0, 0xca, 0xd8, 0xd7, 0xce, 0xfc,
|
||||
0xee, 0xa0, 0xa1, 0xe6, 0x8E, 0x8F, 0xe4, 0xa3, /* 0xC0 */
|
||||
0xe5, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae,
|
||||
0xaf, 0xef, 0xe0, 0xe1, 0xe2, 0xe3, 0x99, 0xa2, /* 0xD0 */
|
||||
0xec, 0xeb, 0xa7, 0xe8, 0xed, 0xe9, 0xe7, 0xea,
|
||||
0x9e, 0x80, 0x81, 0x96, 0x84, 0x86, 0x94, 0x83, /* 0xE0 */
|
||||
0x95, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e,
|
||||
0x8f, 0x9f, 0x90, 0x91, 0x92, 0x93, 0x94, 0x82, /* 0xf0 */
|
||||
0x9c, 0x9b, 0x87, 0x98, 0x9d, 0x99, 0x97, 0x9a
|
||||
};
|
||||
|
||||
/*
|
||||
* Characters mapping for codepages used in Germany.
|
||||
*/
|
||||
static u_int8_t de_nw2unix[] = {
|
||||
0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, /* 0x00 */
|
||||
0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f,
|
||||
0x5f, 0x5f, 0x5f, 0x5f, 0xb6, 0xa7, 0x5f, 0x5f, /* 0x10 */
|
||||
0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f,
|
||||
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, /* 0x20 */
|
||||
0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
|
||||
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, /* 0x30 */
|
||||
0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
|
||||
0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* 0x40 */
|
||||
0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
|
||||
0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, /* 0x50 */
|
||||
0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
|
||||
0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, /* 0x60 */
|
||||
0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
|
||||
0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, /* 0x70 */
|
||||
0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
|
||||
0xc7, 0xfc, 0xe9, 0xe2, 0xe4, 0xe0, 0xe5, 0xe7, /* 0x80 */
|
||||
0xea, 0xeb, 0xe8, 0xef, 0xee, 0xec, 0xc4, 0xc5,
|
||||
0xc9, 0xe6, 0xc6, 0xf4, 0xf6, 0xf2, 0xfb, 0xf9, /* 0x90 */
|
||||
0xff, 0xd6, 0xdc, 0xa2, 0xa3, 0xa5, 0x5f, 0x5f,
|
||||
0xe1, 0xed, 0xf3, 0xfa, 0xf1, 0xd1, 0xaa, 0xba, /* 0xA0 */
|
||||
0xbf, 0x5f, 0xac, 0xbd, 0xbc, 0xa1, 0xab, 0xbb,
|
||||
0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, /* 0xB0 */
|
||||
0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f,
|
||||
0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, /* 0xC0 */
|
||||
0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f,
|
||||
0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, /* 0xD0 */
|
||||
0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f,
|
||||
0x5f, 0xdf, 0x5f, 0x5f, 0x5f, 0x5f, 0xb5, 0x5f, /* 0xE0 */
|
||||
0x5f, 0x5f, 0x5f, 0xf0, 0x5f, 0xf8, 0x5f, 0x5f,
|
||||
0x5f, 0xb1, 0x5f, 0x5f, 0x5f, 0x5f, 0xf7, 0x5f, /* 0xF0 */
|
||||
0xb0, 0x5f, 0xb7, 0x5f, 0x5f, 0xb2, 0x5f, 0xa0
|
||||
};
|
||||
|
||||
static u_int8_t de_unix2nw[] = {
|
||||
0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, /* 0x00 */
|
||||
0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f,
|
||||
0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, /* 0x10 */
|
||||
0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f,
|
||||
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, /* 0x20 */
|
||||
0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
|
||||
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, /* 0x30 */
|
||||
0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
|
||||
0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* 0x40 */
|
||||
0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
|
||||
0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, /* 0x50 */
|
||||
0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
|
||||
0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, /* 0x60 */
|
||||
0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
|
||||
0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, /* 0x70 */
|
||||
0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
|
||||
0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, /* 0x80 */
|
||||
0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f,
|
||||
0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, /* 0x90 */
|
||||
0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f,
|
||||
0xff, 0xad, 0x9b, 0x9c, 0x5f, 0x9d, 0x5f, 0x15, /* 0xA0 */
|
||||
0x5f, 0x5f, 0xa6, 0xae, 0xaa, 0x5f, 0x5f, 0x5f,
|
||||
0xf8, 0xf1, 0xfd, 0x5f, 0x5f, 0xe6, 0x14, 0xfa, /* 0xB0 */
|
||||
0x5f, 0x5f, 0xa7, 0xaf, 0xac, 0xab, 0x5f, 0xa8,
|
||||
0x5f, 0x5f, 0x5f, 0x5f, 0x8e, 0x8f, 0x92, 0x80, /* 0xC0 */
|
||||
0x5f, 0x90, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f,
|
||||
0x5f, 0xa5, 0x5f, 0x5f, 0x5f, 0x5f, 0x99, 0x5f, /* 0xD0 */
|
||||
0x5f, 0x5f, 0x5f, 0x5f, 0x9a, 0x5f, 0x5f, 0xe1,
|
||||
0x85, 0xa0, 0x83, 0x5f, 0x84, 0x86, 0x91, 0x87, /* 0xE0 */
|
||||
0x8a, 0x82, 0x88, 0x89, 0x8d, 0xa1, 0x8c, 0x8b,
|
||||
0xeb, 0xa4, 0x95, 0xa2, 0x93, 0x5f, 0x94, 0xf6, /* 0xF0 */
|
||||
0xed, 0x97, 0xa3, 0x96, 0x81, 0x5f, 0x5f, 0x98
|
||||
};
|
||||
|
||||
|
||||
static u_int8_t def2lower[256];
|
||||
static u_int8_t def2upper[256];
|
||||
|
||||
/*
|
||||
* List of available charsets
|
||||
*/
|
||||
struct ncp_nlsdesc {
|
||||
int scheme;
|
||||
char *name;
|
||||
struct ncp_nlstables nls;
|
||||
};
|
||||
|
||||
static struct ncp_nlsdesc ncp_nlslist[] = {
|
||||
{NCP_NLS_AS_IS, NCP_NLS_AS_IS_NAME,
|
||||
{def2lower, def2upper, NULL, NULL, 0}
|
||||
},
|
||||
#ifdef NCP_NLS_KOI2CP866
|
||||
{NCP_NLS_KOI_866, NCP_NLS_KOI_866_NAME,
|
||||
{def2lower, def2upper, alt2koi8, koi82alt, 0}
|
||||
},
|
||||
#endif
|
||||
{NCP_NLS_SE, NCP_NLS_SE_NAME,
|
||||
{def2lower, def2upper, se_nw2unix, se_unix2nw, 0}
|
||||
},
|
||||
{NCP_NLS_DE, NCP_NLS_DE_NAME,
|
||||
{def2lower, def2upper, de_nw2unix, de_unix2nw, 0}
|
||||
},
|
||||
{0}
|
||||
};
|
||||
|
||||
struct ncp_nlstables ncp_nls;
|
||||
|
||||
int
|
||||
ncp_nls_setlocale(char *name) {
|
||||
int i;
|
||||
|
||||
ncp_nls.to_lower = def2lower;
|
||||
ncp_nls.to_upper = def2upper;
|
||||
if (setlocale(LC_CTYPE, name) == NULL) {
|
||||
fprintf(stderr, "Can't set locale '%s'\n", name);
|
||||
return EINVAL;
|
||||
}
|
||||
for (i = 0; i < 256; i++) {
|
||||
ncp_nls.to_lower[i] = tolower(i);
|
||||
ncp_nls.to_upper[i] = toupper(i);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
ncp_nls_setrecode(int scheme) {
|
||||
struct ncp_nlsdesc *nd;
|
||||
|
||||
if (scheme == 0) {
|
||||
#if NCP_NLS_DEFAULT
|
||||
scheme = NCP_NLS_DEFAULT;
|
||||
#else
|
||||
scheme = NCP_NLS_AS_IS;
|
||||
#endif
|
||||
}
|
||||
for (nd = ncp_nlslist; nd->name; nd++) {
|
||||
if (nd->scheme != scheme) continue;
|
||||
ncp_nls.u2n = nd->nls.u2n;
|
||||
ncp_nls.n2u = nd->nls.n2u;
|
||||
return ncp_nls_setlocale("");
|
||||
}
|
||||
fprintf(stderr, "Character conversion scheme %d was not compiled in\n", scheme);
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
int
|
||||
ncp_nls_setrecodebyname(char *name) {
|
||||
struct ncp_nlsdesc *nd;
|
||||
|
||||
for (nd = ncp_nlslist; nd->name; nd++) {
|
||||
if (strcmp(nd->name, name) != 0) continue;
|
||||
ncp_nls.u2n = nd->nls.u2n;
|
||||
ncp_nls.n2u = nd->nls.n2u;
|
||||
return 0;
|
||||
}
|
||||
fprintf(stderr, "Character conversion scheme %s was not compiled in\n", name);
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
char *
|
||||
ncp_nls_str_n2u(char *dst, const char *src) {
|
||||
char *p;
|
||||
|
||||
if (ncp_nls.n2u == NULL) {
|
||||
return strcpy(dst, src);
|
||||
}
|
||||
p = dst;
|
||||
while (*src)
|
||||
*p++ = ncp_nls.n2u[(u_char)*(src++)];
|
||||
*p = 0;
|
||||
return dst;
|
||||
}
|
||||
|
||||
char *
|
||||
ncp_nls_str_u2n(char *dst, const char *src) {
|
||||
char *p;
|
||||
|
||||
if (ncp_nls.u2n == NULL) {
|
||||
return strcpy(dst, src);
|
||||
}
|
||||
p = dst;
|
||||
while (*src)
|
||||
*p++ = ncp_nls.u2n[(u_char)*(src++)];
|
||||
*p = 0;
|
||||
return dst;
|
||||
}
|
||||
|
||||
char *
|
||||
ncp_nls_mem_n2u(char *dst, const char *src, int size) {
|
||||
char *p;
|
||||
|
||||
if (size == 0) return NULL;
|
||||
if (ncp_nls.n2u == NULL) {
|
||||
return memcpy(dst, src, size);
|
||||
}
|
||||
for(p = dst; size; size--, p++)
|
||||
*p = ncp_nls.n2u[(u_char)*(src++)];
|
||||
return dst;
|
||||
}
|
||||
|
||||
char *
|
||||
ncp_nls_mem_u2n(char *dst, const char *src, int size) {
|
||||
char *p;
|
||||
|
||||
if (size == 0) return NULL;
|
||||
if (ncp_nls.u2n == NULL) {
|
||||
return strcpy(dst, src);
|
||||
}
|
||||
for(p = dst; size; size--, p++)
|
||||
*p = ncp_nls.u2n[(u_char)*(src++)];
|
||||
return dst;
|
||||
}
|
||||
|
||||
char *
|
||||
ncp_str_upper(char *s) {
|
||||
char *p = s;
|
||||
while (*s) {
|
||||
*s = toupper(*s);
|
||||
s++;
|
||||
}
|
||||
return p;
|
||||
}
|
@ -1,222 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 1999, Boris Popov
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the author nor the names of any co-contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* NetWare queue interface
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <netncp/ncp_lib.h>
|
||||
|
||||
int
|
||||
ncp_create_queue_job_and_file(NWCONN_HANDLE connid, u_int32_t queue_id,
|
||||
struct queue_job *job)
|
||||
{
|
||||
int error;
|
||||
DECLARE_RQ;
|
||||
|
||||
ncp_init_request_s(conn, 121);
|
||||
ncp_add_dword_hl(conn, queue_id);
|
||||
ncp_add_mem(conn, &(job->j), sizeof(job->j));
|
||||
|
||||
if ((error = ncp_request(connid, 23, conn)) != 0)
|
||||
return error;
|
||||
memcpy(&(job->j), ncp_reply_data(conn, 0), 78);
|
||||
ConvertToNWfromDWORD(job->j.JobFileHandle, &job->file_handle);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
ncp_close_file_and_start_job(NWCONN_HANDLE connid, u_int32_t queue_id,
|
||||
struct queue_job *job)
|
||||
{
|
||||
int error;
|
||||
DECLARE_RQ;
|
||||
|
||||
ncp_init_request_s(conn, 127);
|
||||
ncp_add_dword_hl(conn, queue_id);
|
||||
ncp_add_dword_lh(conn, job->j.JobNumber);
|
||||
error = ncp_request(connid, 23, conn);
|
||||
return error;
|
||||
}
|
||||
|
||||
int
|
||||
ncp_attach_to_queue(NWCONN_HANDLE connid, u_int32_t queue_id) {
|
||||
int error;
|
||||
DECLARE_RQ;
|
||||
|
||||
ncp_init_request_s(conn, 111);
|
||||
ncp_add_dword_hl(conn, queue_id);
|
||||
error = ncp_request(connid, 23, conn);
|
||||
return error;
|
||||
}
|
||||
|
||||
int
|
||||
ncp_detach_from_queue(NWCONN_HANDLE connid, u_int32_t queue_id) {
|
||||
int error;
|
||||
DECLARE_RQ;
|
||||
|
||||
ncp_init_request_s(conn, 112);
|
||||
ncp_add_dword_hl(conn, queue_id);
|
||||
error= ncp_request(connid, 23, conn);
|
||||
return error;
|
||||
}
|
||||
|
||||
int
|
||||
ncp_service_queue_job(NWCONN_HANDLE connid, u_int32_t queue_id,
|
||||
u_int16_t job_type, struct queue_job *job)
|
||||
{
|
||||
int error;
|
||||
DECLARE_RQ;
|
||||
|
||||
ncp_init_request_s(conn, 124);
|
||||
ncp_add_dword_hl(conn, queue_id);
|
||||
ncp_add_word_hl(conn, job_type);
|
||||
if ((error = ncp_request(connid, 23, conn)) != 0) {
|
||||
return error;
|
||||
}
|
||||
memcpy(&(job->j), ncp_reply_data(conn, 0), 78);
|
||||
ConvertToNWfromDWORD(job->j.JobFileHandle, &job->file_handle);
|
||||
return error;
|
||||
}
|
||||
|
||||
int
|
||||
ncp_finish_servicing_job(NWCONN_HANDLE connid, u_int32_t queue_id,
|
||||
u_int32_t job_number, u_int32_t charge_info)
|
||||
{
|
||||
int error;
|
||||
DECLARE_RQ;
|
||||
|
||||
ncp_init_request_s(conn, 131);
|
||||
ncp_add_dword_hl(conn, queue_id);
|
||||
ncp_add_dword_lh(conn, job_number);
|
||||
ncp_add_dword_hl(conn, charge_info);
|
||||
|
||||
error = ncp_request(connid, 23, conn);
|
||||
return error;
|
||||
}
|
||||
|
||||
int
|
||||
ncp_abort_servicing_job(NWCONN_HANDLE connid, u_int32_t queue_id,
|
||||
u_int32_t job_number)
|
||||
{
|
||||
int error;
|
||||
DECLARE_RQ;
|
||||
|
||||
ncp_init_request_s(conn, 132);
|
||||
ncp_add_dword_hl(conn, queue_id);
|
||||
ncp_add_dword_lh(conn, job_number);
|
||||
error = ncp_request(connid, 23, conn);
|
||||
return error;
|
||||
}
|
||||
|
||||
int
|
||||
ncp_get_queue_length(NWCONN_HANDLE connid, u_int32_t queue_id,
|
||||
u_int32_t *queue_length)
|
||||
{
|
||||
int error;
|
||||
DECLARE_RQ;
|
||||
|
||||
ncp_init_request_s(conn, 125);
|
||||
ncp_add_dword_hl(conn, queue_id);
|
||||
|
||||
if ((error = ncp_request(connid, 23, conn)) != 0)
|
||||
return error;
|
||||
if (conn->rpsize < 12) {
|
||||
ncp_printf("ncp_reply_size %d < 12\n", conn->rpsize);
|
||||
return EINVAL;
|
||||
}
|
||||
if (ncp_reply_dword_hl(conn,0) != queue_id) {
|
||||
printf("Ouch! Server didn't reply with same queue id in ncp_get_queue_length!\n");
|
||||
return EINVAL;
|
||||
}
|
||||
*queue_length = ncp_reply_dword_lh(conn,8);
|
||||
return error;
|
||||
}
|
||||
|
||||
int
|
||||
ncp_get_queue_job_ids(NWCONN_HANDLE connid, u_int32_t queue_id,
|
||||
u_int32_t queue_section, u_int32_t *length1, u_int32_t *length2,
|
||||
u_int32_t ids[])
|
||||
{
|
||||
int error;
|
||||
DECLARE_RQ;
|
||||
|
||||
ncp_init_request_s(conn,129);
|
||||
ncp_add_dword_hl(conn, queue_id);
|
||||
ncp_add_dword_lh(conn, queue_section);
|
||||
|
||||
if ((error = ncp_request(connid, 23, conn)) != 0)
|
||||
return error;
|
||||
if (conn->rpsize < 8) {
|
||||
ncp_printf("ncp_reply_size %d < 8\n", conn->rpsize);
|
||||
return EINVAL;
|
||||
}
|
||||
*length2 = ncp_reply_dword_lh(conn,4);
|
||||
if (conn->rpsize < 8 + 4*(*length2)) {
|
||||
ncp_printf("ncp_reply_size %d < %d\n", conn->rpsize, 8+4*(*length2));
|
||||
return EINVAL;
|
||||
}
|
||||
if (ids) {
|
||||
int count = min(*length1, *length2)*sizeof(u_int32_t);
|
||||
int pos;
|
||||
|
||||
for (pos=0; pos<count; pos+=sizeof(u_int32_t)) {
|
||||
*ids++ = ncp_reply_dword_lh(conn, 8+pos);
|
||||
}
|
||||
}
|
||||
*length1 = ncp_reply_dword_lh(conn,0);
|
||||
return error;
|
||||
}
|
||||
|
||||
int
|
||||
ncp_get_queue_job_info(NWCONN_HANDLE connid, u_int32_t queue_id,
|
||||
u_int32_t job_id, struct nw_queue_job_entry *jobdata)
|
||||
{
|
||||
int error;
|
||||
DECLARE_RQ;
|
||||
|
||||
ncp_init_request_s(conn,122);
|
||||
ncp_add_dword_hl(conn, queue_id);
|
||||
ncp_add_dword_lh(conn, job_id);
|
||||
|
||||
if ((error = ncp_request(connid, 23, conn)) != 0)
|
||||
return error;
|
||||
|
||||
if (conn->rpsize < sizeof(struct nw_queue_job_entry)) {
|
||||
ncp_printf("ncp_reply_size %d < %d\n", conn->rpsize,sizeof(struct nw_queue_job_entry));
|
||||
return EINVAL;
|
||||
}
|
||||
memcpy(jobdata,ncp_reply_data(conn,0), sizeof(struct nw_queue_job_entry));
|
||||
return error;
|
||||
}
|
@ -1,406 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 1999, Boris Popov
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the author nor the names of any co-contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/queue.h>
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <pwd.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <netncp/ncp_lib.h>
|
||||
#include <netncp/ncp_rcfile.h>
|
||||
#include <netncp/ncp_cfg.h>
|
||||
|
||||
#define NWFS_CFG_FILE NCP_PREFIX"/etc/nwfs.conf"
|
||||
|
||||
struct rcfile *ncp_rc = NULL;
|
||||
|
||||
SLIST_HEAD(rcfile_head, rcfile);
|
||||
static struct rcfile_head pf_head = {NULL};
|
||||
|
||||
int rc_merge(char *filename,struct rcfile **rcfile);
|
||||
static struct rcfile* rc_find(char *filename);
|
||||
static struct rcsection *rc_findsect(struct rcfile *rcp, char *sectname);
|
||||
static struct rcsection *rc_addsect(struct rcfile *rcp, char *sectname);
|
||||
static int rc_sect_free(struct rcsection *rsp);
|
||||
static struct rckey *rc_sect_findkey(struct rcsection *rsp, char *keyname);
|
||||
static struct rckey *rc_sect_addkey(struct rcsection *rsp, char *name, char *value);
|
||||
static void rc_key_free(struct rckey *p);
|
||||
static void rc_parse(struct rcfile *rcp);
|
||||
|
||||
|
||||
/*
|
||||
* open rcfile and load its content, if already open - return previous handle
|
||||
*/
|
||||
int
|
||||
rc_open(char *filename,char *mode,struct rcfile **rcfile) {
|
||||
struct rcfile *rcp;
|
||||
FILE *f;
|
||||
|
||||
rcp = rc_find(filename);
|
||||
if( rcp ) {
|
||||
*rcfile = rcp;
|
||||
return 0;
|
||||
}
|
||||
f = fopen (filename, mode);
|
||||
if (f==NULL)
|
||||
return errno;
|
||||
rcp = malloc(sizeof(struct rcfile));
|
||||
if (rcp==NULL) {
|
||||
fclose(f);
|
||||
return ENOMEM;
|
||||
}
|
||||
bzero(rcp, sizeof(struct rcfile));
|
||||
rcp->rf_name = strdup (filename);
|
||||
rcp->rf_f = f;
|
||||
SLIST_INSERT_HEAD(&pf_head, rcp, rf_next);
|
||||
rc_parse(rcp);
|
||||
*rcfile = rcp;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
rc_merge(char *filename,struct rcfile **rcfile) {
|
||||
struct rcfile *rcp = *rcfile;
|
||||
FILE *f, *t;
|
||||
|
||||
if (rcp == NULL) {
|
||||
return rc_open(filename,"r",rcfile);
|
||||
}
|
||||
f = fopen (filename, "r");
|
||||
if (f==NULL)
|
||||
return errno;
|
||||
t = rcp->rf_f;
|
||||
rcp->rf_f = f;
|
||||
rc_parse(rcp);
|
||||
rcp->rf_f = t;
|
||||
fclose(f);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
rc_close(struct rcfile *rcp) {
|
||||
struct rcsection *p,*n;
|
||||
|
||||
fclose(rcp->rf_f);
|
||||
for(p = SLIST_FIRST(&rcp->rf_sect);p;) {
|
||||
n = p;
|
||||
p = SLIST_NEXT(p,rs_next);
|
||||
rc_sect_free(n);
|
||||
}
|
||||
free(rcp->rf_name);
|
||||
SLIST_REMOVE(&pf_head, rcp, rcfile, rf_next);
|
||||
free(rcp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct rcfile*
|
||||
rc_find(char *filename) {
|
||||
struct rcfile *p;
|
||||
|
||||
SLIST_FOREACH(p, &pf_head, rf_next)
|
||||
if (strcmp (filename, p->rf_name)==0)
|
||||
return p;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct rcsection *
|
||||
rc_findsect(struct rcfile *rcp, char *sectname) {
|
||||
struct rcsection *p;
|
||||
|
||||
SLIST_FOREACH(p, &rcp->rf_sect, rs_next)
|
||||
if (strcmp(p->rs_name, sectname)==0)
|
||||
return p;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static struct rcsection *
|
||||
rc_addsect(struct rcfile *rcp, char *sectname) {
|
||||
struct rcsection *p;
|
||||
|
||||
p = rc_findsect(rcp, sectname);
|
||||
if (p) return p;
|
||||
p = malloc(sizeof(*p));
|
||||
if (!p) return NULL;
|
||||
p->rs_name = strdup(sectname);
|
||||
SLIST_INIT(&p->rs_keys);
|
||||
SLIST_INSERT_HEAD(&rcp->rf_sect, p, rs_next);
|
||||
return p;
|
||||
}
|
||||
|
||||
static int
|
||||
rc_sect_free(struct rcsection *rsp) {
|
||||
struct rckey *p,*n;
|
||||
|
||||
for(p = SLIST_FIRST(&rsp->rs_keys);p;) {
|
||||
n = p;
|
||||
p = SLIST_NEXT(p,rk_next);
|
||||
rc_key_free(n);
|
||||
}
|
||||
free(rsp->rs_name);
|
||||
free(rsp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct rckey *
|
||||
rc_sect_findkey(struct rcsection *rsp, char *keyname) {
|
||||
struct rckey *p;
|
||||
|
||||
SLIST_FOREACH(p, &rsp->rs_keys, rk_next)
|
||||
if (strcmp(p->rk_name, keyname)==0)
|
||||
return p;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static struct rckey *
|
||||
rc_sect_addkey(struct rcsection *rsp, char *name, char *value) {
|
||||
struct rckey *p;
|
||||
|
||||
p = rc_sect_findkey(rsp, name);
|
||||
if (p) {
|
||||
free(p->rk_value);
|
||||
} else {
|
||||
p = malloc(sizeof(*p));
|
||||
if (!p) return NULL;
|
||||
SLIST_INSERT_HEAD(&rsp->rs_keys, p, rk_next);
|
||||
p->rk_name = strdup(name);
|
||||
}
|
||||
p->rk_value = value ? strdup(value) : strdup("");
|
||||
return p;
|
||||
}
|
||||
|
||||
void
|
||||
rc_sect_delkey(struct rcsection *rsp, struct rckey *p) {
|
||||
|
||||
SLIST_REMOVE(&rsp->rs_keys,p,rckey,rk_next);
|
||||
rc_key_free(p);
|
||||
return;
|
||||
}
|
||||
|
||||
static void
|
||||
rc_key_free(struct rckey *p){
|
||||
free(p->rk_value);
|
||||
free(p->rk_name);
|
||||
free(p);
|
||||
}
|
||||
|
||||
enum { stNewLine, stHeader, stSkipToEOL, stGetKey, stGetValue};
|
||||
|
||||
static void
|
||||
rc_parse(struct rcfile *rcp) {
|
||||
FILE *f = rcp->rf_f;
|
||||
int state = stNewLine, c;
|
||||
struct rcsection *rsp = NULL;
|
||||
struct rckey *rkp = NULL;
|
||||
char buf[2048];
|
||||
char *next = buf, *last = &buf[sizeof(buf)-1];
|
||||
|
||||
while ((c = getc (f)) != EOF) {
|
||||
if (c == '\r')
|
||||
continue;
|
||||
if (state == stNewLine) {
|
||||
next = buf;
|
||||
if (isspace(c))
|
||||
continue; /* skip leading junk */
|
||||
if (c == '[') {
|
||||
state = stHeader;
|
||||
rsp = NULL;
|
||||
continue;
|
||||
}
|
||||
if (c == '#' || c == ';') {
|
||||
state = stSkipToEOL;
|
||||
} else { /* something meaningfull */
|
||||
state = stGetKey;
|
||||
}
|
||||
}
|
||||
if (state == stSkipToEOL || next == last) {/* ignore long lines */
|
||||
if (c == '\n'){
|
||||
state = stNewLine;
|
||||
next = buf;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (state == stHeader) {
|
||||
if (c == ']') {
|
||||
*next = 0;
|
||||
next = buf;
|
||||
rsp = rc_addsect(rcp, buf);
|
||||
state = stSkipToEOL;
|
||||
} else
|
||||
*next++ = c;
|
||||
continue;
|
||||
}
|
||||
if (state == stGetKey) {
|
||||
if (c == ' ' || c == '\t')/* side effect: 'key name='*/
|
||||
continue; /* become 'keyname=' */
|
||||
if (c == '\n') { /* silently ignore ... */
|
||||
state = stNewLine;
|
||||
continue;
|
||||
}
|
||||
if (c != '=') {
|
||||
*next++ = c;
|
||||
continue;
|
||||
}
|
||||
*next = 0;
|
||||
if (rsp == NULL) {
|
||||
fprintf(stderr, "Key '%s' defined before section\n", buf);
|
||||
state = stSkipToEOL;
|
||||
continue;
|
||||
}
|
||||
rkp = rc_sect_addkey(rsp, buf, NULL);
|
||||
next = buf;
|
||||
state = stGetValue;
|
||||
continue;
|
||||
}
|
||||
/* only stGetValue left */
|
||||
if (state != stGetValue) {
|
||||
fprintf(stderr, "Well, I can't parse file '%s'\n",rcp->rf_name);
|
||||
state = stSkipToEOL;
|
||||
}
|
||||
if (c != '\n') {
|
||||
*next++ = c;
|
||||
continue;
|
||||
}
|
||||
*next = 0;
|
||||
rkp->rk_value = strdup(buf);
|
||||
state = stNewLine;
|
||||
rkp = NULL;
|
||||
} /* while */
|
||||
if (c == EOF && state == stGetValue) {
|
||||
*next = 0;
|
||||
rkp->rk_value = strdup(buf);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
int
|
||||
rc_getstringptr(struct rcfile *rcp,char *section, char *key,char **dest) {
|
||||
struct rcsection *rsp;
|
||||
struct rckey *rkp;
|
||||
|
||||
*dest = NULL;
|
||||
rsp = rc_findsect(rcp, section);
|
||||
if (!rsp) return ENOENT;
|
||||
rkp = rc_sect_findkey(rsp,key);
|
||||
if (!rkp) return ENOENT;
|
||||
*dest = rkp->rk_value;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
rc_getstring(struct rcfile *rcp,char *section, char *key,int maxlen,char *dest) {
|
||||
char *value;
|
||||
int error;
|
||||
|
||||
error = rc_getstringptr(rcp, section, key, &value);
|
||||
if (error) return error;
|
||||
if (strlen(value) >= maxlen) {
|
||||
fprintf(stderr, "line too long for key '%s' in section '%s', max = %d\n",key, section, maxlen);
|
||||
return EINVAL;
|
||||
}
|
||||
strcpy(dest,value);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
rc_getint(struct rcfile *rcp,char *section, char *key,int *value) {
|
||||
struct rcsection *rsp;
|
||||
struct rckey *rkp;
|
||||
|
||||
rsp = rc_findsect(rcp, section);
|
||||
if (!rsp) return ENOENT;
|
||||
rkp = rc_sect_findkey(rsp,key);
|
||||
if (!rkp) return ENOENT;
|
||||
errno = 0;
|
||||
*value = strtol(rkp->rk_value,NULL,0);
|
||||
if (errno) {
|
||||
fprintf(stderr, "invalid int value '%s' for key '%s' in section '%s'\n",rkp->rk_value,key,section);
|
||||
return errno;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* 1,yes,true
|
||||
* 0,no,false
|
||||
*/
|
||||
int
|
||||
rc_getbool(struct rcfile *rcp,char *section, char *key,int *value) {
|
||||
struct rcsection *rsp;
|
||||
struct rckey *rkp;
|
||||
char *p;
|
||||
|
||||
rsp = rc_findsect(rcp, section);
|
||||
if (!rsp) return ENOENT;
|
||||
rkp = rc_sect_findkey(rsp,key);
|
||||
if (!rkp) return ENOENT;
|
||||
p = rkp->rk_value;
|
||||
while (*p && isspace(*p)) p++;
|
||||
if (*p == '0' || strcasecmp(p,"no") == 0 || strcasecmp(p,"false") == 0) {
|
||||
*value = 0;
|
||||
return 0;
|
||||
}
|
||||
if (*p == '1' || strcasecmp(p,"yes") == 0 || strcasecmp(p,"true") == 0) {
|
||||
*value = 1;
|
||||
return 0;
|
||||
}
|
||||
fprintf(stderr, "invalid boolean value '%s' for key '%s' in section '%s' \n",p, key, section);
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
/*
|
||||
* first read ~/.nwfsrc, next try to merge NWFS_CFG_FILE
|
||||
*/
|
||||
int
|
||||
ncp_open_rcfile(void) {
|
||||
char *home, *fn;
|
||||
int error;
|
||||
|
||||
home = getenv("HOME");
|
||||
if (home) {
|
||||
fn = malloc(strlen(home) + 20);
|
||||
sprintf(fn, "%s/.nwfsrc", home);
|
||||
error = rc_open(fn,"r",&ncp_rc);
|
||||
free (fn);
|
||||
}
|
||||
error = rc_merge(NWFS_CFG_FILE, &ncp_rc);
|
||||
if( ncp_rc == NULL ) {
|
||||
printf("Warning: no cfg files found.\n");
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -1,136 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 1999, Boris Popov
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the author nor the names of any co-contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
* NetWare RPCs
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/time.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <netncp/ncp_lib.h>
|
||||
|
||||
struct ncp_rpc_rq {
|
||||
nuint16 len; /* HL */
|
||||
nuint8 subfn;
|
||||
nuint32 reserved[4];
|
||||
nuint8 flags[4];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct ncp_rpc_rp {
|
||||
nuint32 rpccode;
|
||||
nuint32 reserved[4];
|
||||
nuint32 rpcval;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
static NWCCODE
|
||||
ncp_rpc(NWCONN_HANDLE cH, int rpcfn,
|
||||
const nuint8* rpcarg, char* arg1, char *arg2,
|
||||
nuint32* rpcval) {
|
||||
NWCCODE error;
|
||||
NW_FRAGMENT rq[4], rp;
|
||||
struct ncp_rpc_rq rqh;
|
||||
struct ncp_rpc_rp rph;
|
||||
|
||||
rqh.subfn = rpcfn;
|
||||
if (rpcarg)
|
||||
bcopy(rpcarg, rqh.reserved, 4 * 4 + 4);
|
||||
else
|
||||
bzero(rqh.reserved, 4 * 4 + 4);
|
||||
rq[0].fragAddress = (char*)&rqh;
|
||||
rq[0].fragSize = sizeof(rqh);
|
||||
rq[1].fragAddress = arg1;
|
||||
rq[1].fragSize = strlen(arg1) + 1;
|
||||
rq[2].fragAddress = arg2;
|
||||
rq[2].fragSize = arg2 ? (strlen(arg2) + 1) : 0;
|
||||
rqh.len = htons(rq[2].fragSize + rq[1].fragSize + sizeof(rqh) - 2);
|
||||
rp.fragAddress = (char*)&rph;
|
||||
rp.fragSize = sizeof(rph);
|
||||
error = NWRequest(cH, 131, 3, rq, 1, &rp);
|
||||
if (error) return error;
|
||||
if (rp.fragSize < 4) return EBADRPC;
|
||||
error = rph.rpccode;
|
||||
if (error) return error;
|
||||
if (rpcval) {
|
||||
if (rp.fragSize < 24)
|
||||
return EBADRPC;
|
||||
*rpcval = rph.rpcval;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
NWCCODE
|
||||
NWSMLoadNLM(NWCONN_HANDLE cH, pnstr8 cmd) {
|
||||
return ncp_rpc(cH, 1, NULL, cmd, NULL, NULL);
|
||||
}
|
||||
|
||||
NWCCODE
|
||||
NWSMUnloadNLM(NWCONN_HANDLE cH, pnstr8 cmd) {
|
||||
return ncp_rpc(cH, 2, NULL, cmd, NULL, NULL);
|
||||
}
|
||||
|
||||
NWCCODE
|
||||
NWSMMountVolume(NWCONN_HANDLE cH, pnstr8 volName, nuint32* volnum) {
|
||||
return ncp_rpc(cH, 3, NULL, volName, NULL, volnum);
|
||||
}
|
||||
|
||||
NWCCODE
|
||||
NWSMDismountVolumeByName(NWCONN_HANDLE cH, pnstr8 vol) {
|
||||
return ncp_rpc(cH, 4, NULL, vol, NULL, NULL);
|
||||
}
|
||||
|
||||
struct ncp_set_hdr {
|
||||
nuint32 typeFlag; /* 0 - str, 1 - value */
|
||||
nuint32 value;
|
||||
nuint32 pad[20 - 4 - 4];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
NWCCODE
|
||||
NWSMSetDynamicCmdIntValue(NWCONN_HANDLE cH, pnstr8 setCommandName, nuint32 cmdValue) {
|
||||
struct ncp_set_hdr rq;
|
||||
|
||||
memset(&rq, 0, sizeof(rq));
|
||||
rq.typeFlag = 1;
|
||||
rq.value = cmdValue;
|
||||
return ncp_rpc(cH, 6, (char*)&rq, setCommandName, NULL, NULL);
|
||||
}
|
||||
|
||||
NWCCODE
|
||||
NWSMSetDynamicCmdStrValue(NWCONN_HANDLE cH, pnstr8 setCommandName,
|
||||
pnstr8 cmdValue) {
|
||||
return ncp_rpc(cH, 6, NULL, setCommandName, cmdValue, NULL);
|
||||
}
|
||||
|
||||
NWCCODE
|
||||
NWSMExecuteNCFFile(NWCONN_HANDLE cH, pnstr8 NCFFileName) {
|
||||
return ncp_rpc(cH, 7, NULL, NCFFileName, NULL, NULL);
|
||||
}
|
@ -1,490 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 1999, Boris Popov
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the author nor the names of any co-contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/errno.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <unistd.h>
|
||||
#include <ctype.h>
|
||||
#include <fcntl.h>
|
||||
#include <paths.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include <netncp/ncp_lib.h>
|
||||
#include <netncp/ncp_rcfile.h>
|
||||
#include <netncp/ncp_nls.h>
|
||||
/*#include <netncp/ncp_cfg.h>*/
|
||||
#include <netncp/ncpio.h>
|
||||
|
||||
#define _PATH_NCP _PATH_DEV NCP_NAME
|
||||
|
||||
void
|
||||
ncp_add_word_lh(struct ncp_buf *conn, u_int16_t x) {
|
||||
setwle(conn->packet, conn->rqsize, x);
|
||||
conn->rqsize += 2;
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
ncp_add_dword_lh(struct ncp_buf *conn, u_int32_t x) {
|
||||
setdle(conn->packet, conn->rqsize, x);
|
||||
conn->rqsize += 4;
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
ncp_add_word_hl(struct ncp_buf *conn, u_int16_t x){
|
||||
setwbe(conn->packet, conn->rqsize, x);
|
||||
conn->rqsize += 2;
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
ncp_add_dword_hl(struct ncp_buf *conn, u_int32_t x) {
|
||||
setdbe(conn->packet, conn->rqsize, x);
|
||||
conn->rqsize += 4;
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
ncp_add_mem(struct ncp_buf *conn, const void *source, int size) {
|
||||
memcpy(conn->packet+conn->rqsize, source, size);
|
||||
conn->rqsize += size;
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
ncp_add_mem_nls(struct ncp_buf *conn, const void *source, int size) {
|
||||
ncp_nls_mem_u2n(conn->packet+conn->rqsize, source, size);
|
||||
conn->rqsize += size;
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
ncp_add_pstring(struct ncp_buf *conn, const char *s) {
|
||||
int len = strlen(s);
|
||||
if (len > 255) {
|
||||
ncp_printf("ncp_add_pstring: string too long: %s\n", s);
|
||||
len = 255;
|
||||
}
|
||||
ncp_add_byte(conn, len);
|
||||
ncp_add_mem(conn, s, len);
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
ncp_add_handle_path(struct ncp_buf *conn, nuint32 volNumber, nuint32 dirNumber,
|
||||
int handleFlag, const char *path)
|
||||
{
|
||||
ncp_add_byte(conn, volNumber);
|
||||
ncp_add_dword_lh(conn, dirNumber);
|
||||
ncp_add_byte(conn, handleFlag);
|
||||
if (path) {
|
||||
ncp_add_byte(conn, 1); /* 1 component */
|
||||
ncp_add_pstring(conn, path);
|
||||
} else {
|
||||
ncp_add_byte(conn, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ncp_init_request(struct ncp_buf *conn) {
|
||||
conn->rqsize = 0;
|
||||
conn->rpsize = 0;
|
||||
}
|
||||
|
||||
void
|
||||
ncp_init_request_s(struct ncp_buf *conn, int subfn) {
|
||||
ncp_init_request(conn);
|
||||
ncp_add_word_lh(conn, 0);
|
||||
ncp_add_byte(conn, subfn);
|
||||
}
|
||||
|
||||
u_int16_t
|
||||
ncp_reply_word_hl(struct ncp_buf *conn, int offset) {
|
||||
return getwbe(ncp_reply_data(conn, offset), 0);
|
||||
}
|
||||
|
||||
u_int16_t
|
||||
ncp_reply_word_lh(struct ncp_buf *conn, int offset) {
|
||||
return getwle(ncp_reply_data(conn, offset), 0);
|
||||
}
|
||||
|
||||
u_int32_t
|
||||
ncp_reply_dword_hl(struct ncp_buf *conn, int offset) {
|
||||
return getdbe(ncp_reply_data(conn, offset), 0);
|
||||
}
|
||||
|
||||
u_int32_t
|
||||
ncp_reply_dword_lh(struct ncp_buf *conn, int offset) {
|
||||
return getdle(ncp_reply_data(conn, offset), 0);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
ncp_connect(struct ncp_conn_args *li, int *connHandle) {
|
||||
struct ncpioc_connect args;
|
||||
int fd, r;
|
||||
if ((fd = open(_PATH_NCP, O_RDWR)) < 0)
|
||||
return (errno);
|
||||
args.ioc_li = li;
|
||||
args.ioc_connhandle = connHandle;
|
||||
errno = 0;
|
||||
(void)ioctl(fd, NCPIOC_CONNECT, &args);
|
||||
r = errno;
|
||||
close(fd);
|
||||
return (r);
|
||||
}
|
||||
|
||||
int
|
||||
ncp_disconnect(int cH) {
|
||||
DECLARE_RQ;
|
||||
|
||||
ncp_init_request(conn);
|
||||
ncp_add_byte(conn, NCP_CONN_CONNCLOSE);
|
||||
return ncp_conn_request(cH, conn);
|
||||
}
|
||||
|
||||
int
|
||||
ncp_request(int connHandle,int function, struct ncp_buf *ncpbuf){
|
||||
struct ncpioc_request args;
|
||||
int fd, r;
|
||||
if ((fd = open(_PATH_NCP, O_RDWR)) < 0)
|
||||
return (errno);
|
||||
args.ioc_connhandle = connHandle;
|
||||
args.ioc_fn = function;
|
||||
args.ioc_ncpbuf = ncpbuf;
|
||||
errno = 0;
|
||||
(void)ioctl(fd, NCPIOC_REQUEST, &args);
|
||||
r = errno;
|
||||
close(fd);
|
||||
return (r);
|
||||
}
|
||||
|
||||
int
|
||||
ncp_conn_request(int connHandle, struct ncp_buf *ncpbuf){
|
||||
return (ncp_request(connHandle, NCP_CONN, ncpbuf));
|
||||
}
|
||||
|
||||
int
|
||||
ncp_conn_scan(struct ncp_conn_loginfo *li, int *connid) {
|
||||
struct ncpioc_connscan args;
|
||||
int fd, r;
|
||||
if ((fd = open(_PATH_NCP, O_RDWR)) < 0)
|
||||
return (errno);
|
||||
args.ioc_li = li;
|
||||
args.ioc_connhandle = connid;
|
||||
errno = 0;
|
||||
(void)ioctl(fd, NCPIOC_CONNSCAN, &args);
|
||||
r = errno;
|
||||
close(fd);
|
||||
return (r);
|
||||
}
|
||||
|
||||
NWCCODE
|
||||
NWRequest(NWCONN_HANDLE cH, nuint16 fn,
|
||||
nuint16 nrq, NW_FRAGMENT* rq,
|
||||
nuint16 nrp, NW_FRAGMENT* rp)
|
||||
{
|
||||
int error;
|
||||
struct ncp_conn_frag nf;
|
||||
DECLARE_RQ;
|
||||
|
||||
ncp_init_request(conn);
|
||||
ncp_add_byte(conn, NCP_CONN_FRAG);
|
||||
nf.fn = fn;
|
||||
nf.rqfcnt = nrq;
|
||||
nf.rqf = rq;
|
||||
nf.rpf = rp;
|
||||
nf.rpfcnt = nrp;
|
||||
ncp_add_mem(conn, &nf, sizeof(nf));
|
||||
error = ncp_conn_request(cH, conn);
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
ncp_initlib(void){
|
||||
int error;
|
||||
int kv;
|
||||
size_t kvlen = sizeof(kv);
|
||||
static int ncp_initialized;
|
||||
|
||||
if (ncp_initialized)
|
||||
return 0;
|
||||
error = sysctlbyname("net.ncp.version", &kv, &kvlen, NULL, 0);
|
||||
if (error) {
|
||||
if (errno == ENOENT)
|
||||
fprintf(stderr, "Kernel module ncp is not loaded.\n");
|
||||
else
|
||||
fprintf(stderr, "%s: kernel module is old, please recompile it.\n", __func__);
|
||||
return error;
|
||||
}
|
||||
if (NCP_VERSION != kv) {
|
||||
fprintf(stderr, "%s: kernel module version(%d) don't match library(%d).\n", __func__, kv, NCP_VERSION);
|
||||
return EINVAL;
|
||||
}
|
||||
if ((error = ncp_nls_setrecode(0)) != 0) {
|
||||
fprintf(stderr, "%s: can't initialise recode\n", __func__);
|
||||
return error;
|
||||
}
|
||||
if ((error = ncp_nls_setlocale("")) != 0) {
|
||||
fprintf(stderr, "%s: can't initialise locale\n", __func__);
|
||||
return error;
|
||||
}
|
||||
ncp_initialized++;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*/
|
||||
int ncp_opterr = 1, /* if error message should be printed */
|
||||
ncp_optind = 1, /* index into parent argv vector */
|
||||
ncp_optopt, /* character checked for validity */
|
||||
ncp_optreset; /* reset getopt */
|
||||
char *ncp_optarg; /* argument associated with option */
|
||||
|
||||
#define BADCH (int)'?'
|
||||
#define BADARG (int)':'
|
||||
#define EMSG ""
|
||||
|
||||
int
|
||||
ncp_getopt(nargc, nargv, ostr)
|
||||
int nargc;
|
||||
char * const *nargv;
|
||||
const char *ostr;
|
||||
{
|
||||
static char *place = EMSG; /* option letter processing */
|
||||
char *oli; /* option letter list index */
|
||||
int tmpind;
|
||||
|
||||
if (ncp_optreset || !*place) { /* update scanning pointer */
|
||||
ncp_optreset = 0;
|
||||
tmpind = ncp_optind;
|
||||
while (1) {
|
||||
if (tmpind >= nargc) {
|
||||
place = EMSG;
|
||||
return (-1);
|
||||
}
|
||||
if (*(place = nargv[tmpind]) != '-') {
|
||||
tmpind++;
|
||||
continue; /* lookup next option */
|
||||
}
|
||||
if (place[1] && *++place == '-') { /* found "--" */
|
||||
ncp_optind = ++tmpind;
|
||||
place = EMSG;
|
||||
return (-1);
|
||||
}
|
||||
ncp_optind = tmpind;
|
||||
break;
|
||||
}
|
||||
} /* option letter okay? */
|
||||
if ((ncp_optopt = (int)*place++) == (int)':' ||
|
||||
!(oli = strchr(ostr, ncp_optopt))) {
|
||||
/*
|
||||
* if the user didn't specify '-' as an option,
|
||||
* assume it means -1.
|
||||
*/
|
||||
if (ncp_optopt == (int)'-')
|
||||
return (-1);
|
||||
if (!*place)
|
||||
++ncp_optind;
|
||||
if (ncp_opterr && *ostr != ':')
|
||||
(void)fprintf(stderr,
|
||||
"%s: illegal option -- %c\n", _getprogname(), ncp_optopt);
|
||||
return (BADCH);
|
||||
}
|
||||
if (*++oli != ':') { /* don't need argument */
|
||||
ncp_optarg = NULL;
|
||||
if (!*place)
|
||||
++ncp_optind;
|
||||
}
|
||||
else { /* need an argument */
|
||||
if (*place) /* no white space */
|
||||
ncp_optarg = place;
|
||||
else if (nargc <= ++ncp_optind) { /* no arg */
|
||||
place = EMSG;
|
||||
if (*ostr == ':')
|
||||
return (BADARG);
|
||||
if (ncp_opterr)
|
||||
(void)fprintf(stderr,
|
||||
"%s: option requires an argument -- %c\n",
|
||||
_getprogname(), ncp_optopt);
|
||||
return (BADCH);
|
||||
}
|
||||
else /* white space */
|
||||
ncp_optarg = nargv[ncp_optind];
|
||||
place = EMSG;
|
||||
++ncp_optind;
|
||||
}
|
||||
return (ncp_optopt); /* dump back option letter */
|
||||
}
|
||||
/*
|
||||
* misc options parsing routines
|
||||
*/
|
||||
int
|
||||
ncp_args_parserc(struct ncp_args *na, char *sect, ncp_setopt_t *set_callback) {
|
||||
int len, error;
|
||||
|
||||
for (; na->opt; na++) {
|
||||
switch (na->at) {
|
||||
case NCA_STR:
|
||||
if (rc_getstringptr(ncp_rc,sect,na->name,&na->str) == 0) {
|
||||
len = strlen(na->str);
|
||||
if (len > na->ival) {
|
||||
fprintf(stderr,"rc: Argument for option '%c' (%s) too long\n",na->opt,na->name);
|
||||
return EINVAL;
|
||||
}
|
||||
set_callback(na);
|
||||
}
|
||||
break;
|
||||
case NCA_BOOL:
|
||||
error = rc_getbool(ncp_rc,sect,na->name,&na->ival);
|
||||
if (error == ENOENT) break;
|
||||
if (error) return EINVAL;
|
||||
set_callback(na);
|
||||
break;
|
||||
case NCA_INT:
|
||||
if (rc_getint(ncp_rc,sect,na->name,&na->ival) == 0) {
|
||||
if (((na->flag & NAFL_HAVEMIN) &&
|
||||
(na->ival < na->min)) ||
|
||||
((na->flag & NAFL_HAVEMAX) &&
|
||||
(na->ival > na->max))) {
|
||||
fprintf(stderr,"rc: Argument for option '%c' (%s) should be in [%d-%d] range\n",na->opt,na->name,na->min,na->max);
|
||||
return EINVAL;
|
||||
}
|
||||
set_callback(na);
|
||||
};
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
ncp_args_parseopt(struct ncp_args *na, int opt, char *optarg, ncp_setopt_t *set_callback) {
|
||||
int len;
|
||||
|
||||
for (; na->opt; na++) {
|
||||
if (na->opt != opt) continue;
|
||||
switch (na->at) {
|
||||
case NCA_STR:
|
||||
na->str = optarg;
|
||||
if (optarg) {
|
||||
len = strlen(na->str);
|
||||
if (len > na->ival) {
|
||||
fprintf(stderr,"opt: Argument for option '%c' (%s) too long\n",na->opt,na->name);
|
||||
return EINVAL;
|
||||
}
|
||||
set_callback(na);
|
||||
}
|
||||
break;
|
||||
case NCA_BOOL:
|
||||
na->ival = 0;
|
||||
set_callback(na);
|
||||
break;
|
||||
case NCA_INT:
|
||||
errno = 0;
|
||||
na->ival = strtol(optarg, NULL, 0);
|
||||
if (errno) {
|
||||
fprintf(stderr,"opt: Invalid integer value for option '%c' (%s).\n",na->opt,na->name);
|
||||
return EINVAL;
|
||||
}
|
||||
if (((na->flag & NAFL_HAVEMIN) &&
|
||||
(na->ival < na->min)) ||
|
||||
((na->flag & NAFL_HAVEMAX) &&
|
||||
(na->ival > na->max))) {
|
||||
fprintf(stderr,"opt: Argument for option '%c' (%s) should be in [%d-%d] range\n",na->opt,na->name,na->min,na->max);
|
||||
return EINVAL;
|
||||
}
|
||||
set_callback(na);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Print a (descriptive) error message
|
||||
* error values:
|
||||
* 0 - no specific error code available;
|
||||
* -999..-1 - NDS error
|
||||
* 1..32767 - system error
|
||||
* the rest - requester error;
|
||||
*/
|
||||
void
|
||||
ncp_error(const char *fmt, int error, ...) {
|
||||
va_list ap;
|
||||
|
||||
fprintf(stderr, "%s: ", _getprogname());
|
||||
va_start(ap, error);
|
||||
vfprintf(stderr, fmt, ap);
|
||||
va_end(ap);
|
||||
if (error == -1)
|
||||
error = errno;
|
||||
if (error > -1000 && error < 0) {
|
||||
fprintf(stderr, ": dserr = %d\n", error);
|
||||
} else if (error & 0x8000) {
|
||||
fprintf(stderr, ": nwerr = %04x\n", error);
|
||||
} else if (error) {
|
||||
fprintf(stderr, ": syserr = %s\n", strerror(error));
|
||||
} else
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
|
||||
char *
|
||||
ncp_printb(char *dest, int flags, const struct ncp_bitname *bnp) {
|
||||
int first = 1;
|
||||
|
||||
strcpy(dest, "<");
|
||||
for(; bnp->bn_bit; bnp++) {
|
||||
if (flags & bnp->bn_bit) {
|
||||
strcat(dest, bnp->bn_name);
|
||||
first = 0;
|
||||
}
|
||||
if (!first && (flags & bnp[1].bn_bit))
|
||||
strcat(dest, "|");
|
||||
}
|
||||
strcat(dest, ">");
|
||||
return dest;
|
||||
}
|
301
lib/libncp/sap.c
301
lib/libncp/sap.c
@ -1,301 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 1999, Boris Popov
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the author nor the names of any co-contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/time.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netipx/ipx.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include "ipxsap.h"
|
||||
|
||||
/*
|
||||
* TODO: These should go to ipx headers
|
||||
*/
|
||||
#define ipx_set_net(x,y) ((x).x_net.s_net[0] = (y).x_net.s_net[0]); \
|
||||
((x).x_net.s_net[1]=(y).x_net.s_net[1])
|
||||
#define ipx_set_nullnet(x) ((x).x_net.s_net[0]=0); ((x).x_net.s_net[1]=0)
|
||||
#define ipx_set_nullhost(x) ((x).x_host.s_host[0] = 0); \
|
||||
((x).x_host.s_host[1] = 0); ((x).x_host.s_host[2] = 0)
|
||||
#define ipx_set_wildnet(x) ((x).x_net.s_net[0] = 0xFFFF); \
|
||||
((x).x_net.s_net[1]=0xFFFF)
|
||||
#define ipx_set_wildhost(x) ((x).x_host.s_host[0] = 0xFFFF); \
|
||||
((x).x_host.s_host[1] = 0xFFFF); ((x).x_host.s_host[2] = 0xFFFF);
|
||||
|
||||
|
||||
static struct sap_packet* sap_packet_alloc(int entries);
|
||||
static int sap_size(int entries, u_short operation);
|
||||
int (*sap_sendto_func)(void*,int,struct sockaddr_ipx*,int sock)=NULL;
|
||||
|
||||
static int
|
||||
sap_sendto(void* buffer, int size, struct sockaddr_ipx* daddr, int sock)
|
||||
{
|
||||
if (sap_sendto_func)
|
||||
return sap_sendto_func(buffer,size,daddr,sock);
|
||||
return sendto(sock, (char*)buffer, size, 0,
|
||||
(struct sockaddr*)daddr, sizeof(*daddr));
|
||||
}
|
||||
|
||||
static struct sap_packet*
|
||||
sap_packet_alloc(int entries)
|
||||
{
|
||||
if (entries > IPX_SAP_MAX_ENTRIES)
|
||||
return NULL;
|
||||
return
|
||||
(struct sap_packet*)malloc(sap_size(entries, IPX_SAP_GENERAL_RESPONSE));
|
||||
}
|
||||
|
||||
static int
|
||||
sap_size(int entries, u_short operation)
|
||||
{
|
||||
if (entries <= 0)
|
||||
return 0;
|
||||
switch (operation) {
|
||||
case IPX_SAP_GENERAL_QUERY:
|
||||
return entries == 1 ? IPX_SAP_REQUEST_LEN : 0;
|
||||
case IPX_SAP_GENERAL_RESPONSE:
|
||||
if (entries > IPX_SAP_MAX_ENTRIES)
|
||||
return 0;
|
||||
return sizeof(struct sap_packet) + (entries - 1) * sizeof(struct sap_entry);
|
||||
case IPX_SAP_NEAREST_QUERY:
|
||||
return entries == 1 ? IPX_SAP_REQUEST_LEN : 0;
|
||||
case IPX_SAP_NEAREST_RESPONSE:
|
||||
return entries == 1 ? sizeof(struct sap_packet) : 0;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
sap_copyname(char *dest, const char *src)
|
||||
{
|
||||
bzero(dest, IPX_SAP_SERVER_NAME_LEN);
|
||||
strncpy(dest, src, IPX_SAP_SERVER_NAME_LEN - 1);
|
||||
}
|
||||
|
||||
int
|
||||
sap_rq_init(struct sap_rq* rq, int sock)
|
||||
{
|
||||
rq->buffer = sap_packet_alloc(IPX_SAP_MAX_ENTRIES);
|
||||
if (rq->buffer == NULL)
|
||||
return 0;
|
||||
rq->entries = 0;
|
||||
rq->buffer->operation = htons(IPX_SAP_GENERAL_QUERY);
|
||||
rq->dest_addr.sipx_family = AF_IPX;
|
||||
rq->dest_addr.sipx_len = sizeof(struct sockaddr_ipx);
|
||||
rq->sock = sock;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
sap_rq_flush(struct sap_rq* rq)
|
||||
{
|
||||
int result;
|
||||
|
||||
if (rq->entries == 0)
|
||||
return 0;
|
||||
result = sap_sendto(rq->buffer,
|
||||
sap_size(rq->entries, ntohs(rq->buffer->operation)),
|
||||
&rq->dest_addr, rq->sock);
|
||||
rq->entries = 0;
|
||||
return result;
|
||||
}
|
||||
|
||||
void
|
||||
sap_rq_general_query(struct sap_rq* rq, u_short ser_type)
|
||||
{
|
||||
struct sap_entry* sep;
|
||||
|
||||
sap_rq_flush(rq);
|
||||
rq->buffer->operation = htons(IPX_SAP_GENERAL_QUERY);
|
||||
sep = rq->buffer->sap_entries + rq->entries++;
|
||||
sep->server_type = htons(ser_type);
|
||||
}
|
||||
|
||||
void
|
||||
sap_rq_gns_request(struct sap_rq* rq, u_short ser_type)
|
||||
{
|
||||
struct sap_entry* sep;
|
||||
|
||||
sap_rq_flush(rq);
|
||||
rq->buffer->operation = htons(IPX_SAP_NEAREST_QUERY);
|
||||
sep = rq->buffer->sap_entries + rq->entries++;
|
||||
sep->server_type = htons(ser_type);
|
||||
}
|
||||
|
||||
void
|
||||
sap_rq_general_response(struct sap_rq* rq,u_short type,char *name,struct sockaddr_ipx* addr, u_short hops,int down_allow)
|
||||
{
|
||||
struct sap_entry* sep;
|
||||
|
||||
if (hops >= IPX_SAP_SERVER_DOWN && !down_allow) return;
|
||||
if (rq->entries >= IPX_SAP_MAX_ENTRIES)
|
||||
sap_rq_flush(rq);
|
||||
if (rq->buffer->operation != htons(IPX_SAP_GENERAL_RESPONSE)){
|
||||
sap_rq_flush(rq);
|
||||
rq->buffer->operation = htons(IPX_SAP_GENERAL_RESPONSE);
|
||||
}
|
||||
sep = rq->buffer->sap_entries + rq->entries;
|
||||
sep->server_type = htons(type);
|
||||
sap_copyname(sep->server_name, name);
|
||||
memcpy(&sep->ipx, &addr->sipx_addr, sizeof(struct ipx_addr));
|
||||
sep->hops = htons(hops);
|
||||
rq->entries++;
|
||||
}
|
||||
|
||||
void
|
||||
sap_rq_gns_response(struct sap_rq* rq,u_short type,char *name,struct sockaddr_ipx* addr,u_short hops)
|
||||
{
|
||||
struct sap_entry* sep;
|
||||
|
||||
if (hops >= IPX_SAP_SERVER_DOWN) return;
|
||||
sap_rq_flush(rq);
|
||||
rq->buffer->operation = htons(IPX_SAP_NEAREST_RESPONSE);
|
||||
sep = rq->buffer->sap_entries + rq->entries;
|
||||
sep->server_type = htons(type);
|
||||
sap_copyname(sep->server_name, name);
|
||||
memcpy(&sep->ipx, &addr->sipx_addr, sizeof(struct ipx_addr));
|
||||
sep->hops = htons(hops);
|
||||
rq->entries++;
|
||||
}
|
||||
|
||||
void
|
||||
sap_rq_set_destination(struct sap_rq* rq,struct ipx_addr *dest)
|
||||
{
|
||||
sap_rq_flush(rq);
|
||||
memcpy(&rq->dest_addr.sipx_addr,dest,sizeof(struct ipx_addr));
|
||||
}
|
||||
|
||||
int
|
||||
sap_getsock(int *rsock) {
|
||||
struct sockaddr_ipx sap_addr;
|
||||
int opt, sock, slen;
|
||||
|
||||
sock = socket(AF_IPX, SOCK_DGRAM, 0);
|
||||
if (sock < 0)
|
||||
return (errno);
|
||||
slen = sizeof(sap_addr);
|
||||
bzero(&sap_addr, slen);
|
||||
sap_addr.sipx_family = AF_IPX;
|
||||
sap_addr.sipx_len = slen;
|
||||
if (bind(sock, (struct sockaddr*)&sap_addr, slen) == -1) {
|
||||
close(sock);
|
||||
return(errno);
|
||||
}
|
||||
opt = 1;
|
||||
if (setsockopt(sock, SOL_SOCKET, SO_BROADCAST, &opt, sizeof(opt)) != 0){
|
||||
close(sock);
|
||||
return(errno);
|
||||
}
|
||||
*rsock = sock;
|
||||
return(0);
|
||||
}
|
||||
|
||||
static int
|
||||
sap_recv(int sock,void *buf,int len,int flags, int timeout){
|
||||
fd_set rd, wr, ex;
|
||||
struct timeval tv;
|
||||
int result;
|
||||
|
||||
FD_ZERO(&rd);
|
||||
FD_ZERO(&wr);
|
||||
FD_ZERO(&ex);
|
||||
FD_SET(sock, &rd);
|
||||
|
||||
tv.tv_sec = timeout;
|
||||
tv.tv_usec = 0;
|
||||
|
||||
if ((result = select(sock + 1, &rd, &wr, &ex, &tv)) == -1) {
|
||||
return result;
|
||||
}
|
||||
if (FD_ISSET(sock, &rd)) {
|
||||
result = recv(sock, buf, len, flags);
|
||||
} else {
|
||||
errno = ETIMEDOUT;
|
||||
result = -1;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
int
|
||||
sap_find_nearest(int server_type, struct sockaddr_ipx *daddr, char *server_name)
|
||||
{
|
||||
struct ipx_addr addr;
|
||||
char data[1024];
|
||||
int sock, error, packets, len;
|
||||
struct sap_packet *reply = (struct sap_packet*)&data;
|
||||
struct sap_rq sap_rq;
|
||||
|
||||
error = sap_getsock(&sock);
|
||||
if (error)
|
||||
return error;
|
||||
bzero(&addr, sizeof(addr));
|
||||
/* BAD: we should enum all ifs (and nets ?) */
|
||||
if (ipx_iffind(NULL, &addr) != 0) {
|
||||
return (EPROTONOSUPPORT);
|
||||
}
|
||||
ipx_set_wildhost(addr);
|
||||
addr.x_port = htons(IPXPORT_SAP);
|
||||
|
||||
if (!sap_rq_init(&sap_rq, sock)) {
|
||||
close(sock);
|
||||
return(ENOMEM);
|
||||
}
|
||||
sap_rq_set_destination(&sap_rq, &addr);
|
||||
sap_rq_gns_request(&sap_rq, server_type);
|
||||
sap_rq_flush(&sap_rq);
|
||||
packets = 5;
|
||||
do {
|
||||
len = sap_recv(sock, data, sizeof(data), 0, 1);
|
||||
if (len >= 66 &&
|
||||
ntohs(reply->operation) == IPX_SAP_NEAREST_RESPONSE)
|
||||
break;
|
||||
if (len < 0)
|
||||
packets--;
|
||||
} while (packets > 0);
|
||||
|
||||
if (packets == 0) {
|
||||
close(sock);
|
||||
return ENETDOWN;
|
||||
}
|
||||
|
||||
daddr->sipx_addr = reply->sap_entries[0].ipx;
|
||||
daddr->sipx_family = AF_IPX;
|
||||
daddr->sipx_len = sizeof(struct sockaddr_ipx);
|
||||
sap_copyname(server_name, reply->sap_entries[0].server_name);
|
||||
errno = 0;
|
||||
close(sock);
|
||||
return 0;
|
||||
}
|
@ -1,76 +0,0 @@
|
||||
/*-
|
||||
* Copyright (c) 2005-2009 Stanislav Sedov <stas@FreeBSD.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/vnode.h>
|
||||
#define _KERNEL
|
||||
#include <sys/mount.h>
|
||||
#undef _KERNEL
|
||||
|
||||
#include <netinet/in.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <err.h>
|
||||
#include <kvm.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <fs/nwfs/nwfs.h>
|
||||
#include <fs/nwfs/nwfs_node.h>
|
||||
|
||||
#include "libprocstat.h"
|
||||
#include "common_kvm.h"
|
||||
|
||||
int
|
||||
nwfs_filestat(kvm_t *kd, struct vnode *vp, struct vnstat *vn)
|
||||
{
|
||||
struct mount mnt;
|
||||
struct nwnode node;
|
||||
int error;
|
||||
|
||||
assert(kd);
|
||||
assert(vn);
|
||||
error = kvm_read_all(kd, (unsigned long)VTONW(vp), &node, sizeof(node));
|
||||
if (error != 0) {
|
||||
warnx("can't read nwfs fnode at %p", (void *)VTONW(vp));
|
||||
return (1);
|
||||
}
|
||||
error = kvm_read_all(kd, (unsigned long)getvnodemount(vp), &mnt,
|
||||
sizeof(mnt));
|
||||
if (error != 0) {
|
||||
warnx("can't read mount at %p for vnode %p",
|
||||
(void *)getvnodemount(vp), vp);
|
||||
return (1);
|
||||
}
|
||||
vn->vn_fileid = node.n_fid.f_id;
|
||||
if (vn->vn_fileid == 0)
|
||||
vn->vn_fileid = NWFS_ROOT_INO;
|
||||
vn->vn_fsid = mnt.mnt_stat.f_fsid.val[0];
|
||||
return (0);
|
||||
}
|
@ -1,78 +0,0 @@
|
||||
# $FreeBSD$
|
||||
#
|
||||
# Example for .nwfsrc file
|
||||
#
|
||||
# ncplib lookups configuration files in next order:
|
||||
# 1. ~/.nwfsrc
|
||||
# 2. /etc/nwfs.conf - if this file found it will
|
||||
# override values with same keys from user files.
|
||||
#
|
||||
#
|
||||
# This file consist of a set of sections. Each section started by section name
|
||||
# surrounded by square brackets:
|
||||
# [section_name]
|
||||
#
|
||||
# End of the section marked either by new section or by the end of file.
|
||||
# Each section can contain zero or more parameters:
|
||||
# [section_name]
|
||||
# key=value
|
||||
#
|
||||
# where 'key' is a represents parameter name and 'value' a value assigned
|
||||
# to this parameter.
|
||||
#
|
||||
# NetWare library uses next forms of section names:
|
||||
# [SERVER]
|
||||
# [SERVER:USER]
|
||||
# [SERVER:QUEUE]
|
||||
#
|
||||
# When user issues any ncp* command that requires create of new connection
|
||||
# to a NetWare server, library function lookups for parameters in the
|
||||
# corresponding section. First it looks in the [SERVER] section and then in
|
||||
# the [SERVER:USER] section. Please note that server and user names should be
|
||||
# in the upper case.
|
||||
#
|
||||
|
||||
# Following parameters are valid for [SERVER] or [SERVER:USER] section:
|
||||
[BHOME:SUPERVISOR]
|
||||
# if you don't use password leave value empty
|
||||
password=I_DONT_TELL_YOU
|
||||
|
||||
# how many retries before error, default 10
|
||||
retry_count=10
|
||||
|
||||
# timeout for request to complete
|
||||
timeout=5
|
||||
|
||||
# access mode to connection, default 0700
|
||||
access_mode=0700
|
||||
|
||||
# signature level, default 0 - no signatures
|
||||
sig_level=0
|
||||
|
||||
# force bindery login, default no
|
||||
bindery=no
|
||||
|
||||
# default print queue for user, default is none
|
||||
# print_queue=QE_BJ
|
||||
|
||||
|
||||
[ANOTHERSERVER:PLAINUSER]
|
||||
# in this case user have an empty password
|
||||
password=
|
||||
|
||||
# Defaults for printer queues defined as [SERVER:QUEUE]
|
||||
# communication parameters taken from [SERVER:USER] section
|
||||
# see man ncprint(1) for queue parameters description
|
||||
# note: if any banner related option is specified, banner will be printed.
|
||||
[BHOME:QE_BJ]
|
||||
#path_name=/etc
|
||||
#file_name=passwd
|
||||
#banner_name=My Job
|
||||
#job_desc=Printing from FreeBSD
|
||||
|
||||
#lines=66
|
||||
#rows=80
|
||||
copies=1
|
||||
tab_size=8
|
||||
no_form_feed=yes
|
||||
#form_number=0
|
@ -1,34 +0,0 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# $FreeBSD$
|
||||
#
|
||||
# Location: /usr/local/etc/rc.d/nwfs.sh
|
||||
#
|
||||
# Simple script to mount NetWare volumes at startup.
|
||||
# It assumes that all mount points described in fstab file and password
|
||||
# entries listed in /root/.nwfsrc file. See mount_nwfs(8) for details.
|
||||
#
|
||||
|
||||
mount=/sbin/mount
|
||||
umount=/sbin/umount
|
||||
HOME=/root; export HOME
|
||||
vols="/nw/sys /nw/vol1"
|
||||
|
||||
if [ "x$1" = "x" -o "x$1" = "xstart" ]; then
|
||||
echo -n "Mounting NetWare volumes: "
|
||||
for vol in ${vols}; do
|
||||
$mount $vol
|
||||
echo -n "$vol "
|
||||
done
|
||||
echo "Done"
|
||||
elif [ "x$1" = "xstop" ]; then
|
||||
echo -n "Unmounting NetWare mount points: "
|
||||
for vol in ${vols}; do
|
||||
$umount $vol
|
||||
echo -n "$vol "
|
||||
done
|
||||
echo "Done"
|
||||
else
|
||||
echo "Unknown command $1"
|
||||
fi
|
||||
|
@ -1,79 +0,0 @@
|
||||
/*-
|
||||
* Copyright (c) 1999 Boris Popov
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#ifndef _NWFS_H_
|
||||
#define _NWFS_H_
|
||||
|
||||
#include <netncp/ncp.h>
|
||||
#include <fs/nwfs/nwfs_mount.h>
|
||||
|
||||
#define NR_OPEN 0
|
||||
#define NW_NSB_DOS (1 << NW_NS_DOS)
|
||||
#define NW_NSB_MAC (1 << NW_NS_MAC)
|
||||
#define NW_NSB_NFS (1 << NW_NS_NFS)
|
||||
#define NW_NSB_FTAM (1 << NW_NS_FTAM)
|
||||
#define NW_NSB_OS2 (1 << NW_NS_OS2)
|
||||
|
||||
#define NWFSIOC_GETCONN _IOR('n',1,int)
|
||||
#define NWFSIOC_GETEINFO _IOR('n',2,struct nw_entry_info)
|
||||
#define NWFSIOC_GETNS _IOR('n',3,int)
|
||||
|
||||
#ifdef _KERNEL
|
||||
|
||||
#include <sys/vnode.h>
|
||||
#include <sys/mount.h>
|
||||
|
||||
struct nwfsnode;
|
||||
|
||||
struct nwmount {
|
||||
struct nwfs_args m;
|
||||
struct mount *mp;
|
||||
struct ncp_handle *connh;
|
||||
int name_space;
|
||||
struct nwnode *n_root;
|
||||
u_int32_t n_volume;
|
||||
ncpfid n_rootent;
|
||||
int n_id;
|
||||
};
|
||||
|
||||
#define VFSTONWFS(mntp) ((struct nwmount *)((mntp)->mnt_data))
|
||||
#define NWFSTOVFS(mnp) ((struct mount *)((mnp)->mount))
|
||||
#define VTOVFS(vp) ((vp)->v_mount)
|
||||
#define VTONWFS(vp) (VFSTONWFS(VTOVFS(vp)))
|
||||
#define NWFSTOCONN(nmp) ((nmp)->connh->nh_conn)
|
||||
|
||||
int ncp_conn_logged_in(struct nwmount *);
|
||||
int nwfs_ioctl(struct vop_ioctl_args *ap);
|
||||
int nwfs_doio(struct vnode *vp, struct buf *bp, struct ucred *cr, struct thread *td);
|
||||
int nwfs_vinvalbuf(struct vnode *vp, struct thread *td);
|
||||
|
||||
extern struct vop_vector nwfs_vnodeops;
|
||||
|
||||
#endif /* _KERNEL */
|
||||
|
||||
#endif /* _NWFS_H_ */
|
@ -1,599 +0,0 @@
|
||||
/*-
|
||||
* Copyright (c) 1999 Boris Popov
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*
|
||||
*/
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/bio.h>
|
||||
#include <sys/buf.h>
|
||||
#include <sys/mount.h>
|
||||
#include <sys/namei.h>
|
||||
#include <sys/vnode.h>
|
||||
#include <sys/dirent.h>
|
||||
#include <sys/sysctl.h>
|
||||
|
||||
#include <vm/vm.h>
|
||||
#include <vm/vm_param.h>
|
||||
#include <vm/vm_page.h>
|
||||
#include <vm/vm_extern.h>
|
||||
#include <vm/vm_object.h>
|
||||
#include <vm/vm_pager.h>
|
||||
#include <vm/vnode_pager.h>
|
||||
|
||||
#include <netncp/ncp.h>
|
||||
#include <netncp/ncp_conn.h>
|
||||
#include <netncp/ncp_subr.h>
|
||||
#include <netncp/ncp_ncp.h>
|
||||
|
||||
#include <fs/nwfs/nwfs.h>
|
||||
#include <fs/nwfs/nwfs_node.h>
|
||||
#include <fs/nwfs/nwfs_subr.h>
|
||||
|
||||
static int nwfs_fastlookup = 1;
|
||||
|
||||
SYSCTL_DECL(_vfs_nwfs);
|
||||
SYSCTL_INT(_vfs_nwfs, OID_AUTO, fastlookup, CTLFLAG_RW, &nwfs_fastlookup, 0, "");
|
||||
|
||||
|
||||
extern int nwfs_pbuf_freecnt;
|
||||
|
||||
#define DE_SIZE (sizeof(struct dirent))
|
||||
#define NWFS_RWCACHE
|
||||
|
||||
static int
|
||||
nwfs_readvdir(struct vnode *vp, struct uio *uio, struct ucred *cred) {
|
||||
struct nwmount *nmp = VTONWFS(vp);
|
||||
int error, count, i;
|
||||
struct dirent dp;
|
||||
struct nwnode *np = VTONW(vp);
|
||||
struct nw_entry_info fattr;
|
||||
struct vnode *newvp;
|
||||
struct componentname cn;
|
||||
ncpfid fid;
|
||||
|
||||
np = VTONW(vp);
|
||||
NCPVNDEBUG("dirname='%s'\n",np->n_name);
|
||||
if (uio->uio_resid < DE_SIZE || (uio->uio_offset < 0))
|
||||
return (EINVAL);
|
||||
error = 0;
|
||||
count = 0;
|
||||
i = uio->uio_offset / DE_SIZE; /* offset in directory */
|
||||
if (i == 0) {
|
||||
error = ncp_initsearch(vp, uio->uio_td, cred);
|
||||
if (error) {
|
||||
NCPVNDEBUG("cannot initialize search, error=%d",error);
|
||||
return( error );
|
||||
}
|
||||
}
|
||||
|
||||
for (; uio->uio_resid >= DE_SIZE; i++) {
|
||||
bzero((char *) &dp, DE_SIZE);
|
||||
dp.d_reclen = DE_SIZE;
|
||||
switch (i) {
|
||||
case 0: /* `.' */
|
||||
case 1: /* `..' */
|
||||
dp.d_fileno = (i == 0) ? np->n_fid.f_id : np->n_parent.f_id;
|
||||
if (!dp.d_fileno) dp.d_fileno = NWFS_ROOT_INO;
|
||||
dp.d_namlen = i + 1;
|
||||
dp.d_name[0] = '.';
|
||||
dp.d_name[1] = '.';
|
||||
dp.d_name[i + 1] = '\0';
|
||||
dp.d_type = DT_DIR;
|
||||
break;
|
||||
default:
|
||||
error = ncp_search_for_file_or_subdir(nmp, &np->n_seq, &fattr, uio->uio_td, cred);
|
||||
if (error && error < 0x80) break;
|
||||
dp.d_fileno = fattr.dirEntNum;
|
||||
dp.d_type = (fattr.attributes & aDIR) ? DT_DIR : DT_REG;
|
||||
dp.d_namlen = fattr.nameLen;
|
||||
bcopy(fattr.entryName, dp.d_name, dp.d_namlen);
|
||||
dp.d_name[dp.d_namlen] = '\0';
|
||||
#if 0
|
||||
if (error && eofflag) {
|
||||
/* *eofflag = 1;*/
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
if (nwfs_fastlookup && !error && i > 1) {
|
||||
fid.f_id = fattr.dirEntNum;
|
||||
fid.f_parent = np->n_fid.f_id;
|
||||
error = nwfs_nget(vp->v_mount, fid, &fattr, vp, &newvp);
|
||||
if (!error) {
|
||||
VTONW(newvp)->n_ctime = VTONW(newvp)->n_vattr.va_ctime.tv_sec;
|
||||
cn.cn_nameptr = dp.d_name;
|
||||
cn.cn_namelen = dp.d_namlen;
|
||||
cache_enter(vp, newvp, &cn);
|
||||
vput(newvp);
|
||||
} else
|
||||
error = 0;
|
||||
}
|
||||
if (error >= 0x80) {
|
||||
error = 0;
|
||||
break;
|
||||
}
|
||||
if ((error = uiomove(&dp, DE_SIZE, uio)))
|
||||
break;
|
||||
}
|
||||
|
||||
uio->uio_offset = i * DE_SIZE;
|
||||
return (error);
|
||||
}
|
||||
|
||||
int
|
||||
nwfs_readvnode(struct vnode *vp, struct uio *uiop, struct ucred *cred) {
|
||||
struct nwmount *nmp = VFSTONWFS(vp->v_mount);
|
||||
struct nwnode *np = VTONW(vp);
|
||||
struct thread *td;
|
||||
struct vattr vattr;
|
||||
int error, biosize;
|
||||
|
||||
if (vp->v_type != VREG && vp->v_type != VDIR) {
|
||||
printf("%s: vn types other than VREG or VDIR are unsupported !\n",__func__);
|
||||
return EIO;
|
||||
}
|
||||
if (uiop->uio_resid == 0) return 0;
|
||||
if (uiop->uio_offset < 0) return EINVAL;
|
||||
/* if (uiop->uio_offset + uiop->uio_resid > nmp->nm_maxfilesize)
|
||||
return (EFBIG);*/
|
||||
td = uiop->uio_td;
|
||||
if (vp->v_type == VDIR) {
|
||||
error = nwfs_readvdir(vp, uiop, cred);
|
||||
return error;
|
||||
}
|
||||
biosize = NWFSTOCONN(nmp)->buffer_size;
|
||||
if (np->n_flag & NMODIFIED) {
|
||||
nwfs_attr_cacheremove(vp);
|
||||
error = VOP_GETATTR(vp, &vattr, cred);
|
||||
if (error) return (error);
|
||||
np->n_mtime = vattr.va_mtime.tv_sec;
|
||||
} else {
|
||||
error = VOP_GETATTR(vp, &vattr, cred);
|
||||
if (error) return (error);
|
||||
if (np->n_mtime != vattr.va_mtime.tv_sec) {
|
||||
error = nwfs_vinvalbuf(vp, td);
|
||||
if (error) return (error);
|
||||
np->n_mtime = vattr.va_mtime.tv_sec;
|
||||
}
|
||||
}
|
||||
error = ncp_read(NWFSTOCONN(nmp), &np->n_fh, uiop, cred);
|
||||
return (error);
|
||||
}
|
||||
|
||||
int
|
||||
nwfs_writevnode(vp, uiop, cred, ioflag)
|
||||
struct vnode *vp;
|
||||
struct uio *uiop;
|
||||
struct ucred *cred;
|
||||
int ioflag;
|
||||
{
|
||||
struct nwmount *nmp = VTONWFS(vp);
|
||||
struct nwnode *np = VTONW(vp);
|
||||
struct thread *td;
|
||||
/* struct vattr vattr;*/
|
||||
int error = 0;
|
||||
|
||||
if (vp->v_type != VREG) {
|
||||
printf("%s: vn types other than VREG unsupported !\n",__func__);
|
||||
return EIO;
|
||||
}
|
||||
NCPVNDEBUG("ofs=%d,resid=%d\n",(int)uiop->uio_offset, uiop->uio_resid);
|
||||
if (uiop->uio_offset < 0) return EINVAL;
|
||||
/* if (uiop->uio_offset + uiop->uio_resid > nmp->nm_maxfilesize)
|
||||
return (EFBIG);*/
|
||||
td = uiop->uio_td;
|
||||
if (ioflag & (IO_APPEND | IO_SYNC)) {
|
||||
if (np->n_flag & NMODIFIED) {
|
||||
nwfs_attr_cacheremove(vp);
|
||||
error = nwfs_vinvalbuf(vp, td);
|
||||
if (error) return (error);
|
||||
}
|
||||
if (ioflag & IO_APPEND) {
|
||||
/* We can relay only on local information about file size,
|
||||
* because until file is closed NetWare will not return
|
||||
* the correct size. */
|
||||
#ifdef notyet
|
||||
nwfs_attr_cacheremove(vp);
|
||||
error = VOP_GETATTR(vp, &vattr, cred);
|
||||
if (error) return (error);
|
||||
#endif
|
||||
uiop->uio_offset = np->n_size;
|
||||
}
|
||||
}
|
||||
if (uiop->uio_resid == 0) return 0;
|
||||
|
||||
if (vn_rlimit_fsize(vp, uiop, td))
|
||||
return (EFBIG);
|
||||
|
||||
error = ncp_write(NWFSTOCONN(nmp), &np->n_fh, uiop, cred);
|
||||
NCPVNDEBUG("after: ofs=%d,resid=%d\n",(int)uiop->uio_offset, uiop->uio_resid);
|
||||
if (!error) {
|
||||
if (uiop->uio_offset > np->n_size) {
|
||||
np->n_vattr.va_size = np->n_size = uiop->uio_offset;
|
||||
vnode_pager_setsize(vp, np->n_size);
|
||||
}
|
||||
}
|
||||
return (error);
|
||||
}
|
||||
|
||||
/*
|
||||
* Do an I/O operation to/from a cache block.
|
||||
*/
|
||||
int
|
||||
nwfs_doio(vp, bp, cr, td)
|
||||
struct vnode *vp;
|
||||
struct buf *bp;
|
||||
struct ucred *cr;
|
||||
struct thread *td;
|
||||
{
|
||||
struct uio *uiop;
|
||||
struct nwnode *np;
|
||||
struct nwmount *nmp;
|
||||
int error = 0;
|
||||
struct uio uio;
|
||||
struct iovec io;
|
||||
|
||||
np = VTONW(vp);
|
||||
nmp = VFSTONWFS(vp->v_mount);
|
||||
uiop = &uio;
|
||||
uiop->uio_iov = &io;
|
||||
uiop->uio_iovcnt = 1;
|
||||
uiop->uio_segflg = UIO_SYSSPACE;
|
||||
uiop->uio_td = td;
|
||||
if (bp->b_iocmd == BIO_READ) {
|
||||
io.iov_len = uiop->uio_resid = bp->b_bcount;
|
||||
io.iov_base = bp->b_data;
|
||||
uiop->uio_rw = UIO_READ;
|
||||
switch (vp->v_type) {
|
||||
case VREG:
|
||||
uiop->uio_offset = ((off_t)bp->b_blkno) * DEV_BSIZE;
|
||||
error = ncp_read(NWFSTOCONN(nmp), &np->n_fh, uiop, cr);
|
||||
if (error)
|
||||
break;
|
||||
if (uiop->uio_resid) {
|
||||
int left = uiop->uio_resid;
|
||||
int nread = bp->b_bcount - left;
|
||||
if (left > 0)
|
||||
bzero((char *)bp->b_data + nread, left);
|
||||
}
|
||||
break;
|
||||
/* case VDIR:
|
||||
nfsstats.readdir_bios++;
|
||||
uiop->uio_offset = ((u_quad_t)bp->b_lblkno) * NFS_DIRBLKSIZ;
|
||||
if (nmp->nm_flag & NFSMNT_RDIRPLUS) {
|
||||
error = nfs_readdirplusrpc(vp, uiop, cr);
|
||||
if (error == NFSERR_NOTSUPP)
|
||||
nmp->nm_flag &= ~NFSMNT_RDIRPLUS;
|
||||
}
|
||||
if ((nmp->nm_flag & NFSMNT_RDIRPLUS) == 0)
|
||||
error = nfs_readdirrpc(vp, uiop, cr);
|
||||
if (error == 0 && uiop->uio_resid == bp->b_bcount)
|
||||
bp->b_flags |= B_INVAL;
|
||||
break;
|
||||
*/
|
||||
default:
|
||||
printf("nwfs_doio: type %x unexpected\n",vp->v_type);
|
||||
break;
|
||||
};
|
||||
if (error) {
|
||||
bp->b_ioflags |= BIO_ERROR;
|
||||
bp->b_error = error;
|
||||
}
|
||||
} else { /* write */
|
||||
if (((bp->b_blkno * DEV_BSIZE) + bp->b_dirtyend) > np->n_size)
|
||||
bp->b_dirtyend = np->n_size - (bp->b_blkno * DEV_BSIZE);
|
||||
|
||||
if (bp->b_dirtyend > bp->b_dirtyoff) {
|
||||
io.iov_len = uiop->uio_resid = bp->b_dirtyend - bp->b_dirtyoff;
|
||||
uiop->uio_offset = ((off_t)bp->b_blkno) * DEV_BSIZE + bp->b_dirtyoff;
|
||||
io.iov_base = (char *)bp->b_data + bp->b_dirtyoff;
|
||||
uiop->uio_rw = UIO_WRITE;
|
||||
error = ncp_write(NWFSTOCONN(nmp), &np->n_fh, uiop, cr);
|
||||
|
||||
/*
|
||||
* For an interrupted write, the buffer is still valid
|
||||
* and the write hasn't been pushed to the server yet,
|
||||
* so we can't set BIO_ERROR and report the interruption
|
||||
* by setting B_EINTR. For the B_ASYNC case, B_EINTR
|
||||
* is not relevant, so the rpc attempt is essentially
|
||||
* a noop. For the case of a V3 write rpc not being
|
||||
* committed to stable storage, the block is still
|
||||
* dirty and requires either a commit rpc or another
|
||||
* write rpc with iomode == NFSV3WRITE_FILESYNC before
|
||||
* the block is reused. This is indicated by setting
|
||||
* the B_DELWRI and B_NEEDCOMMIT flags.
|
||||
*/
|
||||
if (error == EINTR
|
||||
|| (!error && (bp->b_flags & B_NEEDCOMMIT))) {
|
||||
int s;
|
||||
|
||||
s = splbio();
|
||||
bp->b_flags &= ~(B_INVAL|B_NOCACHE);
|
||||
if ((bp->b_flags & B_ASYNC) == 0)
|
||||
bp->b_flags |= B_EINTR;
|
||||
if ((bp->b_flags & B_PAGING) == 0) {
|
||||
bdirty(bp);
|
||||
bp->b_flags &= ~B_DONE;
|
||||
}
|
||||
if ((bp->b_flags & B_ASYNC) == 0)
|
||||
bp->b_flags |= B_EINTR;
|
||||
splx(s);
|
||||
} else {
|
||||
if (error) {
|
||||
bp->b_ioflags |= BIO_ERROR;
|
||||
bp->b_error /*= np->n_error */= error;
|
||||
/* np->n_flag |= NWRITEERR;*/
|
||||
}
|
||||
bp->b_dirtyoff = bp->b_dirtyend = 0;
|
||||
}
|
||||
} else {
|
||||
bp->b_resid = 0;
|
||||
bufdone(bp);
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
bp->b_resid = uiop->uio_resid;
|
||||
bufdone(bp);
|
||||
return (error);
|
||||
}
|
||||
|
||||
/*
|
||||
* Vnode op for VM getpages.
|
||||
* Wish wish .... get rid from multiple IO routines
|
||||
*/
|
||||
int
|
||||
nwfs_getpages(ap)
|
||||
struct vop_getpages_args /* {
|
||||
struct vnode *a_vp;
|
||||
vm_page_t *a_m;
|
||||
int a_count;
|
||||
int a_reqpage;
|
||||
vm_ooffset_t a_offset;
|
||||
} */ *ap;
|
||||
{
|
||||
#ifndef NWFS_RWCACHE
|
||||
return vop_stdgetpages(ap);(ap->a_vp, ap->a_m, ap->a_count,
|
||||
#else
|
||||
int i, error, nextoff, size, toff, npages, count;
|
||||
struct uio uio;
|
||||
struct iovec iov;
|
||||
vm_offset_t kva;
|
||||
struct buf *bp;
|
||||
struct vnode *vp;
|
||||
struct thread *td;
|
||||
struct ucred *cred;
|
||||
struct nwmount *nmp;
|
||||
struct nwnode *np;
|
||||
vm_object_t object;
|
||||
vm_page_t *pages;
|
||||
|
||||
vp = ap->a_vp;
|
||||
td = curthread; /* XXX */
|
||||
cred = td->td_ucred; /* XXX */
|
||||
np = VTONW(vp);
|
||||
nmp = VFSTONWFS(vp->v_mount);
|
||||
pages = ap->a_m;
|
||||
count = ap->a_count;
|
||||
|
||||
if ((object = vp->v_object) == NULL) {
|
||||
printf("nwfs_getpages: called with non-merged cache vnode??\n");
|
||||
return VM_PAGER_ERROR;
|
||||
}
|
||||
|
||||
bp = getpbuf(&nwfs_pbuf_freecnt);
|
||||
npages = btoc(count);
|
||||
kva = (vm_offset_t) bp->b_data;
|
||||
pmap_qenter(kva, pages, npages);
|
||||
|
||||
iov.iov_base = (caddr_t) kva;
|
||||
iov.iov_len = count;
|
||||
uio.uio_iov = &iov;
|
||||
uio.uio_iovcnt = 1;
|
||||
uio.uio_offset = IDX_TO_OFF(pages[0]->pindex);
|
||||
uio.uio_resid = count;
|
||||
uio.uio_segflg = UIO_SYSSPACE;
|
||||
uio.uio_rw = UIO_READ;
|
||||
uio.uio_td = td;
|
||||
|
||||
error = ncp_read(NWFSTOCONN(nmp), &np->n_fh, &uio,cred);
|
||||
pmap_qremove(kva, npages);
|
||||
|
||||
relpbuf(bp, &nwfs_pbuf_freecnt);
|
||||
|
||||
VM_OBJECT_LOCK(object);
|
||||
if (error && (uio.uio_resid == count)) {
|
||||
printf("nwfs_getpages: error %d\n",error);
|
||||
for (i = 0; i < npages; i++) {
|
||||
if (ap->a_reqpage != i) {
|
||||
vm_page_lock(pages[i]);
|
||||
vm_page_free(pages[i]);
|
||||
vm_page_unlock(pages[i]);
|
||||
}
|
||||
}
|
||||
VM_OBJECT_UNLOCK(object);
|
||||
return VM_PAGER_ERROR;
|
||||
}
|
||||
|
||||
size = count - uio.uio_resid;
|
||||
|
||||
for (i = 0, toff = 0; i < npages; i++, toff = nextoff) {
|
||||
vm_page_t m;
|
||||
nextoff = toff + PAGE_SIZE;
|
||||
m = pages[i];
|
||||
|
||||
if (nextoff <= size) {
|
||||
m->valid = VM_PAGE_BITS_ALL;
|
||||
KASSERT(m->dirty == 0,
|
||||
("nwfs_getpages: page %p is dirty", m));
|
||||
} else {
|
||||
int nvalid = ((size + DEV_BSIZE - 1) - toff) & ~(DEV_BSIZE - 1);
|
||||
vm_page_set_valid_range(m, 0, nvalid);
|
||||
KASSERT((m->dirty & vm_page_bits(0, nvalid)) == 0,
|
||||
("nwfs_getpages: page %p is dirty", m));
|
||||
}
|
||||
|
||||
if (i != ap->a_reqpage)
|
||||
vm_page_readahead_finish(m);
|
||||
}
|
||||
VM_OBJECT_UNLOCK(object);
|
||||
return 0;
|
||||
#endif /* NWFS_RWCACHE */
|
||||
}
|
||||
|
||||
/*
|
||||
* Vnode op for VM putpages.
|
||||
* possible bug: all IO done in sync mode
|
||||
* Note that vop_close always invalidate pages before close, so it's
|
||||
* not necessary to open vnode.
|
||||
*/
|
||||
int
|
||||
nwfs_putpages(ap)
|
||||
struct vop_putpages_args /* {
|
||||
struct vnode *a_vp;
|
||||
vm_page_t *a_m;
|
||||
int a_count;
|
||||
int a_sync;
|
||||
int *a_rtvals;
|
||||
vm_ooffset_t a_offset;
|
||||
} */ *ap;
|
||||
{
|
||||
int error;
|
||||
struct vnode *vp = ap->a_vp;
|
||||
struct thread *td;
|
||||
struct ucred *cred;
|
||||
|
||||
#ifndef NWFS_RWCACHE
|
||||
td = curthread; /* XXX */
|
||||
cred = td->td_ucred; /* XXX */
|
||||
VOP_OPEN(vp, FWRITE, cred, td, NULL);
|
||||
error = vop_stdputpages(ap);
|
||||
VOP_CLOSE(vp, FWRITE, cred, td);
|
||||
return error;
|
||||
#else
|
||||
struct uio uio;
|
||||
struct iovec iov;
|
||||
vm_offset_t kva;
|
||||
struct buf *bp;
|
||||
int i, npages, count;
|
||||
int *rtvals;
|
||||
struct nwmount *nmp;
|
||||
struct nwnode *np;
|
||||
vm_page_t *pages;
|
||||
|
||||
td = curthread; /* XXX */
|
||||
cred = td->td_ucred; /* XXX */
|
||||
/* VOP_OPEN(vp, FWRITE, cred, td, NULL);*/
|
||||
np = VTONW(vp);
|
||||
nmp = VFSTONWFS(vp->v_mount);
|
||||
pages = ap->a_m;
|
||||
count = ap->a_count;
|
||||
rtvals = ap->a_rtvals;
|
||||
npages = btoc(count);
|
||||
|
||||
for (i = 0; i < npages; i++) {
|
||||
rtvals[i] = VM_PAGER_ERROR;
|
||||
}
|
||||
|
||||
bp = getpbuf(&nwfs_pbuf_freecnt);
|
||||
kva = (vm_offset_t) bp->b_data;
|
||||
pmap_qenter(kva, pages, npages);
|
||||
|
||||
iov.iov_base = (caddr_t) kva;
|
||||
iov.iov_len = count;
|
||||
uio.uio_iov = &iov;
|
||||
uio.uio_iovcnt = 1;
|
||||
uio.uio_offset = IDX_TO_OFF(pages[0]->pindex);
|
||||
uio.uio_resid = count;
|
||||
uio.uio_segflg = UIO_SYSSPACE;
|
||||
uio.uio_rw = UIO_WRITE;
|
||||
uio.uio_td = td;
|
||||
NCPVNDEBUG("ofs=%d,resid=%d\n",(int)uio.uio_offset, uio.uio_resid);
|
||||
|
||||
error = ncp_write(NWFSTOCONN(nmp), &np->n_fh, &uio, cred);
|
||||
/* VOP_CLOSE(vp, FWRITE, cred, td);*/
|
||||
NCPVNDEBUG("paged write done: %d\n", error);
|
||||
|
||||
pmap_qremove(kva, npages);
|
||||
relpbuf(bp, &nwfs_pbuf_freecnt);
|
||||
|
||||
if (!error)
|
||||
vnode_pager_undirty_pages(pages, rtvals, count - uio.uio_resid);
|
||||
return rtvals[0];
|
||||
#endif /* NWFS_RWCACHE */
|
||||
}
|
||||
/*
|
||||
* Flush and invalidate all dirty buffers. If another process is already
|
||||
* doing the flush, just wait for completion.
|
||||
*/
|
||||
int
|
||||
nwfs_vinvalbuf(vp, td)
|
||||
struct vnode *vp;
|
||||
struct thread *td;
|
||||
{
|
||||
struct nwnode *np = VTONW(vp);
|
||||
/* struct nwmount *nmp = VTONWFS(vp);*/
|
||||
int error = 0;
|
||||
|
||||
if (vp->v_iflag & VI_DOOMED)
|
||||
return (0);
|
||||
|
||||
while (np->n_flag & NFLUSHINPROG) {
|
||||
np->n_flag |= NFLUSHWANT;
|
||||
error = tsleep(&np->n_flag, PRIBIO + 2, "nwfsvinv", 2 * hz);
|
||||
error = ncp_chkintr(NWFSTOCONN(VTONWFS(vp)), td);
|
||||
if (error == EINTR)
|
||||
return EINTR;
|
||||
}
|
||||
np->n_flag |= NFLUSHINPROG;
|
||||
|
||||
if (vp->v_bufobj.bo_object != NULL) {
|
||||
VM_OBJECT_LOCK(vp->v_bufobj.bo_object);
|
||||
vm_object_page_clean(vp->v_bufobj.bo_object, 0, 0, OBJPC_SYNC);
|
||||
VM_OBJECT_UNLOCK(vp->v_bufobj.bo_object);
|
||||
}
|
||||
|
||||
error = vinvalbuf(vp, V_SAVE, PCATCH, 0);
|
||||
while (error) {
|
||||
if (error == ERESTART || error == EINTR) {
|
||||
np->n_flag &= ~NFLUSHINPROG;
|
||||
if (np->n_flag & NFLUSHWANT) {
|
||||
np->n_flag &= ~NFLUSHWANT;
|
||||
wakeup(&np->n_flag);
|
||||
}
|
||||
return EINTR;
|
||||
}
|
||||
error = vinvalbuf(vp, V_SAVE, PCATCH, 0);
|
||||
}
|
||||
np->n_flag &= ~(NMODIFIED | NFLUSHINPROG);
|
||||
if (np->n_flag & NFLUSHWANT) {
|
||||
np->n_flag &= ~NFLUSHWANT;
|
||||
wakeup(&np->n_flag);
|
||||
}
|
||||
return (error);
|
||||
}
|
@ -1,89 +0,0 @@
|
||||
/*-
|
||||
* Copyright (c) 1999 Boris Popov
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/mount.h>
|
||||
#include <sys/vnode.h>
|
||||
#include <sys/ioccom.h>
|
||||
|
||||
#include <netncp/ncp.h>
|
||||
#include <netncp/ncp_conn.h>
|
||||
#include <netncp/ncp_subr.h>
|
||||
|
||||
#include <fs/nwfs/nwfs.h>
|
||||
#include <fs/nwfs/nwfs_node.h>
|
||||
#include <fs/nwfs/nwfs_subr.h>
|
||||
|
||||
int
|
||||
nwfs_ioctl(ap)
|
||||
struct vop_ioctl_args /* {
|
||||
struct vnode *a_vp;
|
||||
u_long a_command;
|
||||
caddr_t a_data;
|
||||
int fflag;
|
||||
struct ucred *cred;
|
||||
struct thread *td;
|
||||
} */ *ap;
|
||||
{
|
||||
int error;
|
||||
struct thread *td = ap->a_td;
|
||||
struct ucred *cred = ap->a_cred;
|
||||
struct vnode *vp = ap->a_vp;
|
||||
struct nwnode *np = VTONW(vp);
|
||||
struct nwmount *nmp = VTONWFS(vp);
|
||||
struct ncp_conn *conn = NWFSTOCONN(nmp);
|
||||
struct ncp_handle *hp;
|
||||
struct nw_entry_info *fap;
|
||||
void *data = ap->a_data;
|
||||
|
||||
switch (ap->a_command) {
|
||||
case NWFSIOC_GETCONN:
|
||||
error = ncp_conn_lock(conn, td, cred, NCPM_READ);
|
||||
if (error) break;
|
||||
error = ncp_conn_gethandle(conn, td, &hp);
|
||||
ncp_conn_unlock(conn, td);
|
||||
if (error) break;
|
||||
*(int*)data = hp->nh_id;
|
||||
break;
|
||||
case NWFSIOC_GETEINFO:
|
||||
if ((error = VOP_ACCESS(vp, VEXEC, cred, td))) break;
|
||||
fap = data;
|
||||
error = ncp_obtain_info(nmp, np->n_fid.f_id, 0, NULL, fap,
|
||||
ap->a_td,ap->a_cred);
|
||||
strcpy(fap->entryName, np->n_name);
|
||||
fap->nameLen = np->n_nmlen;
|
||||
break;
|
||||
case NWFSIOC_GETNS:
|
||||
if ((error = VOP_ACCESS(vp, VEXEC, cred, td))) break;
|
||||
*(int*)data = nmp->name_space;
|
||||
break;
|
||||
default:
|
||||
error = ENOTTY;
|
||||
}
|
||||
return (error);
|
||||
}
|
@ -1,68 +0,0 @@
|
||||
/*-
|
||||
* Copyright (c) 1999 Boris Popov
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
#ifndef _NWFS_MOUNT_H_
|
||||
#define _NWFS_MOUNT_H_
|
||||
|
||||
#ifndef _NCP_NCP_NLS_H_
|
||||
#include <netncp/ncp_nls.h>
|
||||
#endif
|
||||
|
||||
#define NWFS_VERMAJ 1
|
||||
#define NWFS_VERMIN 3400
|
||||
#define NWFS_VERSION (NWFS_VERMAJ*100000 + NWFS_VERMIN)
|
||||
|
||||
/* Values for flags */
|
||||
#define NWFS_MOUNT_SOFT 0x0001
|
||||
#define WNFS_MOUNT_INTR 0x0002
|
||||
#define NWFS_MOUNT_STRONG 0x0004
|
||||
#define NWFS_MOUNT_NO_OS2 0x0008
|
||||
#define NWFS_MOUNT_NO_NFS 0x0010
|
||||
#define NWFS_MOUNT_NO_LONG 0x0020
|
||||
#define NWFS_MOUNT_GET_SYSENT 0x0040 /* special case, look to vfsops :) */
|
||||
#define NWFS_MOUNT_HAVE_NLS 0x0080
|
||||
|
||||
#define NWFS_VOLNAME_LEN 48
|
||||
|
||||
|
||||
/* Layout of the mount control block for a netware filesystem. */
|
||||
struct nwfs_args {
|
||||
int connRef; /* connection reference */
|
||||
char mount_point[MAXPATHLEN];
|
||||
u_int flags;
|
||||
u_char mounted_vol[NWFS_VOLNAME_LEN + 1];
|
||||
u_char root_path[512+1];
|
||||
int version;
|
||||
uid_t uid;
|
||||
gid_t gid;
|
||||
mode_t file_mode;
|
||||
mode_t dir_mode;
|
||||
struct ncp_nlstables nls;
|
||||
int tz;
|
||||
};
|
||||
|
||||
#endif /* !_NWFS_MOUNT_H_ */
|
@ -1,379 +0,0 @@
|
||||
/*-
|
||||
* Copyright (c) 1999, 2000 Boris Popov
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/lock.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/mount.h>
|
||||
#include <sys/mutex.h>
|
||||
#include <sys/proc.h>
|
||||
#include <sys/queue.h>
|
||||
#include <sys/sx.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/vnode.h>
|
||||
|
||||
#include <vm/vm.h>
|
||||
#include <vm/vm_extern.h>
|
||||
#include <vm/vm_page.h>
|
||||
#include <vm/vm_object.h>
|
||||
|
||||
#include <netncp/ncp.h>
|
||||
#include <netncp/ncp_conn.h>
|
||||
#include <netncp/ncp_subr.h>
|
||||
|
||||
#include <fs/nwfs/nwfs.h>
|
||||
#include <fs/nwfs/nwfs_mount.h>
|
||||
#include <fs/nwfs/nwfs_node.h>
|
||||
#include <fs/nwfs/nwfs_subr.h>
|
||||
|
||||
#define NWNOHASH(fhsum) (&nwhashtbl[(fhsum.f_id) & nwnodehash])
|
||||
|
||||
static LIST_HEAD(nwnode_hash_head,nwnode) *nwhashtbl;
|
||||
static u_long nwnodehash;
|
||||
static struct sx nwhashlock;
|
||||
|
||||
static MALLOC_DEFINE(M_NWNODE, "nwfs_node", "NWFS vnode private part");
|
||||
static MALLOC_DEFINE(M_NWFSHASH, "nwfs_hash", "NWFS has table");
|
||||
|
||||
static int nwfs_sysctl_vnprint(SYSCTL_HANDLER_ARGS);
|
||||
|
||||
SYSCTL_DECL(_vfs_nwfs);
|
||||
|
||||
SYSCTL_PROC(_vfs_nwfs, OID_AUTO, vnprint, CTLFLAG_WR|CTLTYPE_OPAQUE,
|
||||
NULL, 0, nwfs_sysctl_vnprint, "S,vnlist", "vnode hash");
|
||||
|
||||
void
|
||||
nwfs_hash_init(void) {
|
||||
nwhashtbl = hashinit(desiredvnodes, M_NWFSHASH, &nwnodehash);
|
||||
sx_init(&nwhashlock, "nwfshl");
|
||||
}
|
||||
|
||||
void
|
||||
nwfs_hash_free(void) {
|
||||
sx_destroy(&nwhashlock);
|
||||
free(nwhashtbl, M_NWFSHASH);
|
||||
}
|
||||
|
||||
int
|
||||
nwfs_sysctl_vnprint(SYSCTL_HANDLER_ARGS) {
|
||||
struct nwnode *np;
|
||||
struct nwnode_hash_head *nhpp;
|
||||
struct vnode *vp;
|
||||
int i;
|
||||
|
||||
if (nwfs_debuglevel == 0)
|
||||
return 0;
|
||||
printf("Name:uc:hc:fid:pfid\n");
|
||||
for(i = 0; i <= nwnodehash; i++) {
|
||||
nhpp = &nwhashtbl[i];
|
||||
LIST_FOREACH(np, nhpp, n_hash) {
|
||||
vp = NWTOV(np);
|
||||
vprint("", vp);
|
||||
printf("%s:%d:%d:%d:%d\n",np->n_name,vrefcnt(vp),
|
||||
vp->v_holdcnt,np->n_fid.f_id, np->n_fid.f_parent);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Search nwnode with given fid.
|
||||
* Hash list should be locked by caller.
|
||||
*/
|
||||
static int
|
||||
nwfs_hashlookup(struct nwmount *nmp, ncpfid fid, struct nwnode **npp)
|
||||
{
|
||||
struct nwnode *np;
|
||||
struct nwnode_hash_head *nhpp;
|
||||
|
||||
sx_assert(&nwhashlock, SA_XLOCKED);
|
||||
|
||||
nhpp = NWNOHASH(fid);
|
||||
LIST_FOREACH(np, nhpp, n_hash) {
|
||||
if (nmp != np->n_mount || !NWCMPF(&fid, &np->n_fid))
|
||||
continue;
|
||||
if (npp)
|
||||
*npp = np;
|
||||
return 0;
|
||||
}
|
||||
return ENOENT;
|
||||
}
|
||||
|
||||
/*
|
||||
* Allocate new nwfsnode/vnode from given nwnode.
|
||||
* Vnode referenced and not locked.
|
||||
*/
|
||||
static int
|
||||
nwfs_allocvp(struct mount *mp, ncpfid fid, struct nw_entry_info *fap,
|
||||
struct vnode *dvp, struct vnode **vpp)
|
||||
{
|
||||
struct nwnode *np;
|
||||
struct nwnode_hash_head *nhpp;
|
||||
struct nwmount *nmp = VFSTONWFS(mp);
|
||||
struct vnode *vp;
|
||||
int error;
|
||||
|
||||
loop:
|
||||
sx_xlock(&nwhashlock);
|
||||
rescan:
|
||||
if (nwfs_hashlookup(nmp, fid, &np) == 0) {
|
||||
vp = NWTOV(np);
|
||||
VI_LOCK(vp);
|
||||
sx_xunlock(&nwhashlock);
|
||||
if (vget(vp, LK_EXCLUSIVE | LK_INTERLOCK, curthread))
|
||||
goto loop;
|
||||
if (fap)
|
||||
np->n_attr = fap->attributes;
|
||||
*vpp = vp;
|
||||
return(0);
|
||||
}
|
||||
sx_xunlock(&nwhashlock);
|
||||
|
||||
if (fap == NULL || ((fap->attributes & aDIR) == 0 && dvp == NULL))
|
||||
panic("nwfs_allocvp: fap = %p, dvp = %p\n", fap, dvp);
|
||||
/*
|
||||
* Do the MALLOC before the getnewvnode since doing so afterward
|
||||
* might cause a bogus v_data pointer to get dereferenced
|
||||
* elsewhere if MALLOC should block.
|
||||
*/
|
||||
np = malloc(sizeof *np, M_NWNODE, M_WAITOK | M_ZERO);
|
||||
error = getnewvnode("nwfs", mp, &nwfs_vnodeops, &vp);
|
||||
if (error) {
|
||||
*vpp = NULL;
|
||||
free(np, M_NWNODE);
|
||||
return (error);
|
||||
}
|
||||
error = insmntque(vp, mp); /* XXX: Too early for mpsafe fs */
|
||||
if (error != 0) {
|
||||
free(np, M_NWNODE);
|
||||
*vpp = NULL;
|
||||
return (error);
|
||||
}
|
||||
vp->v_data = np;
|
||||
np->n_vnode = vp;
|
||||
np->n_mount = nmp;
|
||||
np->n_attr = fap->attributes;
|
||||
vp->v_type = np->n_attr & aDIR ? VDIR : VREG;
|
||||
np->n_fid = fid;
|
||||
if (dvp) {
|
||||
np->n_parent = VTONW(dvp)->n_fid;
|
||||
}
|
||||
sx_xlock(&nwhashlock);
|
||||
/*
|
||||
* Another process can create vnode while we blocked in malloc() or
|
||||
* getnewvnode(). Rescan list again.
|
||||
*/
|
||||
if (nwfs_hashlookup(nmp, fid, NULL) == 0) {
|
||||
vp->v_data = NULL;
|
||||
np->n_vnode = NULL;
|
||||
vrele(vp);
|
||||
free(np, M_NWNODE);
|
||||
goto rescan;
|
||||
}
|
||||
*vpp = vp;
|
||||
nhpp = NWNOHASH(fid);
|
||||
LIST_INSERT_HEAD(nhpp, np, n_hash);
|
||||
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
|
||||
VN_LOCK_AREC(vp);
|
||||
sx_xunlock(&nwhashlock);
|
||||
|
||||
ASSERT_VOP_LOCKED(dvp, "nwfs_allocvp");
|
||||
if (vp->v_type == VDIR && dvp && (dvp->v_vflag & VV_ROOT) == 0) {
|
||||
np->n_flag |= NREFPARENT;
|
||||
vref(dvp);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
nwfs_nget(struct mount *mp, ncpfid fid, struct nw_entry_info *fap,
|
||||
struct vnode *dvp, struct vnode **vpp)
|
||||
{
|
||||
struct vnode *vp;
|
||||
int error;
|
||||
|
||||
*vpp = NULL;
|
||||
error = nwfs_allocvp(mp, fid, fap, dvp, &vp);
|
||||
if (error)
|
||||
return error;
|
||||
if (fap)
|
||||
nwfs_attr_cacheenter(vp, fap);
|
||||
*vpp = vp;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
nwfs_lookupnp(struct nwmount *nmp, ncpfid fid, struct thread *td,
|
||||
struct nwnode **npp)
|
||||
{
|
||||
int error;
|
||||
|
||||
sx_xlock(&nwhashlock);
|
||||
error = nwfs_hashlookup(nmp, fid, npp);
|
||||
sx_xunlock(&nwhashlock);
|
||||
return error;
|
||||
}
|
||||
|
||||
/*
|
||||
* Free nwnode, and give vnode back to system
|
||||
*/
|
||||
int
|
||||
nwfs_reclaim(ap)
|
||||
struct vop_reclaim_args /* {
|
||||
struct vnode *a_vp;
|
||||
struct thread *a_td;
|
||||
} */ *ap;
|
||||
{
|
||||
struct vnode *dvp = NULL, *vp = ap->a_vp;
|
||||
struct nwnode *dnp, *np = VTONW(vp);
|
||||
struct nwmount *nmp = VTONWFS(vp);
|
||||
struct thread *td = ap->a_td;
|
||||
|
||||
NCPVNDEBUG("%s,%d\n", np->n_name, vrefcnt(vp));
|
||||
/*
|
||||
* Destroy the vm object and flush associated pages.
|
||||
*/
|
||||
vnode_destroy_vobject(vp);
|
||||
|
||||
if (np->n_flag & NREFPARENT) {
|
||||
np->n_flag &= ~NREFPARENT;
|
||||
if (nwfs_lookupnp(nmp, np->n_parent, td, &dnp) == 0) {
|
||||
dvp = dnp->n_vnode;
|
||||
} else {
|
||||
NCPVNDEBUG("%s: has no parent ?\n",np->n_name);
|
||||
}
|
||||
}
|
||||
sx_xlock(&nwhashlock);
|
||||
LIST_REMOVE(np, n_hash);
|
||||
sx_xunlock(&nwhashlock);
|
||||
if (nmp->n_root == np) {
|
||||
nmp->n_root = NULL;
|
||||
}
|
||||
vp->v_data = NULL;
|
||||
free(np, M_NWNODE);
|
||||
if (dvp) {
|
||||
vrele(dvp);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
nwfs_inactive(ap)
|
||||
struct vop_inactive_args /* {
|
||||
struct vnode *a_vp;
|
||||
struct thread *a_td;
|
||||
} */ *ap;
|
||||
{
|
||||
struct thread *td = ap->a_td;
|
||||
struct ucred *cred = td->td_ucred;
|
||||
struct vnode *vp = ap->a_vp;
|
||||
struct nwnode *np = VTONW(vp);
|
||||
int error;
|
||||
|
||||
NCPVNDEBUG("%s: %d\n", VTONW(vp)->n_name, vrefcnt(vp));
|
||||
if (np->opened) {
|
||||
error = nwfs_vinvalbuf(vp, td);
|
||||
error = ncp_close_file(NWFSTOCONN(VTONWFS(vp)), &np->n_fh, td, cred);
|
||||
np->opened = 0;
|
||||
}
|
||||
if (np->n_flag & NSHOULDFREE) {
|
||||
cache_purge(vp);
|
||||
vgone(vp);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
/*
|
||||
* routines to maintain vnode attributes cache
|
||||
* nwfs_attr_cacheenter: unpack np.i to va structure
|
||||
*/
|
||||
void
|
||||
nwfs_attr_cacheenter(struct vnode *vp, struct nw_entry_info *fi)
|
||||
{
|
||||
struct nwnode *np = VTONW(vp);
|
||||
struct nwmount *nmp = VTONWFS(vp);
|
||||
struct vattr *va = &np->n_vattr;
|
||||
|
||||
va->va_type = vp->v_type; /* vnode type (for create) */
|
||||
np->n_nmlen = fi->nameLen;
|
||||
bcopy(fi->entryName, np->n_name, np->n_nmlen);
|
||||
np->n_name[fi->nameLen] = 0;
|
||||
if (vp->v_type == VREG) {
|
||||
if (va->va_size != fi->dataStreamSize) {
|
||||
va->va_size = fi->dataStreamSize;
|
||||
vnode_pager_setsize(vp, va->va_size);
|
||||
}
|
||||
va->va_mode = nmp->m.file_mode; /* files access mode and type */
|
||||
} else if (vp->v_type == VDIR) {
|
||||
va->va_size = 16384; /* should be a better way ... */
|
||||
va->va_mode = nmp->m.dir_mode; /* files access mode and type */
|
||||
} else
|
||||
return;
|
||||
np->n_size = va->va_size;
|
||||
va->va_nlink = 1; /* number of references to file */
|
||||
va->va_uid = nmp->m.uid; /* owner user id */
|
||||
va->va_gid = nmp->m.gid; /* owner group id */
|
||||
va->va_fsid = vp->v_mount->mnt_stat.f_fsid.val[0];
|
||||
va->va_fileid = np->n_fid.f_id; /* file id */
|
||||
if (va->va_fileid == 0)
|
||||
va->va_fileid = NWFS_ROOT_INO;
|
||||
va->va_blocksize=nmp->connh->nh_conn->buffer_size;/* blocksize preferred for i/o */
|
||||
/* time of last modification */
|
||||
ncp_dos2unixtime(fi->modifyDate, fi->modifyTime, 0, nmp->m.tz, &va->va_mtime);
|
||||
/* time of last access */
|
||||
ncp_dos2unixtime(fi->lastAccessDate, 0, 0, nmp->m.tz, &va->va_atime);
|
||||
va->va_ctime = va->va_mtime; /* time file changed */
|
||||
va->va_gen = VNOVAL; /* generation number of file */
|
||||
va->va_flags = 0; /* flags defined for file */
|
||||
va->va_rdev = VNOVAL; /* device the special file represents */
|
||||
va->va_bytes = va->va_size; /* bytes of disk space held by file */
|
||||
va->va_filerev = 0; /* file modification number */
|
||||
va->va_vaflags = 0; /* operations flags */
|
||||
np->n_vattr = *va;
|
||||
if (np->n_mtime == 0) {
|
||||
np->n_mtime = va->va_mtime.tv_sec;
|
||||
}
|
||||
np->n_atime = time_second;
|
||||
np->n_dosfid = fi->DosDirNum;
|
||||
return;
|
||||
}
|
||||
|
||||
int
|
||||
nwfs_attr_cachelookup(struct vnode *vp, struct vattr *va)
|
||||
{
|
||||
struct nwnode *np = VTONW(vp);
|
||||
int diff;
|
||||
|
||||
diff = time_second - np->n_atime;
|
||||
if (diff > 2) { /* XXX should be configurable */
|
||||
return ENOENT;
|
||||
}
|
||||
*va = np->n_vattr;
|
||||
return 0;
|
||||
}
|
@ -1,96 +0,0 @@
|
||||
/*-
|
||||
* Copyright (c) 1999, 2000, 2001 Boris Popov
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
#ifndef _NWFS_NODE_H_
|
||||
#define _NWFS_NODE_H_
|
||||
|
||||
#define NWFS_ROOT_INO 0x7ffffffd
|
||||
|
||||
/* Bits for nwnode.n_flag */
|
||||
#define NFLUSHINPROG 0x0001
|
||||
#define NFLUSHWANT 0x0002 /* they should gone ... */
|
||||
#define NMODIFIED 0x0004 /* bogus, until async IO implemented */
|
||||
#define NREFPARENT 0x0008 /* vnode holds reference to a parent vnode */
|
||||
#define NVOLUME 0x0010 /* vnode references a volume */
|
||||
#define NSHOULDFREE 0x0020 /* vnode should be removed from hash */
|
||||
|
||||
struct nwnode {
|
||||
LIST_ENTRY(nwnode) n_hash;
|
||||
struct vnode *n_vnode;
|
||||
struct vattr n_vattr;
|
||||
struct nwmount *n_mount;
|
||||
time_t n_atime; /* attributes cache time*/
|
||||
time_t n_ctime;
|
||||
time_t n_mtime;
|
||||
int n_flag;
|
||||
ncpfid n_parent;
|
||||
ncpfid n_fid;
|
||||
u_long n_attr; /* LH */
|
||||
u_long n_size;
|
||||
u_long n_dosfid;
|
||||
int opened;
|
||||
/* int access;*/
|
||||
u_long n_origfh;
|
||||
ncp_fh n_fh;
|
||||
struct nw_search_seq n_seq;
|
||||
u_char n_nmlen;
|
||||
u_char n_name[256];
|
||||
};
|
||||
|
||||
#define VTONW(vp) ((struct nwnode *)(vp)->v_data)
|
||||
#define NWTOV(np) ((struct vnode *)(np)->n_vnode)
|
||||
#define NWCMPF(f1,f2) ((f1)->f_parent == (f2)->f_parent && \
|
||||
(f1)->f_id == (f2)->f_id)
|
||||
#define NWCMPN(np1,np2) NWCMPF(&(np1)->n_fid, &(np2)->n_fid)
|
||||
#define NWCMPV(vp1,vp2) NWCMPN(VTONW(vp1),VTONW(vp2))
|
||||
|
||||
struct vop_getpages_args;
|
||||
struct vop_inactive_args;
|
||||
struct vop_putpages_args;
|
||||
struct vop_reclaim_args;
|
||||
struct ucred;
|
||||
struct uio;
|
||||
|
||||
void nwfs_hash_init(void);
|
||||
void nwfs_hash_free(void);
|
||||
int nwfs_lookupnp(struct nwmount *nmp, ncpfid fid, struct thread *td,
|
||||
struct nwnode **npp);
|
||||
int nwfs_inactive(struct vop_inactive_args *);
|
||||
int nwfs_reclaim(struct vop_reclaim_args *);
|
||||
int nwfs_nget(struct mount *mp, ncpfid fid, struct nw_entry_info *fap,
|
||||
struct vnode *dvp, struct vnode **vpp);
|
||||
|
||||
int nwfs_getpages(struct vop_getpages_args *);
|
||||
int nwfs_putpages(struct vop_putpages_args *);
|
||||
int nwfs_readvnode(struct vnode *vp, struct uio *uiop, struct ucred *cred);
|
||||
int nwfs_writevnode(struct vnode *vp, struct uio *uiop, struct ucred *cred, int ioflag);
|
||||
void nwfs_attr_cacheenter(struct vnode *vp, struct nw_entry_info *fi);
|
||||
int nwfs_attr_cachelookup(struct vnode *vp,struct vattr *va);
|
||||
|
||||
#define nwfs_attr_cacheremove(vp) VTONW(vp)->n_atime = 0
|
||||
|
||||
#endif /* _NWFS_NODE_H_ */
|
@ -1,553 +0,0 @@
|
||||
/*-
|
||||
* Copyright (c) 1999, 2001 Boris Popov
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/lock.h>
|
||||
#include <sys/lockmgr.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/clock.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#include <netncp/ncp.h>
|
||||
#include <netncp/ncp_conn.h>
|
||||
#include <netncp/ncp_ncp.h>
|
||||
#include <netncp/ncp_subr.h>
|
||||
#include <netncp/ncp_rq.h>
|
||||
#include <netncp/nwerror.h>
|
||||
|
||||
#include <fs/nwfs/nwfs.h>
|
||||
#include <fs/nwfs/nwfs_node.h>
|
||||
#include <fs/nwfs/nwfs_subr.h>
|
||||
|
||||
#define NCP_INFOSZ (sizeof(struct nw_entry_info) - 257)
|
||||
|
||||
MALLOC_DEFINE(M_NWFSDATA, "nwfs_data", "NWFS private data");
|
||||
|
||||
static int
|
||||
ncp_extract_file_info(struct nwmount *nmp, struct ncp_rq *rqp,
|
||||
struct nw_entry_info *target, int withname)
|
||||
{
|
||||
u_int8_t name_len;
|
||||
|
||||
md_get_mem(&rqp->rp, (caddr_t)target, NCP_INFOSZ, MB_MSYSTEM);
|
||||
if (!withname)
|
||||
return 0;
|
||||
md_get_uint8(&rqp->rp, &name_len);
|
||||
target->nameLen = name_len;
|
||||
md_get_mem(&rqp->rp, (caddr_t)target->entryName, name_len, MB_MSYSTEM);
|
||||
target->entryName[name_len] = '\0';
|
||||
ncp_path2unix(target->entryName, target->entryName, name_len, &nmp->m.nls);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
ncp_initsearch(struct vnode *dvp, struct thread *td, struct ucred *cred)
|
||||
{
|
||||
struct nwmount *nmp = VTONWFS(dvp);
|
||||
struct ncp_conn *conn = NWFSTOCONN(nmp);
|
||||
struct nwnode *np = VTONW(dvp);
|
||||
struct ncp_rq *rqp;
|
||||
u_int8_t volnum = nmp->n_volume;
|
||||
u_int32_t dirent = np->n_fid.f_id;
|
||||
int error;
|
||||
|
||||
NCPNDEBUG("vol=%d,dir=%d\n", volnum, dirent);
|
||||
error = ncp_rq_alloc(87, conn, td, cred, &rqp);
|
||||
if (error)
|
||||
return error;
|
||||
mb_put_uint8(&rqp->rq, 2); /* subfunction */
|
||||
mb_put_uint8(&rqp->rq, nmp->name_space);
|
||||
mb_put_uint8(&rqp->rq, 0); /* reserved */
|
||||
ncp_rq_dbase_path(rqp, volnum, dirent, 0, NULL, NULL);
|
||||
rqp->nr_minrplen = sizeof(np->n_seq);
|
||||
error = ncp_request(rqp);
|
||||
if (error)
|
||||
return error;
|
||||
md_get_mem(&rqp->rp, (caddr_t)&np->n_seq, sizeof(np->n_seq), MB_MSYSTEM);
|
||||
ncp_rq_done(rqp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
ncp_search_for_file_or_subdir(struct nwmount *nmp,
|
||||
struct nw_search_seq *seq,
|
||||
struct nw_entry_info *target,
|
||||
struct thread *td,struct ucred *cred)
|
||||
{
|
||||
struct ncp_conn *conn = NWFSTOCONN(nmp);
|
||||
struct ncp_rq *rqp;
|
||||
int error;
|
||||
|
||||
error = ncp_rq_alloc(87, conn, td, cred, &rqp);
|
||||
if (error)
|
||||
return error;
|
||||
mb_put_uint8(&rqp->rq, 3); /* subfunction */
|
||||
mb_put_uint8(&rqp->rq, nmp->name_space);
|
||||
mb_put_uint8(&rqp->rq, 0); /* data stream */
|
||||
mb_put_uint16le(&rqp->rq, 0xffff); /* Search attribs */
|
||||
mb_put_uint32le(&rqp->rq, IM_ALL); /* return info mask */
|
||||
mb_put_mem(&rqp->rq, (caddr_t)seq, 9, MB_MSYSTEM);
|
||||
mb_put_uint8(&rqp->rq, 2); /* 2 byte pattern */
|
||||
mb_put_uint8(&rqp->rq, 0xff); /* following is a wildcard */
|
||||
mb_put_uint8(&rqp->rq, '*');
|
||||
rqp->nr_minrplen = sizeof(*seq) + 1 + NCP_INFOSZ + 1;
|
||||
error = ncp_request(rqp);
|
||||
if (error)
|
||||
return error;
|
||||
md_get_mem(&rqp->rp, (caddr_t)seq, sizeof(*seq), MB_MSYSTEM);
|
||||
md_get_uint8(&rqp->rp, NULL); /* skip */
|
||||
error = ncp_extract_file_info(nmp, rqp, target, 1);
|
||||
ncp_rq_done(rqp);
|
||||
return error;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
/*
|
||||
* lookup name pointed by cnp in directory dvp and return file info in np.
|
||||
* May be I should create a little cache, but another way is to minimize
|
||||
* number of calls, on other hand, in multiprocess environment ...
|
||||
*/
|
||||
int
|
||||
ncp_lookup(struct vnode *dvp, int len, char *name, struct nw_entry_info *fap,
|
||||
struct thread *td,struct ucred *cred)
|
||||
{
|
||||
struct nwmount *nmp;
|
||||
struct nwnode *dnp;
|
||||
int error;
|
||||
|
||||
if (!dvp || dvp->v_type != VDIR) {
|
||||
nwfs_printf("dvp is NULL or not a directory.\n");
|
||||
return (ENOENT);
|
||||
}
|
||||
dnp = VTONW(dvp);
|
||||
nmp = VTONWFS(dvp);
|
||||
|
||||
if (len == 1 && name[0] == '.') {
|
||||
if (dnp->n_flag & NVOLUME) {
|
||||
error = ncp_obtain_info(nmp, dnp->n_fid.f_id, 0, NULL,
|
||||
fap, td, cred);
|
||||
} else {
|
||||
error = ncp_obtain_info(nmp, dnp->n_fid.f_parent,
|
||||
dnp->n_nmlen, dnp->n_name, fap, td, cred);
|
||||
}
|
||||
return error;
|
||||
} else if (len == 2 && name[0] == '.' && name[1] == '.') {
|
||||
printf("%s: knows NOTHING about '..'\n", __func__);
|
||||
return EIO;
|
||||
} else {
|
||||
error = ncp_obtain_info(nmp, dnp->n_fid.f_id,
|
||||
len, name, fap, td, cred);
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
static void ConvertToNWfromDWORD(u_int32_t sfd, ncp_fh *fh);
|
||||
static void
|
||||
ConvertToNWfromDWORD(u_int32_t sfd, ncp_fh *fh) {
|
||||
fh->val1 = (fh->val.val32 = sfd);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* If both dir and name are NULL, then in target there's already a looked-up
|
||||
* entry that wants to be opened.
|
||||
*/
|
||||
int
|
||||
ncp_open_create_file_or_subdir(struct nwmount *nmp,struct vnode *dvp,int namelen,
|
||||
char *name, int open_create_mode, u_int32_t create_attributes,
|
||||
int desired_acc_rights, struct ncp_open_info *nop,
|
||||
struct thread *td,struct ucred *cred)
|
||||
{
|
||||
|
||||
struct ncp_conn *conn=NWFSTOCONN(nmp);
|
||||
struct ncp_rq *rqp;
|
||||
u_int16_t search_attribs = SA_ALL & (~SA_SUBDIR_FILES);
|
||||
u_int8_t volnum;
|
||||
u_int32_t dirent;
|
||||
int error;
|
||||
|
||||
error = ncp_rq_alloc(87, conn, td, cred, &rqp);
|
||||
if (error)
|
||||
return error;
|
||||
volnum = nmp->n_volume;
|
||||
dirent = VTONW(dvp)->n_fid.f_id;
|
||||
if ((create_attributes & aDIR) != 0) {
|
||||
search_attribs |= SA_SUBDIR_FILES;
|
||||
}
|
||||
mb_put_uint8(&rqp->rq, 1);/* subfunction */
|
||||
mb_put_uint8(&rqp->rq, nmp->name_space);
|
||||
mb_put_uint8(&rqp->rq, open_create_mode);
|
||||
mb_put_uint16le(&rqp->rq, search_attribs);
|
||||
mb_put_uint32le(&rqp->rq, IM_ALL);
|
||||
mb_put_uint32le(&rqp->rq, create_attributes);
|
||||
/*
|
||||
* The desired acc rights seem to be the inherited rights mask for
|
||||
* directories
|
||||
*/
|
||||
mb_put_uint16le(&rqp->rq, desired_acc_rights);
|
||||
ncp_rq_dbase_path(rqp, volnum, dirent, namelen, name, &nmp->m.nls);
|
||||
error = ncp_request(rqp);
|
||||
if (error) {
|
||||
if (error == NWE_FILE_NO_CREATE_PRIV)
|
||||
error = EACCES;
|
||||
return error;
|
||||
}
|
||||
md_get_uint32le(&rqp->rp, &nop->origfh);
|
||||
md_get_uint8(&rqp->rp, &nop->action);
|
||||
md_get_uint8(&rqp->rp, NULL); /* skip */
|
||||
error = ncp_extract_file_info(nmp, rqp, &nop->fattr, 1);
|
||||
ncp_rq_done(rqp);
|
||||
ConvertToNWfromDWORD(nop->origfh, &nop->fh);
|
||||
return error;
|
||||
}
|
||||
|
||||
int
|
||||
ncp_close_file(struct ncp_conn *conn, ncp_fh *fh,struct thread *td,struct ucred *cred)
|
||||
{
|
||||
struct ncp_rq *rqp;
|
||||
int error;
|
||||
|
||||
error = ncp_rq_alloc(66, conn, td, cred, &rqp);
|
||||
if (error)
|
||||
return error;
|
||||
mb_put_uint8(&rqp->rq, 0);
|
||||
mb_put_mem(&rqp->rq, (caddr_t)fh, 6, MB_MSYSTEM);
|
||||
error = ncp_request(rqp);
|
||||
if (error)
|
||||
return error;
|
||||
ncp_rq_done(rqp);
|
||||
return error;
|
||||
}
|
||||
|
||||
int
|
||||
ncp_DeleteNSEntry(struct nwmount *nmp, u_int32_t dirent,
|
||||
int namelen,char *name,struct thread *td,struct ucred *cred)
|
||||
{
|
||||
struct ncp_rq *rqp;
|
||||
int error;
|
||||
struct ncp_conn *conn=NWFSTOCONN(nmp);
|
||||
|
||||
error = ncp_rq_alloc(87, conn, td, cred, &rqp);
|
||||
if (error)
|
||||
return error;
|
||||
mb_put_uint8(&rqp->rq, 8); /* subfunction */
|
||||
mb_put_uint8(&rqp->rq, nmp->name_space);
|
||||
mb_put_uint8(&rqp->rq, 0); /* reserved */
|
||||
mb_put_uint16le(&rqp->rq, SA_ALL); /* search attribs: all */
|
||||
ncp_rq_dbase_path(rqp, nmp->n_volume, dirent, namelen, name, &nmp->m.nls);
|
||||
error = ncp_request(rqp);
|
||||
if (!error)
|
||||
ncp_rq_done(rqp);
|
||||
return error;
|
||||
}
|
||||
|
||||
int
|
||||
ncp_nsrename(struct ncp_conn *conn, int volume, int ns, int oldtype,
|
||||
struct ncp_nlstables *nt,
|
||||
nwdirent fdir, char *old_name, int oldlen,
|
||||
nwdirent tdir, char *new_name, int newlen,
|
||||
struct thread *td, struct ucred *cred)
|
||||
{
|
||||
struct ncp_rq *rqp;
|
||||
int error;
|
||||
|
||||
error = ncp_rq_alloc(87, conn, td, cred, &rqp);
|
||||
if (error)
|
||||
return error;
|
||||
mb_put_uint8(&rqp->rq, 4);
|
||||
mb_put_uint8(&rqp->rq, ns);
|
||||
mb_put_uint8(&rqp->rq, 1); /* RRenameToMySelf */
|
||||
mb_put_uint16le(&rqp->rq, oldtype);
|
||||
/* source Handle Path */
|
||||
mb_put_uint8(&rqp->rq, volume);
|
||||
mb_put_mem(&rqp->rq, (c_caddr_t)&fdir, sizeof(fdir), MB_MSYSTEM);
|
||||
mb_put_uint8(&rqp->rq, 1);
|
||||
mb_put_uint8(&rqp->rq, 1); /* 1 source component */
|
||||
/* dest Handle Path */
|
||||
mb_put_uint8(&rqp->rq, volume);
|
||||
mb_put_mem(&rqp->rq, (c_caddr_t)&tdir, sizeof(tdir), MB_MSYSTEM);
|
||||
mb_put_uint8(&rqp->rq, 1);
|
||||
mb_put_uint8(&rqp->rq, 1); /* 1 destination component */
|
||||
ncp_rq_pathstring(rqp, oldlen, old_name, nt);
|
||||
ncp_rq_pathstring(rqp, newlen, new_name, nt);
|
||||
error = ncp_request(rqp);
|
||||
if (!error)
|
||||
ncp_rq_done(rqp);
|
||||
return error;
|
||||
}
|
||||
|
||||
int
|
||||
ncp_modify_file_or_subdir_dos_info(struct nwmount *nmp, struct vnode *vp,
|
||||
u_int32_t info_mask,
|
||||
struct nw_modify_dos_info *info,
|
||||
struct thread *td,struct ucred *cred)
|
||||
{
|
||||
struct nwnode *np=VTONW(vp);
|
||||
struct ncp_rq *rqp;
|
||||
u_int8_t volnum = nmp->n_volume;
|
||||
u_int32_t dirent = np->n_fid.f_id;
|
||||
struct ncp_conn *conn=NWFSTOCONN(nmp);
|
||||
int error;
|
||||
|
||||
error = ncp_rq_alloc(87, conn, td, cred, &rqp);
|
||||
if (error)
|
||||
return error;
|
||||
mb_put_uint8(&rqp->rq, 7); /* subfunction */
|
||||
mb_put_uint8(&rqp->rq, nmp->name_space);
|
||||
mb_put_uint8(&rqp->rq, 0); /* reserved */
|
||||
mb_put_uint16le(&rqp->rq, SA_ALL); /* search attribs: all */
|
||||
mb_put_uint32le(&rqp->rq, info_mask);
|
||||
mb_put_mem(&rqp->rq, (caddr_t)info, sizeof(*info), MB_MSYSTEM);
|
||||
ncp_rq_dbase_path(rqp, volnum, dirent, 0, NULL, NULL);
|
||||
error = ncp_request(rqp);
|
||||
if (!error)
|
||||
ncp_rq_done(rqp);
|
||||
return error;
|
||||
}
|
||||
|
||||
int
|
||||
ncp_setattr(vp, vap, cred, td)
|
||||
struct vnode *vp;
|
||||
struct vattr *vap;
|
||||
struct ucred *cred;
|
||||
struct thread *td;
|
||||
{
|
||||
struct nwmount *nmp=VTONWFS(vp);
|
||||
struct nwnode *np=VTONW(vp);
|
||||
struct ncp_open_info nwn;
|
||||
struct ncp_conn *conn=NWFSTOCONN(nmp);
|
||||
struct nw_modify_dos_info info;
|
||||
struct ncp_rq *rqp;
|
||||
int error = 0, info_mask;
|
||||
|
||||
if (vap->va_size != VNOVAL) {
|
||||
error = ncp_open_create_file_or_subdir(nmp, vp, 0, NULL, OC_MODE_OPEN, 0,
|
||||
AR_WRITE | AR_READ, &nwn,td,cred);
|
||||
if (error)
|
||||
return error;
|
||||
error = ncp_rq_alloc(73, conn, td, cred, &rqp);
|
||||
if (error) {
|
||||
ncp_close_file(conn, &nwn.fh, td, cred);
|
||||
return error;
|
||||
}
|
||||
mb_put_uint8(&rqp->rq, 0);
|
||||
mb_put_mem(&rqp->rq, (caddr_t)&nwn.fh, 6, MB_MSYSTEM);
|
||||
mb_put_uint32be(&rqp->rq, vap->va_size);
|
||||
mb_put_uint16be(&rqp->rq, 0);
|
||||
error = ncp_request(rqp);
|
||||
np->n_vattr.va_size = np->n_size = vap->va_size;
|
||||
if (!error)
|
||||
ncp_rq_done(rqp);
|
||||
ncp_close_file(conn, &nwn.fh, td, cred);
|
||||
if (error)
|
||||
return error;
|
||||
}
|
||||
info_mask = 0;
|
||||
bzero(&info, sizeof(info));
|
||||
|
||||
if (vap->va_mtime.tv_sec != VNOVAL) {
|
||||
info_mask |= (DM_MODIFY_TIME | DM_MODIFY_DATE);
|
||||
ncp_unix2dostime(&vap->va_mtime, nmp->m.tz, &info.modifyDate, &info.modifyTime, NULL);
|
||||
}
|
||||
if (vap->va_atime.tv_sec != VNOVAL) {
|
||||
info_mask |= (DM_LAST_ACCESS_DATE);
|
||||
ncp_unix2dostime(&vap->va_atime, nmp->m.tz, &info.lastAccessDate, NULL, NULL);
|
||||
}
|
||||
if (info_mask) {
|
||||
error = ncp_modify_file_or_subdir_dos_info(nmp, vp, info_mask, &info,td,cred);
|
||||
}
|
||||
return (error);
|
||||
}
|
||||
|
||||
int
|
||||
ncp_get_volume_info_with_number(struct ncp_conn *conn,
|
||||
int n, struct ncp_volume_info *target,
|
||||
struct thread *td,struct ucred *cred)
|
||||
{
|
||||
struct ncp_rq *rqp;
|
||||
u_int32_t tmp32;
|
||||
u_int8_t len;
|
||||
int error;
|
||||
|
||||
error = ncp_rq_alloc_subfn(22, 44, conn, td, cred, &rqp);
|
||||
if (error)
|
||||
return error;
|
||||
mb_put_uint8(&rqp->rq,n);
|
||||
error = ncp_request(rqp);
|
||||
if (error)
|
||||
return error;
|
||||
md_get_uint32le(&rqp->rp, &target->total_blocks);
|
||||
md_get_uint32le(&rqp->rp, &target->free_blocks);
|
||||
md_get_uint32le(&rqp->rp, &target->purgeable_blocks);
|
||||
md_get_uint32le(&rqp->rp, &target->not_yet_purgeable_blocks);
|
||||
md_get_uint32le(&rqp->rp, &target->total_dir_entries);
|
||||
md_get_uint32le(&rqp->rp, &target->available_dir_entries);
|
||||
md_get_uint32le(&rqp->rp, &tmp32);
|
||||
md_get_uint8(&rqp->rp, &target->sectors_per_block);
|
||||
bzero(&target->volume_name, sizeof(target->volume_name));
|
||||
md_get_uint8(&rqp->rp, &len);
|
||||
if (len > NCP_VOLNAME_LEN) {
|
||||
error = ENAMETOOLONG;
|
||||
} else {
|
||||
md_get_mem(&rqp->rp, (caddr_t)&target->volume_name, len, MB_MSYSTEM);
|
||||
}
|
||||
ncp_rq_done(rqp);
|
||||
return error;
|
||||
}
|
||||
|
||||
int
|
||||
ncp_get_namespaces(struct ncp_conn *conn, u_int32_t volume, int *nsf,
|
||||
struct thread *td,struct ucred *cred)
|
||||
{
|
||||
struct ncp_rq *rqp;
|
||||
int error;
|
||||
u_int8_t ns;
|
||||
u_int16_t nscnt;
|
||||
|
||||
error = ncp_rq_alloc(87, conn, td, cred, &rqp);
|
||||
if (error)
|
||||
return error;
|
||||
mb_put_uint8(&rqp->rq, 24); /* Subfunction: Get Loaded Name Spaces */
|
||||
mb_put_uint16le(&rqp->rq, 0); /* reserved */
|
||||
mb_put_uint8(&rqp->rq, volume);
|
||||
error = ncp_request(rqp);
|
||||
if (error)
|
||||
return error;
|
||||
md_get_uint16le(&rqp->rp, &nscnt);
|
||||
*nsf = 0;
|
||||
while (nscnt-- > 0) {
|
||||
md_get_uint8(&rqp->rp, &ns);
|
||||
*nsf |= 1 << ns;
|
||||
}
|
||||
ncp_rq_done(rqp);
|
||||
return error;
|
||||
}
|
||||
|
||||
int
|
||||
ncp_lookup_volume(struct ncp_conn *conn, char *volname,
|
||||
u_char *volNum, u_int32_t *dirEnt,
|
||||
struct thread *td,struct ucred *cred)
|
||||
{
|
||||
struct ncp_rq *rqp;
|
||||
u_int32_t tmp32;
|
||||
int error;
|
||||
|
||||
NCPNDEBUG("looking up vol %s\n", volname);
|
||||
error = ncp_rq_alloc(87, conn, td, cred, &rqp);
|
||||
if (error)
|
||||
return error;
|
||||
mb_put_uint8(&rqp->rq, 22); /* Subfunction: Generate dir handle */
|
||||
mb_put_uint8(&rqp->rq, 0); /* src name space */
|
||||
mb_put_uint8(&rqp->rq, 0); /* dst name space, always zero */
|
||||
mb_put_uint16le(&rqp->rq, 0); /* dstNSIndicator (Jn) */
|
||||
|
||||
mb_put_uint8(&rqp->rq, 0); /* faked volume number */
|
||||
mb_put_uint32be(&rqp->rq, 0); /* faked dir_base */
|
||||
mb_put_uint8(&rqp->rq, 0xff); /* Don't have a dir_base */
|
||||
mb_put_uint8(&rqp->rq, 1); /* 1 path component */
|
||||
ncp_rq_pstring(rqp, volname);
|
||||
error = ncp_request(rqp);
|
||||
if (error)
|
||||
return error;
|
||||
md_get_uint32le(&rqp->rp, &tmp32);
|
||||
md_get_uint32le(&rqp->rp, dirEnt);
|
||||
md_get_uint8(&rqp->rp, volNum);
|
||||
ncp_rq_done(rqp);
|
||||
return error;
|
||||
}
|
||||
|
||||
/*
|
||||
* XXX: I think the timezone in struct nwfs_args is truly bogus, especially
|
||||
* XXX: considering that nwfs_mount(8) picks this up from the kernel in
|
||||
* XXX: the first place. Since I can't test this, I won't attempt to fix it.
|
||||
* XXX: /phk
|
||||
*/
|
||||
|
||||
void
|
||||
ncp_unix2dostime(tsp, tzoff, ddp, dtp, dhp)
|
||||
struct timespec *tsp;
|
||||
int tzoff;
|
||||
u_int16_t *ddp;
|
||||
u_int16_t *dtp;
|
||||
u_int8_t *dhp;
|
||||
{
|
||||
struct timespec t;
|
||||
|
||||
t = *tsp;
|
||||
|
||||
t.tv_sec = - tzoff * 60 - utc_offset();
|
||||
timespec2fattime(&t, 1, ddp, dtp, dhp);
|
||||
}
|
||||
|
||||
void
|
||||
ncp_dos2unixtime(dd, dt, dh, tzoff, tsp)
|
||||
u_int dd;
|
||||
u_int dt;
|
||||
u_int dh;
|
||||
int tzoff;
|
||||
struct timespec *tsp;
|
||||
{
|
||||
|
||||
fattime2timespec(dd, dt, dh, 1, tsp);
|
||||
tsp->tv_sec += tzoff * 60 + utc_offset();
|
||||
}
|
@ -1,90 +0,0 @@
|
||||
/*-
|
||||
* Copyright (c) 1999 Boris Popov
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
#ifndef _NWFS_SUBR_H_
|
||||
#define _NWFS_SUBR_H_
|
||||
|
||||
extern int nwfs_debuglevel;
|
||||
|
||||
#ifdef MALLOC_DECLARE
|
||||
MALLOC_DECLARE(M_NWFSDATA);
|
||||
#endif
|
||||
|
||||
struct ncp_conn;
|
||||
struct ncp_nlstables;
|
||||
struct ncp_open_info;
|
||||
struct nw_entry_info;
|
||||
struct nw_search_info;
|
||||
struct nwmount;
|
||||
struct thread;
|
||||
struct timespec;
|
||||
struct ucred;
|
||||
struct vattr;
|
||||
struct vnode;
|
||||
|
||||
int ncp_initsearch(struct vnode *dvp,struct thread *td, struct ucred *cred);
|
||||
int ncp_search_for_file_or_subdir(struct nwmount *nmp,struct nw_search_seq *seq,
|
||||
struct nw_entry_info *target,
|
||||
struct thread *td, struct ucred *cred);
|
||||
int ncp_lookup(struct vnode *dvp, int len, char *name, struct nw_entry_info *fap,
|
||||
struct thread *td, struct ucred *cred);
|
||||
int ncp_lookup_volume(struct ncp_conn *conn, char *volname,
|
||||
u_char *volNum, u_int32_t *dirEnt,
|
||||
struct thread *td, struct ucred *cred);
|
||||
int ncp_close_file(struct ncp_conn *conn, ncp_fh *fh,
|
||||
struct thread *td, struct ucred *cred);
|
||||
int ncp_open_create_file_or_subdir(struct nwmount *nmp,struct vnode *dvp, int namelen,char *name,
|
||||
int open_create_mode, u_int32_t create_attributes,
|
||||
int desired_acc_rights, struct ncp_open_info *nop,
|
||||
struct thread *td, struct ucred *cred);
|
||||
int ncp_DeleteNSEntry(struct nwmount *nmp,
|
||||
u_int32_t dirent, int namelen, char *name,
|
||||
struct thread *td, struct ucred *cred);
|
||||
int ncp_nsrename(struct ncp_conn *conn, int volume, int ns, int oldtype,
|
||||
struct ncp_nlstables *nt,
|
||||
nwdirent fdir, char *old_name, int oldlen,
|
||||
nwdirent tdir, char *new_name, int newlen,
|
||||
struct thread *td, struct ucred *cred);
|
||||
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);
|
||||
int ncp_modify_file_or_subdir_dos_info(struct nwmount *nmp, struct vnode *vp,
|
||||
u_int32_t info_mask,
|
||||
struct nw_modify_dos_info *info,
|
||||
struct thread *td, struct ucred *cred);
|
||||
int ncp_setattr(struct vnode *,struct vattr *,struct ucred *,struct thread *td);
|
||||
int ncp_get_namespaces(struct ncp_conn *conn, u_int32_t volume, int *nsf,
|
||||
struct thread *td, struct ucred *cred);
|
||||
int ncp_get_volume_info_with_number(struct ncp_conn *conn,
|
||||
int n, struct ncp_volume_info *target,
|
||||
struct thread *td, struct ucred *cred);
|
||||
|
||||
void ncp_unix2dostime (struct timespec *tsp, int tz, u_int16_t *ddp,
|
||||
u_int16_t *dtp, u_int8_t *dhp);
|
||||
void ncp_dos2unixtime (u_int dd, u_int dt, u_int dh, int tz, struct timespec *tsp);
|
||||
|
||||
#endif /* !_NWFS_SUBR_H_ */
|
@ -1,439 +0,0 @@
|
||||
/*-
|
||||
* Copyright (c) 1999, 2000 Boris Popov
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/proc.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <sys/vnode.h>
|
||||
#include <sys/mount.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/bio.h>
|
||||
#include <sys/buf.h>
|
||||
|
||||
#include <netncp/ncp.h>
|
||||
#include <netncp/ncp_conn.h>
|
||||
#include <netncp/ncp_subr.h>
|
||||
#include <netncp/ncp_ncp.h>
|
||||
#include <netncp/ncp_nls.h>
|
||||
|
||||
#include <fs/nwfs/nwfs.h>
|
||||
#include <fs/nwfs/nwfs_node.h>
|
||||
#include <fs/nwfs/nwfs_subr.h>
|
||||
|
||||
int nwfs_debuglevel = 0;
|
||||
|
||||
static int nwfs_version = NWFS_VERSION;
|
||||
|
||||
SYSCTL_DECL(_vfs_nwfs);
|
||||
SYSCTL_NODE(_vfs, OID_AUTO, nwfs, CTLFLAG_RW, 0, "Netware filesystem");
|
||||
SYSCTL_INT(_vfs_nwfs, OID_AUTO, version, CTLFLAG_RD, &nwfs_version, 0, "");
|
||||
SYSCTL_INT(_vfs_nwfs, OID_AUTO, debuglevel, CTLFLAG_RW, &nwfs_debuglevel, 0, "");
|
||||
|
||||
MODULE_DEPEND(nwfs, ncp, 1, 1, 1);
|
||||
MODULE_DEPEND(nwfs, libmchain, 1, 1, 1);
|
||||
|
||||
static vfs_cmount_t nwfs_cmount;
|
||||
static vfs_mount_t nwfs_mount;
|
||||
static vfs_quotactl_t nwfs_quotactl;
|
||||
static vfs_root_t nwfs_root;
|
||||
static vfs_statfs_t nwfs_statfs;
|
||||
static vfs_unmount_t nwfs_unmount;
|
||||
static vfs_init_t nwfs_init;
|
||||
static vfs_uninit_t nwfs_uninit;
|
||||
|
||||
static struct vfsops nwfs_vfsops = {
|
||||
.vfs_init = nwfs_init,
|
||||
.vfs_mount = nwfs_mount,
|
||||
.vfs_cmount = nwfs_cmount,
|
||||
.vfs_quotactl = nwfs_quotactl,
|
||||
.vfs_root = nwfs_root,
|
||||
.vfs_statfs = nwfs_statfs,
|
||||
.vfs_sync = vfs_stdsync,
|
||||
.vfs_uninit = nwfs_uninit,
|
||||
.vfs_unmount = nwfs_unmount,
|
||||
};
|
||||
|
||||
|
||||
VFS_SET(nwfs_vfsops, nwfs, VFCF_NETWORK);
|
||||
|
||||
int nwfs_pbuf_freecnt = -1; /* start out unlimited */
|
||||
static int nwfsid = 1;
|
||||
|
||||
static int
|
||||
nwfs_initnls(struct nwmount *nmp) {
|
||||
char *pc, *pe;
|
||||
int error = 0;
|
||||
#define COPY_TABLE(t,d) { \
|
||||
if (t) { \
|
||||
error = copyin((t), pc, 256); \
|
||||
if (error) break; \
|
||||
} else \
|
||||
bcopy(d, pc, 256); \
|
||||
(t) = pc; pc += 256; \
|
||||
}
|
||||
|
||||
nmp->m.nls.opt |= NWHP_NLS | NWHP_DOS;
|
||||
if ((nmp->m.flags & NWFS_MOUNT_HAVE_NLS) == 0) {
|
||||
nmp->m.nls.to_lower = ncp_defnls.to_lower;
|
||||
nmp->m.nls.to_upper = ncp_defnls.to_upper;
|
||||
nmp->m.nls.n2u = ncp_defnls.n2u;
|
||||
nmp->m.nls.u2n = ncp_defnls.u2n;
|
||||
return 0;
|
||||
}
|
||||
pe = malloc(256 * 4, M_NWFSDATA, M_WAITOK);
|
||||
pc = pe;
|
||||
do {
|
||||
COPY_TABLE(nmp->m.nls.to_lower, ncp_defnls.to_lower);
|
||||
COPY_TABLE(nmp->m.nls.to_upper, ncp_defnls.to_upper);
|
||||
COPY_TABLE(nmp->m.nls.n2u, ncp_defnls.n2u);
|
||||
COPY_TABLE(nmp->m.nls.u2n, ncp_defnls.u2n);
|
||||
} while(0);
|
||||
if (error) {
|
||||
free(pe, M_NWFSDATA);
|
||||
return error;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int nwfs_cmount(struct mntarg *ma, void *data, uint64_t flags)
|
||||
{
|
||||
struct nwfs_args args; /* will hold data from mount request */
|
||||
int error;
|
||||
|
||||
error = copyin(data, &args, sizeof(struct nwfs_args));
|
||||
if (error)
|
||||
return (error);
|
||||
|
||||
/*
|
||||
* XXX: cheap cop-out here, args contains a structure I don't
|
||||
* XXX: know how we should handle, and I don't see any immediate
|
||||
* XXX: prospect of avoiding a mount_nwfs(8) binary anyway.
|
||||
*/
|
||||
ma = mount_arg(ma, "nwfs_args", &args, sizeof args);
|
||||
|
||||
error = kernel_mount(ma, flags);
|
||||
|
||||
return (error);
|
||||
}
|
||||
|
||||
/*
|
||||
* mp - path - addr in user space of mount point (ie /usr or whatever)
|
||||
* data - addr in user space of mount params
|
||||
*/
|
||||
static int nwfs_mount(struct mount *mp)
|
||||
{
|
||||
struct nwfs_args args; /* will hold data from mount request */
|
||||
int error;
|
||||
struct nwmount *nmp = NULL;
|
||||
struct ncp_conn *conn = NULL;
|
||||
struct ncp_handle *handle = NULL;
|
||||
struct vnode *vp;
|
||||
struct thread *td;
|
||||
char *pc,*pe;
|
||||
|
||||
td = curthread;
|
||||
if (mp->mnt_flag & MNT_ROOTFS)
|
||||
return (EOPNOTSUPP);
|
||||
if (mp->mnt_flag & MNT_UPDATE) {
|
||||
nwfs_printf("MNT_UPDATE not implemented");
|
||||
return (EOPNOTSUPP);
|
||||
}
|
||||
error = vfs_copyopt(mp->mnt_optnew, "nwfs_args", &args, sizeof args);
|
||||
if (error)
|
||||
return (error);
|
||||
if (args.version != NWFS_VERSION) {
|
||||
nwfs_printf("mount version mismatch: kernel=%d, mount=%d\n",NWFS_VERSION,args.version);
|
||||
return (1);
|
||||
}
|
||||
error = ncp_conn_getbyref(args.connRef, td , td->td_ucred,NCPM_EXECUTE,&conn);
|
||||
if (error) {
|
||||
nwfs_printf("invalid connection refernce %d\n",args.connRef);
|
||||
return (error);
|
||||
}
|
||||
error = ncp_conn_gethandle(conn, NULL, &handle);
|
||||
if (error) {
|
||||
nwfs_printf("can't get connection handle\n");
|
||||
return (error);
|
||||
}
|
||||
ncp_conn_unlock(conn, td); /* we keep the ref */
|
||||
mp->mnt_stat.f_iosize = conn->buffer_size;
|
||||
/* We must malloc our own mount info */
|
||||
nmp = malloc(sizeof(struct nwmount), M_NWFSDATA, M_WAITOK | M_ZERO);
|
||||
if (nmp == NULL) {
|
||||
nwfs_printf("could not alloc nwmount\n");
|
||||
error = ENOMEM;
|
||||
goto bad;
|
||||
}
|
||||
mp->mnt_data = nmp;
|
||||
nmp->connh = handle;
|
||||
nmp->n_root = NULL;
|
||||
nmp->n_id = nwfsid++;
|
||||
nmp->m = args;
|
||||
nmp->m.file_mode = (nmp->m.file_mode &
|
||||
(S_IRWXU|S_IRWXG|S_IRWXO)) | S_IFREG;
|
||||
nmp->m.dir_mode = (nmp->m.dir_mode &
|
||||
(S_IRWXU|S_IRWXG|S_IRWXO)) | S_IFDIR;
|
||||
if ((error = nwfs_initnls(nmp)) != 0) goto bad;
|
||||
pc = mp->mnt_stat.f_mntfromname;
|
||||
pe = pc+sizeof(mp->mnt_stat.f_mntfromname);
|
||||
bzero(pc, MNAMELEN);
|
||||
*(pc++) = '/';
|
||||
pc = strchr(strncpy(pc, conn->li.server, pe - pc - 2), 0);
|
||||
if (pc < pe-1) {
|
||||
*(pc++) = ':';
|
||||
pc = strchr(strncpy(pc, conn->li.user, pe - pc - 2), 0);
|
||||
if (pc < pe-1) {
|
||||
*(pc++) = '/';
|
||||
strncpy(pc, nmp->m.mounted_vol, pe-pc-2);
|
||||
}
|
||||
}
|
||||
/* protect against invalid mount points */
|
||||
nmp->m.mount_point[sizeof(nmp->m.mount_point)-1] = '\0';
|
||||
vfs_getnewfsid(mp);
|
||||
error = nwfs_root(mp, LK_EXCLUSIVE, &vp);
|
||||
if (error)
|
||||
goto bad;
|
||||
/*
|
||||
* Lose the lock but keep the ref.
|
||||
*/
|
||||
VOP_UNLOCK(vp, 0);
|
||||
NCPVODEBUG("rootvp.vrefcnt=%d\n",vrefcnt(vp));
|
||||
return error;
|
||||
bad:
|
||||
if (nmp)
|
||||
free(nmp, M_NWFSDATA);
|
||||
if (handle)
|
||||
ncp_conn_puthandle(handle, NULL, 0);
|
||||
return error;
|
||||
}
|
||||
|
||||
/* Unmount the filesystem described by mp. */
|
||||
static int
|
||||
nwfs_unmount(struct mount *mp, int mntflags)
|
||||
{
|
||||
struct thread *td;
|
||||
struct nwmount *nmp = VFSTONWFS(mp);
|
||||
struct ncp_conn *conn;
|
||||
int error, flags;
|
||||
|
||||
NCPVODEBUG("nwfs_unmount: flags=%04x\n",mntflags);
|
||||
td = curthread;
|
||||
flags = 0;
|
||||
if (mntflags & MNT_FORCE)
|
||||
flags |= FORCECLOSE;
|
||||
/* There is 1 extra root vnode reference from nwfs_mount(). */
|
||||
error = vflush(mp, 1, flags, td);
|
||||
if (error)
|
||||
return (error);
|
||||
conn = NWFSTOCONN(nmp);
|
||||
ncp_conn_puthandle(nmp->connh,NULL,0);
|
||||
if (ncp_conn_lock(conn, td, td->td_ucred,NCPM_WRITE | NCPM_EXECUTE) == 0) {
|
||||
if(ncp_conn_free(conn))
|
||||
ncp_conn_unlock(conn, td);
|
||||
}
|
||||
mp->mnt_data = NULL;
|
||||
if (nmp->m.flags & NWFS_MOUNT_HAVE_NLS)
|
||||
free(nmp->m.nls.to_lower, M_NWFSDATA);
|
||||
free(nmp, M_NWFSDATA);
|
||||
MNT_ILOCK(mp);
|
||||
mp->mnt_flag &= ~MNT_LOCAL;
|
||||
MNT_IUNLOCK(mp);
|
||||
return (error);
|
||||
}
|
||||
|
||||
/* Return locked vnode to root of a filesystem */
|
||||
static int
|
||||
nwfs_root(struct mount *mp, int flags, struct vnode **vpp) {
|
||||
struct vnode *vp;
|
||||
struct nwmount *nmp;
|
||||
struct nwnode *np;
|
||||
struct ncp_conn *conn;
|
||||
struct nw_entry_info fattr;
|
||||
struct thread *td;
|
||||
struct ucred *cred;
|
||||
int error, nsf, opt;
|
||||
u_char vol;
|
||||
|
||||
td = curthread;
|
||||
cred = td->td_ucred;
|
||||
|
||||
nmp = VFSTONWFS(mp);
|
||||
conn = NWFSTOCONN(nmp);
|
||||
if (nmp->n_root) {
|
||||
*vpp = NWTOV(nmp->n_root);
|
||||
while (vget(*vpp, LK_EXCLUSIVE, curthread) != 0)
|
||||
;
|
||||
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, "#.ROOT"));
|
||||
nmp->n_rootent.f_parent = nmp->n_rootent.f_id;
|
||||
}
|
||||
error = nwfs_nget(mp, nmp->n_rootent, &fattr, NULL, &vp);
|
||||
if (error)
|
||||
return (error);
|
||||
vp->v_vflag |= VV_ROOT;
|
||||
np = VTONW(vp);
|
||||
if (nmp->m.root_path[0] == 0)
|
||||
np->n_flag |= NVOLUME;
|
||||
nmp->n_root = np;
|
||||
/* error = VOP_GETATTR(vp, &vattr, cred, td);
|
||||
if (error) {
|
||||
vput(vp);
|
||||
NCPFATAL("Can't get root directory entry\n");
|
||||
return error;
|
||||
}*/
|
||||
*vpp = vp;
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Do operations associated with quotas, not supported
|
||||
*/
|
||||
/* ARGSUSED */
|
||||
static int
|
||||
nwfs_quotactl(mp, cmd, uid, arg)
|
||||
struct mount *mp;
|
||||
int cmd;
|
||||
uid_t uid;
|
||||
void *arg;
|
||||
{
|
||||
NCPVODEBUG("return EOPNOTSUPP\n");
|
||||
return (EOPNOTSUPP);
|
||||
}
|
||||
|
||||
/*ARGSUSED*/
|
||||
int
|
||||
nwfs_init(struct vfsconf *vfsp)
|
||||
{
|
||||
nwfs_hash_init();
|
||||
nwfs_pbuf_freecnt = nswbuf / 2 + 1;
|
||||
NCPVODEBUG("always happy to load!\n");
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*ARGSUSED*/
|
||||
int
|
||||
nwfs_uninit(struct vfsconf *vfsp)
|
||||
{
|
||||
|
||||
nwfs_hash_free();
|
||||
NCPVODEBUG("unloaded\n");
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* nwfs_statfs call
|
||||
*/
|
||||
int
|
||||
nwfs_statfs(mp, sbp)
|
||||
struct mount *mp;
|
||||
struct statfs *sbp;
|
||||
{
|
||||
struct nwmount *nmp = VFSTONWFS(mp);
|
||||
struct thread *td = curthread;
|
||||
int error = 0, secsize;
|
||||
struct nwnode *np = nmp->n_root;
|
||||
struct ncp_volume_info vi;
|
||||
|
||||
if (np == NULL) return EINVAL;
|
||||
error = ncp_get_volume_info_with_number(NWFSTOCONN(nmp),
|
||||
nmp->n_volume, &vi, td, td->td_ucred);
|
||||
if (error) return error;
|
||||
secsize = 512; /* XXX how to get real value ??? */
|
||||
/* fundamental filesystem block size */
|
||||
sbp->f_bsize = vi.sectors_per_block*secsize;
|
||||
/* optimal transfer block size */
|
||||
sbp->f_iosize = NWFSTOCONN(nmp)->buffer_size;
|
||||
/* total data blocks in filesystem */
|
||||
sbp->f_blocks= vi.total_blocks;
|
||||
/* free blocks in fs */
|
||||
sbp->f_bfree = vi.free_blocks + vi.purgeable_blocks;
|
||||
/* free blocks avail to non-superuser */
|
||||
sbp->f_bavail= vi.free_blocks+vi.purgeable_blocks;
|
||||
/* total file nodes in filesystem */
|
||||
sbp->f_files = vi.total_dir_entries;
|
||||
/* free file nodes in fs */
|
||||
sbp->f_ffree = vi.available_dir_entries;
|
||||
sbp->f_flags = 0; /* copy of mount exported flags */
|
||||
return 0;
|
||||
}
|
@ -1,967 +0,0 @@
|
||||
/*-
|
||||
* Copyright (c) 1999, 2000, 2001 Boris Popov
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/namei.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/bio.h>
|
||||
#include <sys/buf.h>
|
||||
#include <sys/fcntl.h>
|
||||
#include <sys/mount.h>
|
||||
#include <sys/unistd.h>
|
||||
#include <sys/vnode.h>
|
||||
|
||||
#include <vm/vm.h>
|
||||
#include <vm/vm_extern.h>
|
||||
|
||||
#include <netncp/ncp.h>
|
||||
#include <netncp/ncp_conn.h>
|
||||
#include <netncp/ncp_subr.h>
|
||||
#include <netncp/nwerror.h>
|
||||
#include <netncp/ncp_nls.h>
|
||||
|
||||
#include <fs/nwfs/nwfs.h>
|
||||
#include <fs/nwfs/nwfs_node.h>
|
||||
#include <fs/nwfs/nwfs_subr.h>
|
||||
|
||||
/*
|
||||
* Prototypes for NWFS vnode operations
|
||||
*/
|
||||
static vop_create_t nwfs_create;
|
||||
static vop_mknod_t nwfs_mknod;
|
||||
static vop_open_t nwfs_open;
|
||||
static vop_close_t nwfs_close;
|
||||
static vop_access_t nwfs_access;
|
||||
static vop_getattr_t nwfs_getattr;
|
||||
static vop_setattr_t nwfs_setattr;
|
||||
static vop_read_t nwfs_read;
|
||||
static vop_write_t nwfs_write;
|
||||
static vop_fsync_t nwfs_fsync;
|
||||
static vop_remove_t nwfs_remove;
|
||||
static vop_link_t nwfs_link;
|
||||
static vop_lookup_t nwfs_lookup;
|
||||
static vop_rename_t nwfs_rename;
|
||||
static vop_mkdir_t nwfs_mkdir;
|
||||
static vop_rmdir_t nwfs_rmdir;
|
||||
static vop_symlink_t nwfs_symlink;
|
||||
static vop_readdir_t nwfs_readdir;
|
||||
static vop_strategy_t nwfs_strategy;
|
||||
static vop_print_t nwfs_print;
|
||||
static vop_pathconf_t nwfs_pathconf;
|
||||
|
||||
/* Global vfs data structures for nwfs */
|
||||
struct vop_vector nwfs_vnodeops = {
|
||||
.vop_default = &default_vnodeops,
|
||||
|
||||
.vop_access = nwfs_access,
|
||||
.vop_close = nwfs_close,
|
||||
.vop_create = nwfs_create,
|
||||
.vop_fsync = nwfs_fsync,
|
||||
.vop_getattr = nwfs_getattr,
|
||||
.vop_getpages = nwfs_getpages,
|
||||
.vop_inactive = nwfs_inactive,
|
||||
.vop_ioctl = nwfs_ioctl,
|
||||
.vop_link = nwfs_link,
|
||||
.vop_lookup = nwfs_lookup,
|
||||
.vop_mkdir = nwfs_mkdir,
|
||||
.vop_mknod = nwfs_mknod,
|
||||
.vop_open = nwfs_open,
|
||||
.vop_pathconf = nwfs_pathconf,
|
||||
.vop_print = nwfs_print,
|
||||
.vop_putpages = nwfs_putpages,
|
||||
.vop_read = nwfs_read,
|
||||
.vop_readdir = nwfs_readdir,
|
||||
.vop_reclaim = nwfs_reclaim,
|
||||
.vop_remove = nwfs_remove,
|
||||
.vop_rename = nwfs_rename,
|
||||
.vop_rmdir = nwfs_rmdir,
|
||||
.vop_setattr = nwfs_setattr,
|
||||
.vop_strategy = nwfs_strategy,
|
||||
.vop_symlink = nwfs_symlink,
|
||||
.vop_write = nwfs_write,
|
||||
};
|
||||
|
||||
/*
|
||||
* nwfs_access vnode op
|
||||
*/
|
||||
static int
|
||||
nwfs_access(ap)
|
||||
struct vop_access_args /* {
|
||||
struct vnode *a_vp;
|
||||
accmode_t a_accmode;
|
||||
struct ucred *a_cred;
|
||||
struct thread *td;
|
||||
} */ *ap;
|
||||
{
|
||||
struct vnode *vp = ap->a_vp;
|
||||
mode_t mpmode;
|
||||
struct nwmount *nmp = VTONWFS(vp);
|
||||
|
||||
NCPVNDEBUG("\n");
|
||||
if ((ap->a_accmode & VWRITE) && (vp->v_mount->mnt_flag & MNT_RDONLY)) {
|
||||
switch (vp->v_type) {
|
||||
case VREG: case VDIR: case VLNK:
|
||||
return (EROFS);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
mpmode = vp->v_type == VREG ? nmp->m.file_mode :
|
||||
nmp->m.dir_mode;
|
||||
return (vaccess(vp->v_type, mpmode, nmp->m.uid,
|
||||
nmp->m.gid, ap->a_accmode, ap->a_cred, NULL));
|
||||
}
|
||||
/*
|
||||
* nwfs_open vnode op
|
||||
*/
|
||||
/* ARGSUSED */
|
||||
static int
|
||||
nwfs_open(ap)
|
||||
struct vop_open_args /* {
|
||||
struct vnode *a_vp;
|
||||
int a_mode;
|
||||
struct ucred *a_cred;
|
||||
struct thread *td;
|
||||
} */ *ap;
|
||||
{
|
||||
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, ap->a_td)) == EINTR)
|
||||
return (error);
|
||||
np->n_atime = 0;
|
||||
error = VOP_GETATTR(vp, &vattr, ap->a_cred);
|
||||
if (error) return (error);
|
||||
np->n_mtime = vattr.va_mtime.tv_sec;
|
||||
} else {
|
||||
error = VOP_GETATTR(vp, &vattr, ap->a_cred);
|
||||
if (error) return (error);
|
||||
if (np->n_mtime != vattr.va_mtime.tv_sec) {
|
||||
if ((error = nwfs_vinvalbuf(vp, ap->a_td)) == EINTR)
|
||||
return (error);
|
||||
np->n_mtime = vattr.va_mtime.tv_sec;
|
||||
}
|
||||
}
|
||||
if (np->opened) {
|
||||
np->opened++;
|
||||
return 0;
|
||||
}
|
||||
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, ap->a_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, ap->a_td, ap->a_cred);
|
||||
}
|
||||
if (!error) {
|
||||
np->opened++;
|
||||
np->n_fh = no.fh;
|
||||
np->n_origfh = no.origfh;
|
||||
}
|
||||
np->n_atime = 0;
|
||||
return (error);
|
||||
}
|
||||
|
||||
static int
|
||||
nwfs_close(ap)
|
||||
struct vop_close_args /* {
|
||||
struct vnodeop_desc *a_desc;
|
||||
struct vnode *a_vp;
|
||||
int a_fflag;
|
||||
struct ucred *a_cred;
|
||||
struct thread *td;
|
||||
} */ *ap;
|
||||
{
|
||||
struct vnode *vp = ap->a_vp;
|
||||
struct nwnode *np = VTONW(vp);
|
||||
int error;
|
||||
|
||||
NCPVNDEBUG("name=%s,pid=%d,c=%d\n", np->n_name, ap->a_td->td_proc->p_pid,
|
||||
np->opened);
|
||||
|
||||
if (vp->v_type == VDIR) return 0; /* nothing to do now */
|
||||
error = 0;
|
||||
VI_LOCK(vp);
|
||||
if (np->opened == 0) {
|
||||
VI_UNLOCK(vp);
|
||||
return 0;
|
||||
}
|
||||
VI_UNLOCK(vp);
|
||||
error = nwfs_vinvalbuf(vp, ap->a_td);
|
||||
VI_LOCK(vp);
|
||||
if (np->opened == 0) {
|
||||
VI_UNLOCK(vp);
|
||||
return 0;
|
||||
}
|
||||
if (--np->opened == 0) {
|
||||
VI_UNLOCK(vp);
|
||||
error = ncp_close_file(NWFSTOCONN(VTONWFS(vp)), &np->n_fh,
|
||||
ap->a_td, ap->a_cred);
|
||||
} else
|
||||
VI_UNLOCK(vp);
|
||||
np->n_atime = 0;
|
||||
return (error);
|
||||
}
|
||||
|
||||
/*
|
||||
* nwfs_getattr call from vfs.
|
||||
*/
|
||||
static int
|
||||
nwfs_getattr(ap)
|
||||
struct vop_getattr_args /* {
|
||||
struct vnode *a_vp;
|
||||
struct vattr *a_vap;
|
||||
struct ucred *a_cred;
|
||||
} */ *ap;
|
||||
{
|
||||
struct vnode *vp = ap->a_vp;
|
||||
struct nwnode *np = VTONW(vp);
|
||||
struct vattr *va=ap->a_vap;
|
||||
struct nwmount *nmp = VTONWFS(vp);
|
||||
struct thread *td = curthread;
|
||||
struct nw_entry_info fattr;
|
||||
int error;
|
||||
u_int32_t oldsize;
|
||||
|
||||
NCPVNDEBUG("%lx:%d: '%s' %d\n", (long)vp, nmp->n_volume, np->n_name, (vp->v_vflag & VV_ROOT) != 0);
|
||||
error = nwfs_attr_cachelookup(vp, va);
|
||||
if (!error) return 0;
|
||||
NCPVNDEBUG("not in cache\n");
|
||||
oldsize = np->n_size;
|
||||
if (np->n_flag & NVOLUME) {
|
||||
error = ncp_obtain_info(nmp, np->n_fid.f_id, 0, NULL, &fattr,
|
||||
td, ap->a_cred);
|
||||
} else {
|
||||
error = ncp_obtain_info(nmp, np->n_fid.f_parent, np->n_nmlen,
|
||||
np->n_name, &fattr, td, ap->a_cred);
|
||||
}
|
||||
if (error) {
|
||||
NCPVNDEBUG("error %d\n", error);
|
||||
return error;
|
||||
}
|
||||
nwfs_attr_cacheenter(vp, &fattr);
|
||||
*va = np->n_vattr;
|
||||
if (np->opened)
|
||||
np->n_size = oldsize;
|
||||
return (0);
|
||||
}
|
||||
/*
|
||||
* nwfs_setattr call from vfs.
|
||||
*/
|
||||
static int
|
||||
nwfs_setattr(ap)
|
||||
struct vop_setattr_args /* {
|
||||
struct vnode *a_vp;
|
||||
struct vattr *a_vap;
|
||||
struct ucred *a_cred;
|
||||
} */ *ap;
|
||||
{
|
||||
struct vnode *vp = ap->a_vp;
|
||||
struct nwnode *np = VTONW(vp);
|
||||
struct vattr *vap = ap->a_vap;
|
||||
u_quad_t tsize=0;
|
||||
int error = 0;
|
||||
|
||||
NCPVNDEBUG("\n");
|
||||
if (vap->va_flags != VNOVAL)
|
||||
return (EOPNOTSUPP);
|
||||
/*
|
||||
* Disallow write attempts if the filesystem is mounted read-only.
|
||||
*/
|
||||
if ((vap->va_uid != (uid_t)VNOVAL || vap->va_gid != (gid_t)VNOVAL ||
|
||||
vap->va_atime.tv_sec != VNOVAL || vap->va_mtime.tv_sec != VNOVAL ||
|
||||
vap->va_mode != (mode_t)VNOVAL) &&(vp->v_mount->mnt_flag & MNT_RDONLY))
|
||||
return (EROFS);
|
||||
if (vap->va_size != VNOVAL) {
|
||||
switch (vp->v_type) {
|
||||
case VDIR:
|
||||
return (EISDIR);
|
||||
case VREG:
|
||||
/*
|
||||
* Disallow write attempts if the filesystem is
|
||||
* mounted read-only.
|
||||
*/
|
||||
if (vp->v_mount->mnt_flag & MNT_RDONLY)
|
||||
return (EROFS);
|
||||
vnode_pager_setsize(vp, (u_long)vap->va_size);
|
||||
tsize = np->n_size;
|
||||
np->n_size = vap->va_size;
|
||||
break;
|
||||
default:
|
||||
return EINVAL;
|
||||
};
|
||||
}
|
||||
error = ncp_setattr(vp, vap, ap->a_cred, curthread);
|
||||
if (error && vap->va_size != VNOVAL) {
|
||||
np->n_size = tsize;
|
||||
vnode_pager_setsize(vp, (u_long)tsize);
|
||||
}
|
||||
np->n_atime = 0; /* invalidate cache */
|
||||
VOP_GETATTR(vp, vap, ap->a_cred);
|
||||
np->n_mtime = vap->va_mtime.tv_sec;
|
||||
return (0);
|
||||
}
|
||||
/*
|
||||
* nwfs_read call.
|
||||
*/
|
||||
static int
|
||||
nwfs_read(ap)
|
||||
struct vop_read_args /* {
|
||||
struct vnode *a_vp;
|
||||
struct uio *a_uio;
|
||||
int a_ioflag;
|
||||
struct ucred *a_cred;
|
||||
} */ *ap;
|
||||
{
|
||||
struct vnode *vp = ap->a_vp;
|
||||
struct uio *uio=ap->a_uio;
|
||||
int error;
|
||||
NCPVNDEBUG("nwfs_read:\n");
|
||||
|
||||
if (vp->v_type != VREG && vp->v_type != VDIR)
|
||||
return (EPERM);
|
||||
error = nwfs_readvnode(vp, uio, ap->a_cred);
|
||||
return error;
|
||||
}
|
||||
|
||||
static int
|
||||
nwfs_write(ap)
|
||||
struct vop_write_args /* {
|
||||
struct vnode *a_vp;
|
||||
struct uio *a_uio;
|
||||
int a_ioflag;
|
||||
struct ucred *a_cred;
|
||||
} */ *ap;
|
||||
{
|
||||
struct vnode *vp = ap->a_vp;
|
||||
struct uio *uio = ap->a_uio;
|
||||
int error;
|
||||
|
||||
NCPVNDEBUG("%d,ofs=%d,sz=%d\n", vp->v_type, (int)uio->uio_offset, uio->uio_resid);
|
||||
|
||||
if (vp->v_type != VREG)
|
||||
return (EPERM);
|
||||
error = nwfs_writevnode(vp, uio, ap->a_cred, ap->a_ioflag);
|
||||
return(error);
|
||||
}
|
||||
/*
|
||||
* nwfs_create call
|
||||
* Create a regular file. On entry the directory to contain the file being
|
||||
* created is locked. We must release before we return. We must also free
|
||||
* the pathname buffer pointed at by cnp->cn_pnbuf, always on error, or
|
||||
* only if the SAVESTART bit in cn_flags is clear on success.
|
||||
*/
|
||||
static int
|
||||
nwfs_create(ap)
|
||||
struct vop_create_args /* {
|
||||
struct vnode *a_dvp;
|
||||
struct vnode **a_vpp;
|
||||
struct componentname *a_cnp;
|
||||
struct vattr *a_vap;
|
||||
} */ *ap;
|
||||
{
|
||||
struct vnode *dvp = ap->a_dvp;
|
||||
struct vattr *vap = ap->a_vap;
|
||||
struct vnode **vpp=ap->a_vpp;
|
||||
struct componentname *cnp = ap->a_cnp;
|
||||
struct vnode *vp = (struct vnode *)0;
|
||||
int error = 0, fmode;
|
||||
struct vattr vattr;
|
||||
struct nwnode *np;
|
||||
struct ncp_open_info no;
|
||||
struct nwmount *nmp=VTONWFS(dvp);
|
||||
ncpfid fid;
|
||||
|
||||
|
||||
NCPVNDEBUG("\n");
|
||||
*vpp = NULL;
|
||||
if (vap->va_type == VSOCK)
|
||||
return (EOPNOTSUPP);
|
||||
if ((error = VOP_GETATTR(dvp, &vattr, cnp->cn_cred)))
|
||||
return (error);
|
||||
fmode = AR_READ | AR_WRITE;
|
||||
/* if (vap->va_vaflags & VA_EXCLUSIVE)
|
||||
fmode |= AR_DENY_READ | AR_DENY_WRITE;*/
|
||||
|
||||
error = ncp_open_create_file_or_subdir(nmp, dvp, cnp->cn_namelen, cnp->cn_nameptr,
|
||||
OC_MODE_CREATE | OC_MODE_OPEN | OC_MODE_REPLACE,
|
||||
0, fmode, &no, cnp->cn_thread, cnp->cn_cred);
|
||||
if (!error) {
|
||||
error = ncp_close_file(NWFSTOCONN(nmp), &no.fh, cnp->cn_thread, cnp->cn_cred);
|
||||
fid.f_parent = VTONW(dvp)->n_fid.f_id;
|
||||
fid.f_id = no.fattr.dirEntNum;
|
||||
error = nwfs_nget(VTOVFS(dvp), fid, &no.fattr, dvp, &vp);
|
||||
if (!error) {
|
||||
np = VTONW(vp);
|
||||
np->opened = 0;
|
||||
*vpp = vp;
|
||||
}
|
||||
if (cnp->cn_flags & MAKEENTRY)
|
||||
cache_enter(dvp, vp, cnp);
|
||||
}
|
||||
return (error);
|
||||
}
|
||||
|
||||
/*
|
||||
* nwfs_remove call. It isn't possible to emulate UFS behaivour because
|
||||
* NetWare doesn't allow delete/rename operations on an opened file.
|
||||
*/
|
||||
static int
|
||||
nwfs_remove(ap)
|
||||
struct vop_remove_args /* {
|
||||
struct vnodeop_desc *a_desc;
|
||||
struct vnode * a_dvp;
|
||||
struct vnode * a_vp;
|
||||
struct componentname * a_cnp;
|
||||
} */ *ap;
|
||||
{
|
||||
struct vnode *vp = ap->a_vp;
|
||||
struct vnode *dvp = ap->a_dvp;
|
||||
struct componentname *cnp = ap->a_cnp;
|
||||
struct nwnode *np = VTONW(vp);
|
||||
struct nwmount *nmp = VTONWFS(vp);
|
||||
int error;
|
||||
|
||||
if (vp->v_type == VDIR || np->opened || vrefcnt(vp) != 1)
|
||||
return EPERM;
|
||||
cache_purge(vp);
|
||||
error = ncp_DeleteNSEntry(nmp, VTONW(dvp)->n_fid.f_id,
|
||||
cnp->cn_namelen, cnp->cn_nameptr, cnp->cn_thread, cnp->cn_cred);
|
||||
if (error == 0)
|
||||
np->n_flag |= NSHOULDFREE;
|
||||
else if (error == 0x899c)
|
||||
error = EACCES;
|
||||
return (error);
|
||||
}
|
||||
|
||||
/*
|
||||
* nwfs_file rename call
|
||||
*/
|
||||
static int
|
||||
nwfs_rename(ap)
|
||||
struct vop_rename_args /* {
|
||||
struct vnode *a_fdvp;
|
||||
struct vnode *a_fvp;
|
||||
struct componentname *a_fcnp;
|
||||
struct vnode *a_tdvp;
|
||||
struct vnode *a_tvp;
|
||||
struct componentname *a_tcnp;
|
||||
} */ *ap;
|
||||
{
|
||||
struct vnode *fvp = ap->a_fvp;
|
||||
struct vnode *tvp = ap->a_tvp;
|
||||
struct vnode *fdvp = ap->a_fdvp;
|
||||
struct vnode *tdvp = ap->a_tdvp;
|
||||
struct componentname *tcnp = ap->a_tcnp;
|
||||
struct componentname *fcnp = ap->a_fcnp;
|
||||
struct nwmount *nmp=VTONWFS(fvp);
|
||||
u_int16_t oldtype = 6;
|
||||
int error=0;
|
||||
|
||||
/* Check for cross-device rename */
|
||||
if ((fvp->v_mount != tdvp->v_mount) ||
|
||||
(tvp && (fvp->v_mount != tvp->v_mount))) {
|
||||
error = EXDEV;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (tvp && vrefcnt(tvp) > 1) {
|
||||
error = EBUSY;
|
||||
goto out;
|
||||
}
|
||||
if (fvp->v_type == VDIR) {
|
||||
oldtype |= NW_TYPE_SUBDIR;
|
||||
} else if (fvp->v_type == VREG) {
|
||||
oldtype |= NW_TYPE_FILE;
|
||||
} else {
|
||||
error = EINVAL;
|
||||
goto out;
|
||||
}
|
||||
if (tvp && tvp != fvp) {
|
||||
error = ncp_DeleteNSEntry(nmp, VTONW(tdvp)->n_fid.f_id,
|
||||
tcnp->cn_namelen, tcnp->cn_nameptr,
|
||||
tcnp->cn_thread, tcnp->cn_cred);
|
||||
if (error == 0x899c) error = EACCES;
|
||||
if (error)
|
||||
goto out_cacherem;
|
||||
}
|
||||
error = ncp_nsrename(NWFSTOCONN(nmp), nmp->n_volume, nmp->name_space,
|
||||
oldtype, &nmp->m.nls,
|
||||
VTONW(fdvp)->n_fid.f_id, fcnp->cn_nameptr, fcnp->cn_namelen,
|
||||
VTONW(tdvp)->n_fid.f_id, tcnp->cn_nameptr, tcnp->cn_namelen,
|
||||
tcnp->cn_thread, tcnp->cn_cred);
|
||||
|
||||
if (error == 0x8992)
|
||||
error = EEXIST;
|
||||
if (fvp->v_type == VDIR) {
|
||||
if (tvp != NULL && tvp->v_type == VDIR)
|
||||
cache_purge(tdvp);
|
||||
cache_purge(fdvp);
|
||||
}
|
||||
out_cacherem:
|
||||
nwfs_attr_cacheremove(fdvp);
|
||||
nwfs_attr_cacheremove(tdvp);
|
||||
nwfs_attr_cacheremove(fvp);
|
||||
out:
|
||||
if (tdvp == tvp)
|
||||
vrele(tdvp);
|
||||
else
|
||||
vput(tdvp);
|
||||
if (tvp)
|
||||
vput(tvp);
|
||||
vrele(fdvp);
|
||||
vrele(fvp);
|
||||
if (tvp)
|
||||
nwfs_attr_cacheremove(tvp);
|
||||
/*
|
||||
* Kludge: Map ENOENT => 0 assuming that it is a reply to a retry.
|
||||
*/
|
||||
if (error == ENOENT)
|
||||
error = 0;
|
||||
return (error);
|
||||
}
|
||||
|
||||
/*
|
||||
* nwfs hard link create call
|
||||
* Netware filesystems don't know what links are.
|
||||
*/
|
||||
static int
|
||||
nwfs_link(ap)
|
||||
struct vop_link_args /* {
|
||||
struct vnode *a_tdvp;
|
||||
struct vnode *a_vp;
|
||||
struct componentname *a_cnp;
|
||||
} */ *ap;
|
||||
{
|
||||
return EOPNOTSUPP;
|
||||
}
|
||||
|
||||
/*
|
||||
* nwfs_symlink link create call
|
||||
* Netware filesystems don't know what symlinks are.
|
||||
*/
|
||||
static int
|
||||
nwfs_symlink(ap)
|
||||
struct vop_symlink_args /* {
|
||||
struct vnode *a_dvp;
|
||||
struct vnode **a_vpp;
|
||||
struct componentname *a_cnp;
|
||||
struct vattr *a_vap;
|
||||
char *a_target;
|
||||
} */ *ap;
|
||||
{
|
||||
return (EOPNOTSUPP);
|
||||
}
|
||||
|
||||
static int nwfs_mknod(ap)
|
||||
struct vop_mknod_args /* {
|
||||
} */ *ap;
|
||||
{
|
||||
return (EOPNOTSUPP);
|
||||
}
|
||||
|
||||
/*
|
||||
* nwfs_mkdir call
|
||||
*/
|
||||
static int
|
||||
nwfs_mkdir(ap)
|
||||
struct vop_mkdir_args /* {
|
||||
struct vnode *a_dvp;
|
||||
struct vnode **a_vpp;
|
||||
struct componentname *a_cnp;
|
||||
struct vattr *a_vap;
|
||||
} */ *ap;
|
||||
{
|
||||
struct vnode *dvp = ap->a_dvp;
|
||||
/* struct vattr *vap = ap->a_vap;*/
|
||||
struct componentname *cnp = ap->a_cnp;
|
||||
int len=cnp->cn_namelen;
|
||||
struct ncp_open_info no;
|
||||
struct vnode *newvp = (struct vnode *)0;
|
||||
ncpfid fid;
|
||||
int error = 0;
|
||||
struct vattr vattr;
|
||||
char *name=cnp->cn_nameptr;
|
||||
|
||||
if ((error = VOP_GETATTR(dvp, &vattr, cnp->cn_cred)))
|
||||
return (error);
|
||||
if ((name[0] == '.') && ((len == 1) || ((len == 2) && (name[1] == '.')))) {
|
||||
return EEXIST;
|
||||
}
|
||||
if (ncp_open_create_file_or_subdir(VTONWFS(dvp), dvp, cnp->cn_namelen,
|
||||
cnp->cn_nameptr, OC_MODE_CREATE, aDIR, 0xffff,
|
||||
&no, cnp->cn_thread, cnp->cn_cred) != 0) {
|
||||
error = EACCES;
|
||||
} else {
|
||||
error = 0;
|
||||
}
|
||||
if (!error) {
|
||||
fid.f_parent = VTONW(dvp)->n_fid.f_id;
|
||||
fid.f_id = no.fattr.dirEntNum;
|
||||
error = nwfs_nget(VTOVFS(dvp), fid, &no.fattr, dvp, &newvp);
|
||||
if (!error) {
|
||||
newvp->v_type = VDIR;
|
||||
*ap->a_vpp = newvp;
|
||||
}
|
||||
}
|
||||
return (error);
|
||||
}
|
||||
|
||||
/*
|
||||
* nwfs_remove directory call
|
||||
*/
|
||||
static int
|
||||
nwfs_rmdir(ap)
|
||||
struct vop_rmdir_args /* {
|
||||
struct vnode *a_dvp;
|
||||
struct vnode *a_vp;
|
||||
struct componentname *a_cnp;
|
||||
} */ *ap;
|
||||
{
|
||||
struct vnode *vp = ap->a_vp;
|
||||
struct vnode *dvp = ap->a_dvp;
|
||||
struct componentname *cnp = ap->a_cnp;
|
||||
struct nwnode *np = VTONW(vp);
|
||||
struct nwmount *nmp = VTONWFS(vp);
|
||||
struct nwnode *dnp = VTONW(dvp);
|
||||
int error = EIO;
|
||||
|
||||
if (dvp == vp)
|
||||
return EINVAL;
|
||||
|
||||
error = ncp_DeleteNSEntry(nmp, dnp->n_fid.f_id,
|
||||
cnp->cn_namelen, cnp->cn_nameptr, cnp->cn_thread, cnp->cn_cred);
|
||||
if (error == 0)
|
||||
np->n_flag |= NSHOULDFREE;
|
||||
else if (error == NWE_DIR_NOT_EMPTY)
|
||||
error = ENOTEMPTY;
|
||||
dnp->n_flag |= NMODIFIED;
|
||||
nwfs_attr_cacheremove(dvp);
|
||||
cache_purge(dvp);
|
||||
cache_purge(vp);
|
||||
return (error);
|
||||
}
|
||||
|
||||
/*
|
||||
* nwfs_readdir call
|
||||
*/
|
||||
static int
|
||||
nwfs_readdir(ap)
|
||||
struct vop_readdir_args /* {
|
||||
struct vnode *a_vp;
|
||||
struct uio *a_uio;
|
||||
struct ucred *a_cred;
|
||||
int *a_eofflag;
|
||||
u_long *a_cookies;
|
||||
int a_ncookies;
|
||||
} */ *ap;
|
||||
{
|
||||
struct vnode *vp = ap->a_vp;
|
||||
struct uio *uio = ap->a_uio;
|
||||
int error;
|
||||
|
||||
if (vp->v_type != VDIR)
|
||||
return (EPERM);
|
||||
if (ap->a_ncookies) {
|
||||
printf("nwfs_readdir: no support for cookies now...");
|
||||
return (EOPNOTSUPP);
|
||||
}
|
||||
|
||||
error = nwfs_readvnode(vp, uio, ap->a_cred);
|
||||
return error;
|
||||
}
|
||||
/* ARGSUSED */
|
||||
static int
|
||||
nwfs_fsync(ap)
|
||||
struct vop_fsync_args /* {
|
||||
struct vnodeop_desc *a_desc;
|
||||
struct vnode * a_vp;
|
||||
struct ucred * a_cred;
|
||||
int a_waitfor;
|
||||
struct thread *a_td;
|
||||
} */ *ap;
|
||||
{
|
||||
/* return (nfs_flush(ap->a_vp, ap->a_cred, ap->a_waitfor, ap->a_td, 1));*/
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* ARGSUSED */
|
||||
static
|
||||
int nwfs_print (ap)
|
||||
struct vop_print_args /* {
|
||||
struct vnode *a_vp;
|
||||
} */ *ap;
|
||||
{
|
||||
struct vnode *vp = ap->a_vp;
|
||||
struct nwnode *np = VTONW(vp);
|
||||
|
||||
printf("\tnwfs node: name = '%s', fid = %d, pfid = %d\n",
|
||||
np->n_name, np->n_fid.f_id, np->n_fid.f_parent);
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int nwfs_pathconf (ap)
|
||||
struct vop_pathconf_args /* {
|
||||
struct vnode *vp;
|
||||
int name;
|
||||
register_t *retval;
|
||||
} */ *ap;
|
||||
{
|
||||
int name=ap->a_name, error=0;
|
||||
register_t *retval=ap->a_retval;
|
||||
|
||||
switch(name){
|
||||
case _PC_LINK_MAX:
|
||||
*retval=0;
|
||||
break;
|
||||
case _PC_NAME_MAX:
|
||||
*retval=NCP_MAX_FILENAME; /* XXX from nwfsnode */
|
||||
break;
|
||||
case _PC_PATH_MAX:
|
||||
*retval=NCP_MAXPATHLEN; /* XXX from nwfsnode */
|
||||
break;
|
||||
default:
|
||||
error=EINVAL;
|
||||
}
|
||||
return(error);
|
||||
}
|
||||
|
||||
static int nwfs_strategy (ap)
|
||||
struct vop_strategy_args /* {
|
||||
struct buf *a_bp
|
||||
} */ *ap;
|
||||
{
|
||||
struct buf *bp=ap->a_bp;
|
||||
struct ucred *cr;
|
||||
struct thread *td;
|
||||
|
||||
NCPVNDEBUG("\n");
|
||||
if (bp->b_flags & B_ASYNC)
|
||||
td = (struct thread *)0;
|
||||
else
|
||||
td = curthread; /* XXX */
|
||||
if (bp->b_iocmd == BIO_READ)
|
||||
cr = bp->b_rcred;
|
||||
else
|
||||
cr = bp->b_wcred;
|
||||
/*
|
||||
* If the op is asynchronous and an i/o daemon is waiting
|
||||
* queue the request, wake it up and wait for completion
|
||||
* otherwise just do it ourselves.
|
||||
*/
|
||||
if ((bp->b_flags & B_ASYNC) == 0 )
|
||||
(void)nwfs_doio(ap->a_vp, bp, cr, td);
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* How to keep the brain busy ...
|
||||
* Currently lookup routine can make two lookup for vnode. This can be
|
||||
* avoided by reorg the code.
|
||||
*/
|
||||
int
|
||||
nwfs_lookup(ap)
|
||||
struct vop_lookup_args /* {
|
||||
struct vnodeop_desc *a_desc;
|
||||
struct vnode *a_dvp;
|
||||
struct vnode **a_vpp;
|
||||
struct componentname *a_cnp;
|
||||
} */ *ap;
|
||||
{
|
||||
struct componentname *cnp = ap->a_cnp;
|
||||
struct vnode *dvp = ap->a_dvp;
|
||||
struct vnode **vpp = ap->a_vpp;
|
||||
int flags = cnp->cn_flags;
|
||||
struct vnode *vp;
|
||||
struct nwmount *nmp;
|
||||
struct mount *mp = dvp->v_mount;
|
||||
struct nwnode *dnp, *npp;
|
||||
struct nw_entry_info fattr, *fap;
|
||||
ncpfid fid;
|
||||
int nameiop=cnp->cn_nameiop, islastcn;
|
||||
int error = 0, notfound;
|
||||
struct thread *td = cnp->cn_thread;
|
||||
char _name[cnp->cn_namelen+1];
|
||||
bcopy(cnp->cn_nameptr, _name, cnp->cn_namelen);
|
||||
_name[cnp->cn_namelen]=0;
|
||||
|
||||
if (dvp->v_type != VDIR)
|
||||
return (ENOTDIR);
|
||||
if ((flags & ISDOTDOT) && (dvp->v_vflag & VV_ROOT)) {
|
||||
printf("nwfs_lookup: invalid '..'\n");
|
||||
return EIO;
|
||||
}
|
||||
|
||||
NCPVNDEBUG("%d '%s' in '%s' id=d\n", nameiop, _name,
|
||||
VTONW(dvp)->n_name/*, VTONW(dvp)->n_name*/);
|
||||
|
||||
islastcn = flags & ISLASTCN;
|
||||
if (islastcn && (mp->mnt_flag & MNT_RDONLY) && (nameiop != LOOKUP))
|
||||
return (EROFS);
|
||||
if ((error = VOP_ACCESS(dvp, VEXEC, cnp->cn_cred, td)))
|
||||
return (error);
|
||||
nmp = VFSTONWFS(mp);
|
||||
dnp = VTONW(dvp);
|
||||
/*
|
||||
printf("dvp %d:%d:%d\n", (int)mp, (int)dvp->v_vflag & VV_ROOT, (int)flags & ISDOTDOT);
|
||||
*/
|
||||
error = ncp_pathcheck(cnp->cn_nameptr, cnp->cn_namelen, &nmp->m.nls,
|
||||
(nameiop == CREATE || nameiop == RENAME) && (nmp->m.nls.opt & NWHP_NOSTRICT) == 0);
|
||||
if (error)
|
||||
return ENOENT;
|
||||
|
||||
error = cache_lookup(dvp, vpp, cnp, NULL, NULL);
|
||||
NCPVNDEBUG("cache_lookup returned %d\n", error);
|
||||
if (error > 0)
|
||||
return error;
|
||||
if (error) { /* name was found */
|
||||
struct vattr vattr;
|
||||
|
||||
vp = *vpp;
|
||||
if (!VOP_GETATTR(vp, &vattr, cnp->cn_cred) &&
|
||||
vattr.va_ctime.tv_sec == VTONW(vp)->n_ctime) {
|
||||
if (nameiop != LOOKUP && islastcn)
|
||||
cnp->cn_flags |= SAVENAME;
|
||||
NCPVNDEBUG("use cached vnode");
|
||||
return (0);
|
||||
}
|
||||
cache_purge(vp);
|
||||
if (vp != dvp)
|
||||
vput(vp);
|
||||
else
|
||||
vrele(vp);
|
||||
*vpp = NULLVP;
|
||||
}
|
||||
/* not in cache, so ... */
|
||||
error = 0;
|
||||
*vpp = NULLVP;
|
||||
fap = NULL;
|
||||
if (flags & ISDOTDOT) {
|
||||
if (NWCMPF(&dnp->n_parent, &nmp->n_rootent)) {
|
||||
fid = nmp->n_rootent;
|
||||
fap = NULL;
|
||||
notfound = 0;
|
||||
} else {
|
||||
error = nwfs_lookupnp(nmp, dnp->n_parent, td, &npp);
|
||||
if (error) {
|
||||
return error;
|
||||
}
|
||||
fid = dnp->n_parent;
|
||||
fap = &fattr;
|
||||
/*np = *npp;*/
|
||||
notfound = ncp_obtain_info(nmp, npp->n_dosfid,
|
||||
0, NULL, fap, td, cnp->cn_cred);
|
||||
}
|
||||
} else {
|
||||
fap = &fattr;
|
||||
notfound = ncp_lookup(dvp, cnp->cn_namelen, cnp->cn_nameptr,
|
||||
fap, td, cnp->cn_cred);
|
||||
fid.f_id = fap->dirEntNum;
|
||||
if (cnp->cn_namelen == 1 && cnp->cn_nameptr[0] == '.') {
|
||||
fid.f_parent = dnp->n_fid.f_parent;
|
||||
} else
|
||||
fid.f_parent = dnp->n_fid.f_id;
|
||||
NCPVNDEBUG("call to ncp_lookup returned=%d\n", notfound);
|
||||
}
|
||||
if (notfound && notfound < 0x80 )
|
||||
return (notfound); /* hard error */
|
||||
if (notfound) { /* entry not found */
|
||||
/* Handle RENAME or CREATE case... */
|
||||
if ((nameiop == CREATE || nameiop == RENAME) && islastcn) {
|
||||
cnp->cn_flags |= SAVENAME;
|
||||
return (EJUSTRETURN);
|
||||
}
|
||||
return ENOENT;
|
||||
}/* else {
|
||||
NCPVNDEBUG("Found entry %s with id=%d\n", fap->entryName, fap->dirEntNum);
|
||||
}*/
|
||||
/* handle DELETE case ... */
|
||||
if (nameiop == DELETE && islastcn) { /* delete last component */
|
||||
error = VOP_ACCESS(dvp, VWRITE, cnp->cn_cred, cnp->cn_thread);
|
||||
if (error) return (error);
|
||||
if (NWCMPF(&dnp->n_fid, &fid)) { /* we found ourselfs */
|
||||
VREF(dvp);
|
||||
*vpp = dvp;
|
||||
return 0;
|
||||
}
|
||||
error = nwfs_nget(mp, fid, fap, dvp, &vp);
|
||||
if (error) return (error);
|
||||
*vpp = vp;
|
||||
cnp->cn_flags |= SAVENAME; /* I free it later */
|
||||
return (0);
|
||||
}
|
||||
if (nameiop == RENAME && islastcn) {
|
||||
error = VOP_ACCESS(dvp, VWRITE, cnp->cn_cred, cnp->cn_thread);
|
||||
if (error) return (error);
|
||||
if (NWCMPF(&dnp->n_fid, &fid)) return EISDIR;
|
||||
error = nwfs_nget(mp, fid, fap, dvp, &vp);
|
||||
if (error) return (error);
|
||||
*vpp = vp;
|
||||
cnp->cn_flags |= SAVENAME;
|
||||
return (0);
|
||||
}
|
||||
if (flags & ISDOTDOT) {
|
||||
VOP_UNLOCK(dvp, 0); /* race to get the inode */
|
||||
error = nwfs_nget(mp, fid, NULL, NULL, &vp);
|
||||
vn_lock(dvp, LK_EXCLUSIVE | LK_RETRY);
|
||||
if (error)
|
||||
return (error);
|
||||
*vpp = vp;
|
||||
} else if (NWCMPF(&dnp->n_fid, &fid)) {
|
||||
vref(dvp);
|
||||
*vpp = dvp;
|
||||
} else {
|
||||
error = nwfs_nget(mp, fid, fap, dvp, &vp);
|
||||
if (error) return (error);
|
||||
*vpp = vp;
|
||||
NCPVNDEBUG("lookup: getnewvp!\n");
|
||||
}
|
||||
if ((cnp->cn_flags & MAKEENTRY)/* && !islastcn*/) {
|
||||
VTONW(*vpp)->n_ctime = VTONW(*vpp)->n_vattr.va_ctime.tv_sec;
|
||||
cache_enter(dvp, *vpp, cnp);
|
||||
}
|
||||
return (0);
|
||||
}
|
@ -1,15 +0,0 @@
|
||||
# $FreeBSD$
|
||||
|
||||
.PATH: ${.CURDIR}/../../netncp
|
||||
|
||||
KMOD= ncp
|
||||
|
||||
SRCS= ncp_conn.c ncp_sock.c ncp_ncp.c ncp_subr.c ncp_crypt.c ncp_mod.c \
|
||||
ncp_rq.c ncp_login.c ncp_nls.c opt_ncp.h
|
||||
|
||||
.if defined(NCPBURST)
|
||||
SRCS+= ncp_burst.c
|
||||
CFLAGS+= -DNCPBURST
|
||||
.endif
|
||||
|
||||
.include <bsd.kmod.mk>
|
@ -1,15 +0,0 @@
|
||||
# $FreeBSD$
|
||||
|
||||
.PATH: ${.CURDIR}/../../fs/nwfs
|
||||
|
||||
KMOD= nwfs
|
||||
|
||||
SRCS= vnode_if.h \
|
||||
nwfs_node.c nwfs_ioctl.c nwfs_io.c nwfs_vfsops.c nwfs_vnops.c \
|
||||
nwfs_subr.c
|
||||
|
||||
.if defined(VNPRINT)
|
||||
CFLAGS+= -DVNPRINT
|
||||
.endif
|
||||
|
||||
.include <bsd.kmod.mk>
|
392
sys/netncp/ncp.h
392
sys/netncp/ncp.h
@ -1,392 +0,0 @@
|
||||
/*
|
||||
* ncp.h
|
||||
*/
|
||||
/*-
|
||||
* Copyright (C) 1995 by Volker Lendecke
|
||||
* New version derived from original ncp.h, 1998 Boris Popov
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#ifndef _NETNCP_NCP_H_
|
||||
#define _NETNCP_NCP_H_
|
||||
|
||||
#define NCP_VERMAJ 1
|
||||
#define NCP_VERMIN 3500
|
||||
#define NCP_VERSION (NCP_VERMAJ*100000 + NCP_VERMIN)
|
||||
|
||||
typedef u_int32_t nwdirent;
|
||||
|
||||
typedef char nstr8;
|
||||
typedef nstr8* pnstr8;
|
||||
typedef u_int8_t nuint8;
|
||||
typedef u_int8_t* pnuint8;
|
||||
typedef u_int16_t nuint16;
|
||||
typedef nuint16* pnuint16;
|
||||
typedef u_int32_t nuint32;
|
||||
typedef nuint32* pnuint32;
|
||||
|
||||
|
||||
#define NCP_DEFAULT_BUFSIZE 1024
|
||||
#define NCP_MAX_BUFSIZE 1024
|
||||
#define NCP_MAX_PACKET_SIZE 4070
|
||||
#define NCP_MAXUSERNAMELEN 255
|
||||
#define NCP_MAXPASSWORDLEN 255
|
||||
#define NCP_MAXPATHLEN 255
|
||||
#define NCP_MAX_FILENAME 14
|
||||
#define NCP_FILE_ID_LEN 6
|
||||
|
||||
#define NCP_BINDERY_USER 0x0001
|
||||
#define NCP_BINDERY_UGROUP 0x0002
|
||||
#define NCP_BINDERY_PQUEUE 0x0003
|
||||
#define NCP_BINDERY_FSERVER 0x0004
|
||||
#define NCP_BINDERY_PSERVER 0x0007
|
||||
#define NCP_BINDERY_NAME_LEN 48
|
||||
|
||||
/* Handle Flags */
|
||||
#define NCP_HF_DIRSHORT 0 /* short directory handle */
|
||||
#define NCP_HF_DIRBASE 1 /* directory base */
|
||||
#define NCP_HF_NONE 0xff /* no handle or dirbase */
|
||||
|
||||
/* Options to negotiate */
|
||||
#define NCP_IPX_CHECKSUM 1
|
||||
#define NCP_SECURITY_LEVEL_SIGN_HEADERS 2
|
||||
|
||||
#ifndef NWCONN_HANDLE
|
||||
#define NWCONN_HANDLE unsigned int
|
||||
#define pNWCONN_HANDLE (unsigned int*)
|
||||
#define NWCONN_NUM u_int16_t
|
||||
#define NWCCODE unsigned int
|
||||
#define NWDIR_HANDLE u_int8_t
|
||||
#define NWFILE_HANDLE int
|
||||
#endif
|
||||
|
||||
struct ncp_fh_s {
|
||||
u_int16_t val1;
|
||||
union {
|
||||
u_int32_t val32;
|
||||
u_int16_t val16;
|
||||
} val;
|
||||
} __packed;
|
||||
|
||||
typedef struct ncp_fh_s ncp_fh;
|
||||
|
||||
typedef struct ncpfid_s {
|
||||
nwdirent f_parent;
|
||||
nwdirent f_id;
|
||||
} ncpfid;
|
||||
|
||||
/* -- Bindery properties -- */
|
||||
struct ncp_bindery_object {
|
||||
u_int32_t object_id;
|
||||
u_int16_t object_type;
|
||||
u_int8_t object_name[NCP_BINDERY_NAME_LEN];
|
||||
u_int8_t object_flags;
|
||||
u_int8_t object_security;
|
||||
u_int8_t object_has_prop;
|
||||
};
|
||||
|
||||
struct nw_property {
|
||||
u_int8_t value[128];
|
||||
u_int8_t more_flag;
|
||||
u_int8_t property_flag;
|
||||
};
|
||||
|
||||
struct ncp_filesearch_info {
|
||||
u_int8_t volume_number;
|
||||
u_int16_t directory_id;
|
||||
u_int16_t sequence_no;
|
||||
u_int8_t access_rights;
|
||||
};
|
||||
|
||||
|
||||
struct ncp_file_info {
|
||||
u_int8_t file_id[NCP_FILE_ID_LEN];
|
||||
char file_name[NCP_MAX_FILENAME + 1];
|
||||
u_int8_t file_attributes;
|
||||
u_int8_t file_mode;
|
||||
u_int32_t file_length;
|
||||
u_int16_t creation_date;
|
||||
u_int16_t access_date;
|
||||
u_int16_t update_date;
|
||||
u_int16_t update_time;
|
||||
};
|
||||
|
||||
struct nw_queue_job_entry {
|
||||
u_int16_t InUse;
|
||||
u_int32_t prev;
|
||||
u_int32_t next;
|
||||
u_int32_t ClientStation;
|
||||
u_int32_t ClientTask;
|
||||
u_int32_t ClientObjectID;
|
||||
u_int32_t TargetServerID;
|
||||
u_int8_t TargetExecTime[6];
|
||||
u_int8_t JobEntryTime[6];
|
||||
u_int32_t JobNumber;
|
||||
u_int16_t JobType;
|
||||
u_int16_t JobPosition;
|
||||
u_int16_t JobControlFlags;
|
||||
u_int8_t FileNameLen;
|
||||
char JobFileName[13];
|
||||
u_int32_t JobFileHandle;
|
||||
u_int32_t ServerStation;
|
||||
u_int32_t ServerTaskNumber;
|
||||
u_int32_t ServerObjectID;
|
||||
char JobTextDescription[50];
|
||||
char ClientRecordArea[152];
|
||||
} __packed;
|
||||
|
||||
struct queue_job {
|
||||
struct nw_queue_job_entry j;
|
||||
ncp_fh file_handle;
|
||||
};
|
||||
|
||||
#define QJE_OPER_HOLD 0x80
|
||||
#define QJE_USER_HOLD 0x40
|
||||
#define QJE_ENTRYOPEN 0x20
|
||||
#define QJE_SERV_RESTART 0x10
|
||||
#define QJE_SERV_AUTO 0x08
|
||||
|
||||
/* ClientRecordArea for print jobs */
|
||||
|
||||
#define KEEP_ON 0x0400
|
||||
#define NO_FORM_FEED 0x0800
|
||||
#define NOTIFICATION 0x1000
|
||||
#define DELETE_FILE 0x2000
|
||||
#define EXPAND_TABS 0x4000
|
||||
#define PRINT_BANNER 0x8000
|
||||
|
||||
struct print_job_record {
|
||||
u_int8_t Version;
|
||||
u_int8_t TabSize;
|
||||
u_int16_t Copies;
|
||||
u_int16_t CtrlFlags;
|
||||
u_int16_t Lines;
|
||||
u_int16_t Rows;
|
||||
char FormName[16];
|
||||
u_int8_t Reserved[6];
|
||||
char BannerName[13];
|
||||
char FnameBanner[13];
|
||||
char FnameHeader[14];
|
||||
char Path[80];
|
||||
} __packed;
|
||||
|
||||
struct ncp_station_addr {
|
||||
u_int32_t NetWork;
|
||||
u_int8_t Node[6];
|
||||
u_int16_t Socket;
|
||||
} __packed;
|
||||
|
||||
struct ncp_prop_login_control {
|
||||
u_int8_t AccountExpireDate[3];
|
||||
u_int8_t Disabled;
|
||||
u_int8_t PasswordExpireDate[3];
|
||||
u_int8_t GraceLogins;
|
||||
u_int16_t PasswordExpireInterval;
|
||||
u_int8_t MaxGraceLogins;
|
||||
u_int8_t MinPasswordLength;
|
||||
u_int16_t MaxConnections;
|
||||
u_int8_t ConnectionTimeMask[42];
|
||||
u_int8_t LastLogin[6];
|
||||
u_int8_t RestrictionMask;
|
||||
u_int8_t reserved;
|
||||
u_int32_t MaxDiskUsage;
|
||||
u_int16_t BadLoginCount;
|
||||
u_int32_t BadLoginCountDown;
|
||||
struct ncp_station_addr LastIntruder;
|
||||
} __packed;
|
||||
|
||||
#define NCP_VOLNAME_LEN (16)
|
||||
#define NCP_NUMBER_OF_VOLUMES (64)
|
||||
struct ncp_volume_info {
|
||||
u_int32_t total_blocks;
|
||||
u_int32_t free_blocks;
|
||||
u_int32_t purgeable_blocks;
|
||||
u_int32_t not_yet_purgeable_blocks;
|
||||
u_int32_t total_dir_entries;
|
||||
u_int32_t available_dir_entries;
|
||||
u_int8_t sectors_per_block;
|
||||
char volume_name[NCP_VOLNAME_LEN + 1];
|
||||
};
|
||||
/*
|
||||
* Name space constants, taken from NDK
|
||||
*/
|
||||
#define aRONLY (ntohl(0x01000000))
|
||||
#define aHIDDEN (ntohl(0x02000000))
|
||||
#define aSYSTEM (ntohl(0x04000000))
|
||||
#define aEXECUTE (ntohl(0x08000000))
|
||||
#define aDIR (ntohl(0x10000000))
|
||||
#define aARCH (ntohl(0x20000000))
|
||||
|
||||
/* Defines for Name Spaces */
|
||||
#define NW_NS_DOS 0
|
||||
#define NW_NS_MAC 1
|
||||
#define NW_NS_NFS 2
|
||||
#define NW_NS_FTAM 3
|
||||
#define NW_NS_OS2 4
|
||||
|
||||
/* for _ScanNSEntryInfo */
|
||||
#define IM_NAME 0x00000001
|
||||
#define IM_SPACE_ALLOCATED 0x00000002
|
||||
#define IM_ATTRIBUTES 0x00000004
|
||||
#define IM_SIZE 0x00000008
|
||||
#define IM_TOTAL_SIZE 0x00000010
|
||||
#define IM_EA 0x00000020
|
||||
#define IM_ARCHIVE 0x00000040
|
||||
#define IM_MODIFY 0x00000080
|
||||
#define IM_CREATION 0x00000100
|
||||
#define IM_OWNING_NAMESPACE 0x00000200
|
||||
#define IM_DIRECTORY 0x00000400
|
||||
#define IM_RIGHTS 0x00000800
|
||||
#define IM_ALMOST_ALL 0x00000FED
|
||||
#define IM_ALL 0x00000FFF
|
||||
#define IM_REFERENCE_ID 0x00001000
|
||||
#define IM_NS_ATTRIBUTES 0x00002000
|
||||
#define IM_COMPRESSED_INFO 0x80000000UL
|
||||
|
||||
/* open/create modes */
|
||||
#define OC_MODE_OPEN 0x01
|
||||
#define OC_MODE_TRUNCATE 0x02
|
||||
#define OC_MODE_REPLACE 0x02
|
||||
#define OC_MODE_CREATE 0x08
|
||||
|
||||
/* open/create results */
|
||||
#define OC_ACTION_NONE 0x00
|
||||
#define OC_ACTION_OPEN 0x01
|
||||
#define OC_ACTION_CREATE 0x02
|
||||
#define OC_ACTION_TRUNCATE 0x04
|
||||
#define OC_ACTION_REPLACE 0x04
|
||||
|
||||
/* renameFlag in NSRename */
|
||||
#define NW_TYPE_FILE 0x8000
|
||||
#define NW_TYPE_SUBDIR 0x0010
|
||||
|
||||
#define NW_NAME_CONVERT 0x0003 /* don't report error and set comp mode */
|
||||
#define NW_NO_NAME_CONVERT 0x0004 /* only in specified name space */
|
||||
|
||||
/* search attributes */
|
||||
#ifndef SA_HIDDEN
|
||||
#define SA_NORMAL 0x0000
|
||||
#define SA_HIDDEN 0x0002
|
||||
#define SA_SYSTEM 0x0004
|
||||
#define SA_SUBDIR_ONLY 0x0010
|
||||
#define SA_SUBDIR_FILES 0x8000
|
||||
#define SA_ALL 0x8006
|
||||
#endif
|
||||
|
||||
/* access rights attributes */
|
||||
#ifndef AR_READ
|
||||
#define AR_READ 0x0001
|
||||
#define AR_WRITE 0x0002
|
||||
#define AR_READ_ONLY 0x0001
|
||||
#define AR_WRITE_ONLY 0x0002
|
||||
#define AR_DENY_READ 0x0004
|
||||
#define AR_DENY_WRITE 0x0008
|
||||
#define AR_COMPATIBILITY 0x0010
|
||||
#define AR_WRITE_THROUGH 0x0040
|
||||
#define AR_OPEN_COMPRESSED 0x0100
|
||||
#endif
|
||||
|
||||
struct nw_entry_info {
|
||||
u_int32_t spaceAlloc;
|
||||
u_int32_t attributes; /* LH */
|
||||
u_int16_t flags; /* internal */
|
||||
u_int32_t dataStreamSize;
|
||||
u_int32_t totalStreamSize;
|
||||
u_int16_t numberOfStreams;
|
||||
u_int16_t creationTime; /* LH */
|
||||
u_int16_t creationDate; /* LH */
|
||||
u_int32_t creatorID; /* HL */
|
||||
u_int16_t modifyTime; /* LH */
|
||||
u_int16_t modifyDate; /* LH */
|
||||
u_int32_t modifierID; /* HL */
|
||||
u_int16_t lastAccessDate; /* LH */
|
||||
u_int16_t archiveTime; /* LH */
|
||||
u_int16_t archiveDate; /* LH */
|
||||
u_int32_t archiverID; /* HL */
|
||||
u_int16_t inheritedRightsMask; /* LH */
|
||||
u_int32_t dirEntNum;
|
||||
u_int32_t DosDirNum;
|
||||
u_int32_t volNumber;
|
||||
u_int32_t EADataSize;
|
||||
u_int32_t EAKeyCount;
|
||||
u_int32_t EAKeySize;
|
||||
u_int32_t NSCreator;
|
||||
u_int8_t nameLen;
|
||||
u_int8_t entryName[256];
|
||||
} __packed;
|
||||
|
||||
typedef struct nw_entry_info NW_ENTRY_INFO;
|
||||
|
||||
/* modify mask - use with MODIFY_DOS_INFO structure */
|
||||
#define DM_ATTRIBUTES 0x0002L
|
||||
#define DM_CREATE_DATE 0x0004L
|
||||
#define DM_CREATE_TIME 0x0008L
|
||||
#define DM_CREATOR_ID 0x0010L
|
||||
#define DM_ARCHIVE_DATE 0x0020L
|
||||
#define DM_ARCHIVE_TIME 0x0040L
|
||||
#define DM_ARCHIVER_ID 0x0080L
|
||||
#define DM_MODIFY_DATE 0x0100L
|
||||
#define DM_MODIFY_TIME 0x0200L
|
||||
#define DM_MODIFIER_ID 0x0400L
|
||||
#define DM_LAST_ACCESS_DATE 0x0800L
|
||||
#define DM_INHERITED_RIGHTS_MASK 0x1000L
|
||||
#define DM_MAXIMUM_SPACE 0x2000L
|
||||
|
||||
struct nw_modify_dos_info {
|
||||
u_int32_t attributes;
|
||||
u_int16_t creationDate;
|
||||
u_int16_t creationTime;
|
||||
u_int32_t creatorID;
|
||||
u_int16_t modifyDate;
|
||||
u_int16_t modifyTime;
|
||||
u_int32_t modifierID;
|
||||
u_int16_t archiveDate;
|
||||
u_int16_t archiveTime;
|
||||
u_int32_t archiverID;
|
||||
u_int16_t lastAccessDate;
|
||||
u_int16_t inheritanceGrantMask;
|
||||
u_int16_t inheritanceRevokeMask;
|
||||
u_int32_t maximumSpace;
|
||||
} __packed;
|
||||
|
||||
struct nw_search_seq {
|
||||
u_int8_t volNumber;
|
||||
u_int32_t dirNumber;
|
||||
u_int32_t searchDirNumber;
|
||||
} __packed;
|
||||
|
||||
typedef struct nw_search_seq SEARCH_SEQUENCE;
|
||||
|
||||
struct ncp_file_server_info {
|
||||
u_int8_t ServerName[48];
|
||||
u_int8_t FileServiceVersion;
|
||||
u_int8_t FileServiceSubVersion;
|
||||
u_int16_t MaximumServiceConnections;
|
||||
u_int16_t ConnectionsInUse;
|
||||
u_int16_t NumberMountedVolumes;
|
||||
u_int8_t Revision;
|
||||
u_int8_t SFTLevel;
|
||||
u_int8_t TTSLevel;
|
||||
u_int16_t MaxConnectionsEverUsed;
|
||||
u_int8_t AccountVersion;
|
||||
u_int8_t VAPVersion;
|
||||
u_int8_t QueueVersion;
|
||||
u_int8_t PrintVersion;
|
||||
u_int8_t VirtualConsoleVersion;
|
||||
u_int8_t RestrictionLevel;
|
||||
u_int8_t InternetBridge;
|
||||
u_int8_t Reserved[60];
|
||||
} __packed;
|
||||
|
||||
struct nw_time_buffer {
|
||||
u_int8_t year;
|
||||
u_int8_t month;
|
||||
u_int8_t day;
|
||||
u_int8_t hour;
|
||||
u_int8_t minute;
|
||||
u_int8_t second;
|
||||
u_int8_t wday;
|
||||
} __packed;
|
||||
|
||||
#endif /*_NCP_H_ */
|
@ -1,9 +0,0 @@
|
||||
/*
|
||||
* static configuration for libncp
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#define NCP_NLS_KOI2CP866
|
||||
#define NCP_NLS_DEFAULT NCP_NLS_KOI_866
|
||||
#define NCP_PREFIX ""
|
@ -1,662 +0,0 @@
|
||||
/*-
|
||||
* Copyright (c) 1999 Boris Popov
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* Connection tables
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/priv.h>
|
||||
#include <sys/proc.h>
|
||||
#include <sys/lock.h>
|
||||
#include <sys/sysctl.h>
|
||||
|
||||
#include <netncp/ncp.h>
|
||||
#include <netncp/nwerror.h>
|
||||
#include <netncp/ncp_subr.h>
|
||||
#include <netncp/ncp_conn.h>
|
||||
#include <netncp/ncp_sock.h>
|
||||
#include <netncp/ncp_ncp.h>
|
||||
|
||||
SLIST_HEAD(ncp_handle_head,ncp_handle);
|
||||
|
||||
int ncp_burst_enabled = 1;
|
||||
|
||||
struct ncp_conn_head conn_list={NULL};
|
||||
static int ncp_conn_cnt = 0;
|
||||
static int ncp_next_ref = 1;
|
||||
static struct lock listlock;
|
||||
|
||||
struct ncp_handle_head lhlist={NULL};
|
||||
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 thread *td,
|
||||
struct ucred *cred);
|
||||
|
||||
SYSCTL_DECL(_net_ncp);
|
||||
SYSCTL_INT (_net_ncp, OID_AUTO, burst_enabled, CTLFLAG_RD, &ncp_burst_enabled, 0, "");
|
||||
SYSCTL_INT (_net_ncp, OID_AUTO, conn_cnt, CTLFLAG_RD, &ncp_conn_cnt, 0, "");
|
||||
SYSCTL_PROC(_net_ncp, OID_AUTO, conn_stat, CTLFLAG_RD|CTLTYPE_OPAQUE,
|
||||
NULL, 0, ncp_sysctl_connstat, "S,connstat", "Connections list");
|
||||
|
||||
MALLOC_DEFINE(M_NCPDATA, "ncp_data", "NCP private data");
|
||||
|
||||
int
|
||||
ncp_conn_init(void)
|
||||
{
|
||||
lockinit(&listlock, PSOCK, "ncpll", 0, 0);
|
||||
lockinit(&lhlock, PSOCK, "ncplh", 0, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
ncp_conn_destroy(void)
|
||||
{
|
||||
if (ncp_conn_cnt) {
|
||||
NCPERROR("There are %d connections active\n", ncp_conn_cnt);
|
||||
return EBUSY;
|
||||
}
|
||||
lockdestroy(&listlock);
|
||||
lockdestroy(&lhlock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
ncp_conn_locklist(int flags, struct thread *td)
|
||||
{
|
||||
return lockmgr(&listlock, flags | LK_CANRECURSE, 0);
|
||||
}
|
||||
|
||||
void
|
||||
ncp_conn_unlocklist(struct thread *td)
|
||||
{
|
||||
lockmgr(&listlock, LK_RELEASE, 0);
|
||||
}
|
||||
|
||||
int
|
||||
ncp_conn_access(struct ncp_conn *conn, struct ucred *cred, mode_t mode)
|
||||
{
|
||||
int error;
|
||||
|
||||
if (cred == NOCRED || ncp_suser(cred) == 0 ||
|
||||
cred->cr_uid == conn->nc_owner->cr_uid)
|
||||
return 0;
|
||||
mode >>= 3;
|
||||
if (!groupmember(conn->nc_group, cred))
|
||||
mode >>= 3;
|
||||
error = (conn->li.access_mode & mode) == mode ? 0 : EACCES;
|
||||
return error;
|
||||
}
|
||||
|
||||
int
|
||||
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);
|
||||
if (error == ERESTART)
|
||||
return EINTR;
|
||||
error = ncp_chkintr(conn, td);
|
||||
if (error) {
|
||||
lockmgr(&conn->nc_lock, LK_RELEASE, 0);
|
||||
return error;
|
||||
}
|
||||
|
||||
if (conn->nc_id == 0) {
|
||||
lockmgr(&conn->nc_lock, LK_RELEASE, 0);
|
||||
return EACCES;
|
||||
}
|
||||
conn->td = td; /* who currently operates */
|
||||
conn->ucred = cred;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
ncp_conn_lock(struct ncp_conn *conn, struct thread *td, struct ucred *cred, int mode)
|
||||
{
|
||||
int error;
|
||||
|
||||
error = ncp_conn_access(conn, cred, mode);
|
||||
if (error) return error;
|
||||
return ncp_conn_lock_any(conn, td, cred);
|
||||
}
|
||||
|
||||
/*
|
||||
* Lock conn but unlock connlist
|
||||
*/
|
||||
static int
|
||||
ncp_conn_lock2(struct ncp_conn *conn, struct thread *td, struct ucred *cred, int mode)
|
||||
{
|
||||
int error;
|
||||
|
||||
error = ncp_conn_access(conn, cred, mode);
|
||||
if (error) {
|
||||
ncp_conn_unlocklist(td);
|
||||
return error;
|
||||
}
|
||||
conn->nc_lwant++;
|
||||
ncp_conn_unlocklist(td);
|
||||
error = ncp_conn_lock_any(conn, td, cred);
|
||||
conn->nc_lwant--;
|
||||
if (conn->nc_lwant == 0) {
|
||||
wakeup(&conn->nc_lwant);
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
void
|
||||
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);
|
||||
}
|
||||
|
||||
int
|
||||
ncp_conn_assert_locked(struct ncp_conn *conn, const char *checker, struct thread *td)
|
||||
{
|
||||
if (lockstatus(&conn->nc_lock) == LK_EXCLUSIVE) return 0;
|
||||
printf("%s: connection isn't locked!\n", checker);
|
||||
return EIO;
|
||||
}
|
||||
|
||||
void
|
||||
ncp_conn_invalidate(struct ncp_conn *ncp)
|
||||
{
|
||||
ncp->flags &= ~(NCPFL_ATTACHED | NCPFL_LOGGED | NCPFL_INVALID);
|
||||
}
|
||||
|
||||
int
|
||||
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 thread *td, struct ucred *cred,
|
||||
struct ncp_conn **conn)
|
||||
{
|
||||
struct ncp_conn *ncp;
|
||||
struct ucred *owner;
|
||||
int error, isroot;
|
||||
|
||||
if (cap->saddr.sa_family != AF_INET && cap->saddr.sa_family != AF_IPX)
|
||||
return EPROTONOSUPPORT;
|
||||
/*
|
||||
* Only root can change ownership.
|
||||
*/
|
||||
isroot = ncp_suser(cred) == 0;
|
||||
if (cap->owner != NCP_DEFAULT_OWNER && !isroot)
|
||||
return EPERM;
|
||||
if (cap->group != NCP_DEFAULT_GROUP &&
|
||||
!groupmember(cap->group, cred) && !isroot)
|
||||
return EPERM;
|
||||
if (cap->owner != NCP_DEFAULT_OWNER) {
|
||||
owner = crget();
|
||||
crcopy(owner, cred);
|
||||
owner->cr_uid = cap->owner;
|
||||
} else
|
||||
owner = crhold(cred);
|
||||
ncp = malloc(sizeof(struct ncp_conn),
|
||||
M_NCPDATA, M_WAITOK | M_ZERO);
|
||||
error = 0;
|
||||
lockinit(&ncp->nc_lock, PZERO, "ncplck", 0, 0);
|
||||
ncp_conn_cnt++;
|
||||
ncp->nc_id = ncp_next_ref++;
|
||||
ncp->nc_owner = owner;
|
||||
ncp->seq = 0;
|
||||
ncp->connid = 0xFFFF;
|
||||
ncp->li = *cap;
|
||||
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, td, ncp->nc_owner);
|
||||
*conn = ncp;
|
||||
ncp_conn_locklist(LK_EXCLUSIVE, td);
|
||||
SLIST_INSERT_HEAD(&conn_list,ncp,nc_next);
|
||||
ncp_conn_unlocklist(td);
|
||||
return (error);
|
||||
}
|
||||
|
||||
/*
|
||||
* Remove the connection, on entry it must be locked
|
||||
*/
|
||||
int
|
||||
ncp_conn_free(struct ncp_conn *ncp)
|
||||
{
|
||||
struct thread *td;
|
||||
int error;
|
||||
|
||||
if (ncp == NULL) {
|
||||
NCPFATAL("ncp == NULL\n");
|
||||
return 0;
|
||||
}
|
||||
if (ncp->nc_id == 0) {
|
||||
NCPERROR("nc_id == 0\n");
|
||||
return EACCES;
|
||||
}
|
||||
td = ncp->td;
|
||||
error = ncp_conn_assert_locked(ncp, __func__, td);
|
||||
if (error)
|
||||
return error;
|
||||
if (ncp->ref_cnt != 0 || (ncp->flags & NCPFL_PERMANENT))
|
||||
return EBUSY;
|
||||
if (ncp_conn_access(ncp, ncp->ucred, NCPM_WRITE))
|
||||
return EACCES;
|
||||
|
||||
if (ncp->flags & NCPFL_ATTACHED)
|
||||
ncp_ncp_disconnect(ncp);
|
||||
ncp_sock_disconnect(ncp);
|
||||
|
||||
/*
|
||||
* Mark conn as dead and wait for other process
|
||||
*/
|
||||
ncp->nc_id = 0;
|
||||
ncp_conn_unlock(ncp, td);
|
||||
/*
|
||||
* if signal is raised - how I do react ?
|
||||
*/
|
||||
lockmgr(&ncp->nc_lock, LK_DRAIN, 0);
|
||||
lockmgr(&ncp->nc_lock, LK_RELEASE, 0);
|
||||
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, td);
|
||||
SLIST_REMOVE(&conn_list, ncp, ncp_conn, nc_next);
|
||||
ncp_conn_cnt--;
|
||||
ncp_conn_unlocklist(td);
|
||||
if (ncp->li.user)
|
||||
free(ncp->li.user, M_NCPDATA);
|
||||
if (ncp->li.password)
|
||||
free(ncp->li.password, M_NCPDATA);
|
||||
crfree(ncp->nc_owner);
|
||||
free(ncp, M_NCPDATA);
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
ncp_conn_reconnect(struct ncp_conn *ncp)
|
||||
{
|
||||
int error;
|
||||
|
||||
/*
|
||||
* Close opened sockets if any
|
||||
*/
|
||||
ncp_sock_disconnect(ncp);
|
||||
error = ncp_sock_connect(ncp);
|
||||
if (error)
|
||||
return error;
|
||||
error = ncp_ncp_connect(ncp);
|
||||
if (error)
|
||||
return error;
|
||||
error = ncp_renegotiate_connparam(ncp, NCP_DEFAULT_BUFSIZE, 0);
|
||||
if (error == NWE_SIGNATURE_LEVEL_CONFLICT) {
|
||||
printf("Unable to negotiate requested security level\n");
|
||||
error = EOPNOTSUPP;
|
||||
}
|
||||
if (error) {
|
||||
ncp_ncp_disconnect(ncp);
|
||||
return error;
|
||||
}
|
||||
#ifdef NCPBURST
|
||||
error = ncp_burst_connect(ncp);
|
||||
if (error) {
|
||||
ncp_ncp_disconnect(ncp);
|
||||
return error;
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
ncp_conn_login(struct ncp_conn *conn, struct thread *td, struct ucred *cred)
|
||||
{
|
||||
struct ncp_bindery_object user;
|
||||
u_char ncp_key[8];
|
||||
int error;
|
||||
|
||||
error = ncp_get_encryption_key(conn, ncp_key);
|
||||
if (error) {
|
||||
printf("%s: Warning: use unencrypted login\n", __func__);
|
||||
error = ncp_login_unencrypted(conn, conn->li.objtype,
|
||||
conn->li.user, conn->li.password, td, cred);
|
||||
} else {
|
||||
error = ncp_get_bindery_object_id(conn, conn->li.objtype,
|
||||
conn->li.user, &user, td, cred);
|
||||
if (error)
|
||||
return error;
|
||||
error = ncp_login_encrypted(conn, &user, ncp_key,
|
||||
conn->li.password, td, cred);
|
||||
}
|
||||
if (!error)
|
||||
conn->flags |= NCPFL_LOGGED | NCPFL_WASLOGGED;
|
||||
return error;
|
||||
}
|
||||
|
||||
/*
|
||||
* Lookup connection by handle, return a locked conn descriptor
|
||||
*/
|
||||
int
|
||||
ncp_conn_getbyref(int ref, struct thread *td, struct ucred *cred, int mode,
|
||||
struct ncp_conn **connpp)
|
||||
{
|
||||
struct ncp_conn *ncp;
|
||||
int error = 0;
|
||||
|
||||
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(td);
|
||||
return(EBADF);
|
||||
}
|
||||
error = ncp_conn_lock2(ncp, td, cred, mode);
|
||||
if (!error)
|
||||
*connpp = ncp;
|
||||
return (error);
|
||||
}
|
||||
/*
|
||||
* find attached, but not logged in connection to specified server
|
||||
*/
|
||||
int
|
||||
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, td);
|
||||
SLIST_FOREACH(ncp, &conn_list, nc_next) {
|
||||
if ((ncp->flags & NCPFL_LOGGED) != 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 ||
|
||||
cred->cr_uid == ncp->nc_owner->cr_uid)
|
||||
break;
|
||||
error = ncp_conn_access(ncp,cred,mode);
|
||||
if (!error && ncp2 == NULL)
|
||||
ncp2 = ncp;
|
||||
}
|
||||
if (ncp == NULL) ncp = ncp2;
|
||||
if (ncp == NULL) {
|
||||
ncp_conn_unlocklist(td);
|
||||
return(EBADF);
|
||||
}
|
||||
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
|
||||
* based on owner.
|
||||
* Connection selected in next order:
|
||||
* 1. Try to search conn with ucred owner, if li is NULL also find a primary
|
||||
* 2. If 1. fails try to get first suitable shared connection
|
||||
* 3. If 2. fails then nothing can help to poor ucred owner
|
||||
*/
|
||||
|
||||
int
|
||||
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, td);
|
||||
SLIST_FOREACH(ncp, &conn_list, nc_next) {
|
||||
if (partial) {
|
||||
if (cred->cr_uid == ncp->nc_owner->cr_uid) {
|
||||
if (haveserv) {
|
||||
if (strcmp(ncp->li.server,li->server) == 0)
|
||||
break;
|
||||
} else {
|
||||
if (ncp->flags & NCPFL_PRIMARY)
|
||||
break;
|
||||
ncp2 = ncp;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
if (strcmp(ncp->li.server,li->server) != 0 ||
|
||||
ncp->li.user == NULL ||
|
||||
strcmp(ncp->li.user,li->user) != 0)
|
||||
continue;
|
||||
if (cred->cr_uid == ncp->nc_owner->cr_uid)
|
||||
break;
|
||||
if (ncp_suser(cred) == 0)
|
||||
ncp2 = ncp;
|
||||
}
|
||||
error = ncp_conn_access(ncp,cred,mode);
|
||||
if (!error && ncp2 == NULL)
|
||||
ncp2 = ncp;
|
||||
}
|
||||
if (ncp == NULL) ncp = ncp2;
|
||||
if (ncp == NULL) {
|
||||
ncp_conn_unlocklist(td);
|
||||
return(EBADF);
|
||||
}
|
||||
error = ncp_conn_lock2(ncp, td, cred,mode);
|
||||
if (!error)
|
||||
*connpp=ncp;
|
||||
return (error);
|
||||
}
|
||||
|
||||
/*
|
||||
* Set primary connection flag, since it have sence only for an owner,
|
||||
* only owner can modify this flag.
|
||||
* connection expected to be locked.
|
||||
*/
|
||||
int
|
||||
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->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->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 thread *td, struct ncp_handle **handle)
|
||||
{
|
||||
struct ncp_handle *refp;
|
||||
|
||||
lockmgr(&lhlock, LK_EXCLUSIVE, 0);
|
||||
SLIST_FOREACH(refp, &lhlist, nh_next)
|
||||
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);
|
||||
return 0;
|
||||
}
|
||||
refp = malloc(sizeof(struct ncp_handle),M_NCPDATA,
|
||||
M_WAITOK | M_ZERO);
|
||||
SLIST_INSERT_HEAD(&lhlist,refp,nh_next);
|
||||
refp->nh_ref++;
|
||||
refp->nh_td = td;
|
||||
refp->nh_conn = conn;
|
||||
refp->nh_id = ncp_next_handle++;
|
||||
*handle = refp;
|
||||
conn->ref_cnt++;
|
||||
lockmgr(&lhlock, LK_RELEASE, 0);
|
||||
return 0;
|
||||
}
|
||||
/*
|
||||
* release reference, if force - ignore refcount
|
||||
*/
|
||||
int
|
||||
ncp_conn_puthandle(struct ncp_handle *handle, struct thread *td, int force)
|
||||
{
|
||||
struct ncp_handle *refp = handle;
|
||||
|
||||
lockmgr(&lhlock, LK_EXCLUSIVE, 0);
|
||||
refp->nh_ref--;
|
||||
refp->nh_conn->ref_cnt--;
|
||||
if (force) {
|
||||
refp->nh_conn->ref_cnt -= refp->nh_ref;
|
||||
refp->nh_ref = 0;
|
||||
}
|
||||
if (refp->nh_ref == 0) {
|
||||
SLIST_REMOVE(&lhlist, refp, ncp_handle, nh_next);
|
||||
free(refp, M_NCPDATA);
|
||||
}
|
||||
lockmgr(&lhlock, LK_RELEASE, 0);
|
||||
return 0;
|
||||
}
|
||||
/*
|
||||
* find a connHandle
|
||||
*/
|
||||
int
|
||||
ncp_conn_findhandle(int connHandle, struct thread *td, struct ncp_handle **handle) {
|
||||
struct ncp_handle *refp;
|
||||
|
||||
lockmgr(&lhlock, LK_SHARED, 0);
|
||||
SLIST_FOREACH(refp, &lhlist, nh_next)
|
||||
if (refp->nh_td == td && refp->nh_id == connHandle) break;
|
||||
lockmgr(&lhlock, LK_RELEASE, 0);
|
||||
if (refp == NULL) {
|
||||
return EBADF;
|
||||
}
|
||||
*handle = refp;
|
||||
return 0;
|
||||
}
|
||||
/*
|
||||
* Clear handles associated with specified process
|
||||
*/
|
||||
int
|
||||
ncp_conn_putprochandles(struct thread *td)
|
||||
{
|
||||
struct ncp_handle *hp, *nhp;
|
||||
int haveone = 0;
|
||||
|
||||
lockmgr(&lhlock, LK_EXCLUSIVE, 0);
|
||||
for (hp = SLIST_FIRST(&lhlist); hp; hp = nhp) {
|
||||
nhp = SLIST_NEXT(hp, nh_next);
|
||||
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);
|
||||
return haveone;
|
||||
}
|
||||
/*
|
||||
* remove references in all possible connections,
|
||||
* XXX - possible problem is a locked list.
|
||||
*/
|
||||
/*void
|
||||
ncp_conn_list_rm_ref(pid_t pid) {
|
||||
struct ncp_conn *ncp;
|
||||
|
||||
ncp_conn_locklist(LK_SHARED, NULL);
|
||||
SLIST_FOREACH(ncp, &conn_list, nc_next) {
|
||||
ncp_conn_rm_ref(ncp,pid,1);
|
||||
}
|
||||
ncp_conn_unlocklist(NULL);
|
||||
return;
|
||||
}
|
||||
*/
|
||||
int
|
||||
ncp_conn_getinfo(struct ncp_conn *ncp, struct ncp_conn_stat *ncs) {
|
||||
bzero(ncs,sizeof(*ncs));
|
||||
ncs->li = ncp->li;
|
||||
ncs->li.user = ncs->user;
|
||||
if (ncp->li.user)
|
||||
strcpy(ncs->user, ncp->li.user);
|
||||
ncs->li.password = NULL;
|
||||
ncs->connRef = ncp->nc_id;
|
||||
ncs->ref_cnt = ncp->ref_cnt;
|
||||
ncs->connid = ncp->connid;
|
||||
ncs->owner = ncp->nc_owner->cr_uid;
|
||||
ncs->group = ncp->nc_group;
|
||||
ncs->flags = ncp->flags;
|
||||
ncs->buffer_size = ncp->buffer_size;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
ncp_sysctl_connstat(SYSCTL_HANDLER_ARGS)
|
||||
{
|
||||
int error;
|
||||
struct ncp_conn_stat ncs;
|
||||
struct ncp_conn *ncp;
|
||||
/* struct ucred *cred = req->td->td_ucred;*/
|
||||
|
||||
error = sysctl_wire_old_buffer(req, 0);
|
||||
if (error != 0)
|
||||
return (error);
|
||||
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;
|
||||
/* I can't do conn_lock while list is locked */
|
||||
ncp->nc_lwant++;
|
||||
ncp_conn_getinfo(ncp, &ncs);
|
||||
ncp->nc_lwant--;
|
||||
error = SYSCTL_OUT(req, &ncs, sizeof(ncs));
|
||||
}
|
||||
ncp_conn_unlocklist(req->td);
|
||||
return(error);
|
||||
}
|
@ -1,229 +0,0 @@
|
||||
/*-
|
||||
* Copyright (c) 1999 Boris Popov
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
#ifndef _NETNCP_NCP_CONN_H_
|
||||
#define _NETNCP_NCP_CONN_H_
|
||||
|
||||
#ifndef _NETINET_IN_H_
|
||||
#include <netinet/in.h>
|
||||
#endif
|
||||
|
||||
#ifndef _NETIPX_IPX_H_
|
||||
#include <netipx/ipx.h>
|
||||
#endif
|
||||
|
||||
#ifndef _SYS_SOCKET_H_
|
||||
#include <sys/socket.h>
|
||||
#endif
|
||||
|
||||
/* type of transport we use */
|
||||
/*#define NCP_ON_IPX 0
|
||||
#define NCP_ON_TCP 1*/
|
||||
|
||||
/* flags field in conn structure */
|
||||
#define NCPFL_SOCONN 0x0001 /* socket layer is up */
|
||||
#define NCPFL_ATTACHED 0x0002 /* ncp layer is up */
|
||||
#define NCPFL_LOGGED 0x0004 /* logged in to server */
|
||||
#define NCPFL_INVALID 0x0008 /* last request was not completed */
|
||||
#define NCPFL_INTR 0x0010 /* interrupted call */
|
||||
#define NCPFL_RESTORING 0x0020 /* trying to reconnect */
|
||||
#define NCPFL_PERMANENT 0x0040 /* no way to kill conn, when this set */
|
||||
#define NCPFL_PRIMARY 0x0080 /* have meaning only for owner */
|
||||
#define NCPFL_WASATTACHED 0x0100 /* there was at least one successfull connect */
|
||||
#define NCPFL_WASLOGGED 0x0200 /* there was at least one successfull login */
|
||||
#define NCPFL_SIGNACTIVE 0x1000 /* packet signing active */
|
||||
#define NCPFL_SIGNWANTED 0x2000 /* signing should start */
|
||||
|
||||
/* access mode for connection */
|
||||
#define NCPM_READ 0400 /* able to fetch conn params */
|
||||
#define NCPM_WRITE 0200 /* modify/close */
|
||||
#define NCPM_EXECUTE 0100 /* run requests */
|
||||
|
||||
#define NCP_DEFAULT_OWNER ((uid_t)-1)
|
||||
#define NCP_DEFAULT_GROUP ((uid_t)-1)
|
||||
|
||||
|
||||
/* args used to create connection */
|
||||
#define ncp_conn_loginfo ncp_conn_args
|
||||
struct ncp_conn_args {
|
||||
int opt;
|
||||
#define NCP_OPT_WDOG 1 /* need watch dog socket */
|
||||
#define NCP_OPT_MSG 2 /* need message socket */
|
||||
#define NCP_OPT_SIGN 4 /* signatures wanted */
|
||||
#define NCP_OPT_BIND 8 /* force bindery login */
|
||||
#define NCP_OPT_PERMANENT 0x10 /* only for refernce, completly ignored */
|
||||
#define NCP_OPT_NOUPCASEPASS 0x20 /* leave password as is */
|
||||
int sig_level; /* wanted signature level */
|
||||
char server[NCP_BINDERY_NAME_LEN+1];
|
||||
char *user;
|
||||
char *password;
|
||||
u_int32_t objtype;
|
||||
union {
|
||||
struct sockaddr addr;
|
||||
struct sockaddr_ipx ipxaddr;
|
||||
struct sockaddr_in inaddr;
|
||||
} addr;
|
||||
int timeout; /* ncp rq timeout */
|
||||
int retry_count; /* counts to give an error */
|
||||
uid_t owner; /* proposed owner of connection */
|
||||
gid_t group; /* proposed group of connection */
|
||||
mode_t access_mode; /* R/W - can do rq's, X - can see the conn */
|
||||
};
|
||||
|
||||
#define ipxaddr addr.ipxaddr
|
||||
#define inaddr addr.inaddr
|
||||
#define saddr addr.addr
|
||||
|
||||
/* user side structure to issue ncp calls */
|
||||
struct ncp_buf {
|
||||
int rqsize; /* request size without ncp header */
|
||||
int rpsize; /* reply size minus ncp header */
|
||||
int cc; /* completion code */
|
||||
int cs; /* connection state */
|
||||
char packet[NCP_MAX_PACKET_SIZE];/* Here we prepare requests and receive replies */
|
||||
};
|
||||
|
||||
/*
|
||||
* Connection status, returned via sysctl(vfs.nwfs.connstat)
|
||||
*/
|
||||
struct ncp_conn_stat {
|
||||
struct ncp_conn_args li;
|
||||
int connRef;
|
||||
int ref_cnt;
|
||||
int connid;
|
||||
int buffer_size;
|
||||
int flags;
|
||||
int sign_active;
|
||||
uid_t owner;
|
||||
gid_t group;
|
||||
char user[NCP_MAXUSERNAMELEN+1];
|
||||
};
|
||||
|
||||
#ifdef _KERNEL
|
||||
|
||||
#ifndef LK_SHARED
|
||||
#include <sys/lock.h>
|
||||
#include <sys/lockmgr.h>
|
||||
#endif
|
||||
|
||||
struct socket;
|
||||
struct u_cred;
|
||||
|
||||
SLIST_HEAD(ncp_conn_head,ncp_conn);
|
||||
|
||||
struct ncp_rq;
|
||||
struct ncp_conn;
|
||||
|
||||
/*
|
||||
* External and internal processes can reference connection only by handle.
|
||||
* This gives us a freedom in maintance of underlying connections.
|
||||
*/
|
||||
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 thread * nh_td; /* who owns the handle */
|
||||
int nh_ref; /* one process can asquire many handles, but we return the one */
|
||||
};
|
||||
|
||||
/*
|
||||
* Describes any connection to server
|
||||
*/
|
||||
struct ncp_conn {
|
||||
SLIST_ENTRY(ncp_conn) nc_next;
|
||||
struct ncp_conn_args li;
|
||||
struct ucred *nc_owner;
|
||||
gid_t nc_group;
|
||||
int flags;
|
||||
int nc_id;
|
||||
struct socket *ncp_so;
|
||||
struct socket *wdg_so;
|
||||
struct socket *msg_so;
|
||||
struct socket *bc_so;
|
||||
int ref_cnt; /* how many handles leased */
|
||||
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 thread *td; /* pid currently operates */
|
||||
struct ucred *ucred; /* usr currently operates */
|
||||
/* Fields used to process ncp requests */
|
||||
int connid; /* assigned by server */
|
||||
u_int8_t seq;
|
||||
int buffer_size; /* Negotiated bufsize */
|
||||
/* Fields used to make packet signatures */
|
||||
u_int32_t sign_root[2];
|
||||
u_int32_t sign_state[4]; /* md4 state */
|
||||
#ifdef NCPBURST
|
||||
/* Fields used for packet bursting */
|
||||
u_long bc_pktseq; /* raw packet sequence */
|
||||
u_short bc_seq; /* burst sequence */
|
||||
u_long bc_locid; /* local connection id */
|
||||
u_long bc_remid; /* remote connection id */
|
||||
u_long bc_pktsize; /* negotiated burst packet size */
|
||||
#endif
|
||||
};
|
||||
|
||||
int ncp_conn_init(void);
|
||||
int ncp_conn_destroy(void);
|
||||
int ncp_conn_alloc(struct ncp_conn_args *cap,
|
||||
struct thread *td, struct ucred *cred, struct ncp_conn **connid);
|
||||
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,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);
|
||||
int ncp_conn_rm_ref(struct ncp_conn *conn, pid_t pid, int force);
|
||||
void ncp_conn_list_rm_ref(pid_t pid);*/
|
||||
int ncp_conn_getbyref(int connRef,struct thread *td, struct ucred *cred, int mode,
|
||||
struct ncp_conn **connpp);
|
||||
int ncp_conn_getbyli(struct ncp_conn_loginfo *li,struct thread *td, struct ucred *cred,
|
||||
int mode, struct ncp_conn **connpp);
|
||||
int ncp_conn_setprimary(struct ncp_conn *conn, int on);
|
||||
int ncp_conn_locklist(int flags, struct thread *td);
|
||||
void ncp_conn_unlocklist(struct thread *td);
|
||||
int ncp_conn_gethandle(struct ncp_conn *conn, struct thread *td, struct ncp_handle **handle);
|
||||
int ncp_conn_puthandle(struct ncp_handle *handle, struct thread *td, int force);
|
||||
int ncp_conn_findhandle(int connHandle, struct thread *td, struct ncp_handle **handle);
|
||||
int ncp_conn_getattached(struct ncp_conn_args *li,struct thread *td, struct ucred *cred,int mode, struct ncp_conn **connpp);
|
||||
int ncp_conn_putprochandles(struct thread *td);
|
||||
int ncp_conn_getinfo(struct ncp_conn *ncp, struct ncp_conn_stat *ncs);
|
||||
|
||||
int ncp_conn_reconnect(struct ncp_conn *ncp);
|
||||
int ncp_conn_login(struct ncp_conn *conn, struct thread *td, struct ucred *cred);
|
||||
|
||||
extern struct ncp_conn_head conn_list;
|
||||
extern int ncp_burst_enabled;
|
||||
|
||||
#ifdef MALLOC_DECLARE
|
||||
MALLOC_DECLARE(M_NCPDATA);
|
||||
#endif
|
||||
|
||||
#endif /* _KERNEL */
|
||||
#endif /* _NCP_CONN_H_ */
|
@ -1,271 +0,0 @@
|
||||
/*
|
||||
* Routines in this file based on work of Volker Lendecke
|
||||
*/
|
||||
/*$*********************************************************
|
||||
$*
|
||||
$* This code has been taken from DDJ 11/93, from an
|
||||
$* article by Pawel Szczerbina.
|
||||
$*
|
||||
$* Password encryption routines follow.
|
||||
$* Converted to C from Barry Nance's Pascal
|
||||
$* prog published in the March -93 issue of Byte.
|
||||
$*
|
||||
$* Adapted to be useable for ncpfs by
|
||||
$* Volker Lendecke <lendecke@namu01.gwdg.de> in
|
||||
$* October 1995.
|
||||
$*
|
||||
$********************************************************* */
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <netncp/ncp.h>
|
||||
#include <netncp/ncp_subr.h>
|
||||
|
||||
typedef unsigned char buf32[32];
|
||||
|
||||
static unsigned char encrypttable[256] = {
|
||||
0x7, 0x8, 0x0, 0x8, 0x6, 0x4, 0xE, 0x4, 0x5, 0xC, 0x1, 0x7, 0xB, 0xF, 0xA, 0x8,
|
||||
0xF, 0x8, 0xC, 0xC, 0x9, 0x4, 0x1, 0xE, 0x4, 0x6, 0x2, 0x4, 0x0, 0xA, 0xB, 0x9,
|
||||
0x2, 0xF, 0xB, 0x1, 0xD, 0x2, 0x1, 0x9, 0x5, 0xE, 0x7, 0x0, 0x0, 0x2, 0x6, 0x6,
|
||||
0x0, 0x7, 0x3, 0x8, 0x2, 0x9, 0x3, 0xF, 0x7, 0xF, 0xC, 0xF, 0x6, 0x4, 0xA, 0x0,
|
||||
0x2, 0x3, 0xA, 0xB, 0xD, 0x8, 0x3, 0xA, 0x1, 0x7, 0xC, 0xF, 0x1, 0x8, 0x9, 0xD,
|
||||
0x9, 0x1, 0x9, 0x4, 0xE, 0x4, 0xC, 0x5, 0x5, 0xC, 0x8, 0xB, 0x2, 0x3, 0x9, 0xE,
|
||||
0x7, 0x7, 0x6, 0x9, 0xE, 0xF, 0xC, 0x8, 0xD, 0x1, 0xA, 0x6, 0xE, 0xD, 0x0, 0x7,
|
||||
0x7, 0xA, 0x0, 0x1, 0xF, 0x5, 0x4, 0xB, 0x7, 0xB, 0xE, 0xC, 0x9, 0x5, 0xD, 0x1,
|
||||
0xB, 0xD, 0x1, 0x3, 0x5, 0xD, 0xE, 0x6, 0x3, 0x0, 0xB, 0xB, 0xF, 0x3, 0x6, 0x4,
|
||||
0x9, 0xD, 0xA, 0x3, 0x1, 0x4, 0x9, 0x4, 0x8, 0x3, 0xB, 0xE, 0x5, 0x0, 0x5, 0x2,
|
||||
0xC, 0xB, 0xD, 0x5, 0xD, 0x5, 0xD, 0x2, 0xD, 0x9, 0xA, 0xC, 0xA, 0x0, 0xB, 0x3,
|
||||
0x5, 0x3, 0x6, 0x9, 0x5, 0x1, 0xE, 0xE, 0x0, 0xE, 0x8, 0x2, 0xD, 0x2, 0x2, 0x0,
|
||||
0x4, 0xF, 0x8, 0x5, 0x9, 0x6, 0x8, 0x6, 0xB, 0xA, 0xB, 0xF, 0x0, 0x7, 0x2, 0x8,
|
||||
0xC, 0x7, 0x3, 0xA, 0x1, 0x4, 0x2, 0x5, 0xF, 0x7, 0xA, 0xC, 0xE, 0x5, 0x9, 0x3,
|
||||
0xE, 0x7, 0x1, 0x2, 0xE, 0x1, 0xF, 0x4, 0xA, 0x6, 0xC, 0x6, 0xF, 0x4, 0x3, 0x0,
|
||||
0xC, 0x0, 0x3, 0x6, 0xF, 0x8, 0x7, 0xB, 0x2, 0xD, 0xC, 0x6, 0xA, 0xA, 0x8, 0xD
|
||||
};
|
||||
|
||||
static buf32 encryptkeys = {
|
||||
0x48, 0x93, 0x46, 0x67, 0x98, 0x3D, 0xE6, 0x8D,
|
||||
0xB7, 0x10, 0x7A, 0x26, 0x5A, 0xB9, 0xB1, 0x35,
|
||||
0x6B, 0x0F, 0xD5, 0x70, 0xAE, 0xFB, 0xAD, 0x11,
|
||||
0xF4, 0x47, 0xDC, 0xA7, 0xEC, 0xCF, 0x50, 0xC0
|
||||
};
|
||||
|
||||
/*
|
||||
* Create table-based 16-bytes hash from a 32-bytes array
|
||||
*/
|
||||
static void
|
||||
nw_hash(buf32 temp, unsigned char *target) {
|
||||
short sum;
|
||||
unsigned char b3;
|
||||
int s, b2, i;
|
||||
|
||||
sum = 0;
|
||||
|
||||
for (b2 = 0; b2 <= 1; ++b2) {
|
||||
for (s = 0; s <= 31; ++s) {
|
||||
b3 = (temp[s] + sum) ^ (temp[(s + sum) & 31] - encryptkeys[s]);
|
||||
sum += b3;
|
||||
temp[s] = b3;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i <= 15; ++i) {
|
||||
target[i] = encrypttable[temp[2 * i]]
|
||||
| (encrypttable[temp[2 * i + 1]] << 4);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Create a 16-bytes pattern from given buffer based on a four bytes key
|
||||
*/
|
||||
void
|
||||
nw_keyhash(const u_char *key, const u_char *buf, int buflen, u_char *target) {
|
||||
int b2, d, s;
|
||||
buf32 temp;
|
||||
|
||||
while (buflen > 0 && buf[buflen - 1] == 0)
|
||||
buflen--;
|
||||
|
||||
bzero(temp, sizeof(temp));
|
||||
|
||||
d = 0;
|
||||
while (buflen >= 32) {
|
||||
for (s = 0; s <= 31; ++s)
|
||||
temp[s] ^= buf[d++];
|
||||
buflen -= 32;
|
||||
}
|
||||
b2 = d;
|
||||
if (buflen > 0) {
|
||||
for (s = 0; s <= 31; ++s) {
|
||||
if (d + buflen == b2) {
|
||||
temp[s] ^= encryptkeys[s];
|
||||
b2 = d;
|
||||
} else
|
||||
temp[s] ^= buf[b2++];
|
||||
}
|
||||
}
|
||||
for (s = 0; s <= 31; ++s)
|
||||
temp[s] ^= key[s & 3];
|
||||
|
||||
nw_hash(temp, target);
|
||||
}
|
||||
|
||||
/*
|
||||
* Create an 8-bytes pattern from an 8-bytes key and 16-bytes of data
|
||||
*/
|
||||
void
|
||||
nw_encrypt(const u_char *fra, const u_char *buf, u_char *target) {
|
||||
buf32 k;
|
||||
int s;
|
||||
|
||||
nw_keyhash(fra, buf, 16, k);
|
||||
nw_keyhash(fra + 4, buf, 16, k + 16);
|
||||
|
||||
for (s = 0; s < 16; s++)
|
||||
k[s] ^= k[31 - s];
|
||||
|
||||
for (s = 0; s < 8; s++)
|
||||
*target++ = k[s] ^ k[15 - s];
|
||||
}
|
||||
|
||||
#ifdef _KERNEL
|
||||
/*
|
||||
* MD4 routine taken from libmd sources
|
||||
*/
|
||||
typedef u_int32_t UINT4;
|
||||
typedef unsigned char *POINTER;
|
||||
|
||||
#define PROTO_LIST(list) list
|
||||
|
||||
static void Decode PROTO_LIST
|
||||
((UINT4 *, const unsigned char *, unsigned int));
|
||||
|
||||
/* Constants for MD4Transform routine.
|
||||
*/
|
||||
#define S11 3
|
||||
#define S12 7
|
||||
#define S13 11
|
||||
#define S14 19
|
||||
#define S21 3
|
||||
#define S22 5
|
||||
#define S23 9
|
||||
#define S24 13
|
||||
#define S31 3
|
||||
#define S32 9
|
||||
#define S33 11
|
||||
#define S34 15
|
||||
|
||||
/* F, G and H are basic MD4 functions.
|
||||
*/
|
||||
#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
|
||||
#define G(x, y, z) (((x) & (y)) | ((x) & (z)) | ((y) & (z)))
|
||||
#define H(x, y, z) ((x) ^ (y) ^ (z))
|
||||
|
||||
/* ROTATE_LEFT rotates x left n bits.
|
||||
*/
|
||||
#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
|
||||
|
||||
/* FF, GG and HH are transformations for rounds 1, 2 and 3 */
|
||||
/* Rotation is separate from addition to prevent recomputation */
|
||||
#define FF(a, b, c, d, x, s) { \
|
||||
(a) += F ((b), (c), (d)) + (x); \
|
||||
(a) = ROTATE_LEFT ((a), (s)); \
|
||||
}
|
||||
#define GG(a, b, c, d, x, s) { \
|
||||
(a) += G ((b), (c), (d)) + (x) + (UINT4)0x5a827999; \
|
||||
(a) = ROTATE_LEFT ((a), (s)); \
|
||||
}
|
||||
#define HH(a, b, c, d, x, s) { \
|
||||
(a) += H ((b), (c), (d)) + (x) + (UINT4)0x6ed9eba1; \
|
||||
(a) = ROTATE_LEFT ((a), (s)); \
|
||||
}
|
||||
|
||||
void
|
||||
ncp_sign(const u_int32_t *state, const char *block, u_int32_t *ostate) {
|
||||
UINT4 a, b, c, d, x[16];
|
||||
|
||||
Decode (x, block, 64);
|
||||
a = state[0];
|
||||
b = state[1];
|
||||
c = state[2];
|
||||
d = state[3];
|
||||
/* Round 1 */
|
||||
FF (a, b, c, d, x[ 0], S11); /* 1 */
|
||||
FF (d, a, b, c, x[ 1], S12); /* 2 */
|
||||
FF (c, d, a, b, x[ 2], S13); /* 3 */
|
||||
FF (b, c, d, a, x[ 3], S14); /* 4 */
|
||||
FF (a, b, c, d, x[ 4], S11); /* 5 */
|
||||
FF (d, a, b, c, x[ 5], S12); /* 6 */
|
||||
FF (c, d, a, b, x[ 6], S13); /* 7 */
|
||||
FF (b, c, d, a, x[ 7], S14); /* 8 */
|
||||
FF (a, b, c, d, x[ 8], S11); /* 9 */
|
||||
FF (d, a, b, c, x[ 9], S12); /* 10 */
|
||||
FF (c, d, a, b, x[10], S13); /* 11 */
|
||||
FF (b, c, d, a, x[11], S14); /* 12 */
|
||||
FF (a, b, c, d, x[12], S11); /* 13 */
|
||||
FF (d, a, b, c, x[13], S12); /* 14 */
|
||||
FF (c, d, a, b, x[14], S13); /* 15 */
|
||||
FF (b, c, d, a, x[15], S14); /* 16 */
|
||||
|
||||
/* Round 2 */
|
||||
GG (a, b, c, d, x[ 0], S21); /* 17 */
|
||||
GG (d, a, b, c, x[ 4], S22); /* 18 */
|
||||
GG (c, d, a, b, x[ 8], S23); /* 19 */
|
||||
GG (b, c, d, a, x[12], S24); /* 20 */
|
||||
GG (a, b, c, d, x[ 1], S21); /* 21 */
|
||||
GG (d, a, b, c, x[ 5], S22); /* 22 */
|
||||
GG (c, d, a, b, x[ 9], S23); /* 23 */
|
||||
GG (b, c, d, a, x[13], S24); /* 24 */
|
||||
GG (a, b, c, d, x[ 2], S21); /* 25 */
|
||||
GG (d, a, b, c, x[ 6], S22); /* 26 */
|
||||
GG (c, d, a, b, x[10], S23); /* 27 */
|
||||
GG (b, c, d, a, x[14], S24); /* 28 */
|
||||
GG (a, b, c, d, x[ 3], S21); /* 29 */
|
||||
GG (d, a, b, c, x[ 7], S22); /* 30 */
|
||||
GG (c, d, a, b, x[11], S23); /* 31 */
|
||||
GG (b, c, d, a, x[15], S24); /* 32 */
|
||||
|
||||
/* Round 3 */
|
||||
HH (a, b, c, d, x[ 0], S31); /* 33 */
|
||||
HH (d, a, b, c, x[ 8], S32); /* 34 */
|
||||
HH (c, d, a, b, x[ 4], S33); /* 35 */
|
||||
HH (b, c, d, a, x[12], S34); /* 36 */
|
||||
HH (a, b, c, d, x[ 2], S31); /* 37 */
|
||||
HH (d, a, b, c, x[10], S32); /* 38 */
|
||||
HH (c, d, a, b, x[ 6], S33); /* 39 */
|
||||
HH (b, c, d, a, x[14], S34); /* 40 */
|
||||
HH (a, b, c, d, x[ 1], S31); /* 41 */
|
||||
HH (d, a, b, c, x[ 9], S32); /* 42 */
|
||||
HH (c, d, a, b, x[ 5], S33); /* 43 */
|
||||
HH (b, c, d, a, x[13], S34); /* 44 */
|
||||
HH (a, b, c, d, x[ 3], S31); /* 45 */
|
||||
HH (d, a, b, c, x[11], S32); /* 46 */
|
||||
HH (c, d, a, b, x[ 7], S33); /* 47 */
|
||||
HH (b, c, d, a, x[15], S34); /* 48 */
|
||||
|
||||
ostate[0] = state[0] + a;
|
||||
ostate[1] = state[1] + b;
|
||||
ostate[2] = state[2] + c;
|
||||
ostate[3] = state[3] + d;
|
||||
}
|
||||
|
||||
/* Decodes input (unsigned char) into output (UINT4). Assumes len is
|
||||
a multiple of 4.
|
||||
*/
|
||||
static void Decode (output, input, len)
|
||||
|
||||
UINT4 *output;
|
||||
const unsigned char *input;
|
||||
unsigned int len;
|
||||
{
|
||||
unsigned int i, j;
|
||||
|
||||
for (i = 0, j = 0; j < len; i++, j += 4)
|
||||
output[i] = ((UINT4)input[j]) | (((UINT4)input[j+1]) << 8) |
|
||||
(((UINT4)input[j+2]) << 16) | (((UINT4)input[j+3]) << 24);
|
||||
}
|
||||
|
||||
#endif /* _KERNEL */
|
@ -1,76 +0,0 @@
|
||||
/*-
|
||||
* Copyright (c) 1999 Boris Popov
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#ifndef _NETNCP_NCP_FILE_H_
|
||||
#define _NETNCP_NCP_FILE_H_
|
||||
|
||||
typedef struct {
|
||||
nuint32 sequence;
|
||||
nuint32 parent;
|
||||
nuint32 attributes;
|
||||
nuint8 uniqueID;
|
||||
nuint8 flags;
|
||||
nuint8 nameSpace;
|
||||
nuint8 nameLength;
|
||||
nuint8 name [256];
|
||||
nuint32 creationDateAndTime;
|
||||
nuint32 ownerID;
|
||||
nuint32 lastArchiveDateAndTime;
|
||||
nuint32 lastArchiverID;
|
||||
nuint32 updateDateAndTime;
|
||||
nuint32 updatorID;
|
||||
nuint32 fileSize;
|
||||
nuint8 reserved[44];
|
||||
nuint16 inheritedRightsMask;
|
||||
nuint16 lastAccessDate;
|
||||
nuint32 deletedTime;
|
||||
nuint32 deletedDateAndTime;
|
||||
nuint32 deletorID;
|
||||
nuint8 reserved3 [16];
|
||||
} __packed NWDELETED_INFO;
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
int ncp_AllocTempDirHandle(char *, NWDIR_HANDLE *);
|
||||
int ncp_DeallocateDirHandle(NWDIR_HANDLE);
|
||||
int ncp_GetNSEntryInfo(NWDIR_HANDLE, struct nw_entry_info *, int *);
|
||||
|
||||
NWCCODE ncp_ScanNSEntryInfo(NWCONN_HANDLE, nuint8, nuint16,
|
||||
SEARCH_SEQUENCE *, pnstr8, nuint32, NW_ENTRY_INFO *);
|
||||
|
||||
NWCCODE ncp_PurgeDeletedFile(NWCONN_HANDLE, nuint32, nuint32, nuint32, nuint8);
|
||||
|
||||
NWCCODE NWRecoverDeletedFile(NWCONN_HANDLE, NWDIR_HANDLE,
|
||||
nuint32, nuint32, nuint32, pnstr8, pnstr8);
|
||||
|
||||
NWCCODE ncp_ScanForDeletedFiles(NWCONN_HANDLE, pnuint32, pnuint32, pnuint32,
|
||||
nuint8, NWDELETED_INFO *);
|
||||
|
||||
__END_DECLS
|
||||
|
||||
#endif /* _NCP_NCP_FILE_ */
|
@ -1,246 +0,0 @@
|
||||
/*-
|
||||
* Copyright (c) 1999, 2000, 2001 Boris Popov
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#ifndef _NETNCP_NCP_LIB_H_
|
||||
#define _NETNCP_NCP_LIB_H_
|
||||
|
||||
#define IPX
|
||||
#define INET
|
||||
|
||||
#include <netncp/ncp.h>
|
||||
#include <netncp/ncp_conn.h>
|
||||
#include <netncp/ncp_user.h>
|
||||
#include <netncp/ncp_rq.h>
|
||||
|
||||
#define ncp_printf printf
|
||||
|
||||
#define sipx_cnetwork sipx_addr.x_net.c_net
|
||||
#define sipx_node sipx_addr.x_host.c_host
|
||||
#define ipx_netlong(iaddr) (((union ipx_net_u *)(&((iaddr).x_net)))->long_e)
|
||||
|
||||
#define STDPARAM_ARGS 'A':case 'B':case 'C':case 'I':case 'M': \
|
||||
case 'N':case 'U':case 'R':case 'S':case 'T': \
|
||||
case 'W':case 'O':case 'P'
|
||||
|
||||
#define STDPARAM_OPT "A:BCI:M:NO:P:U:R:S:T:W:"
|
||||
|
||||
#ifndef min
|
||||
#define min(a,b) (((a)<(b)) ? (a) : (b))
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* An attempt to do a unified options parser
|
||||
*/
|
||||
enum ncp_argtype {NCA_STR,NCA_INT,NCA_BOOL};
|
||||
|
||||
struct ncp_args;
|
||||
|
||||
typedef int ncp_setopt_t (struct ncp_args*);
|
||||
|
||||
#define NAFL_NONE 0x0000
|
||||
#define NAFL_HAVEMIN 0x0001
|
||||
#define NAFL_HAVEMAX 0x0002
|
||||
#define NAFL_MINMAX NAFL_HAVEMIN | NAFL_HAVEMAX
|
||||
|
||||
struct ncp_args {
|
||||
enum ncp_argtype at;
|
||||
int opt; /* command line option */
|
||||
char *name; /* rc file equiv */
|
||||
int flag; /* NAFL_* */
|
||||
int ival; /* int/bool values, or max len for str value */
|
||||
char *str; /* string value */
|
||||
int min; /* min for ival */
|
||||
int max; /* max for ival */
|
||||
ncp_setopt_t *fn;/* call back to validate */
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
nuint8 day;
|
||||
nuint8 month;
|
||||
nuint16 year;
|
||||
} NW_DATE;
|
||||
|
||||
/* hours is a nuint16 so that this structure will be the same length as a dword */
|
||||
typedef struct {
|
||||
nuint8 seconds;
|
||||
nuint8 minutes;
|
||||
nuint16 hours;
|
||||
} NW_TIME;
|
||||
|
||||
struct ncp_bitname {
|
||||
u_int bn_bit;
|
||||
const char *bn_name;
|
||||
};
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
int ncp_args_parserc(struct ncp_args *, char *, ncp_setopt_t *);
|
||||
int ncp_args_parseopt(struct ncp_args *, int, char *, ncp_setopt_t *);
|
||||
|
||||
|
||||
struct sockaddr_ipx;
|
||||
struct ipx_addr;
|
||||
struct sockaddr;
|
||||
struct ncp_buf;
|
||||
struct rcfile;
|
||||
|
||||
int ncp_initlib(void);
|
||||
int ncp_connect(struct ncp_conn_args *, int *);
|
||||
int ncp_connect_addr(struct sockaddr *, NWCONN_HANDLE *);
|
||||
int ncp_disconnect(int);
|
||||
int ncp_request(int, int, struct ncp_buf *);
|
||||
int ncp_conn_request(int, struct ncp_buf *);
|
||||
int ncp_login(int, const char *, int, const char *);
|
||||
int ncp_conn_scan(struct ncp_conn_loginfo *, int *);
|
||||
int ncp_conn_cnt(void);
|
||||
void *ncp_conn_list(void);
|
||||
int ncp_conn_getinfo(int, struct ncp_conn_stat *);
|
||||
int ncp_conn_getuser(int, char **);
|
||||
int ncp_conn2ref(int, int *);
|
||||
int ncp_conn_dup(NWCONN_HANDLE, NWCONN_HANDLE *);
|
||||
int ncp_path2conn(char *, int *);
|
||||
int ncp_li_init(struct ncp_conn_loginfo *, int, char *[]);
|
||||
void ncp_li_done(struct ncp_conn_loginfo *);
|
||||
int ncp_li_login(struct ncp_conn_loginfo *, int *);
|
||||
int ncp_li_readrc(struct ncp_conn_loginfo *);
|
||||
int ncp_li_check(struct ncp_conn_loginfo *);
|
||||
int ncp_li_arg(struct ncp_conn_loginfo *, int, char *);
|
||||
int ncp_li_setserver(struct ncp_conn_loginfo *, const char *);
|
||||
int ncp_li_setuser(struct ncp_conn_loginfo *, char *);
|
||||
int ncp_li_setpassword(struct ncp_conn_loginfo *, const char *);
|
||||
int ncp_conn_setflags(int, u_int16_t, u_int16_t);
|
||||
int ncp_conn_find(char *, char *);
|
||||
NWCCODE NWRequest(NWCONN_HANDLE, nuint16, nuint16, NW_FRAGMENT *,
|
||||
nuint16, NW_FRAGMENT *);
|
||||
|
||||
#define ncp_setpermanent(connHandle,on) ncp_conn_setflags(connHandle, NCPFL_PERMANENT, (on) ? NCPFL_PERMANENT : 0)
|
||||
#define ncp_setprimary(connHandle,on) ncp_conn_setflags(connHandle, NCPFL_PRIMARY, (on) ? NCPFL_PRIMARY : 0)
|
||||
|
||||
int ncp_find_fileserver(struct ncp_conn_loginfo *, int, char *);
|
||||
int ncp_find_server(struct ncp_conn_loginfo *, int, int, char *);
|
||||
|
||||
/* misc rotines */
|
||||
char* ncp_str_upper(char *);
|
||||
int ncp_open_rcfile(void);
|
||||
int ncp_getopt(int, char * const *, const char *);
|
||||
void NWUnpackDateTime(nuint32, NW_DATE *, NW_TIME *);
|
||||
void NWUnpackDate(nuint16, NW_DATE *);
|
||||
void NWUnpackTime(nuint16, NW_TIME *);
|
||||
time_t ncp_UnpackDateTime(nuint32);
|
||||
int ncp_GetFileServerDateAndTime(NWCONN_HANDLE, time_t *);
|
||||
int ncp_SetFileServerDateAndTime(NWCONN_HANDLE, time_t *);
|
||||
NWCCODE NWDownFileServer(NWCONN_HANDLE, int);
|
||||
NWCCODE NWCloseBindery(NWCONN_HANDLE);
|
||||
NWCCODE NWOpenBindery(NWCONN_HANDLE);
|
||||
NWCCODE NWDisableTTS(NWCONN_HANDLE);
|
||||
NWCCODE NWEnableTTS(NWCONN_HANDLE);
|
||||
NWCCODE NWDisableFileServerLogin(NWCONN_HANDLE);
|
||||
NWCCODE NWEnableFileServerLogin(NWCONN_HANDLE);
|
||||
void ncp_error(const char *, int, ...) __printf0like(1, 3);
|
||||
char *ncp_printb(char *, int, const struct ncp_bitname *);
|
||||
void nw_keyhash(const u_char *, const u_char *, int, u_char *);
|
||||
void nw_encrypt(const u_char *, const u_char *, u_char *);
|
||||
void ipx_print_addr(struct ipx_addr *);
|
||||
|
||||
/* bindery calls */
|
||||
int ncp_get_bindery_object_id(NWCONN_HANDLE, u_int16_t, const char *,
|
||||
struct ncp_bindery_object *);
|
||||
int ncp_get_bindery_object_name(NWCONN_HANDLE, u_int32_t,
|
||||
struct ncp_bindery_object *);
|
||||
int ncp_scan_bindery_object(NWCONN_HANDLE, u_int32_t, u_int16_t,
|
||||
const char *, struct ncp_bindery_object *);
|
||||
int ncp_read_property_value(NWCONN_HANDLE, int object_type, const char *,
|
||||
int, const char *, struct nw_property *);
|
||||
int ncp_get_encryption_key(NWCONN_HANDLE, char *);
|
||||
int ncp_change_obj_passwd(NWCONN_HANDLE,
|
||||
const struct ncp_bindery_object *, const u_char *,
|
||||
const u_char *, const u_char *);
|
||||
int ncp_keyed_verify_password(NWCONN_HANDLE, char *, char *,
|
||||
struct ncp_bindery_object *);
|
||||
|
||||
/* queue calls */
|
||||
int ncp_create_queue_job_and_file(NWCONN_HANDLE, u_int32_t, struct queue_job *);
|
||||
int ncp_close_file_and_start_job(NWCONN_HANDLE, u_int32_t, struct queue_job *);
|
||||
int ncp_attach_to_queue(NWCONN_HANDLE, u_int32_t);
|
||||
int ncp_detach_from_queue(NWCONN_HANDLE, u_int32_t);
|
||||
int ncp_service_queue_job(NWCONN_HANDLE, u_int32_t, u_int16_t,
|
||||
struct queue_job *);
|
||||
int ncp_finish_servicing_job(NWCONN_HANDLE, u_int32_t, u_int32_t, u_int32_t);
|
||||
int ncp_abort_servicing_job(NWCONN_HANDLE, u_int32_t, u_int32_t);
|
||||
int ncp_get_queue_length(NWCONN_HANDLE, u_int32_t, u_int32_t *);
|
||||
int ncp_get_queue_job_ids(NWCONN_HANDLE, u_int32_t, u_int32_t,
|
||||
u_int32_t *, u_int32_t *, u_int32_t []);
|
||||
int ncp_get_queue_job_info(NWCONN_HANDLE, u_int32_t, u_int32_t,
|
||||
struct nw_queue_job_entry *);
|
||||
/*
|
||||
* filesystem and volume calls
|
||||
*/
|
||||
int ncp_read(NWCONN_HANDLE, ncp_fh *, off_t, size_t, char *);
|
||||
int ncp_write(NWCONN_HANDLE, ncp_fh *, off_t, size_t, char *);
|
||||
int ncp_geteinfo(char *, struct nw_entry_info *);
|
||||
int ncp_NSEntryInfo(NWCONN_HANDLE, nuint8, nuint8, nuint32, NW_ENTRY_INFO *);
|
||||
|
||||
NWCCODE NWGetVolumeName(NWCONN_HANDLE, u_char, char *);
|
||||
|
||||
/* misc ncp calls */
|
||||
int ncp_get_file_server_information(NWCONN_HANDLE, struct ncp_file_server_info *);
|
||||
int ncp_get_stations_logged_info(NWCONN_HANDLE, u_int32_t,
|
||||
struct ncp_bindery_object *, time_t *);
|
||||
int ncp_get_internet_address(NWCONN_HANDLE, u_int32_t, struct ipx_addr *,
|
||||
u_int8_t *);
|
||||
NWCCODE NWGetObjectConnectionNumbers(NWCONN_HANDLE, pnstr8, nuint16,
|
||||
pnuint16, pnuint16, nuint16);
|
||||
/*
|
||||
* Message broadcast
|
||||
*/
|
||||
NWCCODE NWDisableBroadcasts(NWCONN_HANDLE);
|
||||
NWCCODE NWEnableBroadcasts(NWCONN_HANDLE);
|
||||
NWCCODE NWBroadcastToConsole(NWCONN_HANDLE, pnstr8);
|
||||
NWCCODE NWSendBroadcastMessage(NWCONN_HANDLE, pnstr8, nuint16, pnuint16, pnuint8);
|
||||
NWCCODE NWGetBroadcastMessage(NWCONN_HANDLE, pnstr8);
|
||||
|
||||
/*
|
||||
* RPC calls
|
||||
*/
|
||||
NWCCODE NWSMExecuteNCFFile(NWCONN_HANDLE, pnstr8);
|
||||
NWCCODE NWSMLoadNLM(NWCONN_HANDLE, pnstr8);
|
||||
NWCCODE NWSMUnloadNLM(NWCONN_HANDLE, pnstr8);
|
||||
NWCCODE NWSMMountVolume(NWCONN_HANDLE, pnstr8, nuint32 *);
|
||||
NWCCODE NWSMDismountVolumeByName(NWCONN_HANDLE, pnstr8);
|
||||
NWCCODE NWSMSetDynamicCmdIntValue(NWCONN_HANDLE, pnstr8, nuint32);
|
||||
NWCCODE NWSMSetDynamicCmdStrValue(NWCONN_HANDLE, pnstr8, pnstr8);
|
||||
|
||||
__END_DECLS
|
||||
|
||||
extern int ncp_opterr, ncp_optind, ncp_optopt, ncp_optreset;
|
||||
extern char *ncp_optarg;
|
||||
|
||||
extern struct rcfile *ncp_rc;
|
||||
extern int sysentoffset;
|
||||
#endif /* _NETNCP_NCP_LIB_H_ */
|
@ -1,43 +0,0 @@
|
||||
/*-
|
||||
* Copyright (c) 1999, 2000, 2001 Boris Popov
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/errno.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/proc.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include <netncp/ncp.h>
|
||||
#include <netncp/ncp_conn.h>
|
||||
#include <netncp/ncp_subr.h>
|
||||
#include <netncp/ncp_ncp.h>
|
||||
#include <netncp/ncp_rq.h>
|
||||
#include <netncp/ncp_nls.h>
|
||||
#include <netncp/nwerror.h>
|
@ -1,529 +0,0 @@
|
||||
/*-
|
||||
* Copyright (c) 2003 Tim J. Robbins.
|
||||
* Copyright (c) 1999, 2000, 2001 Boris Popov
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by Boris Popov.
|
||||
* 4. Neither the name of the author nor the names of any co-contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/conf.h>
|
||||
#include <sys/priv.h>
|
||||
#include <sys/proc.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/module.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/uio.h>
|
||||
#include <sys/ioccom.h>
|
||||
|
||||
#include <netncp/ncp.h>
|
||||
#include <netncp/ncp_conn.h>
|
||||
#include <netncp/ncp_subr.h>
|
||||
#include <netncp/ncp_ncp.h>
|
||||
#include <netncp/ncp_user.h>
|
||||
#include <netncp/ncp_rq.h>
|
||||
#include <netncp/ncp_nls.h>
|
||||
#include <netncp/ncpio.h>
|
||||
|
||||
int ncp_version = NCP_VERSION;
|
||||
|
||||
SYSCTL_NODE(_net, OID_AUTO, ncp, CTLFLAG_RW, NULL, "NetWare requester");
|
||||
SYSCTL_INT(_net_ncp, OID_AUTO, version, CTLFLAG_RD, &ncp_version, 0, "");
|
||||
|
||||
MODULE_VERSION(ncp, 1);
|
||||
MODULE_DEPEND(ncp, libmchain, 1, 1, 1);
|
||||
|
||||
static struct cdev *ncp_dev;
|
||||
|
||||
static d_ioctl_t ncp_ioctl;
|
||||
|
||||
static struct cdevsw ncp_cdevsw = {
|
||||
.d_version = D_VERSION,
|
||||
.d_flags = D_NEEDGIANT,
|
||||
.d_ioctl = ncp_ioctl,
|
||||
.d_name = "ncp",
|
||||
};
|
||||
|
||||
static int ncp_conn_frag_rq(struct ncp_conn *, struct thread *,
|
||||
struct ncp_conn_frag *);
|
||||
static int ncp_conn_handler(struct thread *, struct ncpioc_request *,
|
||||
struct ncp_conn *, struct ncp_handle *);
|
||||
static int sncp_conn_scan(struct thread *, struct ncpioc_connscan *);
|
||||
static int sncp_connect(struct thread *, struct ncpioc_connect *);
|
||||
static int sncp_request(struct thread *, struct ncpioc_request *);
|
||||
|
||||
static int
|
||||
ncp_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag, struct thread *td)
|
||||
{
|
||||
|
||||
switch (cmd) {
|
||||
case NCPIOC_CONNECT:
|
||||
return (sncp_connect(td, (struct ncpioc_connect *)data));
|
||||
case NCPIOC_CONNSCAN:
|
||||
return (sncp_conn_scan(td, (struct ncpioc_connscan *)data));
|
||||
case NCPIOC_REQUEST:
|
||||
return (sncp_request(td, (struct ncpioc_request *)data));
|
||||
}
|
||||
return (EINVAL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Attach to NCP server
|
||||
*/
|
||||
|
||||
static int
|
||||
sncp_connect(struct thread *td, struct ncpioc_connect *args)
|
||||
{
|
||||
int connHandle = 0, error;
|
||||
struct ncp_conn *conn;
|
||||
struct ncp_handle *handle;
|
||||
struct ncp_conn_args li;
|
||||
|
||||
checkbad(copyin(args->ioc_li,&li,sizeof(li)));
|
||||
/* XXX Should be useracc() */
|
||||
checkbad(copyout(&connHandle,args->ioc_connhandle,
|
||||
sizeof(connHandle)));
|
||||
li.password = li.user = NULL;
|
||||
error = ncp_conn_getattached(&li, td, td->td_ucred, NCPM_WRITE | NCPM_EXECUTE, &conn);
|
||||
if (error) {
|
||||
error = ncp_conn_alloc(&li, td, td->td_ucred, &conn);
|
||||
if (error)
|
||||
goto bad;
|
||||
error = ncp_conn_reconnect(conn);
|
||||
if (error)
|
||||
ncp_conn_free(conn);
|
||||
}
|
||||
if (!error) {
|
||||
error = ncp_conn_gethandle(conn, td, &handle);
|
||||
copyout(&handle->nh_id, args->ioc_connhandle,
|
||||
sizeof(args->ioc_connhandle));
|
||||
ncp_conn_unlock(conn,td);
|
||||
}
|
||||
bad:
|
||||
return error;
|
||||
}
|
||||
|
||||
static int
|
||||
sncp_request(struct thread *td, struct ncpioc_request *args)
|
||||
{
|
||||
struct ncp_rq *rqp;
|
||||
struct ncp_conn *conn;
|
||||
struct ncp_handle *handle;
|
||||
int error = 0, rqsize;
|
||||
|
||||
error = ncp_conn_findhandle(args->ioc_connhandle, td, &handle);
|
||||
if (error)
|
||||
return error;
|
||||
conn = handle->nh_conn;
|
||||
if (args->ioc_fn == NCP_CONN)
|
||||
return ncp_conn_handler(td, args, conn, handle);
|
||||
error = copyin(&args->ioc_ncpbuf->rqsize, &rqsize, sizeof(int));
|
||||
if (error)
|
||||
return(error);
|
||||
error = ncp_rq_alloc(args->ioc_fn, conn, td, td->td_ucred, &rqp);
|
||||
if (error)
|
||||
return error;
|
||||
if (rqsize) {
|
||||
error = mb_put_mem(&rqp->rq, (caddr_t)args->ioc_ncpbuf->packet,
|
||||
rqsize, MB_MUSER);
|
||||
if (error)
|
||||
goto bad;
|
||||
}
|
||||
rqp->nr_flags |= NCPR_DONTFREEONERR;
|
||||
error = ncp_request(rqp);
|
||||
if (error == 0 && rqp->nr_rpsize)
|
||||
error = md_get_mem(&rqp->rp, (caddr_t)args->ioc_ncpbuf->packet,
|
||||
rqp->nr_rpsize, MB_MUSER);
|
||||
copyout(&rqp->nr_cs, &args->ioc_ncpbuf->cs, sizeof(rqp->nr_cs));
|
||||
copyout(&rqp->nr_cc, &args->ioc_ncpbuf->cc, sizeof(rqp->nr_cc));
|
||||
copyout(&rqp->nr_rpsize, &args->ioc_ncpbuf->rpsize, sizeof(rqp->nr_rpsize));
|
||||
bad:
|
||||
ncp_rq_done(rqp);
|
||||
return error;
|
||||
}
|
||||
|
||||
static int
|
||||
ncp_mod_login(struct ncp_conn *conn, char *user, int objtype, char *password,
|
||||
struct thread *td, struct ucred *cred)
|
||||
{
|
||||
int error;
|
||||
|
||||
if (ncp_suser(cred) != 0 && cred->cr_uid != conn->nc_owner->cr_uid)
|
||||
return EACCES;
|
||||
conn->li.user = ncp_str_dup(user);
|
||||
if (conn->li.user == NULL)
|
||||
return ENOMEM;
|
||||
conn->li.password = ncp_str_dup(password);
|
||||
if (conn->li.password == NULL) {
|
||||
error = ENOMEM;
|
||||
goto bad;
|
||||
}
|
||||
ncp_str_upper(conn->li.user);
|
||||
if ((conn->li.opt & NCP_OPT_NOUPCASEPASS) == 0)
|
||||
ncp_str_upper(conn->li.password);
|
||||
conn->li.objtype = objtype;
|
||||
error = ncp_conn_login(conn, td, cred);
|
||||
return error;
|
||||
bad:
|
||||
if (conn->li.user) {
|
||||
free(conn->li.user, M_NCPDATA);
|
||||
conn->li.user = NULL;
|
||||
}
|
||||
if (conn->li.password) {
|
||||
free(conn->li.password, M_NCPDATA);
|
||||
conn->li.password = NULL;
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
static int
|
||||
ncp_conn_handler(struct thread *td, struct ncpioc_request *args,
|
||||
struct ncp_conn *conn, struct ncp_handle *hp)
|
||||
{
|
||||
int error = 0, rqsize, subfn;
|
||||
struct ucred *cred;
|
||||
|
||||
char *pdata;
|
||||
|
||||
cred = td->td_ucred;
|
||||
error = copyin(&args->ioc_ncpbuf->rqsize, &rqsize, sizeof(int));
|
||||
if (error)
|
||||
return(error);
|
||||
error = 0;
|
||||
pdata = args->ioc_ncpbuf->packet;
|
||||
subfn = *(pdata++) & 0xff;
|
||||
rqsize--;
|
||||
switch (subfn) {
|
||||
case NCP_CONN_READ: case NCP_CONN_WRITE: {
|
||||
struct ncp_rw rwrq;
|
||||
struct uio auio;
|
||||
struct iovec iov;
|
||||
|
||||
if (rqsize != sizeof(rwrq))
|
||||
return (EBADRPC);
|
||||
error = copyin(pdata,&rwrq,rqsize);
|
||||
if (error)
|
||||
return (error);
|
||||
iov.iov_base = rwrq.nrw_base;
|
||||
iov.iov_len = rwrq.nrw_cnt;
|
||||
auio.uio_iov = &iov;
|
||||
auio.uio_iovcnt = 1;
|
||||
auio.uio_offset = rwrq.nrw_offset;
|
||||
auio.uio_resid = rwrq.nrw_cnt;
|
||||
auio.uio_segflg = UIO_USERSPACE;
|
||||
auio.uio_rw = (subfn == NCP_CONN_READ) ? UIO_READ : UIO_WRITE;
|
||||
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;
|
||||
/*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;
|
||||
pdata += sizeof(mask);
|
||||
error = copyin(pdata,&flags,sizeof(flags));
|
||||
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);
|
||||
}
|
||||
if (mask & NCPFL_PRIMARY) {
|
||||
error = ncp_conn_setprimary(conn, flags & NCPFL_PRIMARY);
|
||||
if (error) {
|
||||
ncp_conn_unlock(conn, td);
|
||||
break;
|
||||
}
|
||||
}
|
||||
ncp_conn_unlock(conn, td);
|
||||
break;
|
||||
}
|
||||
case NCP_CONN_LOGIN: {
|
||||
struct ncp_conn_login la;
|
||||
|
||||
if (rqsize != sizeof(la))
|
||||
return EBADRPC;
|
||||
if (conn->flags & NCPFL_LOGGED)
|
||||
return EALREADY;
|
||||
if ((error = copyin(pdata,&la,rqsize)) != 0)
|
||||
break;
|
||||
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);
|
||||
break;
|
||||
}
|
||||
case NCP_CONN_GETINFO: {
|
||||
struct ncp_conn_stat ncs;
|
||||
int len = sizeof(ncs);
|
||||
|
||||
error = ncp_conn_lock(conn, td, td->td_ucred, NCPM_READ);
|
||||
if (error)
|
||||
return error;
|
||||
ncp_conn_getinfo(conn, &ncs);
|
||||
copyout(&len, &args->ioc_ncpbuf->rpsize, sizeof(int));
|
||||
error = copyout(&ncs, &args->ioc_ncpbuf->packet, len);
|
||||
ncp_conn_unlock(conn, td);
|
||||
break;
|
||||
}
|
||||
case NCP_CONN_GETUSER: {
|
||||
int len;
|
||||
|
||||
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, &args->ioc_ncpbuf->rpsize, sizeof(int));
|
||||
if (len) {
|
||||
error = copyout(conn->li.user,
|
||||
&args->ioc_ncpbuf->packet, len);
|
||||
}
|
||||
ncp_conn_unlock(conn, td);
|
||||
break;
|
||||
}
|
||||
case NCP_CONN_CONN2REF: {
|
||||
int len = sizeof(int);
|
||||
|
||||
error = ncp_conn_lock(conn, td, td->td_ucred, NCPM_READ);
|
||||
if (error)
|
||||
return error;
|
||||
copyout(&len, &args->ioc_ncpbuf->rpsize, sizeof(int));
|
||||
if (len) {
|
||||
error = copyout(&conn->nc_id,
|
||||
&args->ioc_ncpbuf->packet, len);
|
||||
}
|
||||
ncp_conn_unlock(conn, td);
|
||||
break;
|
||||
}
|
||||
case NCP_CONN_FRAG: {
|
||||
struct ncp_conn_frag nf;
|
||||
|
||||
if (rqsize != sizeof(nf))
|
||||
return (EBADRPC);
|
||||
if ((error = copyin(pdata, &nf, rqsize)) != 0) break;
|
||||
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));
|
||||
td->td_retval[0] = error;
|
||||
break;
|
||||
}
|
||||
case NCP_CONN_DUP: {
|
||||
struct ncp_handle *newhp;
|
||||
int len = sizeof(NWCONN_HANDLE);
|
||||
|
||||
error = ncp_conn_lock(conn, td, cred, NCPM_READ);
|
||||
if (error) break;
|
||||
copyout(&len, &args->ioc_ncpbuf->rpsize, len);
|
||||
error = ncp_conn_gethandle(conn, td, &newhp);
|
||||
if (!error)
|
||||
error = copyout(&newhp->nh_id,
|
||||
args->ioc_ncpbuf->packet, len);
|
||||
ncp_conn_unlock(conn, td);
|
||||
break;
|
||||
}
|
||||
case NCP_CONN_CONNCLOSE: {
|
||||
error = ncp_conn_lock(conn, td, cred, NCPM_EXECUTE);
|
||||
if (error) break;
|
||||
ncp_conn_puthandle(hp, td, 0);
|
||||
error = ncp_conn_free(conn);
|
||||
if (error)
|
||||
ncp_conn_unlock(conn, td);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
error = EOPNOTSUPP;
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
static int
|
||||
sncp_conn_scan(struct thread *td, struct ncpioc_connscan *args)
|
||||
{
|
||||
int connHandle = 0, error;
|
||||
struct ncp_conn_args li, *lip;
|
||||
struct ncp_conn *conn;
|
||||
struct ncp_handle *hp;
|
||||
char *user = NULL, *password = NULL;
|
||||
|
||||
if (args->ioc_li) {
|
||||
if (copyin(args->ioc_li, &li, sizeof(li)))
|
||||
return EFAULT;
|
||||
lip = &li;
|
||||
} else {
|
||||
lip = NULL;
|
||||
}
|
||||
|
||||
if (lip != NULL) {
|
||||
lip->server[sizeof(lip->server)-1]=0; /* just to make sure */
|
||||
ncp_str_upper(lip->server);
|
||||
if (lip->user) {
|
||||
user = ncp_str_dup(lip->user);
|
||||
if (user == NULL)
|
||||
return EINVAL;
|
||||
ncp_str_upper(user);
|
||||
}
|
||||
if (lip->password) {
|
||||
password = ncp_str_dup(lip->password);
|
||||
if (password == NULL) {
|
||||
if (user)
|
||||
free(user, M_NCPDATA);
|
||||
return EINVAL;
|
||||
}
|
||||
ncp_str_upper(password);
|
||||
}
|
||||
lip->user = user;
|
||||
lip->password = password;
|
||||
}
|
||||
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, td);
|
||||
copyout(&connHandle, args->ioc_connhandle, sizeof(connHandle));
|
||||
}
|
||||
if (user)
|
||||
free(user, M_NCPDATA);
|
||||
if (password)
|
||||
free(password, M_NCPDATA);
|
||||
return error;
|
||||
|
||||
}
|
||||
|
||||
int
|
||||
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, td, td->td_ucred, &rqp);
|
||||
if (error)
|
||||
return error;
|
||||
for(fp = nfp->rqf, i = 0; i < nfp->rqfcnt; i++, fp++) {
|
||||
error = mb_put_mem(&rqp->rq, (caddr_t)fp->fragAddress, fp->fragSize, MB_MUSER);
|
||||
if (error)
|
||||
goto bad;
|
||||
}
|
||||
rqp->nr_flags |= NCPR_DONTFREEONERR;
|
||||
error = ncp_request(rqp);
|
||||
if (error)
|
||||
goto bad;
|
||||
rpsize = rqp->nr_rpsize;
|
||||
if (rpsize && nfp->rpfcnt) {
|
||||
for(fp = nfp->rpf, i = 0; i < nfp->rpfcnt; i++, fp++) {
|
||||
error = copyin(&fp->fragSize, &fsize, sizeof (fsize));
|
||||
if (error)
|
||||
break;
|
||||
fsize = min(fsize, rpsize);
|
||||
error = md_get_mem(&rqp->rp, (caddr_t)fp->fragAddress, fsize, MB_MUSER);
|
||||
if (error)
|
||||
break;
|
||||
rpsize -= fsize;
|
||||
error = copyout(&fsize, &fp->fragSize, sizeof (fsize));
|
||||
if (error)
|
||||
break;
|
||||
}
|
||||
}
|
||||
nfp->cs = rqp->nr_cs;
|
||||
nfp->cc = rqp->nr_cc;
|
||||
bad:
|
||||
ncp_rq_done(rqp);
|
||||
return error;
|
||||
}
|
||||
|
||||
static int
|
||||
ncp_load(void)
|
||||
{
|
||||
int error;
|
||||
|
||||
if ((error = ncp_init()) != 0)
|
||||
return (error);
|
||||
ncp_dev = make_dev(&ncp_cdevsw, 0, 0, 0, 0666, "ncp");
|
||||
printf("ncp_load: loaded\n");
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
ncp_unload(void)
|
||||
{
|
||||
int error;
|
||||
|
||||
error = ncp_done();
|
||||
if (error)
|
||||
return (error);
|
||||
destroy_dev(ncp_dev);
|
||||
printf("ncp_unload: unloaded\n");
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
ncp_mod_handler(module_t mod, int type, void *data)
|
||||
{
|
||||
int error;
|
||||
|
||||
switch (type) {
|
||||
case MOD_LOAD:
|
||||
error = ncp_load();
|
||||
break;
|
||||
case MOD_UNLOAD:
|
||||
error = ncp_unload();
|
||||
break;
|
||||
default:
|
||||
error = EINVAL;
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
static moduledata_t ncp_mod = {
|
||||
"ncp",
|
||||
ncp_mod_handler,
|
||||
NULL
|
||||
};
|
||||
DECLARE_MODULE(ncp, ncp_mod, SI_SUB_PROTO_DOMAIN, SI_ORDER_ANY);
|
@ -1,503 +0,0 @@
|
||||
/*-
|
||||
* Copyright (c) 1999, 2000, 2001 Boris Popov
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* Core of NCP protocol
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/errno.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/proc.h>
|
||||
#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>
|
||||
#include <netipx/ipx_var.h>
|
||||
|
||||
#include <netncp/ncp.h>
|
||||
#include <netncp/ncp_conn.h>
|
||||
#include <netncp/ncp_sock.h>
|
||||
#include <netncp/ncp_subr.h>
|
||||
#include <netncp/ncp_ncp.h>
|
||||
#include <netncp/ncp_rq.h>
|
||||
#include <netncp/nwerror.h>
|
||||
|
||||
#ifdef NCP_DATA_DEBUG
|
||||
static
|
||||
void m_dumpm(struct mbuf *m) {
|
||||
char *p;
|
||||
int len;
|
||||
printf("d=");
|
||||
while(m) {
|
||||
p=mtod(m,char *);
|
||||
len=m->m_len;
|
||||
printf("(%d)",len);
|
||||
while(len--){
|
||||
printf("%02x ",((int)*(p++)) & 0xff);
|
||||
}
|
||||
m=m->m_next;
|
||||
};
|
||||
printf("\n");
|
||||
}
|
||||
#endif /* NCP_DATA_DEBUG */
|
||||
|
||||
int
|
||||
ncp_chkintr(struct ncp_conn *conn, struct thread *td)
|
||||
{
|
||||
struct proc *p;
|
||||
sigset_t tmpset;
|
||||
|
||||
if (td == NULL)
|
||||
return 0;
|
||||
p = td->td_proc;
|
||||
PROC_LOCK(p);
|
||||
tmpset = p->p_siglist;
|
||||
SIGSETOR(tmpset, td->td_siglist);
|
||||
SIGSETNAND(tmpset, td->td_sigmask);
|
||||
mtx_lock(&p->p_sigacts->ps_mtx);
|
||||
SIGSETNAND(tmpset, p->p_sigacts->ps_sigignore);
|
||||
mtx_unlock(&p->p_sigacts->ps_mtx);
|
||||
if (SIGNOTEMPTY(td->td_siglist) && NCP_SIGMASK(tmpset)) {
|
||||
PROC_UNLOCK(p);
|
||||
return EINTR;
|
||||
}
|
||||
PROC_UNLOCK(p);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Process initial NCP handshake (attach)
|
||||
* NOTE: Since all functions below may change conn attributes, they
|
||||
* should be called with LOCKED connection, also they use procp & ucred
|
||||
*/
|
||||
int
|
||||
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->td, conn->ucred, &rqp);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
conn->flags &= ~(NCPFL_SIGNACTIVE | NCPFL_SIGNWANTED |
|
||||
NCPFL_ATTACHED | NCPFL_LOGGED | NCPFL_INVALID);
|
||||
conn->seq = 0;
|
||||
error = ncp_request_int(rqp);
|
||||
if (!error) {
|
||||
rp = mtod(rqp->rp.md_top, struct ncp_rphdr*);
|
||||
conn->connid = rp->conn_low + (rp->conn_high << 8);
|
||||
}
|
||||
ncp_rq_done(rqp);
|
||||
if (error)
|
||||
return error;
|
||||
conn->flags |= NCPFL_ATTACHED | NCPFL_WASATTACHED;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
ncp_ncp_disconnect(struct ncp_conn *conn)
|
||||
{
|
||||
struct ncp_rq *rqp;
|
||||
int error;
|
||||
|
||||
NCPSDEBUG("for connid=%d\n",conn->nc_id);
|
||||
#ifdef NCPBURST
|
||||
ncp_burst_disconnect(conn);
|
||||
#endif
|
||||
if (conn->flags & NCPFL_ATTACHED) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
ncp_conn_invalidate(conn);
|
||||
ncp_sock_disconnect(conn);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* All negotiation functions expect a locked connection
|
||||
*/
|
||||
|
||||
int
|
||||
ncp_negotiate_buffersize(struct ncp_conn *conn, int size, int *target)
|
||||
{
|
||||
struct ncp_rq *rqp;
|
||||
u_int16_t bsize;
|
||||
int error;
|
||||
|
||||
error = ncp_rq_alloc(0x21, conn, conn->td, conn->ucred, &rqp);
|
||||
if (error)
|
||||
return error;
|
||||
mb_put_uint16be(&rqp->rq, size);
|
||||
error = ncp_request(rqp);
|
||||
if (error)
|
||||
return error;
|
||||
md_get_uint16be(&rqp->rp, &bsize);
|
||||
*target = min(bsize, size);
|
||||
ncp_rq_done(rqp);
|
||||
return error;
|
||||
}
|
||||
|
||||
static int
|
||||
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->td, conn->ucred, &rqp);
|
||||
if (error)
|
||||
return error;
|
||||
mb_put_uint16be(&rqp->rq, size);
|
||||
mb_put_uint8(&rqp->rq, options);
|
||||
rqp->nr_minrplen = 2 + 2 + 1;
|
||||
error = ncp_request(rqp);
|
||||
if (error)
|
||||
return error;
|
||||
md_get_uint16be(&rqp->rp, &rs);
|
||||
*ret_size = (rs == 0) ? size : min(rs, size);
|
||||
md_get_uint16be(&rqp->rp, &rs); /* skip echo socket */
|
||||
md_get_uint8(&rqp->rp, ret_options);
|
||||
ncp_rq_done(rqp);
|
||||
return error;
|
||||
}
|
||||
|
||||
int
|
||||
ncp_renegotiate_connparam(struct ncp_conn *conn, int buffsize, u_int8_t in_options)
|
||||
{
|
||||
u_int8_t options;
|
||||
int neg_buffsize, error, sl, ckslevel;
|
||||
size_t ilen;
|
||||
|
||||
sl = conn->li.sig_level;
|
||||
if (sl >= 2)
|
||||
in_options |= NCP_SECURITY_LEVEL_SIGN_HEADERS;
|
||||
if (conn->li.saddr.sa_family == AF_IPX) {
|
||||
ilen = sizeof(ckslevel);
|
||||
error = kernel_sysctlbyname(curthread, "net.ipx.ipx.checksum",
|
||||
&ckslevel, &ilen, NULL, 0, NULL, 0);
|
||||
if (error)
|
||||
return error;
|
||||
if (ckslevel == 2)
|
||||
in_options |= NCP_IPX_CHECKSUM;
|
||||
}
|
||||
error = ncp_negotiate_size_and_options(conn, buffsize, in_options,
|
||||
&neg_buffsize, &options);
|
||||
if (!error) {
|
||||
if (conn->li.saddr.sa_family == AF_IPX &&
|
||||
((options ^ in_options) & NCP_IPX_CHECKSUM)) {
|
||||
if (ckslevel == 2) {
|
||||
printf("Server refuses to support IPX checksums\n");
|
||||
return NWE_REQUESTER_FAILURE;
|
||||
}
|
||||
in_options |= NCP_IPX_CHECKSUM;
|
||||
error = 1;
|
||||
}
|
||||
if ((options ^ in_options) & 2) {
|
||||
if (sl == 0 || sl == 3)
|
||||
return NWE_SIGNATURE_LEVEL_CONFLICT;
|
||||
if (sl == 1) {
|
||||
in_options |= NCP_SECURITY_LEVEL_SIGN_HEADERS;
|
||||
error = 1;
|
||||
}
|
||||
}
|
||||
if (error) {
|
||||
error = ncp_negotiate_size_and_options(conn,
|
||||
buffsize, in_options, &neg_buffsize, &options);
|
||||
if ((options ^ in_options) & 3) {
|
||||
return NWE_SIGNATURE_LEVEL_CONFLICT;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
in_options &= ~NCP_SECURITY_LEVEL_SIGN_HEADERS;
|
||||
error = ncp_negotiate_buffersize(conn, NCP_DEFAULT_BUFSIZE,
|
||||
&neg_buffsize);
|
||||
}
|
||||
if (error) return error;
|
||||
if ((neg_buffsize < 512) || (neg_buffsize > NCP_MAX_BUFSIZE))
|
||||
return EINVAL;
|
||||
conn->buffer_size = neg_buffsize;
|
||||
if (in_options & NCP_SECURITY_LEVEL_SIGN_HEADERS)
|
||||
conn->flags |= NCPFL_SIGNWANTED;
|
||||
if (conn->li.saddr.sa_family == AF_IPX)
|
||||
ncp_sock_checksum(conn, in_options & NCP_IPX_CHECKSUM);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
ncp_check_rq(struct ncp_conn *conn)
|
||||
{
|
||||
return;
|
||||
if (conn->flags & NCPFL_INTR)
|
||||
return;
|
||||
/* first, check for signals */
|
||||
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,
|
||||
struct ncp_bindery_object *target,
|
||||
struct thread *td, struct ucred *cred)
|
||||
{
|
||||
struct ncp_rq *rqp;
|
||||
int error;
|
||||
|
||||
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;
|
||||
error = ncp_request(rqp);
|
||||
if (error)
|
||||
return error;
|
||||
md_get_uint32be(&rqp->rp, &target->object_id);
|
||||
md_get_uint16be(&rqp->rp, &target->object_type);
|
||||
md_get_mem(&rqp->rp, (caddr_t)target->object_name, 48, MB_MSYSTEM);
|
||||
ncp_rq_done(rqp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* target is a 8-byte buffer
|
||||
*/
|
||||
int
|
||||
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->td, conn->ucred, &rqp);
|
||||
if (error)
|
||||
return error;
|
||||
rqp->nr_minrplen = 8;
|
||||
error = ncp_request(rqp);
|
||||
if (error)
|
||||
return error;
|
||||
md_get_mem(&rqp->rp, target, 8, MB_MSYSTEM);
|
||||
ncp_rq_done(rqp);
|
||||
return error;
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize packet signatures. They a slightly modified MD4.
|
||||
* The first 16 bytes of logindata are the shuffled password,
|
||||
* the last 8 bytes the encryption key as received from the server.
|
||||
*/
|
||||
static int
|
||||
ncp_sign_start(struct ncp_conn *conn, char *logindata)
|
||||
{
|
||||
char msg[64];
|
||||
u_int32_t state[4];
|
||||
|
||||
memcpy(msg, logindata, 24);
|
||||
memcpy(msg + 24, "Authorized NetWare Client", 25);
|
||||
bzero(msg + 24 + 25, sizeof(msg) - 24 - 25);
|
||||
|
||||
conn->sign_state[0] = 0x67452301;
|
||||
conn->sign_state[1] = 0xefcdab89;
|
||||
conn->sign_state[2] = 0x98badcfe;
|
||||
conn->sign_state[3] = 0x10325476;
|
||||
ncp_sign(conn->sign_state, msg, state);
|
||||
conn->sign_root[0] = state[0];
|
||||
conn->sign_root[1] = state[1];
|
||||
conn->flags |= NCPFL_SIGNACTIVE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
ncp_login_encrypted(struct ncp_conn *conn, struct ncp_bindery_object *object,
|
||||
const u_char *key, const u_char *passwd,
|
||||
struct thread *td, struct ucred *cred)
|
||||
{
|
||||
struct ncp_rq *rqp;
|
||||
struct mbchain *mbp;
|
||||
u_int32_t tmpID = htonl(object->object_id);
|
||||
u_char buf[16 + 8];
|
||||
u_char encrypted[8];
|
||||
int error;
|
||||
|
||||
nw_keyhash((u_char*)&tmpID, passwd, strlen(passwd), buf);
|
||||
nw_encrypt(key, buf, encrypted);
|
||||
|
||||
error = ncp_rq_alloc_subfn(23, 24, conn, td, cred, &rqp);
|
||||
if (error)
|
||||
return error;
|
||||
mbp = &rqp->rq;
|
||||
mb_put_mem(mbp, encrypted, 8, MB_MSYSTEM);
|
||||
mb_put_uint16be(mbp, object->object_type);
|
||||
ncp_rq_pstring(rqp, object->object_name);
|
||||
error = ncp_request(rqp);
|
||||
if (!error)
|
||||
ncp_rq_done(rqp);
|
||||
if ((conn->flags & NCPFL_SIGNWANTED) &&
|
||||
(error == 0 || error == NWE_PASSWORD_EXPIRED)) {
|
||||
bcopy(key, buf + 16, 8);
|
||||
error = ncp_sign_start(conn, buf);
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
int
|
||||
ncp_login_unencrypted(struct ncp_conn *conn, u_int16_t object_type,
|
||||
const char *object_name, const u_char *passwd,
|
||||
struct thread *td, struct ucred *cred)
|
||||
{
|
||||
struct ncp_rq *rqp;
|
||||
int error;
|
||||
|
||||
error = ncp_rq_alloc_subfn(23, 20, conn, td, cred, &rqp);
|
||||
if (error)
|
||||
return error;
|
||||
mb_put_uint16be(&rqp->rq, object_type);
|
||||
ncp_rq_pstring(rqp, object_name);
|
||||
ncp_rq_pstring(rqp, passwd);
|
||||
error = ncp_request(rqp);
|
||||
if (!error)
|
||||
ncp_rq_done(rqp);
|
||||
return error;
|
||||
}
|
||||
|
||||
int
|
||||
ncp_read(struct ncp_conn *conn, ncp_fh *file, struct uio *uiop, struct ucred *cred)
|
||||
{
|
||||
struct ncp_rq *rqp;
|
||||
struct mbchain *mbp;
|
||||
u_int16_t retlen = 0 ;
|
||||
int error = 0, len = 0, tsiz, burstio;
|
||||
|
||||
tsiz = uiop->uio_resid;
|
||||
#ifdef NCPBURST
|
||||
burstio = (ncp_burst_enabled && tsiz > conn->buffer_size);
|
||||
#else
|
||||
burstio = 0;
|
||||
#endif
|
||||
|
||||
while (tsiz > 0) {
|
||||
if (!burstio) {
|
||||
len = min(4096 - (uiop->uio_offset % 4096), tsiz);
|
||||
len = min(len, conn->buffer_size);
|
||||
error = ncp_rq_alloc(72, conn, uiop->uio_td, cred, &rqp);
|
||||
if (error)
|
||||
break;
|
||||
mbp = &rqp->rq;
|
||||
mb_put_uint8(mbp, 0);
|
||||
mb_put_mem(mbp, (caddr_t)file, 6, MB_MSYSTEM);
|
||||
mb_put_uint32be(mbp, uiop->uio_offset);
|
||||
mb_put_uint16be(mbp, len);
|
||||
rqp->nr_minrplen = 2;
|
||||
error = ncp_request(rqp);
|
||||
if (error)
|
||||
break;
|
||||
md_get_uint16be(&rqp->rp, &retlen);
|
||||
if (uiop->uio_offset & 1)
|
||||
md_get_mem(&rqp->rp, NULL, 1, MB_MSYSTEM);
|
||||
error = md_get_uio(&rqp->rp, uiop, retlen);
|
||||
ncp_rq_done(rqp);
|
||||
} else {
|
||||
#ifdef NCPBURST
|
||||
error = ncp_burst_read(conn, file, tsiz, &len, &retlen, uiop, cred);
|
||||
#endif
|
||||
}
|
||||
if (error)
|
||||
break;
|
||||
tsiz -= retlen;
|
||||
if (retlen < len)
|
||||
break;
|
||||
}
|
||||
return (error);
|
||||
}
|
||||
|
||||
int
|
||||
ncp_write(struct ncp_conn *conn, ncp_fh *file, struct uio *uiop, struct ucred *cred)
|
||||
{
|
||||
struct ncp_rq *rqp;
|
||||
struct mbchain *mbp;
|
||||
int error = 0, len, tsiz, backup;
|
||||
|
||||
if (uiop->uio_iovcnt != 1) {
|
||||
printf("%s: can't handle iovcnt>1 !!!\n", __func__);
|
||||
return EIO;
|
||||
}
|
||||
tsiz = uiop->uio_resid;
|
||||
while (tsiz > 0) {
|
||||
len = min(4096 - (uiop->uio_offset % 4096), tsiz);
|
||||
len = min(len, conn->buffer_size);
|
||||
if (len == 0) {
|
||||
printf("gotcha!\n");
|
||||
}
|
||||
/* rq head */
|
||||
error = ncp_rq_alloc(73, conn, uiop->uio_td, cred, &rqp);
|
||||
if (error)
|
||||
break;
|
||||
mbp = &rqp->rq;
|
||||
mb_put_uint8(mbp, 0);
|
||||
mb_put_mem(mbp, (caddr_t)file, 6, MB_MSYSTEM);
|
||||
mb_put_uint32be(mbp, uiop->uio_offset);
|
||||
mb_put_uint16be(mbp, len);
|
||||
error = mb_put_uio(mbp, uiop, len);
|
||||
if (error) {
|
||||
ncp_rq_done(rqp);
|
||||
break;
|
||||
}
|
||||
error = ncp_request(rqp);
|
||||
if (!error)
|
||||
ncp_rq_done(rqp);
|
||||
if (len == 0)
|
||||
break;
|
||||
if (error) {
|
||||
backup = len;
|
||||
uiop->uio_iov->iov_base =
|
||||
(char *)uiop->uio_iov->iov_base - backup;
|
||||
uiop->uio_iov->iov_len += backup;
|
||||
uiop->uio_offset -= backup;
|
||||
uiop->uio_resid += backup;
|
||||
break;
|
||||
}
|
||||
tsiz -= len;
|
||||
}
|
||||
if (error)
|
||||
uiop->uio_resid = tsiz;
|
||||
switch (error) {
|
||||
case NWE_INSUFFICIENT_SPACE:
|
||||
error = ENOSPC;
|
||||
break;
|
||||
}
|
||||
return (error);
|
||||
}
|
@ -1,127 +0,0 @@
|
||||
/*-
|
||||
* Copyright (c) 1999 Boris Popov
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
#ifndef _NETNCP_NCP_NCP_H_
|
||||
#define _NETNCP_NCP_NCP_H_
|
||||
|
||||
#define NCP_ALLOC_SLOT 0x1111
|
||||
#define NCP_REQUEST 0x2222
|
||||
#define NCP_REPLY 0x3333
|
||||
#define NCP_FREE_SLOT 0x5555
|
||||
#define NCP_PACKET_BURST 0x7777
|
||||
#define NCP_POSITIVE_ACK 0x9999
|
||||
|
||||
/*
|
||||
* Bits for connection state field in ncp_rphdr
|
||||
*/
|
||||
#define NCP_CS_BAD_CONN 0x01 /* no such connection */
|
||||
#define NCP_CS_NO_SLOTS 0x04 /* no connection slots available */
|
||||
#define NCP_CS_SERVER_DOWN 0x10 /* server in down state */
|
||||
#define NCP_CS_HAVE_BROADCAST 0x40 /* server holds broadcast for us */
|
||||
|
||||
#define NCP_RETRY_COUNT 5
|
||||
#define NCP_RETRY_TIMEOUT 10
|
||||
#define NCP_RESTORE_COUNT 2 /* how many times try to restore per
|
||||
* single request, should be an _even_ */
|
||||
|
||||
struct ncp_rqhdr {
|
||||
u_int16_t type;
|
||||
u_int8_t seq;
|
||||
u_int8_t conn_low;
|
||||
u_int8_t task;
|
||||
u_int8_t conn_high;
|
||||
u_int8_t fn;
|
||||
u_int8_t data[0];
|
||||
} __packed;
|
||||
|
||||
|
||||
struct ncp_rphdr {
|
||||
u_int16_t type;
|
||||
u_int8_t seq;
|
||||
u_int8_t conn_low;
|
||||
u_int8_t task;
|
||||
u_int8_t conn_high;
|
||||
u_int8_t completion_code;
|
||||
u_int8_t connection_state;
|
||||
u_int8_t data[0];
|
||||
}__packed;
|
||||
|
||||
#define BFL_ABT 0x04
|
||||
#define BFL_EOB 0x10
|
||||
#define BFL_SYS 0x80
|
||||
|
||||
#define BOP_READ 1L
|
||||
#define BOP_WRITE 2L
|
||||
|
||||
#define BERR_NONE 0
|
||||
#define BERR_INIT 1
|
||||
#define BERR_IO 2
|
||||
#define BERR_NODATA 3
|
||||
#define BERR_WRITE 4
|
||||
|
||||
struct ncp_bursthdr {
|
||||
u_short bh_type;
|
||||
u_char bh_flags;
|
||||
u_char bh_streamtype;
|
||||
u_long bh_srcid;
|
||||
u_long bh_dstid;
|
||||
u_long bh_seq; /* HL */
|
||||
u_long bh_send_delay; /* HL */
|
||||
u_short bh_bseq; /* HL */
|
||||
u_short bh_aseq; /* HL */
|
||||
u_long bh_blen; /* HL */
|
||||
u_long bh_dofs; /* HL */
|
||||
u_short bh_dlen; /* HL */
|
||||
u_short bh_misfrags; /* HL */
|
||||
} __packed;
|
||||
|
||||
struct ncp_conn;
|
||||
struct ncp_conn_args;
|
||||
struct ncp_rq;
|
||||
struct ucred;
|
||||
|
||||
int ncp_ncp_connect(struct ncp_conn *conn);
|
||||
int ncp_ncp_disconnect(struct ncp_conn *conn);
|
||||
int ncp_negotiate_buffersize(struct ncp_conn *conn, int size, int *target);
|
||||
int ncp_renegotiate_connparam(struct ncp_conn *conn, int buffsize,
|
||||
u_int8_t in_options);
|
||||
int ncp_get_bindery_object_id(struct ncp_conn *conn,
|
||||
u_int16_t object_type, char *object_name,
|
||||
struct ncp_bindery_object *target,
|
||||
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 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 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);
|
||||
|
||||
#endif /* _NCP_NCP_H_ */
|
@ -1,304 +0,0 @@
|
||||
/*-
|
||||
* Copyright (c) 1999 Boris Popov
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* Character conversion routines
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/errno.h>
|
||||
#include <sys/systm.h>
|
||||
|
||||
#include <netncp/ncp.h>
|
||||
#include <netncp/ncp_nls.h>
|
||||
|
||||
/*
|
||||
* 0 - character disallowed in NetWare file name.
|
||||
*/
|
||||
static u_char ncp_u2n[256] = {
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10 */
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x20, 0x21, 0x00, 0x23, 0x24, 0x25, 0x26, 0x27, /* 0x20 */
|
||||
0x28, 0x29, 0x00, 0x00, 0x00, 0x2d, 0x2e, 0x00,
|
||||
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, /* 0x30 */
|
||||
0x38, 0x39, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00,
|
||||
0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* 0x40 */
|
||||
0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
|
||||
0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, /* 0x50 */
|
||||
0x58, 0x59, 0x5a, 0x00, 0x00, 0x00, 0x5e, 0x5f,
|
||||
0x00, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, /* 0x60 */
|
||||
0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
|
||||
0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, /* 0x70 */
|
||||
0x78, 0x79, 0x7a, 0x7b, 0x00, 0x7d, 0x7e, 0x00,
|
||||
0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, /* 0x80 */
|
||||
0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
|
||||
0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, /* 0x90 */
|
||||
0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
|
||||
0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, /* 0xa0 */
|
||||
0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
|
||||
0xb0, 0xbf, 0xbf, 0xbf, 0xbf, 0xb1, 0xb2, 0xb7, /* 0xb0 */
|
||||
0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
|
||||
0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, /* 0xc0 */
|
||||
0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
|
||||
0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, /* 0xd0 */
|
||||
0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
|
||||
0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, /* 0xe0 */
|
||||
0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
|
||||
0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, /* 0xf0 */
|
||||
0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff
|
||||
};
|
||||
|
||||
static u_char ncp_n2u[256] = {
|
||||
0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, /* 0x00 */
|
||||
0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f,
|
||||
0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, /* 0x10 */
|
||||
0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f,
|
||||
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, /* 0x20 */
|
||||
0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
|
||||
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, /* 0x30 */
|
||||
0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x5f,
|
||||
0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* 0x40 */
|
||||
0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
|
||||
0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, /* 0x50 */
|
||||
0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
|
||||
0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, /* 0x60 */
|
||||
0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
|
||||
0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, /* 0x70 */
|
||||
0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
|
||||
0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, /* 0x80 */
|
||||
0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
|
||||
0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, /* 0x90 */
|
||||
0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
|
||||
0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, /* 0xa0 */
|
||||
0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
|
||||
0xb0, 0xbf, 0xbf, 0xbf, 0xbf, 0xb1, 0xb2, 0xb7, /* 0xb0 */
|
||||
0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
|
||||
0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, /* 0xc0 */
|
||||
0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
|
||||
0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, /* 0xd0 */
|
||||
0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
|
||||
0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, /* 0xe0 */
|
||||
0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
|
||||
0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, /* 0xf0 */
|
||||
0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff
|
||||
};
|
||||
|
||||
static u_char ncp_u2l[256] = {
|
||||
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00 */
|
||||
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
|
||||
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10 */
|
||||
0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
|
||||
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, /* 0x20 */
|
||||
0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
|
||||
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, /* 0x30 */
|
||||
0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
|
||||
0x40, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, /* 0x40 */
|
||||
0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
|
||||
0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, /* 0x50 */
|
||||
0x78, 0x79, 0x7a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
|
||||
0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, /* 0x60 */
|
||||
0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
|
||||
0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, /* 0x70 */
|
||||
0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
|
||||
0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, /* 0x80 */
|
||||
0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
|
||||
0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, /* 0x90 */
|
||||
0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
|
||||
0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, /* 0xa0 */
|
||||
0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
|
||||
0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, /* 0xb0 */
|
||||
0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
|
||||
0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, /* 0xc0 */
|
||||
0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
|
||||
0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, /* 0xd0 */
|
||||
0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
|
||||
0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, /* 0xe0 */
|
||||
0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
|
||||
0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, /* 0xf0 */
|
||||
0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff
|
||||
};
|
||||
|
||||
static u_char ncp_l2u[256] = {
|
||||
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00 */
|
||||
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
|
||||
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 10-17 */
|
||||
0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
|
||||
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, /* 20-27 */
|
||||
0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
|
||||
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, /* 30-37 */
|
||||
0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
|
||||
0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* 40-47 */
|
||||
0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
|
||||
0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, /* 50-57 */
|
||||
0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
|
||||
0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* 60-67 */
|
||||
0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
|
||||
0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, /* 70-77 */
|
||||
0x58, 0x59, 0x5a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
|
||||
0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, /* 0x80 */
|
||||
0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
|
||||
0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, /* 0x90 */
|
||||
0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
|
||||
0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, /* 0xa0 */
|
||||
0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
|
||||
0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, /* 0xb0 */
|
||||
0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
|
||||
0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, /* 0xc0 */
|
||||
0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
|
||||
0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, /* 0xd0 */
|
||||
0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
|
||||
0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, /* 0xe0 */
|
||||
0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
|
||||
0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, /* 0xf0 */
|
||||
0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff
|
||||
};
|
||||
|
||||
struct ncp_nlstables ncp_defnls = {
|
||||
ncp_u2l, ncp_l2u, ncp_n2u, ncp_u2n, 0
|
||||
};
|
||||
|
||||
void ncp_str_upper(char *name) {
|
||||
while (*name) {
|
||||
*name = ncp_defnls.to_upper[(u_char)*name];
|
||||
name++;
|
||||
}
|
||||
}
|
||||
|
||||
void ncp_str_lower(char *name) {
|
||||
while (*name) {
|
||||
*name = ncp_defnls.to_lower[(u_char)*name];
|
||||
name++;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Check if pathname is valid under given conditions.
|
||||
*/
|
||||
int
|
||||
ncp_pathcheck(char *s, int len, struct ncp_nlstables *nt, int strict) {
|
||||
u_char *tbl = NULL, sc;
|
||||
int opt = nt->opt;
|
||||
|
||||
if (opt & (NWHP_UPPER | NWHP_LOWER))
|
||||
tbl = (opt & NWHP_UPPER) ? nt->to_upper : nt->to_lower;
|
||||
if ((opt & NWHP_DOS) == 0) {
|
||||
while (len--) {
|
||||
sc = (u_char)*(s++);
|
||||
if (nt->u2n[sc] == 0) /* illegal char */
|
||||
return EINVAL;
|
||||
if (tbl && strict && tbl[sc] != sc)
|
||||
return EINVAL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
while (len--) {
|
||||
sc = (u_char)*(s++);
|
||||
if (nt->u2n[sc] == 0) /* illegal char */
|
||||
return EINVAL;
|
||||
if (sc == ' ') return EINVAL;
|
||||
if (tbl && strict && tbl[sc] != sc) {
|
||||
return EINVAL;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
/*
|
||||
* Convert name from Unix to NetWare representation.
|
||||
* XXX: it should be complementary with path2unix, but for now
|
||||
* leave it as is.
|
||||
*/
|
||||
void
|
||||
ncp_pathcopy(const char *src, char *dst, int len, struct ncp_nlstables *nt)
|
||||
{
|
||||
int donls;
|
||||
u_char c;
|
||||
/* char *d = dst, *s = src;*/
|
||||
|
||||
if (nt == NULL) {
|
||||
ovbcopy(src, dst, len);
|
||||
return;
|
||||
}
|
||||
donls = (nt->opt & NWHP_NLS);
|
||||
if ((nt->opt & (NWHP_UPPER | NWHP_LOWER)) == 0) {
|
||||
while (len--) {
|
||||
*dst = donls ? nt->u2n[(u_char)*src] : *src;
|
||||
dst++;
|
||||
src++;
|
||||
}
|
||||
} else if (nt->opt & NWHP_DOS) {
|
||||
while (len--) {
|
||||
c = nt->to_upper[(u_char)*src];
|
||||
*dst = donls ? nt->u2n[c] : c;
|
||||
dst++;
|
||||
src++;
|
||||
}
|
||||
return;
|
||||
} else { /* probably incorrect... */
|
||||
while (len--) {
|
||||
*dst = donls ? nt->u2n[(u_char)*src] : *src;
|
||||
dst++;
|
||||
src++;
|
||||
}
|
||||
}
|
||||
/* printf("fromux: %s:%s\n", s, d);*/
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert NetWare filename to Unix with optional conversions
|
||||
*/
|
||||
void
|
||||
ncp_path2unix(char *src, char *dst, int len, struct ncp_nlstables *nt) {
|
||||
int donls;
|
||||
u_char c, *tbl;
|
||||
/* char *d = dst, *s = src;*/
|
||||
|
||||
/* printf("toux(%02x): %s:",nt->opt, s);*/
|
||||
if (nt == NULL) {
|
||||
ovbcopy(src, dst, len);
|
||||
return;
|
||||
}
|
||||
donls = (nt->opt & NWHP_NLS);
|
||||
if ((nt->opt & (NWHP_UPPER | NWHP_LOWER)) == 0) {
|
||||
while (len--) {
|
||||
c = *src;
|
||||
*dst = donls ? nt->n2u[c] : c;
|
||||
dst++;
|
||||
src++;
|
||||
}
|
||||
return;
|
||||
}
|
||||
tbl = (nt->opt & NWHP_LOWER) ? nt->to_lower : nt->to_upper;
|
||||
while (len--) {
|
||||
c = *src;
|
||||
*dst = tbl[donls ? nt->n2u[c] : c];
|
||||
dst++;
|
||||
src++;
|
||||
}
|
||||
/* printf("%s\n", d);*/
|
||||
}
|
@ -1,88 +0,0 @@
|
||||
/*-
|
||||
* Copyright (c) 1999 Boris Popov
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
#ifndef _NETNCP_NCP_NLS_H_
|
||||
#define _NETNCP_NCP_NLS_H_
|
||||
|
||||
/* options for handle path & caseopt in mount struct */
|
||||
#define NWHP_HDB 0x01 /* have dir base */
|
||||
#define NWHP_UPPER 0x02 /* local names has upper case */
|
||||
#define NWHP_LOWER 0x04 /* --"-- lower case */
|
||||
#define NWHP_DOS 0x08 /* using dos name space */
|
||||
#define NWHP_NLS 0x10 /* do name translation via tables, any nmspc */
|
||||
#define NWHP_NOSTRICT 0x20 /* pretend to be a case insensitive */
|
||||
|
||||
struct ncp_nlstables {
|
||||
u_char *to_lower; /* local charset to lower case */
|
||||
u_char *to_upper; /* local charset to upper case */
|
||||
u_char *n2u; /* NetWare to Unix */
|
||||
u_char *u2n;
|
||||
int opt; /* may depend on context */
|
||||
};
|
||||
|
||||
#ifndef _KERNEL
|
||||
/*
|
||||
* NLS, supported character conversion schemes.
|
||||
* NCP_NLS_UNIXCHARSET_NETWARECHARSET
|
||||
*/
|
||||
#define NCP_NLS_AS_IS 1
|
||||
#define NCP_NLS_AS_IS_NAME "asis"
|
||||
#define NCP_NLS_KOI_866 2
|
||||
#define NCP_NLS_KOI_866_NAME "koi2cp866"
|
||||
#define NCP_NLS_SE 3
|
||||
#define NCP_NLS_SE_NAME "se"
|
||||
#define NCP_NLS_DE 4
|
||||
#define NCP_NLS_DE_NAME "de"
|
||||
|
||||
extern struct ncp_nlstables ncp_nls; /* active nls */
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
int ncp_nls_setrecode(int scheme);
|
||||
int ncp_nls_setrecodebyname(char *name);
|
||||
int ncp_nls_setlocale(char *name);
|
||||
char* ncp_nls_str_n2u(char *dst, const char *src);
|
||||
char* ncp_nls_str_u2n(char *dst, const char *src);
|
||||
char* ncp_nls_mem_n2u(char *dst, const char *src, int size);
|
||||
char* ncp_nls_mem_u2n(char *dst, const char *src, int size);
|
||||
|
||||
__END_DECLS
|
||||
|
||||
#else /* !_KERNEL */
|
||||
|
||||
|
||||
extern struct ncp_nlstables ncp_defnls;
|
||||
|
||||
void ncp_str_upper(char *name);
|
||||
void ncp_str_lower(char *name);
|
||||
void ncp_pathcopy(const char *src, char *dst, int len, struct ncp_nlstables *nt);
|
||||
int ncp_pathcheck(char *s, int len, struct ncp_nlstables *nt, int strict);
|
||||
void ncp_path2unix(char *src, char *dst, int len, struct ncp_nlstables *nt);
|
||||
|
||||
#endif /* !_KERNEL */
|
||||
|
||||
#endif /* _NCP_NCP_NLS_H_ */
|
@ -1,62 +0,0 @@
|
||||
/*-
|
||||
* Copyright (c) 1999 Boris Popov
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
#ifndef _NETNCP_NCP_RCFILE_H_
|
||||
#define _NETNCP_NCP_RCFILE_H_
|
||||
#include <sys/queue.h>
|
||||
|
||||
struct rckey {
|
||||
SLIST_ENTRY(rckey) rk_next;
|
||||
char *rk_name;
|
||||
char *rk_value;
|
||||
};
|
||||
|
||||
struct rcsection {
|
||||
SLIST_ENTRY(rcsection) rs_next;
|
||||
SLIST_HEAD(rckey_head,rckey) rs_keys;
|
||||
char *rs_name;
|
||||
};
|
||||
|
||||
struct rcfile {
|
||||
SLIST_ENTRY(rcfile) rf_next;
|
||||
SLIST_HEAD(rcsec_head, rcsection) rf_sect;
|
||||
char *rf_name;
|
||||
FILE *rf_f;
|
||||
};
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
int rc_open(char *, char *,struct rcfile **);
|
||||
int rc_close(struct rcfile *);
|
||||
int rc_getstringptr(struct rcfile *, char *, char *, char **);
|
||||
int rc_getstring(struct rcfile *, char *, char *, int, char *);
|
||||
int rc_getint(struct rcfile *, char *, char *, int *);
|
||||
int rc_getbool(struct rcfile *, char *, char *, int *);
|
||||
|
||||
__END_DECLS
|
||||
|
||||
#endif /* _NETNCP_NCP_RCFILE_H_ */
|
@ -1,480 +0,0 @@
|
||||
/*-
|
||||
* Copyright (c) 1999-2001 Boris Popov
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* Routines to prepare request and fetch reply
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/errno.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/mbuf.h>
|
||||
#include <sys/poll.h>
|
||||
#include <sys/proc.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/socketvar.h>
|
||||
#include <sys/uio.h>
|
||||
|
||||
#include <netncp/ncp.h>
|
||||
#include <netncp/ncp_conn.h>
|
||||
#include <netncp/ncp_rq.h>
|
||||
#include <netncp/ncp_subr.h>
|
||||
#include <netncp/ncp_ncp.h>
|
||||
#include <netncp/ncp_sock.h>
|
||||
#include <netncp/ncp_nls.h>
|
||||
|
||||
static MALLOC_DEFINE(M_NCPRQ, "NCPRQ", "NCP request");
|
||||
|
||||
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 thread *td, struct ucred *cred,
|
||||
struct ncp_rq **rqpp)
|
||||
{
|
||||
struct ncp_rq *rqp;
|
||||
int error;
|
||||
|
||||
rqp = malloc(sizeof(*rqp), M_NCPRQ, M_WAITOK);
|
||||
error = ncp_rq_init_any(rqp, ptype, fn, ncp, td, cred);
|
||||
rqp->nr_flags |= NCPR_ALLOCED;
|
||||
if (error) {
|
||||
ncp_rq_done(rqp);
|
||||
return error;
|
||||
}
|
||||
*rqpp = rqp;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
ncp_rq_alloc(u_int8_t fn, struct ncp_conn *ncp,
|
||||
struct thread *td, struct ucred *cred, struct ncp_rq **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 thread *td, struct ucred *cred, struct ncp_rq **rqpp)
|
||||
{
|
||||
struct ncp_rq *rqp;
|
||||
int error;
|
||||
|
||||
error = ncp_rq_alloc_any(NCP_REQUEST, fn, ncp, td, cred, &rqp);
|
||||
if (error)
|
||||
return error;
|
||||
mb_reserve(&rqp->rq, 2);
|
||||
mb_put_uint8(&rqp->rq, subfn);
|
||||
*rqpp = rqp;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
ncp_rq_init_any(struct ncp_rq *rqp, u_int32_t ptype, u_int8_t fn,
|
||||
struct ncp_conn *ncp,
|
||||
struct thread *td, struct ucred *cred)
|
||||
{
|
||||
struct ncp_rqhdr *rq;
|
||||
struct ncp_bursthdr *brq;
|
||||
struct mbchain *mbp;
|
||||
int error;
|
||||
|
||||
bzero(rqp, sizeof(*rqp));
|
||||
error = ncp_conn_access(ncp, cred, NCPM_EXECUTE);
|
||||
if (error)
|
||||
return error;
|
||||
rqp->nr_td = td;
|
||||
rqp->nr_cred = cred;
|
||||
rqp->nr_conn = ncp;
|
||||
mbp = &rqp->rq;
|
||||
if (mb_init(mbp) != 0)
|
||||
return ENOBUFS;
|
||||
switch(ptype) {
|
||||
case NCP_PACKET_BURST:
|
||||
brq = (struct ncp_bursthdr*)mb_reserve(mbp, sizeof(*brq));
|
||||
brq->bh_type = ptype;
|
||||
brq->bh_streamtype = 0x2;
|
||||
break;
|
||||
default:
|
||||
rq = (struct ncp_rqhdr*)mb_reserve(mbp, sizeof(*rq));
|
||||
rq->type = ptype;
|
||||
rq->seq = 0; /* filled later */
|
||||
rq->fn = fn;
|
||||
break;
|
||||
}
|
||||
rqp->nr_minrplen = -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
ncp_rq_done(struct ncp_rq *rqp)
|
||||
{
|
||||
mb_done(&rqp->rq);
|
||||
md_done(&rqp->rp);
|
||||
if (rqp->nr_flags & NCPR_ALLOCED)
|
||||
free(rqp, M_NCPRQ);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Routines to fill the request
|
||||
*/
|
||||
|
||||
static int
|
||||
ncp_rq_pathstrhelp(struct mbchain *mbp, c_caddr_t src, caddr_t dst,
|
||||
size_t *srclen, size_t *dstlen)
|
||||
{
|
||||
int len;
|
||||
|
||||
if (*srclen < *dstlen) {
|
||||
*dstlen = *srclen;
|
||||
len = (int)*srclen;
|
||||
} else {
|
||||
*srclen = *dstlen;
|
||||
len = (int)*dstlen;
|
||||
}
|
||||
ncp_pathcopy(src, dst, len, mbp->mb_udata);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
ncp_rq_pathstring(struct ncp_rq *rqp, int size, const char *name,
|
||||
struct ncp_nlstables *nt)
|
||||
{
|
||||
struct mbchain *mbp = &rqp->rq;
|
||||
|
||||
mb_put_uint8(mbp, size);
|
||||
mbp->mb_copy = ncp_rq_pathstrhelp;
|
||||
mbp->mb_udata = nt;
|
||||
return mb_put_mem(mbp, (c_caddr_t)name, size, MB_MCUSTOM);
|
||||
}
|
||||
|
||||
int
|
||||
ncp_rq_pstring(struct ncp_rq *rqp, const char *s)
|
||||
{
|
||||
u_int len = strlen(s);
|
||||
int error;
|
||||
|
||||
if (len > 255)
|
||||
return EINVAL;
|
||||
error = mb_put_uint8(&rqp->rq, len);
|
||||
if (error)
|
||||
return error;
|
||||
return mb_put_mem(&rqp->rq, s, len, MB_MSYSTEM);
|
||||
}
|
||||
|
||||
int
|
||||
ncp_rq_dbase_path(struct ncp_rq *rqp, u_int8_t vol_num, u_int32_t dir_base,
|
||||
int namelen, u_char *path, struct ncp_nlstables *nt)
|
||||
{
|
||||
struct mbchain *mbp = &rqp->rq;
|
||||
int complen;
|
||||
|
||||
mb_put_uint8(mbp, vol_num);
|
||||
mb_put_mem(mbp, (c_caddr_t)&dir_base, sizeof(dir_base), MB_MSYSTEM);
|
||||
mb_put_uint8(mbp, 1); /* with dirbase */
|
||||
if (path != NULL && path[0]) {
|
||||
if (namelen < 0) {
|
||||
namelen = *path++;
|
||||
mb_put_uint8(mbp, namelen);
|
||||
for(; namelen; namelen--) {
|
||||
complen = *path++;
|
||||
mb_put_uint8(mbp, complen);
|
||||
mb_put_mem(mbp, path, complen, MB_MSYSTEM);
|
||||
path += complen;
|
||||
}
|
||||
} else {
|
||||
mb_put_uint8(mbp, 1); /* 1 component */
|
||||
ncp_rq_pathstring(rqp, namelen, path, nt);
|
||||
}
|
||||
} else {
|
||||
mb_put_uint8(mbp, 0);
|
||||
mb_put_uint8(mbp, 0);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Make a signature for the current packet and add it at the end of the
|
||||
* packet.
|
||||
*/
|
||||
static int
|
||||
ncp_sign_packet(struct ncp_conn *conn, struct ncp_rq *rqp, int *size)
|
||||
{
|
||||
u_char data[64];
|
||||
int error;
|
||||
|
||||
bzero(data, sizeof(data));
|
||||
bcopy(conn->sign_root, data, 8);
|
||||
setdle(data, 8, *size);
|
||||
m_copydata(rqp->rq.mb_top, sizeof(struct ncp_rqhdr) - 1,
|
||||
min((*size) - sizeof(struct ncp_rqhdr)+1, 52), data + 12);
|
||||
ncp_sign(conn->sign_state, data, conn->sign_state);
|
||||
error = mb_put_mem(&rqp->rq, (caddr_t)conn->sign_state, 8, MB_MSYSTEM);
|
||||
if (error)
|
||||
return error;
|
||||
(*size) += 8;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Low level send rpc, here we do not attempt to restore any connection,
|
||||
* Connection expected to be locked
|
||||
*/
|
||||
int
|
||||
ncp_request_int(struct ncp_rq *rqp)
|
||||
{
|
||||
struct ncp_conn *conn = rqp->nr_conn;
|
||||
struct thread *td = conn->td;
|
||||
struct socket *so = conn->ncp_so;
|
||||
struct ncp_rqhdr *rq;
|
||||
struct ncp_rphdr *rp=NULL;
|
||||
struct timeval tv;
|
||||
struct mbuf *m, *mreply = NULL;
|
||||
struct mbchain *mbp;
|
||||
int error, len, dosend, plen = 0, gotpacket;
|
||||
|
||||
if (so == NULL) {
|
||||
printf("%s: ncp_so is NULL !\n",__func__);
|
||||
ncp_conn_invalidate(conn);
|
||||
return ENOTCONN;
|
||||
}
|
||||
if (td == NULL)
|
||||
td = curthread; /* XXX maybe procpage ? */
|
||||
/*
|
||||
* Flush out replies on previous reqs
|
||||
*/
|
||||
tv.tv_sec = 0;
|
||||
tv.tv_usec = 0;
|
||||
while (selsocket(so, POLLIN, &tv, td) == 0) {
|
||||
if (ncp_sock_recv(so, &m, &len) != 0)
|
||||
break;
|
||||
m_freem(m);
|
||||
}
|
||||
mbp = &rqp->rq;
|
||||
len = mb_fixhdr(mbp);
|
||||
rq = mtod(mbp->mb_top, struct ncp_rqhdr *);
|
||||
rq->seq = conn->seq;
|
||||
m = rqp->rq.mb_top;
|
||||
|
||||
switch (rq->fn) {
|
||||
case 0x15: case 0x16: case 0x17: case 0x23:
|
||||
*(u_int16_t*)(rq + 1) = htons(len - 2 - sizeof(*rq));
|
||||
break;
|
||||
}
|
||||
if (conn->flags & NCPFL_SIGNACTIVE) {
|
||||
error = ncp_sign_packet(conn, rqp, &len);
|
||||
if (error)
|
||||
return error;
|
||||
mbp->mb_top->m_pkthdr.len = len;
|
||||
}
|
||||
rq->conn_low = conn->connid & 0xff;
|
||||
/* rq->task = p->p_pgrp->pg_id & 0xff; */ /*p->p_pid*/
|
||||
/* XXX: this is temporary fix till I find a better solution */
|
||||
rq->task = rq->conn_low;
|
||||
rq->conn_high = conn->connid >> 8;
|
||||
rqp->rexmit = conn->li.retry_count;
|
||||
error = 0;
|
||||
for(dosend = 1;;) {
|
||||
if (rqp->rexmit-- == 0) {
|
||||
error = ETIMEDOUT;
|
||||
break;
|
||||
}
|
||||
error = 0;
|
||||
if (dosend) {
|
||||
NCPSDEBUG("send:%04x f=%02x c=%d l=%d s=%d t=%d\n",rq->type, rq->fn, (rq->conn_high << 8) + rq->conn_low,
|
||||
mbp->mb_top->m_pkthdr.len, rq->seq, rq->task
|
||||
);
|
||||
error = ncp_sock_send(so, mbp->mb_top, rqp);
|
||||
if (error)
|
||||
break;
|
||||
}
|
||||
tv.tv_sec = conn->li.timeout;
|
||||
tv.tv_usec = 0;
|
||||
error = selsocket(so, POLLIN, &tv, td);
|
||||
if (error == EWOULDBLOCK ) /* timeout expired */
|
||||
continue;
|
||||
error = ncp_chkintr(conn, td);
|
||||
if (error)
|
||||
break;
|
||||
/*
|
||||
* At this point it is possible to get more than one
|
||||
* reply from server. In general, last reply should be for
|
||||
* current request, but not always. So, we loop through
|
||||
* all replies to find the right answer and flush others.
|
||||
*/
|
||||
gotpacket = 0; /* nothing good found */
|
||||
dosend = 1; /* resend rq if error */
|
||||
for (;;) {
|
||||
error = 0;
|
||||
tv.tv_sec = 0;
|
||||
tv.tv_usec = 0;
|
||||
if (selsocket(so, POLLIN, &tv, td) != 0)
|
||||
break;
|
||||
/* if (so->so_rcv.sb_cc == 0) {
|
||||
break;
|
||||
}*/
|
||||
error = ncp_sock_recv(so, &m, &len);
|
||||
if (error)
|
||||
break; /* must be more checks !!! */
|
||||
if (m->m_len < sizeof(*rp)) {
|
||||
m = m_pullup(m, sizeof(*rp));
|
||||
if (m == NULL) {
|
||||
printf("%s: reply too short\n",__func__);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
rp = mtod(m, struct ncp_rphdr*);
|
||||
if (len == sizeof(*rp) && rp->type == NCP_POSITIVE_ACK) {
|
||||
NCPSDEBUG("got positive acknowledge\n");
|
||||
m_freem(m);
|
||||
rqp->rexmit = conn->li.retry_count;
|
||||
dosend = 0; /* server just busy and will reply ASAP */
|
||||
continue;
|
||||
}
|
||||
NCPSDEBUG("recv:%04x c=%d l=%d s=%d t=%d cc=%02x cs=%02x\n",rp->type,
|
||||
(rp->conn_high << 8) + rp->conn_low, len, rp->seq, rp->task,
|
||||
rp->completion_code, rp->connection_state);
|
||||
NCPDDEBUG(m);
|
||||
if ( (rp->type == NCP_REPLY) &&
|
||||
((rq->type == NCP_ALLOC_SLOT) ||
|
||||
((rp->conn_low == rq->conn_low) &&
|
||||
(rp->conn_high == rq->conn_high)
|
||||
))) {
|
||||
if (rq->seq > rp->seq || (rq->seq == 0 && rp->seq == 0xff)) {
|
||||
dosend = 1;
|
||||
}
|
||||
if (rp->seq == rq->seq) {
|
||||
if (gotpacket) {
|
||||
m_freem(m);
|
||||
} else {
|
||||
gotpacket = 1;
|
||||
mreply = m;
|
||||
plen = len;
|
||||
}
|
||||
continue; /* look up other for other packets */
|
||||
}
|
||||
}
|
||||
m_freem(m);
|
||||
NCPSDEBUG("reply mismatch\n");
|
||||
} /* for receive */
|
||||
if (error || gotpacket)
|
||||
break;
|
||||
/* try to resend, or just wait */
|
||||
}
|
||||
conn->seq++;
|
||||
if (error) {
|
||||
NCPSDEBUG("error=%d\n", error);
|
||||
/*
|
||||
* Any error except interruped call means that we have
|
||||
* to reconnect. So, eliminate future timeouts by invalidating
|
||||
* connection now.
|
||||
*/
|
||||
if (error != EINTR)
|
||||
ncp_conn_invalidate(conn);
|
||||
return (error);
|
||||
}
|
||||
if (conn->flags & NCPFL_SIGNACTIVE) {
|
||||
/* XXX: check reply signature */
|
||||
m_adj(mreply, -8);
|
||||
plen -= 8;
|
||||
}
|
||||
rp = mtod(mreply, struct ncp_rphdr*);
|
||||
md_initm(&rqp->rp, mreply);
|
||||
rqp->nr_rpsize = plen - sizeof(*rp);
|
||||
rqp->nr_cc = error = rp->completion_code;
|
||||
if (error)
|
||||
error |= 0x8900; /* server error */
|
||||
rqp->nr_cs = rp->connection_state;
|
||||
if (rqp->nr_cs & (NCP_CS_BAD_CONN | NCP_CS_SERVER_DOWN)) {
|
||||
NCPSDEBUG("server drop us\n");
|
||||
ncp_conn_invalidate(conn);
|
||||
error = ECONNRESET;
|
||||
}
|
||||
md_get_mem(&rqp->rp, NULL, sizeof(*rp), MB_MSYSTEM);
|
||||
return error;
|
||||
}
|
||||
|
||||
/*
|
||||
* Here we will try to restore any loggedin & dropped connection,
|
||||
* connection should be locked on entry
|
||||
*/
|
||||
static __inline int
|
||||
ncp_restore_login(struct ncp_conn *conn)
|
||||
{
|
||||
int error;
|
||||
|
||||
printf("ncprq: Restoring connection, flags = %x\n", conn->flags);
|
||||
conn->flags |= NCPFL_RESTORING;
|
||||
error = ncp_conn_reconnect(conn);
|
||||
if (!error && (conn->flags & NCPFL_WASLOGGED))
|
||||
error = ncp_conn_login(conn, conn->td, conn->ucred);
|
||||
if (error)
|
||||
ncp_ncp_disconnect(conn);
|
||||
conn->flags &= ~NCPFL_RESTORING;
|
||||
return error;
|
||||
}
|
||||
|
||||
int
|
||||
ncp_request(struct ncp_rq *rqp)
|
||||
{
|
||||
struct ncp_conn *ncp = rqp->nr_conn;
|
||||
int error, rcnt;
|
||||
|
||||
error = ncp_conn_lock(ncp, rqp->nr_td, rqp->nr_cred, NCPM_EXECUTE);
|
||||
if (error)
|
||||
goto out;
|
||||
rcnt = NCP_RESTORE_COUNT;
|
||||
for(;;) {
|
||||
if (ncp->flags & NCPFL_ATTACHED) {
|
||||
error = ncp_request_int(rqp);
|
||||
if (ncp->flags & NCPFL_ATTACHED)
|
||||
break;
|
||||
}
|
||||
if (rcnt-- == 0) {
|
||||
error = ECONNRESET;
|
||||
break;
|
||||
}
|
||||
/*
|
||||
* Do not attempt to restore connection recursively
|
||||
*/
|
||||
if (ncp->flags & NCPFL_RESTORING) {
|
||||
error = ENOTCONN;
|
||||
break;
|
||||
}
|
||||
error = ncp_restore_login(ncp);
|
||||
if (error)
|
||||
continue;
|
||||
}
|
||||
ncp_conn_unlock(ncp, rqp->nr_td);
|
||||
out:
|
||||
if (error && (rqp->nr_flags & NCPR_DONTFREEONERR) == 0)
|
||||
ncp_rq_done(rqp);
|
||||
return error;
|
||||
}
|
@ -1,136 +0,0 @@
|
||||
/*-
|
||||
* Copyright (c) 1999, 2000, 2001 Boris Popov
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
#ifndef _NETNCP_NCP_RQ_H_
|
||||
#define _NETNCP_NCP_RQ_H_
|
||||
|
||||
#include <sys/endian.h>
|
||||
|
||||
#define getb(buf,ofs) (((const u_int8_t *)(buf))[ofs])
|
||||
#define setb(buf,ofs,val) (((u_int8_t*)(buf))[ofs])=val
|
||||
#define getbw(buf,ofs) ((u_int16_t)(getb(buf,ofs)))
|
||||
|
||||
#define getwle(buf,ofs) (le16toh(*((u_int16_t*)(&((u_int8_t*)(buf))[ofs]))))
|
||||
#define getdle(buf,ofs) (le32toh(*((u_int32_t*)(&((u_int8_t*)(buf))[ofs]))))
|
||||
#define getwbe(buf,ofs) (be16toh(*((u_int16_t*)(&((u_int8_t*)(buf))[ofs]))))
|
||||
#define getdbe(buf,ofs) (be32toh(*((u_int32_t*)(&((u_int8_t*)(buf))[ofs]))))
|
||||
|
||||
#define setwle(buf,ofs,val) \
|
||||
(*((u_int16_t*)(&((u_int8_t*)(buf))[ofs])))=htole16(val)
|
||||
#define setdle(buf,ofs,val) \
|
||||
(*((u_int32_t*)(&((u_int8_t*)(buf))[ofs])))=htole32(val)
|
||||
#define setwbe(buf,ofs,val) \
|
||||
(*((u_int16_t*)(&((u_int8_t*)(buf))[ofs])))=htobe16(val)
|
||||
#define setdbe(buf,ofs,val) \
|
||||
(*((u_int32_t*)(&((u_int8_t*)(buf))[ofs])))=htobe32(val)
|
||||
|
||||
#ifdef _KERNEL
|
||||
|
||||
#include <sys/mchain.h>
|
||||
|
||||
#define NCPR_ALLOCED 0x0001 /* request structure was allocated */
|
||||
#define NCPR_DONTFREEONERR 0x0002 /* do not free structure on error */
|
||||
|
||||
/*
|
||||
* Structure to prepare ncp request and receive reply
|
||||
*/
|
||||
struct ncp_rq {
|
||||
int nr_flags;
|
||||
struct mbchain rq;
|
||||
struct mdchain rp;
|
||||
int nr_minrplen; /* minimal rp size (-1 if not known) */
|
||||
int nr_rpsize; /* reply size minus ncp header */
|
||||
int nr_cc; /* completion code */
|
||||
int nr_cs; /* connection state */
|
||||
struct thread * nr_td; /* thread that did rq */
|
||||
struct ucred * nr_cred; /* user that did rq */
|
||||
int rexmit;
|
||||
struct ncp_conn*nr_conn; /* back link */
|
||||
};
|
||||
|
||||
int ncp_rq_alloc(u_int8_t fn, struct ncp_conn *ncp, struct thread *td,
|
||||
struct ucred *cred, struct ncp_rq **rqpp);
|
||||
int ncp_rq_alloc_any(u_int32_t ptype, u_int8_t fn, struct ncp_conn *ncp,
|
||||
struct thread *td, struct ucred *cred, struct ncp_rq **rqpp);
|
||||
int ncp_rq_alloc_subfn(u_int8_t fn, u_int8_t subfn, struct ncp_conn *ncp,
|
||||
struct thread *td, struct ucred *cred, struct ncp_rq **rqpp);
|
||||
int ncp_rq_init_any(struct ncp_rq *rqp, u_int32_t ptype, u_int8_t fn,
|
||||
struct ncp_conn *ncp,
|
||||
struct thread *td, struct ucred *cred);
|
||||
void ncp_rq_done(struct ncp_rq *rqp);
|
||||
int ncp_request(struct ncp_rq *rqp);
|
||||
int ncp_request_int(struct ncp_rq *rqp);
|
||||
|
||||
struct ncp_nlstables;
|
||||
|
||||
int ncp_rq_pathstring(struct ncp_rq *rqp, int size, const char *name, struct ncp_nlstables*);
|
||||
int ncp_rq_dbase_path(struct ncp_rq *, u_int8_t vol_num,
|
||||
u_int32_t dir_base, int namelen, u_char *name, struct ncp_nlstables *nt);
|
||||
int ncp_rq_pstring(struct ncp_rq *rqp, const char *s);
|
||||
|
||||
void ncp_sign_init(const char *logindata, char *sign_root);
|
||||
|
||||
#else /* ifdef _KERNEL */
|
||||
|
||||
#define DECLARE_RQ struct ncp_buf conn1, *conn=&conn1
|
||||
|
||||
#define ncp_add_byte(conn,x) (conn)->packet[(conn)->rqsize++]=x
|
||||
|
||||
struct ncp_buf;
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
void ncp_init_request(struct ncp_buf *);
|
||||
void ncp_init_request_s(struct ncp_buf *, int);
|
||||
void ncp_add_word_lh(struct ncp_buf *, u_int16_t);
|
||||
void ncp_add_dword_lh(struct ncp_buf *, u_int32_t);
|
||||
void ncp_add_word_hl(struct ncp_buf *, u_int16_t);
|
||||
void ncp_add_dword_hl(struct ncp_buf *, u_int32_t);
|
||||
void ncp_add_mem(struct ncp_buf *, const void *, int);
|
||||
void ncp_add_mem_nls(struct ncp_buf *, const void *, int);
|
||||
void ncp_add_pstring(struct ncp_buf *, const char *);
|
||||
void ncp_add_handle_path(struct ncp_buf *, nuint32, nuint32, int, const char *);
|
||||
|
||||
#define ncp_reply_data(conn,offset) ((conn)->packet+offset)
|
||||
#define ncp_reply_byte(conn,offset) (*(u_int8_t*)(ncp_reply_data(conn, offset)))
|
||||
|
||||
u_int16_t ncp_reply_word_hl(struct ncp_buf *, int);
|
||||
u_int16_t ncp_reply_word_lh(struct ncp_buf *, int);
|
||||
u_int32_t ncp_reply_dword_hl(struct ncp_buf *, int);
|
||||
u_int32_t ncp_reply_dword_lh(struct ncp_buf *, int);
|
||||
|
||||
static __inline void
|
||||
ConvertToNWfromDWORD(u_int32_t sfd, ncp_fh *fh) {
|
||||
fh->val1 = (fh->val.val32 = sfd);
|
||||
return;
|
||||
}
|
||||
|
||||
__END_DECLS
|
||||
|
||||
#endif /* ifdef _KERNEL */
|
||||
|
||||
#endif /* !_NETNCP_NCP_RQ_H_ */
|
@ -1,381 +0,0 @@
|
||||
/*-
|
||||
* Copyright (c) 1999, 2001 Boris Popov
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* Low level socket routines
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/errno.h>
|
||||
#include <sys/lock.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/mutex.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/proc.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/socketvar.h>
|
||||
#include <sys/protosw.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/uio.h>
|
||||
#include <sys/syslog.h>
|
||||
#include <sys/mbuf.h>
|
||||
#include <sys/condvar.h>
|
||||
#include <net/route.h>
|
||||
|
||||
#include <netipx/ipx.h>
|
||||
#include <netipx/ipx_pcb.h>
|
||||
|
||||
#include <netncp/ncp.h>
|
||||
#include <netncp/ncp_conn.h>
|
||||
#include <netncp/ncp_sock.h>
|
||||
#include <netncp/ncp_subr.h>
|
||||
#include <netncp/ncp_rq.h>
|
||||
|
||||
#define ipx_setnullnet(x) ((x).x_net.s_net[0]=0); ((x).x_net.s_net[1]=0);
|
||||
#define ipx_setnullhost(x) ((x).x_host.s_host[0] = 0); \
|
||||
((x).x_host.s_host[1] = 0); ((x).x_host.s_host[2] = 0);
|
||||
|
||||
/*static int ncp_getsockname(struct socket *so, caddr_t asa, int *alen);*/
|
||||
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 thread *td)
|
||||
{
|
||||
int error, s;
|
||||
|
||||
error = soconnect(so, (struct sockaddr*)target, td);
|
||||
if (error)
|
||||
return error;
|
||||
/*
|
||||
* Wait for the connection to complete. Cribbed from the
|
||||
* connect system call but with the wait timing out so
|
||||
* that interruptible mounts don't hang here for a long time.
|
||||
*/
|
||||
error = EIO;
|
||||
s = splnet();
|
||||
while ((so->so_state & SS_ISCONNECTING) && so->so_error == 0) {
|
||||
(void) tsleep((caddr_t)&so->so_timeo, PSOCK, "ncpcon", 2 * hz);
|
||||
if ((so->so_state & SS_ISCONNECTING) &&
|
||||
so->so_error == 0 /*&& rep &&*/) {
|
||||
so->so_state &= ~SS_ISCONNECTING;
|
||||
splx(s);
|
||||
goto bad;
|
||||
}
|
||||
}
|
||||
if (so->so_error) {
|
||||
error = so->so_error;
|
||||
so->so_error = 0;
|
||||
splx(s);
|
||||
goto bad;
|
||||
}
|
||||
splx(s);
|
||||
error=0;
|
||||
bad:
|
||||
return error;
|
||||
}
|
||||
#ifdef notyet
|
||||
static int
|
||||
ncp_getsockname(struct socket *so, caddr_t asa, int *alen) {
|
||||
struct sockaddr *sa;
|
||||
int len=0, error;
|
||||
|
||||
sa = 0;
|
||||
error = (*so->so_proto->pr_usrreqs->pru_sockaddr)(so, &sa);
|
||||
if (error==0) {
|
||||
if (sa) {
|
||||
len = min(len, sa->sa_len);
|
||||
bcopy(sa, (caddr_t)asa, (u_int)len);
|
||||
}
|
||||
*alen=len;
|
||||
}
|
||||
if (sa)
|
||||
free(sa, M_SONAME);
|
||||
return (error);
|
||||
}
|
||||
#endif
|
||||
int ncp_sock_recv(struct socket *so, struct mbuf **mp, int *rlen)
|
||||
{
|
||||
struct uio auio;
|
||||
struct thread *td = curthread; /* XXX */
|
||||
int error,flags,len;
|
||||
|
||||
auio.uio_resid = len = 1000000;
|
||||
auio.uio_td = td;
|
||||
flags = MSG_DONTWAIT;
|
||||
|
||||
/* error = soreceive(so, 0, &auio, (struct mbuf **)0, (struct mbuf **)0,
|
||||
&flags);*/
|
||||
error = soreceive(so, 0, &auio, mp, (struct mbuf **)0, &flags);
|
||||
*rlen = len - auio.uio_resid;
|
||||
/* if (!error) {
|
||||
*rlen=iov.iov_len;
|
||||
} else
|
||||
*rlen=0;*/
|
||||
#ifdef NCP_SOCKET_DEBUG
|
||||
if (error)
|
||||
printf("ncp_recv: err=%d\n", error);
|
||||
#endif
|
||||
return (error);
|
||||
}
|
||||
|
||||
int
|
||||
ncp_sock_send(struct socket *so, struct mbuf *top, struct ncp_rq *rqp)
|
||||
{
|
||||
struct thread *td = curthread; /* XXX */
|
||||
struct sockaddr *to = 0;
|
||||
struct ncp_conn *conn = rqp->nr_conn;
|
||||
struct mbuf *m;
|
||||
int error, flags=0;
|
||||
|
||||
for (;;) {
|
||||
m = m_copym(top, 0, M_COPYALL, M_WAITOK);
|
||||
/* NCPDDEBUG(m);*/
|
||||
error = sosend(so, to, 0, m, 0, flags, td);
|
||||
if (error == 0 || error == EINTR || error == ENETDOWN)
|
||||
break;
|
||||
if (rqp->rexmit == 0) break;
|
||||
rqp->rexmit--;
|
||||
pause("ncprsn", conn->li.timeout * hz);
|
||||
error = ncp_chkintr(conn, td);
|
||||
if (error == EINTR) break;
|
||||
}
|
||||
if (error) {
|
||||
log(LOG_INFO, "ncp_send: error %d for server %s", error, conn->li.server);
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
/*
|
||||
* Connect to specified server via IPX
|
||||
*/
|
||||
static int
|
||||
ncp_sock_connect_ipx(struct ncp_conn *conn)
|
||||
{
|
||||
struct sockaddr_ipx sipx;
|
||||
struct ipxpcb *npcb;
|
||||
struct thread *td = conn->td;
|
||||
int addrlen, error, count;
|
||||
|
||||
sipx.sipx_port = htons(0);
|
||||
|
||||
for (count = 0;;count++) {
|
||||
if (count > (IPXPORT_WELLKNOWN-IPXPORT_RESERVED)*2) {
|
||||
error = EADDRINUSE;
|
||||
goto bad;
|
||||
}
|
||||
conn->ncp_so = conn->wdg_so = NULL;
|
||||
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, 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, td);
|
||||
if (error == 0) {
|
||||
if ((conn->li.opt & NCP_OPT_WDOG) == 0)
|
||||
break;
|
||||
sipx.sipx_addr = sotoipxpcb(conn->ncp_so)->ipxp_laddr;
|
||||
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, td);
|
||||
}
|
||||
if (!error) break;
|
||||
if (error != EADDRINUSE) goto bad;
|
||||
sipx.sipx_port = htons((ntohs(sipx.sipx_port)+4) & 0xfff8);
|
||||
soclose(conn->ncp_so);
|
||||
if (conn->wdg_so)
|
||||
soclose(conn->wdg_so);
|
||||
}
|
||||
npcb = sotoipxpcb(conn->ncp_so);
|
||||
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, 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;
|
||||
}
|
||||
if (!error) {
|
||||
conn->flags |= NCPFL_SOCONN;
|
||||
}
|
||||
#ifdef NCPBURST
|
||||
if (ncp_burst_enabled) {
|
||||
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, td));
|
||||
checkbad(ncp_soconnect(conn->bc_so, &conn->li.saddr, td));
|
||||
}
|
||||
#endif
|
||||
if (!error) {
|
||||
conn->flags |= NCPFL_SOCONN;
|
||||
ncp_sock_checksum(conn, 0);
|
||||
}
|
||||
return error;
|
||||
bad:
|
||||
ncp_sock_disconnect(conn);
|
||||
return (error);
|
||||
}
|
||||
|
||||
int
|
||||
ncp_sock_checksum(struct ncp_conn *conn, int enable)
|
||||
{
|
||||
|
||||
if (enable) {
|
||||
sotoipxpcb(conn->ncp_so)->ipxp_flags |= IPXP_CHECKSUM;
|
||||
} else {
|
||||
sotoipxpcb(conn->ncp_so)->ipxp_flags &= ~IPXP_CHECKSUM;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Connect to specified server via IP
|
||||
*/
|
||||
static int
|
||||
ncp_sock_connect_in(struct ncp_conn *conn)
|
||||
{
|
||||
struct sockaddr_in sin;
|
||||
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, td->td_ucred, td));
|
||||
sin.sin_family = AF_INET;
|
||||
sin.sin_len = addrlen;
|
||||
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;
|
||||
bad:
|
||||
ncp_sock_disconnect(conn);
|
||||
return (error);
|
||||
}
|
||||
|
||||
int
|
||||
ncp_sock_connect(struct ncp_conn *ncp)
|
||||
{
|
||||
int error;
|
||||
|
||||
switch (ncp->li.saddr.sa_family) {
|
||||
case AF_IPX:
|
||||
error = ncp_sock_connect_ipx(ncp);
|
||||
break;
|
||||
case AF_INET:
|
||||
error = ncp_sock_connect_in(ncp);
|
||||
break;
|
||||
default:
|
||||
return EPROTONOSUPPORT;
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
/*
|
||||
* Connection expected to be locked
|
||||
*/
|
||||
int
|
||||
ncp_sock_disconnect(struct ncp_conn *conn) {
|
||||
register struct socket *so;
|
||||
conn->flags &= ~(NCPFL_SOCONN | NCPFL_ATTACHED | NCPFL_LOGGED);
|
||||
if (conn->ncp_so) {
|
||||
so = conn->ncp_so;
|
||||
conn->ncp_so = (struct socket *)0;
|
||||
soshutdown(so, 2);
|
||||
soclose(so);
|
||||
}
|
||||
if (conn->wdg_so) {
|
||||
so = conn->wdg_so;
|
||||
conn->wdg_so = (struct socket *)0;
|
||||
soshutdown(so, 2);
|
||||
soclose(so);
|
||||
}
|
||||
#ifdef NCPBURST
|
||||
if (conn->bc_so) {
|
||||
so = conn->bc_so;
|
||||
conn->bc_so = (struct socket *)NULL;
|
||||
soshutdown(so, 2);
|
||||
soclose(so);
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
ncp_watchdog(struct ncp_conn *conn) {
|
||||
char *buf;
|
||||
struct mbuf *m;
|
||||
int error, len, flags;
|
||||
struct socket *so;
|
||||
struct sockaddr *sa;
|
||||
struct uio auio;
|
||||
|
||||
sa = NULL;
|
||||
while (conn->wdg_so) { /* not a loop */
|
||||
so = conn->wdg_so;
|
||||
auio.uio_resid = len = 1000000;
|
||||
auio.uio_td = curthread;
|
||||
flags = MSG_DONTWAIT;
|
||||
error = soreceive(so, (struct sockaddr**)&sa, &auio, &m,
|
||||
(struct mbuf**)0, &flags);
|
||||
if (error) break;
|
||||
len -= auio.uio_resid;
|
||||
NCPSDEBUG("got watch dog %d\n",len);
|
||||
if (len != 2) break;
|
||||
buf = mtod(m, char*);
|
||||
if (buf[1] != '?') break;
|
||||
buf[1] = 'Y';
|
||||
error = sosend(so, (struct sockaddr*)sa, 0, m, 0, 0, curthread);
|
||||
NCPSDEBUG("send watch dog %d\n",error);
|
||||
break;
|
||||
}
|
||||
if (sa) free(sa, M_SONAME);
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
ncp_check_conn(struct ncp_conn *conn) {
|
||||
int s;
|
||||
|
||||
if (conn == NULL || !(conn->flags & NCPFL_ATTACHED))
|
||||
return;
|
||||
s = splnet();
|
||||
ncp_check_rq(conn);
|
||||
splx(s);
|
||||
if (conn->li.saddr.sa_family == AF_IPX)
|
||||
ncp_watchdog(conn);
|
||||
}
|
@ -1,49 +0,0 @@
|
||||
/*-
|
||||
* Copyright (c) 1999 Boris Popov
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
#ifndef _NETNCP_NCP_SOCK_H_
|
||||
#define _NETNCP_NCP_SOCK_H_
|
||||
|
||||
struct ncp_conn;
|
||||
struct mbuf;
|
||||
struct ncp_rq;
|
||||
struct proc;
|
||||
struct socket;
|
||||
struct timeval;
|
||||
|
||||
int ncp_sock_connect(struct ncp_conn *ncp);
|
||||
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_sock_checksum(struct ncp_conn *conn, int enable);
|
||||
|
||||
void ncp_check_rq(struct ncp_conn *conn);
|
||||
void ncp_check_conn(struct ncp_conn *conn);
|
||||
|
||||
void ncp_check_wd(struct ncp_conn *conn);
|
||||
|
||||
#endif /* _NCP_SOCK_H_ */
|
@ -1,137 +0,0 @@
|
||||
/*-
|
||||
* Copyright (c) 1999, 2000, 2001 Boris Popov
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/errno.h>
|
||||
#include <sys/eventhandler.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/lock.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/proc.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#include <netncp/ncp.h>
|
||||
#include <netncp/ncp_conn.h>
|
||||
#include <netncp/ncp_sock.h>
|
||||
#include <netncp/ncp_subr.h>
|
||||
#include <netncp/ncp_rq.h>
|
||||
#include <netncp/ncp_ncp.h>
|
||||
#include <netncp/nwerror.h>
|
||||
|
||||
int ncp_debuglevel = 0;
|
||||
|
||||
struct callout_handle ncp_timer_handle;
|
||||
static eventhandler_tag ncp_exit_tag;
|
||||
|
||||
static void ncp_at_exit(void *arg, struct proc *p);
|
||||
static void ncp_timer(void *arg);
|
||||
|
||||
/*
|
||||
* duplicate string from user space. It should be very-very slow.
|
||||
*/
|
||||
char *
|
||||
ncp_str_dup(char *s) {
|
||||
char *p, bt;
|
||||
int len = 0;
|
||||
|
||||
for (p = s;;p++) {
|
||||
if (copyin(p, &bt, 1)) return NULL;
|
||||
len++;
|
||||
if (bt == 0) break;
|
||||
}
|
||||
p = malloc(len, M_NCPDATA, M_WAITOK);
|
||||
copyin(s, p, len);
|
||||
return p;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ncp_at_exit(void *arg, struct proc *p)
|
||||
{
|
||||
struct ncp_conn *ncp, *nncp;
|
||||
struct thread *td;
|
||||
|
||||
mtx_lock(&Giant);
|
||||
FOREACH_THREAD_IN_PROC(p, td) {
|
||||
if (ncp_conn_putprochandles(td) == 0)
|
||||
continue;
|
||||
|
||||
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);
|
||||
}
|
||||
mtx_unlock(&Giant);
|
||||
}
|
||||
|
||||
int
|
||||
ncp_init(void)
|
||||
{
|
||||
ncp_conn_init();
|
||||
ncp_exit_tag = EVENTHANDLER_REGISTER(process_exit, ncp_at_exit, NULL,
|
||||
EVENTHANDLER_PRI_ANY);
|
||||
ncp_timer_handle = timeout(ncp_timer, NULL, NCP_TIMER_TICK);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
ncp_done(void)
|
||||
{
|
||||
int error;
|
||||
|
||||
error = ncp_conn_destroy();
|
||||
if (error)
|
||||
return error;
|
||||
untimeout(ncp_timer, NULL, ncp_timer_handle);
|
||||
EVENTHANDLER_DEREGISTER(process_exit, ncp_exit_tag);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* tick every second and check for watch dog packets and lost connections */
|
||||
static void
|
||||
ncp_timer(void *arg)
|
||||
{
|
||||
struct ncp_conn *conn;
|
||||
|
||||
if(ncp_conn_locklist(LK_SHARED | LK_NOWAIT, NULL) == 0) {
|
||||
SLIST_FOREACH(conn, &conn_list, nc_next)
|
||||
ncp_check_conn(conn);
|
||||
ncp_conn_unlocklist(NULL);
|
||||
}
|
||||
ncp_timer_handle = timeout(ncp_timer, NULL, NCP_TIMER_TICK);
|
||||
}
|
@ -1,116 +0,0 @@
|
||||
/*-
|
||||
* Copyright (c) 1999 Boris Popov
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
#ifndef _NETNCP_NCP_SUBR_H_
|
||||
#define _NETNCP_NCP_SUBR_H_
|
||||
|
||||
#define NCP_TIMER_TICK 2*hz /* 1sec */
|
||||
#define NCP_SIGMASK(set) \
|
||||
(SIGISMEMBER(set, SIGINT) || SIGISMEMBER(set, SIGTERM) || \
|
||||
SIGISMEMBER(set, SIGHUP) || SIGISMEMBER(set, SIGKILL) || \
|
||||
SIGISMEMBER(set, SIGQUIT))
|
||||
|
||||
|
||||
#define NCP_PRINT(format, args...) printf("FATAL: %s: "format, __func__ ,## args)
|
||||
#define nwfs_printf NCP_PRINT
|
||||
/* Maybe this should panic, but I dont like that */
|
||||
#define NCPFATAL NCP_PRINT
|
||||
#define NCPERROR NCP_PRINT
|
||||
|
||||
/* socket debugging */
|
||||
#ifdef NCP_SOCKET_DEBUG
|
||||
#define NCPSDEBUG(format, args...) printf("%s: "format, __func__ ,## args)
|
||||
#else
|
||||
#define NCPSDEBUG(format, args...)
|
||||
#endif
|
||||
|
||||
/* NCP calls debug */
|
||||
#ifdef NCP_NCP_DEBUG
|
||||
#define NCPNDEBUG(format, args...) printf("%s: "format, __func__ ,## args)
|
||||
#else
|
||||
#define NCPNDEBUG(format, args...)
|
||||
#endif
|
||||
|
||||
/* NCP data dump */
|
||||
#ifdef NCP_DATA_DEBUG
|
||||
#define NCPDDEBUG(m) m_dumpm(m)
|
||||
#else
|
||||
#define NCPDDEBUG(m)
|
||||
#endif
|
||||
|
||||
/* FS VOPS debug */
|
||||
#ifdef NWFS_VOPS_DEBUG
|
||||
#define NCPVODEBUG(format, args...) printf("%s: "format, __func__ ,## args)
|
||||
#else
|
||||
#define NCPVODEBUG(format, args...)
|
||||
#endif
|
||||
|
||||
/* FS VNOPS debug */
|
||||
#ifdef NWFS_VNOPS_DEBUG
|
||||
#define NCPVNDEBUG(format, args...) printf("%s: "format, __func__ ,## args)
|
||||
#else
|
||||
#define NCPVNDEBUG(format, args...)
|
||||
#endif
|
||||
|
||||
#define checkbad(fn) {error=(fn);if(error) goto bad;}
|
||||
|
||||
#define ncp_suser(cred) priv_check_cred(cred, PRIV_NETNCP, 0)
|
||||
|
||||
#define ncp_isowner(conn,cred) ((cred)->cr_uid == (conn)->nc_owner->cr_uid)
|
||||
|
||||
struct ncp_conn;
|
||||
|
||||
struct nwmount;
|
||||
struct vnode;
|
||||
struct nwnode;
|
||||
struct vattr;
|
||||
struct uio;
|
||||
struct ncp_nlstables;
|
||||
|
||||
struct ncp_open_info {
|
||||
u_int32_t origfh;
|
||||
ncp_fh fh;
|
||||
u_int8_t action;
|
||||
struct nw_entry_info fattr;
|
||||
};
|
||||
|
||||
extern int ncp_debuglevel;
|
||||
|
||||
struct proc;
|
||||
struct ucred;
|
||||
|
||||
int ncp_init(void);
|
||||
int ncp_done(void);
|
||||
int ncp_chkintr(struct ncp_conn *conn, struct thread *td);
|
||||
char*ncp_str_dup(char *s);
|
||||
|
||||
/* ncp_crypt.c */
|
||||
void nw_keyhash(const u_char *key, const u_char *buf, int buflen, u_char *target);
|
||||
void nw_encrypt(const u_char *fra, const u_char *buf, u_char *target);
|
||||
void ncp_sign(const u_int32_t *state, const char *x, u_int32_t *ostate);
|
||||
|
||||
#endif /* _NCP_SUBR_H_ */
|
@ -1,91 +0,0 @@
|
||||
/*-
|
||||
* Copyright (c) 1999 Boris Popov
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
#ifndef _NETNCP_NCP_USER_H_
|
||||
#define _NETNCP_NCP_USER_H_
|
||||
|
||||
/*
|
||||
* "ncp" interface to kernel, this can be done via syscalls but may eat
|
||||
* a lot of them, so we select internal code, define req's and replays
|
||||
* as necessary. Structure for call is simple:
|
||||
* byte=NCP_CONN
|
||||
* byte=NCP_CONN_SUBFN
|
||||
* ....=data
|
||||
*/
|
||||
#define NCP_CONN 0xF5 /* change if that will occupied */
|
||||
#define NCP_CONN_READ 0x01 /* read from file handle */
|
||||
#define NCP_CONN_WRITE 0x02 /* write to file handle */
|
||||
#define NCP_CONN_SETFLAGS 0x03 /* word mask, word flags */
|
||||
#define NCP_CONN_LOGIN 0x04 /* bind login on handle */
|
||||
#define NCP_CONN_GETINFO 0x05 /* get information about connection */
|
||||
#define NCP_CONN_GETUSER 0x06 /* get user name for connection */
|
||||
#define NCP_CONN_CONN2REF 0x07 /* convert handle to reference */
|
||||
#define NCP_CONN_CONNCLOSE 0x08 /* release connection handle */
|
||||
#define NCP_CONN_FRAG 0x09 /* ncp fragmented request */
|
||||
#define NCP_CONN_DUP 0x0A /* get an additional handle */
|
||||
#define NCP_CONN_GETDATA 0x0B /* retrieve NCP_CD_* vals */
|
||||
#define NCP_CONN_SETDATA 0x0C /* store NCP_CD_* vals */
|
||||
|
||||
/*
|
||||
* Internal connection data can be set by owner or superuser and retrieved
|
||||
* only by superuser
|
||||
*/
|
||||
#define NCP_CD_NDSLOGINKEY 0x01
|
||||
#define NCP_CD_NDSPRIVATEKEY 0x02
|
||||
#define NCP_CD_NDSUFLAGS 0x03
|
||||
|
||||
/* user side structures to issue fragmented ncp calls */
|
||||
typedef struct {
|
||||
char *fragAddress;
|
||||
u_int32_t fragSize;
|
||||
} NW_FRAGMENT;
|
||||
|
||||
|
||||
struct ncp_rw {
|
||||
ncp_fh nrw_fh;
|
||||
char *nrw_base;
|
||||
off_t nrw_offset;
|
||||
int nrw_cnt;
|
||||
};
|
||||
|
||||
struct ncp_conn_login {
|
||||
char *username;
|
||||
int objtype;
|
||||
char *password;
|
||||
};
|
||||
|
||||
struct ncp_conn_frag {
|
||||
int cc; /* completion code */
|
||||
int cs; /* connection state */
|
||||
int fn;
|
||||
int rqfcnt;
|
||||
NW_FRAGMENT *rqf;
|
||||
int rpfcnt;
|
||||
NW_FRAGMENT *rpf;
|
||||
};
|
||||
|
||||
#endif
|
@ -1,62 +0,0 @@
|
||||
/*-
|
||||
* Copyright (c) 2003 Tim J. Robbins.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#ifndef _NETNCP_NCPIO_H_
|
||||
#define _NETNCP_NCPIO_H_
|
||||
|
||||
#ifndef _KERNEL
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
#include <sys/ioccom.h>
|
||||
|
||||
#define NCP_NAME "ncp"
|
||||
|
||||
struct ncp_conn_args;
|
||||
struct ncp_buf;
|
||||
|
||||
struct ncpioc_connect {
|
||||
struct ncp_conn_args *ioc_li;
|
||||
int *ioc_connhandle;
|
||||
};
|
||||
|
||||
struct ncpioc_request {
|
||||
int ioc_connhandle;
|
||||
int ioc_fn;
|
||||
struct ncp_buf *ioc_ncpbuf;
|
||||
};
|
||||
|
||||
struct ncpioc_connscan {
|
||||
struct ncp_conn_args *ioc_li;
|
||||
int *ioc_connhandle;
|
||||
};
|
||||
|
||||
#define NCPIOC_CONNECT _IOW('N', 100, struct ncpioc_connect)
|
||||
#define NCPIOC_REQUEST _IOW('N', 101, struct ncpioc_request)
|
||||
#define NCPIOC_CONNSCAN _IOW('N', 102, struct ncpioc_connscan)
|
||||
|
||||
#endif /* _NETNCP_NCPIO_H_ */
|
@ -1,634 +0,0 @@
|
||||
/*
|
||||
* NetWare requestor error codes, they taken from NDK
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
#ifndef _NETNCP_NWERROR_H_
|
||||
#define _NETNCP_NWERROR_H_
|
||||
|
||||
#ifndef SUCCESS
|
||||
#define SUCCESS 0
|
||||
#endif
|
||||
|
||||
#define SHELL_ERROR 0x8800
|
||||
#define VLM_ERROR 0x8800
|
||||
#define ALREADY_ATTACHED 0x8800 /* 0 - Attach attempted to server with valid, existing connection */
|
||||
#define INVALID_CONNECTION 0x8801 /* 1 - Request attempted with invalid or non-attached connection handle */
|
||||
#define DRIVE_IN_USE 0x8802 /* 2 - OS/2 only (NOT USED) */
|
||||
#define CANT_ADD_CDS 0x8803 /* 3 - Map drive attempted but unable to add new current directory structure */
|
||||
#define DRIVE_CANNOT_MAP 0x8803
|
||||
#define BAD_DRIVE_BASE 0x8804 /* 4 - Map drive attempted with invalid path specification */
|
||||
#define NET_READ_ERROR 0x8805 /* 5 - Attempt to receive from the selected transport failed */
|
||||
#define NET_RECV_ERROR 0x8805 /* 5 */
|
||||
#define UNKNOWN_NET_ERROR 0x8806 /* 6 - Network send attempted with an un-specific network error */
|
||||
#define SERVER_INVALID_SLOT 0x8807 /* 7 - Server request attempted with invalid server connection slot */
|
||||
#define BAD_SERVER_SLOT 0x8807 /* 7 */
|
||||
#define NO_SERVER_SLOTS 0x8808 /* 8 - Attach attempted to server with no connection slots available */
|
||||
#define NET_WRITE_ERROR 0x8809 /* 9 - Attempt to send on the selected transport failed */
|
||||
#define CONNECTION_IN_ERROR_STATE 0x8809 /* Client-32 */
|
||||
#define NET_SEND_ERROR 0x8809 /* 9 */
|
||||
#define SERVER_NO_ROUTE 0x880A /* 10 - Attempted to find route to server where no route exists */
|
||||
#define BAD_LOCAL_TARGET 0x880B /* 11 - OS/2 only */
|
||||
#define TOO_MANY_REQ_FRAGS 0x880C /* 12 - Attempted request with too many request fragments specified */
|
||||
#define CONNECT_LIST_OVERFLOW 0x880D /* 13 */
|
||||
#define BUFFER_OVERFLOW 0x880E /* 14 - Attempt to receive more data than the reply buffer had room for */
|
||||
#define MORE_DATA_ERROR 0x880E /* Client-32 */
|
||||
#define NO_CONN_TO_SERVER 0x880F /* 15 */
|
||||
#define NO_CONNECTION_TO_SERVER 0x880F /* 15 - Attempt to get connection for a server not connected */
|
||||
#define NO_ROUTER_FOUND 0x8810 /* 16 - OS/2 only */
|
||||
#define BAD_FUNC_ERROR 0x8811 /* 17 */
|
||||
#define INVALID_SHELL_CALL 0x8811 /* 17 - Attempted function call to non- existent or illegal function */
|
||||
#define SCAN_COMPLETE 0x8812
|
||||
#define LIP_RESIZE_ERROR 0x8812 /* Client-32 */
|
||||
#define UNSUPPORTED_NAME_FORMAT_TYPE 0x8813
|
||||
#define INVALID_DIR_HANDLE 0x8813 /* Client-32 */
|
||||
#define HANDLE_ALREADY_LICENSED 0x8814
|
||||
#define OUT_OF_CLIENT_MEMORY 0x8814 /* Client-32 */
|
||||
#define HANDLE_ALREADY_UNLICENSED 0x8815
|
||||
#define PATH_NOT_OURS 0x8815 /* Client-32 */
|
||||
#define INVALID_NCP_PACKET_LENGTH 0x8816
|
||||
#define PATH_IS_PRINT_DEVICE 0x8816 /* Client-32 */
|
||||
#define SETTING_UP_TIMEOUT 0x8817
|
||||
#define PATH_IS_EXCLUDED_DEVICE 0x8817 /* Client-32 */
|
||||
#define SETTING_SIGNALS 0x8818
|
||||
#define PATH_IS_INVALID 0x8818 /* Client-32 */
|
||||
#define SERVER_CONNECTION_LOST 0x8819
|
||||
#define NOT_SAME_DEVICE 0x8819 /* Client-32 */
|
||||
#define OUT_OF_HEAP_SPACE 0x881A
|
||||
#define INVALID_SERVICE_REQUEST 0x881B
|
||||
#define INVALID_SEARCH_HANDLE 0x881B /* Client-32 */
|
||||
#define INVALID_TASK_NUMBER 0x881C
|
||||
#define INVALID_DEVICE_HANDLE 0x881C /* Client-32 */
|
||||
#define INVALID_MESSAGE_LENGTH 0x881D
|
||||
#define INVALID_SEM_HANDLE 0x881D /* Client-32 */
|
||||
#define EA_SCAN_DONE 0x881E
|
||||
#define INVALID_CFG_HANDLE 0x881E /* Client-32 */
|
||||
#define BAD_CONNECTION_NUMBER 0x881F
|
||||
#define INVALID_MOD_HANDLE 0x881F /* Client-32 */
|
||||
#define ASYN_FIRST_PASS 0x8820
|
||||
#define INVALID_DEVICE_INDEX 0x8821
|
||||
#define INVALID_CONN_HANDLE 0x8822
|
||||
#define INVALID_QUEUE_ID 0x8823
|
||||
#define INVALID_PDEVICE_HANDLE 0x8824
|
||||
#define INVALID_JOB_HANDLE 0x8825
|
||||
#define INVALID_ELEMENT_ID 0x8826
|
||||
#define ALIAS_NOT_FOUND 0x8827
|
||||
#define RESOURCE_SUSPENDED 0x8828
|
||||
#define INVALID_QUEUE_SPECIFIED 0x8829
|
||||
#define DEVICE_ALREADY_OPEN 0x882A
|
||||
#define JOB_ALREADY_OPEN 0x882B
|
||||
#define QUEUE_NAME_ID_MISMATCH 0x882C
|
||||
#define JOB_ALREADY_STARTED 0x882D
|
||||
#define SPECT_DAA_TYPE_NOT_SUPPORTED 0x882E
|
||||
#define INVALID_ENVIR_HANDLE 0x882F
|
||||
#define NOT_SAME_CONNECTION 0x8830 /* 48 - Internal server request attempted accross different server connections */
|
||||
#define PRIMARY_CONNECTION_NOT_SET 0x8831 /* 49 - Attempt to retrieve default connection with no primary connection set */
|
||||
#define NO_PRIMARY_SET 0x8831 /* 49 */
|
||||
#define KEYWORD_NOT_FOUND 0x8832 /* Client-32 */
|
||||
#define PRINT_CAPTURE_NOT_IN_PROGRESS 0x8832 /* Client-32 */
|
||||
#define NO_CAPTURE_SET 0x8832 /* 50 */
|
||||
#define NO_CAPTURE_IN_PROGRESS 0x8832 /* 50 - Capture information requested on port with no capture in progress */
|
||||
#define BAD_BUFFER_LENGTH 0x8833 /* 51 */
|
||||
#define INVALID_BUFFER_LENGTH 0x8833 /* 51 - Used to indicate length which caller requested on a GetDNC or SetDNC was too large */
|
||||
#define NO_USER_NAME 0x8834 /* 52 */
|
||||
#define NO_NETWARE_PRINT_SPOOLER 0x8835 /* 53 - Capture requested without having the local print spooler installed */
|
||||
#define INVALID_PARAMETER 0x8836 /* 54 - Attempted function with an invalid function parameter specified */
|
||||
#define CONFIG_FILE_OPEN_FAILED 0x8837 /* 55 - OS/2 only */
|
||||
#define NO_CONFIG_FILE 0x8838 /* 56 - OS/2 only */
|
||||
#define CONFIG_FILE_READ_FAILED 0x8839 /* 57 - OS/2 only */
|
||||
#define CONFIG_LINE_TOO_LONG 0x883A /* 58 - OS/2 only */
|
||||
#define CONFIG_LINES_IGNORED 0x883B /* 59 - OS/2 only */
|
||||
#define NOT_MY_RESOURCE 0x883C /* 60 - Attempted request made with a parameter using foriegn resource */
|
||||
#define DAEMON_INSTALLED 0x883D /* 61 - OS/2 only */
|
||||
#define SPOOLER_INSTALLED 0x883E /* 62 - Attempted load of print spooler with print spooler already installed */
|
||||
#define CONN_TABLE_FULL 0x883F /* 63 */
|
||||
#define CONNECTION_TABLE_FULL 0x883F /* 63 - Attempted to allocate a connection handle with no more local connection table entries */
|
||||
#define CONFIG_SECTION_NOT_FOUND 0x8840 /* 64 - OS/2 only */
|
||||
#define BAD_TRAN_TYPE 0x8841 /* 65 */
|
||||
#define INVALID_TRANSPORT_TYPE 0x8841 /* 65 - Attempted function on a connection with an invalid transport selected */
|
||||
#define TDS_TAG_IN_USE 0x8842 /* 66 - OS/2 only */
|
||||
#define TDS_OUT_OF_MEMORY 0x8843 /* 67 - OS/2 only */
|
||||
#define TDS_INVALID_TAG 0x8844 /* 68 - Attempted TDS function with invalid tag */
|
||||
#define TDS_WRITE_TRUNCATED 0x8845 /* 69 - Attempted TDS write with buffer that exceeded buffer */
|
||||
#define NO_CONNECTION_TO_DS 0x8846 /* Client-32 */
|
||||
#define NO_DIRECTORY_SERVICE_CONNECTION 0x8846 /* 70 */
|
||||
#define SERVICE_BUSY 0x8846 /* 70 - Attempted request made to partially asynchronous function in busy state */
|
||||
#define NO_SERVER_ERROR 0x8847 /* 71 - Attempted connect failed to find any servers responding */
|
||||
#define BAD_VLM_ERROR 0x8848 /* 72 - Attempted function call to non-existant or not-loaded overlay */
|
||||
#define NETWORK_DRIVE_IN_USE 0x8849 /* 73 - Attempted map to network drive that was already mapped */
|
||||
#define LOCAL_DRIVE_IN_USE 0x884A /* 74 - Attempted map to local drive that was in use */
|
||||
#define NO_DRIVES_AVAILABLE 0x884B /* 75 - Attempted map to next available drive when none were available */
|
||||
#define DEVICE_NOT_REDIRECTED 0x884C /* 76 - The device is not redirected */
|
||||
#define NO_MORE_SFT_ENTRIES 0x884D /* 77 - Maximum number of files was reached */
|
||||
#define UNLOAD_ERROR 0x884E /* 78 - Attempted unload failed */
|
||||
#define IN_USE_ERROR 0x884F /* 79 - Attempted re-use of already in use connection entry */
|
||||
#define TOO_MANY_REP_FRAGS 0x8850 /* 80 - Attempted request with too many reply fragments specified */
|
||||
#define TABLE_FULL 0x8851 /* 81 - Attempted to add a name into the name table after it was full */
|
||||
#ifndef SOCKET_NOT_OPEN
|
||||
#define SOCKET_NOT_OPEN 0x8852 /* 82 - Listen was posted on unopened socket */
|
||||
#endif
|
||||
#define MEM_MGR_ERROR 0x8853 /* 83 - Attempted enhanced memory operation failed */
|
||||
#define SFT3_ERROR 0x8854 /* 84 - An SFT3 switch occured mid-transfer */
|
||||
#define PREFERRED_NOT_FOUND 0x8855 /* 85 - the preferred directory server was not established but another directory server was returned */
|
||||
#define DEVICE_NOT_RECOGNIZED 0x8856 /* 86 - used to determine if the device is not used by VISE so pass it on to the next redirector, if any. */
|
||||
#define BAD_NET_TYPE 0x8857 /* 87 - the network type (Bind/NDS) does not match the server version */
|
||||
#define ERROR_OPENING_FILE 0x8858 /* 88 - generic open failure error, invalid path, access denied, etc.. */
|
||||
#define NO_PREFERRED_SPECIFIED 0x8859 /* 89 - no preferred name specified */
|
||||
#define ERROR_OPENING_SOCKET 0x885A /* 90 - error opening a socket */
|
||||
#define REQUESTER_FAILURE 0x885A /* Client-32 */
|
||||
#define RESOURCE_ACCESS_DENIED 0x885B /* Client-32 */
|
||||
#define SIGNATURE_LEVEL_CONFLICT 0x8861
|
||||
#define NO_LOCK_FOUND 0x8862 /* OS/2 - process lock on conn handle failed, process ID not recognized */
|
||||
#define LOCK_TABLE_FULL 0x8863 /* OS/2 - process lock on conn handle failed, process lock table full */
|
||||
#define INVALID_MATCH_DATA 0x8864
|
||||
#define MATCH_FAILED 0x8865
|
||||
#define NO_MORE_ENTRIES 0x8866
|
||||
#define INSUFFICIENT_RESOURCES 0x8867
|
||||
#define STRING_TRANSLATION 0x8868
|
||||
#define STRING_TRANSLATION_NEEDED 0x8868 /* Client-32 */
|
||||
#define ACCESS_VIOLATION 0x8869
|
||||
#define NOT_AUTHENTICATED 0x886A
|
||||
#define INVALID_LEVEL 0x886B
|
||||
#define RESOURCE_LOCK_ERROR 0x886C
|
||||
#define INVALID_NAME_FORMAT 0x886D
|
||||
#define OBJECT_EXISTS 0x886E
|
||||
#define OBJECT_NOT_FOUND 0x886F
|
||||
#define UNSUPPORTED_TRAN_TYPE 0x8870
|
||||
#define INVALID_STRING_TYPE 0x8871
|
||||
#define INVALID_OWNER 0x8872
|
||||
#define UNSUPPORTED_AUTHENTICATOR 0x8873
|
||||
#define IO_PENDING 0x8874
|
||||
#define INVALID_DRIVE_NUM 0x8875
|
||||
#define SHELL_FAILURE 0x88FF
|
||||
#define VLM_FAILURE 0x88FF
|
||||
|
||||
#define SVC_ALREADY_REGISTERED 0x8880 /* Client-32 */
|
||||
#define SVC_REGISTRY_FULL 0x8881 /* Client-32 */
|
||||
#define SVC_NOT_REGISTERED 0x8882 /* Client-32 */
|
||||
#define OUT_OF_RESOURCES 0x8883 /* Client-32 */
|
||||
#define RESOLVE_SVC_FAILED 0x8884 /* Client-32 */
|
||||
#define CONNECT_FAILED 0x8885 /* Client-32 */
|
||||
#define PROTOCOL_NOT_BOUND 0x8886 /* Client-32 */
|
||||
#define AUTHENTICATION_FAILED 0x8887 /* Client-32 */
|
||||
#define INVALID_AUTHEN_HANDLE 0x8888 /* Client-32 */
|
||||
#define AUTHEN_HANDLE_ALREADY_EXISTS 0x8889 /* Client-32 */
|
||||
|
||||
#define DIFF_OBJECT_ALREADY_AUTHEN 0x8890 /* Client-32 */
|
||||
#define REQUEST_NOT_SERVICEABLE 0x8891 /* Client-32 */
|
||||
#define AUTO_RECONNECT_SO_REBUILD 0x8892 /* Client-32 */
|
||||
#define AUTO_RECONNECT_RETRY_REQUEST 0x8893 /* Client-32 */
|
||||
#define ASYNC_REQUEST_IN_USE 0x8894 /* Client-32 */
|
||||
#define ASYNC_REQUEST_CANCELED 0x8895 /* Client-32 */
|
||||
#define SESS_SVC_ALREADY_REGISTERED 0x8896 /* Client-32 */
|
||||
#define SESS_SVC_NOT_REGISTERED 0x8897 /* Client-32 */
|
||||
#define PREVIOUSLY_AUTHENTICATED 0x8899 /* Client-32 */
|
||||
#define RESOLVE_SVC_PARTIAL 0x889A /* Client-32 */
|
||||
#define NO_DEFAULT_SPECIFIED 0x889B /* Client-32 */
|
||||
#define HOOK_REQUEST_NOT_HANDLED 0x889C /* Client-32 */
|
||||
#define HOOK_REQUEST_BUSY 0x889D /* Client-32 */
|
||||
#define HOOK_REQUEST_QUEUED 0x889D /* Client-32 */
|
||||
#define AUTO_RECONNECT_SO_IGNORE 0x889E /* Client-32 */
|
||||
#define ASYNC_REQUEST_NOT_IN_USE 0x889F /* Client-32 */
|
||||
#define AUTO_RECONNECT_FAILURE 0x88A0 /* Client-32 */
|
||||
#define NET_ERROR_ABORT_APPLICATION 0x88A1 /* Client-32 */
|
||||
#define NET_ERROR_SUSPEND_APPLICATION 0x88A2 /* Client-32 */
|
||||
#define NET_ERROR_ABORTED_PROCESS_GROUP 0x88A3 /* Client-32 */
|
||||
#define NET_ERROR_PASSWORD_HAS_EXPIRED 0x88A5 /* Client-32 */
|
||||
#define NET_ERROR_NETWORK_INACTIVE 0x88A6 /* Client-32 */
|
||||
#define REPLY_TRUNCATED 0x88e6 /* 230 NLM */
|
||||
|
||||
|
||||
/* Server Errors */
|
||||
|
||||
#define ERR_INSUFFICIENT_SPACE 0x8901 /* 001 */
|
||||
#define ERR_NO_MORE_ENTRY 0x8914 /* 020 */
|
||||
#define NLM_INVALID_CONNECTION 0x890a /* 010 */
|
||||
#define ERR_BUFFER_TOO_SMALL 0x8977 /* 119 */
|
||||
#define ERR_VOLUME_FLAG_NOT_SET 0x8978 /* 120 the service requested, not avail. on the selected vol. */
|
||||
#define ERR_NO_ITEMS_FOUND 0x8979 /* 121 */
|
||||
#define ERR_CONN_ALREADY_TEMP 0x897a /* 122 */
|
||||
#define ERR_CONN_ALREADY_LOGGED_IN 0x897b /* 123 */
|
||||
#define ERR_CONN_NOT_AUTHENTICATED 0x897c /* 124 */
|
||||
#define ERR_CONN_NOT_LOGGED_IN 0x897d /* 125 */
|
||||
#define NCP_BOUNDARY_CHECK_FAILED 0x897e /* 126 */
|
||||
#define ERR_LOCK_WAITING 0x897f /* 127 */
|
||||
#define ERR_LOCK_FAIL 0x8980 /* 128 */
|
||||
#define FILE_IN_USE_ERROR 0x8980 /* 128 */
|
||||
#define NO_MORE_FILE_HANDLES 0x8981 /* 129 */
|
||||
#define NO_OPEN_PRIVILEGES 0x8982 /* 130 */
|
||||
#define IO_ERROR_NETWORK_DISK 0x8983 /* 131 */
|
||||
#define ERR_AUDITING_HARD_IO_ERROR 0x8983 /* 131 */
|
||||
#define NO_CREATE_PRIVILEGES 0x8984 /* 132 */
|
||||
#define ERR_AUDITING_NOT_SUPV 0x8984 /* 132 */
|
||||
#define NO_CREATE_DELETE_PRIVILEGES 0x8985 /* 133 */
|
||||
#define CREATE_FILE_EXISTS_READ_ONLY 0x8986 /* 134 */
|
||||
#define WILD_CARDS_IN_CREATE_FILE_NAME 0x8987 /* 135 */
|
||||
#define CREATE_FILENAME_ERROR 0x8987 /* 135 */
|
||||
#define INVALID_FILE_HANDLE 0x8988 /* 136 */
|
||||
#define NO_SEARCH_PRIVILEGES 0x8989 /* 137 */
|
||||
#define NO_DELETE_PRIVILEGES 0x898A /* 138 */
|
||||
#define NO_RENAME_PRIVILEGES 0x898B /* 139 */
|
||||
#define NO_MODIFY_PRIVILEGES 0x898C /* 140 */
|
||||
#define SOME_FILES_AFFECTED_IN_USE 0x898D /* 141 */
|
||||
#define NO_FILES_AFFECTED_IN_USE 0x898E /* 142 */
|
||||
#define SOME_FILES_AFFECTED_READ_ONLY 0x898F /* 143 */
|
||||
#define NO_FILES_AFFECTED_READ_ONLY 0x8990 /* 144 */
|
||||
#define SOME_FILES_RENAMED_NAME_EXISTS 0x8991 /* 145 */
|
||||
#define NO_FILES_RENAMED_NAME_EXISTS 0x8992 /* 146 */
|
||||
#define NO_READ_PRIVILEGES 0x8993 /* 147 */
|
||||
#define NO_WRITE_PRIVILEGES_OR_READONLY 0x8994 /* 148 */
|
||||
#define FILE_DETACHED 0x8995 /* 149 */
|
||||
#define SERVER_OUT_OF_MEMORY 0x8996 /* 150 */
|
||||
#define ERR_TARGET_NOT_A_SUBDIRECTORY 0x8996 /* 150 can be changed later (note written by server people). */
|
||||
#define NO_DISK_SPACE_FOR_SPOOL_FILE 0x8997 /* 151 */
|
||||
#define ERR_AUDITING_NOT_ENABLED 0x8997 /* 151 */
|
||||
#define VOLUME_DOES_NOT_EXIST 0x8998 /* 152 */
|
||||
#define DIRECTORY_FULL 0x8999 /* 153 */
|
||||
#define RENAMING_ACROSS_VOLUMES 0x899A /* 154 */
|
||||
#define BAD_DIRECTORY_HANDLE 0x899B /* 155 */
|
||||
#define INVALID_PATH 0x899C /* 156 */
|
||||
#define NO_MORE_TRUSTEES 0x899C /* 156 */
|
||||
#define NO_MORE_DIRECTORY_HANDLES 0x899D /* 157 */
|
||||
#define INVALID_FILENAME 0x899E /* 158 */
|
||||
#define DIRECTORY_ACTIVE 0x899F /* 159 */
|
||||
#define DIRECTORY_NOT_EMPTY 0x89A0 /* 160 */
|
||||
#define DIRECTORY_IO_ERROR 0x89A1 /* 161 */
|
||||
#define READ_FILE_WITH_RECORD_LOCKED 0x89A2 /* 162 */
|
||||
#define ERR_TRANSACTION_RESTARTED 0x89A3 /* 163 */
|
||||
#define ERR_RENAME_DIR_INVALID 0x89A4 /* 164 */
|
||||
#define ERR_INVALID_OPENCREATE_MODE 0x89A5 /* 165 */
|
||||
#define ERR_ALREADY_IN_USE 0x89A6 /* 166 */
|
||||
#define ERR_AUDITING_ACTIVE 0x89A6 /* 166 */
|
||||
#define ERR_INVALID_RESOURCE_TAG 0x89A7 /* 167 */
|
||||
#define ERR_ACCESS_DENIED 0x89A8 /* 168 */
|
||||
#define ERR_AUDITING_NO_RIGHTS 0x89A8 /* 168 */
|
||||
#define INVALID_DATA_STREAM 0x89BE /* 190 */
|
||||
#define INVALID_NAME_SPACE 0x89BF /* 191 */
|
||||
#define NO_ACCOUNTING_PRIVILEGES 0x89C0 /* 192 */
|
||||
#define LOGIN_DENIED_NO_ACCOUNT_BALANCE 0x89C1 /* 193 */
|
||||
#define LOGIN_DENIED_NO_CREDIT 0x89C2 /* 194 */
|
||||
#define ERR_AUDITING_RECORD_SIZE 0x89C2 /* 194 */
|
||||
#define ERR_TOO_MANY_HOLDS 0x89C3 /* 195 */
|
||||
#define ACCOUNTING_DISABLED 0x89C4 /* 196 */
|
||||
#define INTRUDER_DETECTION_LOCK 0x89C5 /* 197 */
|
||||
#define NO_CONSOLE_OPERATOR 0x89C6 /* 198 */
|
||||
#define NO_CONSOLE_PRIVILEGES 0x89C6 /* 198 */
|
||||
#define ERR_Q_IO_FAILURE 0x89D0 /* 208 */
|
||||
#define ERR_NO_QUEUE 0x89D1 /* 209 */
|
||||
#define ERR_NO_Q_SERVER 0x89D2 /* 210 */
|
||||
#define ERR_NO_Q_RIGHTS 0x89D3 /* 211 */
|
||||
#define ERR_Q_FULL 0x89D4 /* 212 */
|
||||
#define ERR_NO_Q_JOB 0x89D5 /* 213 */
|
||||
#define ERR_NO_Q_JOB_RIGHTS 0x89D6 /* 214 */
|
||||
#define ERR_Q_IN_SERVICE 0x89D7 /* 215 */
|
||||
#define PASSWORD_NOT_UNIQUE 0x89D7 /* 215 */
|
||||
#define ERR_Q_NOT_ACTIVE 0x89D8 /* 216 */
|
||||
#define PASSWORD_TOO_SHORT 0x89D8 /* 216 */
|
||||
#define ERR_Q_STN_NOT_SERVER 0x89D9 /* 217 */
|
||||
#define LOGIN_DENIED_NO_CONNECTION 0x89D9 /* 217 */
|
||||
#define ERR_MAXIMUM_LOGINS_EXCEEDED 0x89D9 /* 217 */
|
||||
#define ERR_Q_HALTED 0x89DA /* 218 */
|
||||
#define UNAUTHORIZED_LOGIN_TIME 0x89DA /* 218 */
|
||||
#define UNAUTHORIZED_LOGIN_STATION 0x89DB /* 219 */
|
||||
#define ERR_Q_MAX_SERVERS 0x89DB /* 219 */
|
||||
#define ACCOUNT_DISABLED 0x89DC /* 220 */
|
||||
#define PASSWORD_HAS_EXPIRED_NO_GRACE 0x89DE /* 222 */
|
||||
#define PASSWORD_HAS_EXPIRED 0x89DF /* 223 */
|
||||
#define E_NO_MORE_USERS 0x89E7 /* 231 */
|
||||
#define NOT_ITEM_PROPERTY 0x89E8 /* 232 */
|
||||
#define WRITE_PROPERTY_TO_GROUP 0x89E8 /* 232 */
|
||||
#define MEMBER_ALREADY_EXISTS 0x89E9 /* 233 */
|
||||
#define NO_SUCH_MEMBER 0x89EA /* 234 */
|
||||
#define NOT_GROUP_PROPERTY 0x89EB /* 235 */
|
||||
#define NO_SUCH_SEGMENT 0x89EC /* 236 */
|
||||
#define PROPERTY_ALREADY_EXISTS 0x89ED /* 237 */
|
||||
#define OBJECT_ALREADY_EXISTS 0x89EE /* 238 */
|
||||
#define INVALID_NAME 0x89EF /* 239 */
|
||||
#define WILD_CARD_NOT_ALLOWED 0x89F0 /* 240 */
|
||||
#define INVALID_BINDERY_SECURITY 0x89F1 /* 241 */
|
||||
#define NO_OBJECT_READ_PRIVILEGE 0x89F2 /* 242 */
|
||||
#define NO_OBJECT_RENAME_PRIVILEGE 0x89F3 /* 243 */
|
||||
#define NO_OBJECT_DELETE_PRIVILEGE 0x89F4 /* 244 */
|
||||
#define NO_OBJECT_CREATE_PRIVILEGE 0x89F5 /* 245 */
|
||||
#define NO_PROPERTY_DELETE_PRIVILEGE 0x89F6 /* 246 */
|
||||
#define NO_PROPERTY_CREATE_PRIVILEGE 0x89F7 /* 247 */
|
||||
#define NO_PROPERTY_WRITE_PRIVILEGE 0x89F8 /* 248 */
|
||||
#define NO_FREE_CONNECTION_SLOTS 0x89F9 /* 249 */
|
||||
#define NO_PROPERTY_READ_PRIVILEGE 0x89F9 /* 249 */
|
||||
#define NO_MORE_SERVER_SLOTS 0x89FA /* 250 */
|
||||
#define TEMP_REMAP_ERROR 0x89FA /* 250 */
|
||||
#define INVALID_PARAMETERS 0x89FB /* 251 */
|
||||
#define NO_SUCH_PROPERTY 0x89FB /* 251 */
|
||||
#define ERR_NCP_NOT_SUPPORTED 0x89FB /* 251 */
|
||||
#define INTERNET_PACKET_REQT_CANCELED 0x89FC /* 252 */
|
||||
#define UNKNOWN_FILE_SERVER 0x89FC /* 252 */
|
||||
#define MESSAGE_QUEUE_FULL 0x89FC /* 252 */
|
||||
#define NO_SUCH_OBJECT 0x89FC /* 252 */
|
||||
#define LOCK_COLLISION 0x89FD /* 253 */
|
||||
#define BAD_STATION_NUMBER 0x89FD /* 253 */
|
||||
#define INVALID_PACKET_LENGTH 0x89FD /* 253 */
|
||||
#define UNKNOWN_REQUEST 0x89FD /* 253 */
|
||||
#define BINDERY_LOCKED 0x89FE /* 254 */
|
||||
#define TRUSTEE_NOT_FOUND 0x89FE /* 254 */
|
||||
#define DIRECTORY_LOCKED 0x89FE /* 254 */
|
||||
#define INVALID_SEMAPHORE_NAME_LENGTH 0x89FE /* 254 */
|
||||
#define PACKET_NOT_DELIVERABLE 0x89FE /* 254 */
|
||||
#define SERVER_BINDERY_LOCKED 0x89FE /* 254 */
|
||||
#define SOCKET_TABLE_FULL 0x89FE /* 254 */
|
||||
#define SPOOL_DIRECTORY_ERROR 0x89FE /* 254 */
|
||||
#define SUPERVISOR_HAS_DISABLED_LOGIN 0x89FE /* 254 */
|
||||
#define TIMEOUT_FAILURE 0x89FE /* 254 */
|
||||
#define BAD_PRINTER_ERROR 0x89FF /* 255 */
|
||||
#define BAD_RECORD_OFFSET 0x89FF /* 255 */
|
||||
#define CLOSE_FCB_ERROR 0x89FF /* 255 */
|
||||
#define FILE_EXTENSION_ERROR 0x89FF /* 255 */
|
||||
#define FILE_NAME_ERROR 0x89FF /* 255 */
|
||||
#define HARDWARE_FAILURE 0x89FF /* 255 */
|
||||
#define INVALID_DRIVE_NUMBER 0x89FF /* 255 */
|
||||
#define DOS_INVALID_DRIVE 0x000F /* 255 */
|
||||
#define INVALID_INITIAL_SEMAPHORE_VALUE 0x89FF /* 255 */
|
||||
#define INVALID_SEMAPHORE_HANDLE 0x89FF /* 255 */
|
||||
#define IO_BOUND_ERROR 0x89FF /* 255 */
|
||||
#define NO_FILES_FOUND_ERROR 0x89FF /* 255 */
|
||||
#define NO_RESPONSE_FROM_SERVER 0x89FF /* 255 */
|
||||
#define NO_SUCH_OBJECT_OR_BAD_PASSWORD 0x89FF /* 255 */
|
||||
#define PATH_NOT_LOCATABLE 0x89FF /* 255 */
|
||||
#define QUEUE_FULL_ERROR 0x89FF /* 255 */
|
||||
#define REQUEST_NOT_OUTSTANDING 0x89FF /* 255 */
|
||||
#ifndef SOCKET_ALREADY_OPEN
|
||||
#define SOCKET_ALREADY_OPEN 0x89FF /* 255 */
|
||||
#endif
|
||||
#define LOCK_ERROR 0x89FF /* 255 */
|
||||
#ifndef FAILURE
|
||||
#define FAILURE 0x89FF /* 255 Generic Failure */
|
||||
#endif
|
||||
|
||||
/* #define NOT_SAME_LOCAL_DRIVE 0x89F6 */
|
||||
/* #define TARGET_DRIVE_NOT_LOCAL 0x89F7 */
|
||||
/* #define ALREADY_ATTACHED_TO_SERVER 0x89F8 */ /* 248 */
|
||||
/* #define NOT_ATTACHED_TO_SERVER 0x89F8 */
|
||||
|
||||
/**** Network errors ****/
|
||||
/* Decimal values at end of line are 32768 lower than actual */
|
||||
|
||||
#define NWE_ALREADY_ATTACHED 0x8800 /* 0 - Attach attempted to server with valid, existing connection */
|
||||
#define NWE_CONN_INVALID 0x8801 /* 1 - Request attempted with invalid or non-attached connection handle */
|
||||
#define NWE_DRIVE_IN_USE 0x8802 /* 2 - OS/2 only (NOT USED) */
|
||||
#define NWE_DRIVE_CANNOT_MAP 0x8803 /* 3 - Map drive attempted but unable to add new current directory structure */
|
||||
#define NWE_DRIVE_BAD_PATH 0x8804 /* 4 - Map drive attempted with invalid path specification */
|
||||
#define NWE_NET_RECEIVE 0x8805 /* 5 - Attempt to receive from the selected transport failed */
|
||||
#define NWE_NET_UNKNOWN 0x8806 /* 6 - Network send attempted with an un-specific network error */
|
||||
#define NWE_SERVER_BAD_SLOT 0x8807 /* 7 - Server request attempted with invalid server connection slot */
|
||||
#define NWE_SERVER_NO_SLOTS 0x8808 /* 8 - Attach attempted to server with no connection slots available */
|
||||
#define NWE_NET_SEND 0x8809 /* 9 - Attempt to send on the selected transport failed */
|
||||
#define NWE_SERVER_NO_ROUTE 0x880A /* 10 - Attempted to find route to server where no route exists */
|
||||
#define NWE_BAD_LOCAL_TARGET 0x880B /* 11 - OS/2 only */
|
||||
#define NWE_REQ_TOO_MANY_REQ_FRAGS 0x880C /* 12 - Attempted request with too many request fragments specified */
|
||||
#define NWE_CONN_LIST_OVERFLOW 0x880D /* 13 */
|
||||
#define NWE_BUFFER_OVERFLOW 0x880E /* 14 - Attempt to receive more data than the reply buffer had room for */
|
||||
#define NWE_SERVER_NO_CONN 0x880F /* 15 - Attempt to get connection for a server not connected */
|
||||
#define NWE_NO_ROUTER_FOUND 0x8810 /* 16 - OS/2 only */
|
||||
#define NWE_FUNCTION_INVALID 0x8811 /* 17 - Attempted function call to non- existent or illegal function */
|
||||
#define NWE_SCAN_COMPLETE 0x8812
|
||||
#define NWE_UNSUPPORTED_NAME_FORMAT_TYP 0x8813
|
||||
#define NWE_HANDLE_ALREADY_LICENSED 0x8814
|
||||
#define NWE_HANDLE_ALREADY_UNLICENSED 0x8815
|
||||
#define NWE_INVALID_NCP_PACKET_LENGTH 0x8816
|
||||
#define NWE_SETTING_UP_TIMEOUT 0x8817
|
||||
#define NWE_SETTING_SIGNALS 0x8818
|
||||
#define NWE_SERVER_CONNECTION_LOST 0x8819
|
||||
#define NWE_OUT_OF_HEAP_SPACE 0x881A
|
||||
#define NWE_INVALID_SERVICE_REQUEST 0x881B
|
||||
#define NWE_INVALID_TASK_NUMBER 0x881C
|
||||
#define NWE_INVALID_MESSAGE_LENGTH 0x881D
|
||||
#define NWE_EA_SCAN_DONE 0x881E
|
||||
#define NWE_BAD_CONNECTION_NUMBER 0x881F
|
||||
#define NWE_MULT_TREES_NOT_SUPPORTED 0x8820 /* 32 - Attempt to open a connection to a DS tree other than the default tree */
|
||||
#define NWE_CONN_NOT_SAME 0x8830 /* 48 - Internal server request attempted across different server connections */
|
||||
#define NWE_CONN_PRIMARY_NOT_SET 0x8831 /* 49 - Attempt to retrieve default connection with no primary connection set */
|
||||
#define NWE_PRN_CAPTURE_NOT_IN_PROGRESS 0x8832 /* 50 - Capture information requested on port with no capture in progress */
|
||||
#define NWE_BUFFER_INVALID_LEN 0x8833 /* 51 - Used to indicate length which caller requested on a GetDNC or SetDNC was too large */
|
||||
#define NWE_USER_NO_NAME 0x8834 /* 52 */
|
||||
#define NWE_PRN_NO_LOCAL_SPOOLER 0x8835 /* 53 - Capture requested without having the local print spooler installed */
|
||||
#define NWE_PARAM_INVALID 0x8836 /* 54 - Attempted function with an invalid function parameter specified */
|
||||
#define NWE_CFG_OPEN_FAILED 0x8837 /* 55 - OS/2 only */
|
||||
#define NWE_CFG_NO_FILE 0x8838 /* 56 - OS/2 only */
|
||||
#define NWE_CFG_READ_FAILED 0x8839 /* 57 - OS/2 only */
|
||||
#define NWE_CFG_LINE_TOO_LONG 0x883A /* 58 - OS/2 only */
|
||||
#define NWE_CFG_LINES_IGNORED 0x883B /* 59 - OS/2 only */
|
||||
#define NWE_RESOURCE_NOT_OWNED 0x883C /* 60 - Attempted request made with a parameter using foriegn resource */
|
||||
#define NWE_DAEMON_INSTALLED 0x883D /* 61 - OS/2 only */
|
||||
#define NWE_PRN_SPOOLER_INSTALLED 0x883E /* 62 - Attempted load of print spooler with print spooler already installed */
|
||||
#define NWE_CONN_TABLE_FULL 0x883F /* 63 - Attempted to allocate a connection handle with no more local connection table entries */
|
||||
#define NWE_CFG_SECTION_NOT_FOUND 0x8840 /* 64 - OS/2 only */
|
||||
#define NWE_TRAN_INVALID_TYPE 0x8841 /* 65 - Attempted function on a connection with an invalid transport selected */
|
||||
#define NWE_TDS_TAG_IN_USE 0x8842 /* 66 - OS/2 only */
|
||||
#define NWE_TDS_OUT_OF_MEMORY 0x8843 /* 67 - OS/2 only */
|
||||
#define NWE_TDS_INVALID_TAG 0x8844 /* 68 - Attempted TDS function with invalid tag */
|
||||
#define NWE_TDS_WRITE_TRUNCATED 0x8845 /* 69 - Attempted TDS write with buffer that exceeded buffer */
|
||||
#define NWE_DS_NO_CONN 0x8846 /* 70 */
|
||||
#define NWE_SERVICE_BUSY 0x8846 /* 70 - Attempted request made to partially asynchronous function in busy state */
|
||||
#define NWE_SERVER_NOT_FOUND 0x8847 /* 71 - Attempted connect failed to find any servers responding */
|
||||
#define NWE_VLM_INVALID 0x8848 /* 72 - Attempted function call to non-existant or not-loaded overlay */
|
||||
#define NWE_DRIVE_ALREADY_MAPPED 0x8849 /* 73 - Attempted map to network drive that was already mapped */
|
||||
#define NWE_DRIVE_LOCAL_IN_USE 0x884A /* 74 - Attempted map to local drive that was in use */
|
||||
#define NWE_DRIVE_NONE_AVAILABLE 0x884B /* 75 - Attempted map to next available drive when none were available */
|
||||
#define NWE_DEVICE_NOT_REDIRECTED 0x884C /* 76 - The device is not redirected */
|
||||
#define NWE_FILE_MAX_REACHED 0x884D /* 77 - Maximum number of files was reached */
|
||||
#define NWE_UNLOAD_FAILED 0x884E /* 78 - Attempted unload failed */
|
||||
#define NWE_CONN_IN_USE 0x884F /* 79 - Attempted re-use of already in use connection entry */
|
||||
#define NWE_REQ_TOO_MANY_REP_FRAGS 0x8850 /* 80 - Attempted request with too many reply fragments specified */
|
||||
#define NWE_NAME_TABLE_FULL 0x8851 /* 81 - Attempted to add a name into the name table after it was full */
|
||||
#define NWE_SOCKET_NOT_OPEN 0x8852 /* 82 - Listen was posted on unopened socket */
|
||||
#define NWE_MEMORY_MGR_ERROR 0x8853 /* 83 - Attempted enhanced memory operation failed */
|
||||
#define NWE_SFT3_ERROR 0x8854 /* 84 - An SFT3 switch occured mid-transfer */
|
||||
#define NWE_DS_PREFERRED_NOT_FOUND 0x8855 /* 85 - the preferred directory server was not established but another directory server was returned */
|
||||
#define NWE_DEVICE_NOT_RECOGNIZED 0x8856 /* 86 - used to determine if the device is not used by VISE so pass it on to the next redirector, if any. */
|
||||
#define NWE_NET_INVALID_TYPE 0x8857 /* 87 - the network type (Bind/NDS) does not match the server version */
|
||||
#define NWE_FILE_OPEN_FAILED 0x8858 /* 88 - generic open failure error, invalid path, access denied, etc.. */
|
||||
#define NWE_DS_PREFERRED_NOT_SPECIFIED 0x8859 /* 89 - no preferred name specified */
|
||||
#define NWE_SOCKET_OPEN_FAILED 0x885A /* 90 - error opening a socket */
|
||||
#define NWE_SIGNATURE_LEVEL_CONFLICT 0x8861
|
||||
#define NWE_NO_LOCK_FOUND 0x8862 /* OS/2 - process lock on conn handle failed, process ID not recognized */
|
||||
#define NWE_LOCK_TABLE_FULL 0x8863 /* OS/2 - process lock on conn handle failed, process lock table full */
|
||||
#define NWE_INVALID_MATCH_DATA 0x8864
|
||||
#define NWE_MATCH_FAILED 0x8865
|
||||
#define NWE_NO_MORE_ENTRIES 0x8866
|
||||
#define NWE_INSUFFICIENT_RESOURCES 0x8867
|
||||
#define NWE_STRING_TRANSLATION 0x8868
|
||||
#define NWE_ACCESS_VIOLATION 0x8869
|
||||
#define NWE_NOT_AUTHENTICATED 0x886A
|
||||
#define NWE_INVALID_LEVEL 0x886B
|
||||
#define NWE_RESOURCE_LOCK 0x886C
|
||||
#define NWE_INVALID_NAME_FORMAT 0x886D
|
||||
#define NWE_OBJECT_EXISTS 0x886E
|
||||
#define NWE_OBJECT_NOT_FOUND 0x886F
|
||||
#define NWE_UNSUPPORTED_TRAN_TYPE 0x8870
|
||||
#define NWE_INVALID_STRING_TYPE 0x8871
|
||||
#define NWE_INVALID_OWNER 0x8872
|
||||
#define NWE_UNSUPPORTED_AUTHENTICATOR 0x8873
|
||||
#define NWE_IO_PENDING 0x8874
|
||||
#define NWE_INVALID_DRIVE_NUMBER 0x8875
|
||||
#define NWE_REPLY_TRUNCATED 0x88e6 /* 230 NLM */
|
||||
#define NWE_REQUESTER_FAILURE 0x88FF
|
||||
|
||||
/* Server Errors */
|
||||
|
||||
#define NWE_INSUFFICIENT_SPACE 0x8901 /* 001 */
|
||||
#define NWE_BUFFER_TOO_SMALL 0x8977 /* 119 */
|
||||
#define NWE_VOL_FLAG_NOT_SET 0x8978 /* 120 the service requested, not avail. on the selected vol. */
|
||||
#define NWE_NO_ITEMS_FOUND 0x8979 /* 121 */
|
||||
#define NWE_CONN_ALREADY_TEMP 0x897a /* 122 */
|
||||
#define NWE_CONN_ALREADY_LOGGED_IN 0x897b /* 123 */
|
||||
#define NWE_CONN_NOT_AUTHENTICATED 0x897c /* 124 */
|
||||
#define NWE_CONN_NOT_LOGGED_IN 0x897d /* 125 */
|
||||
#define NWE_NCP_BOUNDARY_CHECK_FAILED 0x897e /* 126 */
|
||||
#define NWE_LOCK_WAITING 0x897f /* 127 */
|
||||
#define NWE_LOCK_FAIL 0x8980 /* 128 */
|
||||
#define NWE_FILE_IN_USE 0x8980 /* 128 */
|
||||
#define NWE_FILE_NO_HANDLES 0x8981 /* 129 */
|
||||
#define NWE_FILE_NO_OPEN_PRIV 0x8982 /* 130 */
|
||||
#define NWE_DISK_IO_ERROR 0x8983 /* 131 */
|
||||
#define NWE_AUDITING_HARD_IO_ERROR 0x8983 /* 131 */
|
||||
#define NWE_FILE_NO_CREATE_PRIV 0x8984 /* 132 */
|
||||
#define NWE_AUDITING_NOT_SUPV 0x8984 /* 132 */
|
||||
#define NWE_FILE_NO_CREATE_DEL_PRIV 0x8985 /* 133 */
|
||||
#define NWE_FILE_EXISTS_READ_ONLY 0x8986 /* 134 */
|
||||
#define NWE_FILE_WILD_CARDS_IN_NAME 0x8987 /* 135 */
|
||||
#define NWE_FILE_INVALID_HANDLE 0x8988 /* 136 */
|
||||
#define NWE_FILE_NO_SRCH_PRIV 0x8989 /* 137 */
|
||||
#define NWE_FILE_NO_DEL_PRIV 0x898A /* 138 */
|
||||
#define NWE_FILE_NO_RENAME_PRIV 0x898B /* 139 */
|
||||
#define NWE_FILE_NO_MOD_PRIV 0x898C /* 140 */
|
||||
#define NWE_FILE_SOME_IN_USE 0x898D /* 141 */
|
||||
#define NWE_FILE_NONE_IN_USE 0x898E /* 142 */
|
||||
#define NWE_FILE_SOME_READ_ONLY 0x898F /* 143 */
|
||||
#define NWE_FILE_NONE_READ_ONLY 0x8990 /* 144 */
|
||||
#define NWE_FILE_SOME_RENAMED_EXIST 0x8991 /* 145 */
|
||||
#define NWE_FILE_NONE_RENAMED_EXIST 0x8992 /* 146 */
|
||||
#define NWE_FILE_NO_READ_PRIV 0x8993 /* 147 */
|
||||
#define NWE_FILE_NO_WRITE_PRIV 0x8994 /* 148 */
|
||||
#define NWE_FILE_READ_ONLY 0x8994 /* 148 */
|
||||
#define NWE_FILE_DETACHED 0x8995 /* 149 */
|
||||
#define NWE_SERVER_OUT_OF_MEMORY 0x8996 /* 150 */
|
||||
#define NWE_DIR_TARGET_INVALID 0x8996 /* 150 */
|
||||
#define NWE_DISK_NO_SPOOL_SPACE 0x8997 /* 151 */
|
||||
#define NWE_AUDITING_NOT_ENABLED 0x8997 /* 151 */
|
||||
#define NWE_VOL_INVALID 0x8998 /* 152 */
|
||||
#define NWE_DIR_FULL 0x8999 /* 153 */
|
||||
#define NWE_VOL_RENAMING_ACROSS 0x899A /* 154 */
|
||||
#define NWE_DIRHANDLE_INVALID 0x899B /* 155 */
|
||||
#define NWE_PATH_INVALID 0x899C /* 156 */
|
||||
#define NWE_TRUSTEES_NO_MORE 0x899C /* 156 */
|
||||
#define NWE_DIRHANDLE_NO_MORE 0x899D /* 157 */
|
||||
#define NWE_FILE_NAME_INVALID 0x899E /* 158 */
|
||||
#define NWE_DIR_ACTIVE 0x899F /* 159 */
|
||||
#define NWE_DIR_NOT_EMPTY 0x89A0 /* 160 */
|
||||
#define NWE_DIR_IO_ERROR 0x89A1 /* 161 */
|
||||
#define NWE_FILE_IO_LOCKED 0x89A2 /* 162 */
|
||||
#define NWE_TTS_RANSACTION_RESTARTED 0x89A3 /* 163 */
|
||||
#define NWE_TTS_TRANSACTION_RESTARTED 0x89A3 /* 163 */
|
||||
#define NWE_DIR_RENAME_INVALID 0x89A4 /* 164 */
|
||||
#define NWE_FILE_OPENCREAT_MODE_INVALID 0x89A5 /* 165 */
|
||||
#define NWE_ALREADY_IN_USE 0x89A6 /* 166 */
|
||||
#define NWE_AUDITING_ACTIVE 0x89A6 /* 166 */
|
||||
#define NWE_RESOURCE_TAG_INVALID 0x89A7 /* 167 */
|
||||
#define NWE_ACCESS_DENIED 0x89A8 /* 168 */
|
||||
#define NWE_AUDITING_NO_RIGHTS 0x89A8 /* 168 */
|
||||
#define NWE_DATA_STREAM_INVALID 0x89BE /* 190 */
|
||||
#define NWE_NAME_SPACE_INVALID 0x89BF /* 191 */
|
||||
#define NWE_ACCTING_NO_PRIV 0x89C0 /* 192 */
|
||||
#define NWE_ACCTING_NO_BALANCE 0x89C1 /* 193 */
|
||||
#define NWE_ACCTING_NO_CREDIT 0x89C2 /* 194 */
|
||||
#define NWE_AUDITING_RECORD_SIZE 0x89C2 /* 194 */
|
||||
#define NWE_ACCTING_TOO_MANY_HOLDS 0x89C3 /* 195 */
|
||||
#define NWE_ACCTING_DISABLED 0x89C4 /* 196 */
|
||||
#define NWE_LOGIN_LOCKOUT 0x89C5 /* 197 */
|
||||
#define NWE_CONSOLE_NO_PRIV 0x89C6 /* 198 */
|
||||
#define NWE_Q_IO_FAILURE 0x89D0 /* 208 */
|
||||
#define NWE_Q_NONE 0x89D1 /* 209 */
|
||||
#define NWE_Q_NO_SERVER 0x89D2 /* 210 */
|
||||
#define NWE_Q_NO_RIGHTS 0x89D3 /* 211 */
|
||||
#define NWE_Q_FULL 0x89D4 /* 212 */
|
||||
#define NWE_Q_NO_JOB 0x89D5 /* 213 */
|
||||
#define NWE_Q_NO_JOB_RIGHTS 0x89D6 /* 214 */
|
||||
#define NWE_PASSWORD_UNENCRYPTED 0x89D6 /* 214 */
|
||||
#define NWE_Q_IN_SERVICE 0x89D7 /* 215 */
|
||||
#define NWE_PASSWORD_NOT_UNIQUE 0x89D7 /* 215 */
|
||||
#define NWE_Q_NOT_ACTIVE 0x89D8 /* 216 */
|
||||
#define NWE_PASSWORD_TOO_SHORT 0x89D8 /* 216 */
|
||||
#define NWE_Q_STN_NOT_SERVER 0x89D9 /* 217 */
|
||||
#define NWE_LOGIN_NO_CONN 0x89D9 /* 217 */
|
||||
#define NWE_LOGIN_MAX_EXCEEDED 0x89D9 /* 217 */
|
||||
#define NWE_Q_HALTED 0x89DA /* 218 */
|
||||
#define NWE_LOGIN_UNAUTHORIZED_TIME 0x89DA /* 218 */
|
||||
#define NWE_LOGIN_UNAUTHORIZED_STATION 0x89DB /* 219 */
|
||||
#define NWE_Q_MAX_SERVERS 0x89DB /* 219 */
|
||||
#define NWE_ACCT_DISABLED 0x89DC /* 220 */
|
||||
#define NWE_PASSWORD_INVALID 0x89DE /* 222 */
|
||||
#define NWE_PASSWORD_EXPIRED 0x89DF /* 223 */
|
||||
#define NWE_LOGIN_NO_CONN_AVAIL 0x89E0 /* 224 */
|
||||
#define NWE_E_NO_MORE_USERS 0x89E7 /* 231 */
|
||||
#define NWE_BIND_NOT_ITEM_PROP 0x89E8 /* 232 */
|
||||
#define NWE_BIND_WRITE_TO_GROUP_PROP 0x89E8 /* 232 */
|
||||
#define NWE_BIND_MEMBER_ALREADY_EXISTS 0x89E9 /* 233 */
|
||||
#define NWE_BIND_NO_SUCH_MEMBER 0x89EA /* 234 */
|
||||
#define NWE_BIND_NOT_GROUP_PROP 0x89EB /* 235 */
|
||||
#define NWE_BIND_NO_SUCH_SEGMENT 0x89EC /* 236 */
|
||||
#define NWE_BIND_PROP_ALREADY_EXISTS 0x89ED /* 237 */
|
||||
#define NWE_BIND_OBJ_ALREADY_EXISTS 0x89EE /* 238 */
|
||||
#define NWE_BIND_NAME_INVALID 0x89EF /* 239 */
|
||||
#define NWE_BIND_WILDCARD_INVALID 0x89F0 /* 240 */
|
||||
#define NWE_BIND_SECURITY_INVALID 0x89F1 /* 241 */
|
||||
#define NWE_BIND_OBJ_NO_READ_PRIV 0x89F2 /* 242 */
|
||||
#define NWE_BIND_OBJ_NO_RENAME_PRIV 0x89F3 /* 243 */
|
||||
#define NWE_BIND_OBJ_NO_DELETE_PRIV 0x89F4 /* 244 */
|
||||
#define NWE_BIND_OBJ_NO_CREATE_PRIV 0x89F5 /* 245 */
|
||||
#define NWE_BIND_PROP_NO_DELETE_PRIV 0x89F6 /* 246 */
|
||||
#define NWE_BIND_PROP_NO_CREATE_PRIV 0x89F7 /* 247 */
|
||||
#define NWE_BIND_PROP_NO_WRITE_PRIV 0x89F8 /* 248 */
|
||||
#define NWE_BIND_PROP_NO_READ_PRIV 0x89F9 /* 249 */
|
||||
#define NWE_NO_FREE_CONN_SLOTS 0x89F9 /* 249 */
|
||||
#define NWE_NO_MORE_SERVER_SLOTS 0x89FA /* 250 */
|
||||
#define NWE_TEMP_REMAP_ERROR 0x89FA /* 250 */
|
||||
#define NWE_PARAMETERS_INVALID 0x89FB /* 251 */
|
||||
#define NWE_BIND_NO_SUCH_PROP 0x89FB /* 251 */
|
||||
#define NWE_NCP_NOT_SUPPORTED 0x89FB /* 251 */
|
||||
#define NWE_INET_PACKET_REQ_CANCELED 0x89FC /* 252 */
|
||||
#define NWE_SERVER_UNKNOWN 0x89FC /* 252 */
|
||||
#define NWE_MSG_Q_FULL 0x89FC /* 252 */
|
||||
#define NWE_BIND_NO_SUCH_OBJ 0x89FC /* 252 */
|
||||
#define NWE_LOCK_COLLISION 0x89FD /* 253 */
|
||||
#define NWE_CONN_NUM_INVALID 0x89FD /* 253 */
|
||||
#define NWE_PACKET_LEN_INVALID 0x89FD /* 253 */
|
||||
#define NWE_UNKNOWN_REQ 0x89FD /* 253 */
|
||||
#define NWE_BIND_LOCKED 0x89FE /* 254 */
|
||||
#define NWE_TRUSTEE_NOT_FOUND 0x89FE /* 254 */
|
||||
#define NWE_DIR_LOCKED 0x89FE /* 254 */
|
||||
#define NWE_SEM_INVALID_NAME_LEN 0x89FE /* 254 */
|
||||
#define NWE_PACKET_NOT_DELIVERABLE 0x89FE /* 254 */
|
||||
#define NWE_SOCKET_TABLE_FULL 0x89FE /* 254 */
|
||||
#define NWE_SPOOL_DIR_ERROR 0x89FE /* 254 */
|
||||
#define NWE_LOGIN_DISABLED_BY_SUPER 0x89FE /* 254 */
|
||||
#define NWE_TIMEOUT_FAILURE 0x89FE /* 254 */
|
||||
#define NWE_FILE_EXT 0x89FF /* 255 */
|
||||
#define NWE_FILE_NAME 0x89FF /* 255 */
|
||||
#define NWE_HARD_FAILURE 0x89FF /* 255 */
|
||||
#define NWE_FCB_CLOSE 0x89FF /* 255 */
|
||||
#define NWE_IO_BOUND 0x89FF /* 255 */
|
||||
#define NWE_BAD_SPOOL_PRINTER 0x89FF /* 255 */
|
||||
#define NWE_BAD_RECORD_OFFSET 0x89FF /* 255 */
|
||||
#define NWE_DRIVE_INVALID_NUM 0x89FF /* 255 */
|
||||
#define NWE_SEM_INVALID_INIT_VAL 0x89FF /* 255 */
|
||||
#define NWE_SEM_INVALID_HANDLE 0x89FF /* 255 */
|
||||
#define NWE_NO_FILES_FOUND_ERROR 0x89FF /* 255 */
|
||||
#define NWE_NO_RESPONSE_FROM_SERVER 0x89FF /* 255 */
|
||||
#define NWE_NO_OBJ_OR_BAD_PASSWORD 0x89FF /* 255 */
|
||||
#define NWE_PATH_NOT_LOCATABLE 0x89FF /* 255 */
|
||||
#define NWE_Q_FULL_ERROR 0x89FF /* 255 */
|
||||
#define NWE_REQ_NOT_OUTSTANDING 0x89FF /* 255 */
|
||||
#define NWE_SOCKET_ALREADY_OPEN 0x89FF /* 255 */
|
||||
#define NWE_LOCK_ERROR 0x89FF /* 255 */
|
||||
#define NWE_FAILURE 0x89FF /* 255 Generic Failure */
|
||||
|
||||
#endif /* !_NWERROR_H_ */
|
@ -1,9 +0,0 @@
|
||||
# $FreeBSD$
|
||||
|
||||
PROG= ncplist
|
||||
NO_WCAST_ALIGN=
|
||||
|
||||
DPADD= ${LIBNCP} ${LIBIPX}
|
||||
LDADD= -lncp -lipx
|
||||
|
||||
.include <bsd.prog.mk>
|
@ -1,88 +0,0 @@
|
||||
.\" $FreeBSD$
|
||||
.Dd January 21, 2010
|
||||
.Dt NCPLIST 1
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm ncplist
|
||||
.Nd "display various information about ncplib and NetWare servers"
|
||||
.Sh SYNOPSIS
|
||||
.Nm
|
||||
.Ar command
|
||||
.Op Ar arguments
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Nm
|
||||
utility displays the state of ncplib and NetWare servers.
|
||||
The first argument
|
||||
is a one-letter
|
||||
.Ar command
|
||||
that may be followed by
|
||||
.Ar arguments .
|
||||
.Pp
|
||||
The commands are:
|
||||
.Bl -tag -width indent
|
||||
.It Ic b Ar server type Op Ar pattern
|
||||
Lists bindery objects of
|
||||
.Ar type
|
||||
on a specified
|
||||
.Ar server .
|
||||
The
|
||||
.Ar type
|
||||
argument
|
||||
can be one of the following:
|
||||
.Pp
|
||||
.Bl -tag -width ".Cm pserver" -offset indent -compact
|
||||
.It Em Type
|
||||
.Em Meaning
|
||||
.It Cm user
|
||||
bindery users
|
||||
.It Cm group
|
||||
bindery groups
|
||||
.It Cm pserver
|
||||
bindery print servers
|
||||
.It Cm tree
|
||||
tree name hosted by given server
|
||||
.El
|
||||
.Pp
|
||||
Note that if you are not logged in to the specified server,
|
||||
the list may be incomplete or empty.
|
||||
.It Ic c
|
||||
List active NCP connections on the local machine.
|
||||
.It Ic s Op Ar server
|
||||
Display
|
||||
.Tn NetWare
|
||||
servers known to a given
|
||||
.Ar server .
|
||||
If no server is specified, the nearest server will be used.
|
||||
.It Ic u Ar server
|
||||
Displays a list of users logged in on a given
|
||||
.Ar server .
|
||||
If you are not logged in to the specified server,
|
||||
the list will be empty.
|
||||
.It Ic q Ar server Op Ar pattern
|
||||
Displays bindery queues on a given
|
||||
.Ar server .
|
||||
.It Ic v Ar server
|
||||
Displays mounted volumes on a given
|
||||
.Ar server .
|
||||
.El
|
||||
.Sh IMPLEMENTATION NOTES
|
||||
This utility is provided mostly for educational purposes.
|
||||
.Sh FILES
|
||||
.Bl -tag -width /var/log/utx.log -compact
|
||||
.It Pa ~/.nwfsrc
|
||||
keeps description for each connection.
|
||||
See
|
||||
.Pa /usr/share/examples/nwclient/dot.nwfsrc
|
||||
for details.
|
||||
.El
|
||||
.Sh HISTORY
|
||||
The
|
||||
.Nm
|
||||
utility first appeared in
|
||||
.Fx 4.0 .
|
||||
.Sh AUTHORS
|
||||
.An Boris Popov Aq bp@butya.kz ,
|
||||
.Aq rbp@chat.ru
|
||||
.Sh BUGS
|
||||
Please report any bugs to the author.
|
@ -1,474 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 1999, Boris Popov
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by Boris Popov.
|
||||
* 4. Neither the name of the author nor the names of any co-contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#include <grp.h>
|
||||
#include <pwd.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <netncp/ncp_lib.h>
|
||||
|
||||
extern char *__progname;
|
||||
|
||||
static struct ncp_conn_stat conndesc;
|
||||
|
||||
static void help(void);
|
||||
static void show_connlist(void);
|
||||
static void show_serverlist(char *server);
|
||||
static void show_userlist(char *server);
|
||||
static void list_volumes(char *server);
|
||||
static void str_trim_right(char *s, char c);
|
||||
|
||||
|
||||
static int
|
||||
ncp_get_connid(char *server, int justattach)
|
||||
{
|
||||
int connid, error;
|
||||
struct ncp_conn_loginfo li;
|
||||
|
||||
connid = ncp_conn_find(server, NULL);
|
||||
if (connid > 0) {
|
||||
ncp_conn_getinfo(connid, &conndesc);
|
||||
return connid;
|
||||
}
|
||||
if (!justattach) {
|
||||
if (connid == -1) {
|
||||
printf("You are not attached to server %s\n",server);
|
||||
return -1;
|
||||
}
|
||||
printf("You are not attached to any server\n");
|
||||
return -1;
|
||||
}
|
||||
ncp_li_init(&li, 0, NULL);
|
||||
if (server) {
|
||||
ncp_li_setserver(&li, server);
|
||||
error = ncp_find_fileserver(&li, AF_IPX, NULL);
|
||||
if (error) {
|
||||
printf("Could not find server %s\n", li.server);
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
error = ncp_find_fileserver(&li, AF_IPX, NULL);
|
||||
if (error) {
|
||||
printf("Can't find any file server\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
error = ncp_connect(&li, &connid);
|
||||
if (error) {
|
||||
printf("Can't attach to a nearest server\n");
|
||||
return -1;
|
||||
}
|
||||
ncp_conn_getinfo(connid, &conndesc);
|
||||
return connid;
|
||||
}
|
||||
|
||||
static struct ncp_bitname conn_statenames [] = {
|
||||
{NCPFL_INVALID, "invalid"},
|
||||
{NCPFL_LOGGED, "active"},
|
||||
{NCPFL_PERMANENT, "permanent"},
|
||||
{NCPFL_PRIMARY, "primary"},
|
||||
{0, NULL}
|
||||
};
|
||||
|
||||
static void
|
||||
str_trim_right(char *s, char c)
|
||||
{
|
||||
int len;
|
||||
|
||||
for (len = strlen(s) - 1; len > 0 && s[len] == c; len--)
|
||||
s[len] = '\0';
|
||||
}
|
||||
|
||||
void
|
||||
show_connlist(void)
|
||||
{
|
||||
void *p;
|
||||
int cnt;
|
||||
char buf[200];
|
||||
struct ncp_conn_stat *ncsp;
|
||||
|
||||
printf("Active NCP connections:\n");
|
||||
p = ncp_conn_list();
|
||||
if (p == NULL) {
|
||||
printf("None\n");
|
||||
return;
|
||||
}
|
||||
printf(" refid server:user(connid), owner:group(mode), refs, <state>\n");
|
||||
cnt = *(int*)p;
|
||||
ncsp = (struct ncp_conn_stat*)(((int*)p)+1);
|
||||
while (cnt--) {
|
||||
printf("%6d %s:%s(%d), %s:%s(%o), %d, %s",
|
||||
ncsp->connRef, ncsp->li.server,ncsp->user,ncsp->connid,
|
||||
user_from_uid(ncsp->owner, 0),
|
||||
group_from_gid(ncsp->group, 0),
|
||||
ncsp->li.access_mode,
|
||||
ncsp->ref_cnt,
|
||||
ncp_printb(buf, ncsp->flags, conn_statenames));
|
||||
printf("\n");
|
||||
ncsp++;
|
||||
}
|
||||
free(p);
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
void
|
||||
show_serverlist(char *server)
|
||||
{
|
||||
int found = 0, connid;
|
||||
struct ncp_bindery_object obj;
|
||||
const char *pattern = "*";
|
||||
|
||||
connid = ncp_get_connid(server, 1);
|
||||
if (connid < 0)
|
||||
return;
|
||||
printf("Visible servers (from %s):\n", conndesc.li.server);
|
||||
printf("Name Network Node Port\n");
|
||||
printf("----------------------------------------------- -------- ------------ ----\n");
|
||||
obj.object_id = 0xffffffff;
|
||||
|
||||
while (ncp_scan_bindery_object(connid, obj.object_id, NCP_BINDERY_FSERVER,
|
||||
pattern, &obj) == 0) {
|
||||
struct nw_property prop;
|
||||
struct ipx_addr *naddr = (struct ipx_addr *) ∝
|
||||
|
||||
found = 1;
|
||||
printf("%-48s", obj.object_name);
|
||||
|
||||
if (ncp_read_property_value(connid, NCP_BINDERY_FSERVER,
|
||||
obj.object_name, 1, "NET_ADDRESS",
|
||||
&prop) == 0) {
|
||||
ipx_print_addr(naddr);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
printf("No servers found\n");
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
show_userlist(char *server)
|
||||
{
|
||||
int connid, error, i;
|
||||
struct ncp_file_server_info info;
|
||||
struct ncp_bindery_object user;
|
||||
time_t login_time;
|
||||
struct ipx_addr addr;
|
||||
u_int8_t conn_type;
|
||||
|
||||
connid = ncp_get_connid(server, 0);
|
||||
if (connid < 0) return;
|
||||
if (ncp_get_file_server_information(connid, &info) != 0) {
|
||||
perror("Could not get server information");
|
||||
return;
|
||||
}
|
||||
printf("User information for server %s\n",info.ServerName);
|
||||
printf("\n%-6s%-21s%-27s%-12s\n"
|
||||
"---------------------------------------------"
|
||||
"---------------------------------\n",
|
||||
"Conn",
|
||||
"User name",
|
||||
"Station Address",
|
||||
"Login time");
|
||||
for (i = 1; i <= info.MaximumServiceConnections; i++) {
|
||||
char name[49];
|
||||
name[48] = '\0';
|
||||
error = ncp_get_stations_logged_info(connid, i, &user, &login_time);
|
||||
if (error) continue;
|
||||
memset(&addr, 0, sizeof(addr));
|
||||
error = ncp_get_internet_address(connid, i, &addr, &conn_type);
|
||||
if (error) continue;
|
||||
memcpy(name, user.object_name, 48);
|
||||
str_trim_right(name, ' ');
|
||||
printf("%4d: %-20s ", i, name);
|
||||
ipx_print_addr(&addr);
|
||||
printf(" ");
|
||||
printf("%s", ctime(&login_time));
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static void
|
||||
show_queuelist(char *server, char *patt)
|
||||
{
|
||||
struct ncp_bindery_object q;
|
||||
int found = 0, connid;
|
||||
char default_pattern[] = "*";
|
||||
char *pattern = default_pattern;
|
||||
|
||||
connid = ncp_get_connid(server, 1);
|
||||
if (connid < 0) return;
|
||||
if (patt != NULL)
|
||||
pattern = patt;
|
||||
ncp_str_upper(pattern);
|
||||
|
||||
printf("\nServer: %s\n", server);
|
||||
printf("%-52s%-10s\n"
|
||||
"-----------------------------------------------"
|
||||
"-------------\n",
|
||||
"Print queue name",
|
||||
"Queue ID");
|
||||
q.object_id = 0xffffffff;
|
||||
|
||||
while (ncp_scan_bindery_object(connid, q.object_id,
|
||||
NCP_BINDERY_PQUEUE, pattern, &q) == 0)
|
||||
{
|
||||
found = 1;
|
||||
printf("%-52s", q.object_name);
|
||||
printf("%08X\n", (unsigned int) q.object_id);
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
printf("No queues found\n");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
list_volumes(char *server)
|
||||
{
|
||||
int found = 0, connid, i, error;
|
||||
struct ncp_file_server_info si;
|
||||
char volname[NCP_VOLNAME_LEN+1];
|
||||
|
||||
connid = ncp_get_connid(server, 1);
|
||||
if (connid < 0) return;
|
||||
|
||||
error = ncp_get_file_server_information(connid, &si);
|
||||
if (error) {
|
||||
ncp_error("Can't get information for server %s", error, server);
|
||||
return;
|
||||
}
|
||||
|
||||
printf("\nMounted volumes on server %s:\n", server);
|
||||
printf("Number Name\n");
|
||||
printf("------ -----------------------------------------------\n");
|
||||
|
||||
for(i = 0; i < si.NumberMountedVolumes; i++) {
|
||||
if (NWGetVolumeName(connid, i, volname))
|
||||
continue;
|
||||
found = 1;
|
||||
printf("%6d %s\n", i, volname);
|
||||
}
|
||||
|
||||
if (!found)
|
||||
printf("No volumes found ?\n");
|
||||
return;
|
||||
}
|
||||
|
||||
struct ncp_bind_type {
|
||||
u_long type;
|
||||
const char *name;
|
||||
};
|
||||
|
||||
static struct ncp_bind_type btypes[] = {
|
||||
{NCP_BINDERY_USER, "USER"},
|
||||
{NCP_BINDERY_UGROUP, "GROUP"},
|
||||
{NCP_BINDERY_PSERVER, "PSERVER"},
|
||||
{0x278, "TREE"},
|
||||
{0, NULL}
|
||||
};
|
||||
|
||||
static void
|
||||
list_bindery(char *server, char *type, char *patt)
|
||||
{
|
||||
struct ncp_bindery_object q;
|
||||
int i, found = 0, connid;
|
||||
char default_pattern[] = "*";
|
||||
char *pattern = default_pattern;
|
||||
u_long objtype;
|
||||
|
||||
ncp_str_upper(type);
|
||||
objtype = 0;
|
||||
|
||||
for(i = 0; btypes[i].type; i++) {
|
||||
if (strcmp(btypes[i].name, type) == 0) {
|
||||
objtype = btypes[i].type;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!objtype) {
|
||||
printf("Bindery object of type %s is unknown\n", type);
|
||||
return;
|
||||
}
|
||||
if (patt != NULL)
|
||||
pattern = patt;
|
||||
ncp_str_upper(pattern);
|
||||
connid = ncp_get_connid(server, 1);
|
||||
if (connid < 0) return;
|
||||
|
||||
connid = ncp_get_connid(server, 1);
|
||||
if (connid < 0) return;
|
||||
|
||||
|
||||
printf("\nServer: %s\n", server);
|
||||
printf("%-52s%-10s\n"
|
||||
"-----------------------------------------------"
|
||||
"-------------\n",
|
||||
"Object name",
|
||||
"Object ID");
|
||||
|
||||
q.object_id = 0xffffffff;
|
||||
while (ncp_scan_bindery_object(connid, q.object_id,
|
||||
objtype, pattern, &q) == 0)
|
||||
{
|
||||
found = 1;
|
||||
printf("%-52s", q.object_name);
|
||||
printf("%08X\n", (unsigned int) q.object_id);
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
printf("No bindery objects found\n");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
enum listop {
|
||||
LO_NONE, LO_SERVERS, LO_QUEUES, LO_BINDERY, LO_USERS, LO_VOLUMES
|
||||
};
|
||||
|
||||
#define MAX_ARGS 10
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
int opt, nargs = 0, i;
|
||||
enum listop what;
|
||||
char *args[MAX_ARGS];
|
||||
|
||||
bzero(args, sizeof(args));
|
||||
|
||||
what = LO_NONE;
|
||||
while ((opt = getopt(argc, argv, "h")) != -1) {
|
||||
switch (opt) {
|
||||
case 'h': case '?':
|
||||
help();
|
||||
/*NOTREACHED */
|
||||
default:
|
||||
help();
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
if (optind >= argc)
|
||||
help();
|
||||
|
||||
if(ncp_initlib())
|
||||
exit(1);
|
||||
|
||||
switch(argv[optind++][0]) {
|
||||
case 'b':
|
||||
what = LO_BINDERY;
|
||||
nargs = 2;
|
||||
break;
|
||||
case 'c':
|
||||
show_connlist();
|
||||
return 0;
|
||||
case 's':
|
||||
what = LO_SERVERS;
|
||||
break;
|
||||
case 'u':
|
||||
what = LO_USERS;
|
||||
nargs = 1;
|
||||
break;
|
||||
case 'q':
|
||||
what = LO_QUEUES;
|
||||
nargs = 1;
|
||||
break;
|
||||
case 'v':
|
||||
what = LO_VOLUMES;
|
||||
nargs = 1;
|
||||
break;
|
||||
default:
|
||||
printf("Unknown command %s\n", argv[optind-1]);
|
||||
help();
|
||||
}
|
||||
for (i = 0; i < MAX_ARGS; i++) {
|
||||
if (optind < argc) {
|
||||
args[i] = argv[optind++];
|
||||
} else if (i < nargs) {
|
||||
printf("Not enough arguments\n");
|
||||
help();
|
||||
return 1;
|
||||
} else
|
||||
break;
|
||||
}
|
||||
switch(what) {
|
||||
case LO_SERVERS:
|
||||
show_serverlist(args[0]);
|
||||
break;
|
||||
case LO_USERS:
|
||||
show_userlist(args[0]);
|
||||
break;
|
||||
case LO_QUEUES:
|
||||
show_queuelist(args[0], args[1]);
|
||||
break;
|
||||
case LO_VOLUMES:
|
||||
list_volumes(args[0]);
|
||||
break;
|
||||
case LO_BINDERY:
|
||||
list_bindery(args[0], args[1], args[2]);
|
||||
break;
|
||||
default:
|
||||
help();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
help(void)
|
||||
{
|
||||
printf("\n");
|
||||
printf("usage: %s command [args]\n", __progname);
|
||||
printf("where commands are:\n"
|
||||
" b server user|group [pattern] list bindery objects on server\n"
|
||||
" c display opened connections\n"
|
||||
" s [server] display known servers\n"
|
||||
" u server list logged-in users on server\n"
|
||||
" q server [pattern] list print queues on server\n"
|
||||
" v server list mounted volumes on a specified server\n"
|
||||
"\n");
|
||||
exit(1);
|
||||
}
|
@ -1,11 +0,0 @@
|
||||
# $FreeBSD$
|
||||
|
||||
PROG= ncplogin
|
||||
MAN= ncplogin.1 ncplogout.1
|
||||
|
||||
LINKS= ${BINDIR}/ncplogin ${BINDIR}/ncplogout
|
||||
|
||||
LDADD= -lncp -lipx
|
||||
DPADD= ${LIBNCP} ${LIBIPX}
|
||||
|
||||
.include <bsd.prog.mk>
|
@ -1,262 +0,0 @@
|
||||
.\" $FreeBSD$
|
||||
.Dd September 15, 1999
|
||||
.Dt NCPLOGIN 1
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm ncplogin
|
||||
.Nd create permanent connection to a NetWare server
|
||||
.Sh SYNOPSIS
|
||||
.Nm
|
||||
.Op Fl BCDN
|
||||
.Op Fl S Ar server
|
||||
.Op Fl U Ar user
|
||||
.Op Fl A Ar host
|
||||
.Op Fl I Ar level
|
||||
.Op Fl M Ar mode
|
||||
.Oo
|
||||
.Fl O Xo
|
||||
.Op Ar owner Ns
|
||||
.Op : Ns Ar group
|
||||
.Xc
|
||||
.Oc
|
||||
.Op Fl R Ar retrycount
|
||||
.Op Fl T Ar tree
|
||||
.Op Fl W Ar timeout
|
||||
.Nm
|
||||
.Op Fl BCDN
|
||||
.Op Fl A Ar host
|
||||
.Op Fl I Ar level
|
||||
.Op Fl M Ar mode
|
||||
.Oo
|
||||
.Fl O Xo
|
||||
.Op Ar owner Ns
|
||||
.Op : Ns Ar group
|
||||
.Xc
|
||||
.Oc
|
||||
.Op Fl R Ar retrycount
|
||||
.Op Fl T Ar tree
|
||||
.Op Fl W Ar timeout
|
||||
.No / Ns Ar server Ns : Ns Ar user
|
||||
.Sh DESCRIPTION
|
||||
Connections to a
|
||||
.Tn NetWare
|
||||
server can be created and used independently of the
|
||||
.Xr mount_nwfs 8
|
||||
command.
|
||||
Connections can be created by any user.
|
||||
Each user can have multiple
|
||||
connections, but each
|
||||
.Ar NetWareServer Ns : Ns Ar NetWareUser
|
||||
pair should be unique.
|
||||
.Pp
|
||||
The
|
||||
.Nm
|
||||
command is used to create a permanent connection to a
|
||||
.Tn NetWare
|
||||
server.
|
||||
Permanent connections will stay open even if no application uses them.
|
||||
This allows users to run different
|
||||
.Pa ncp*
|
||||
programs
|
||||
without specifying a file server and user to use.
|
||||
Established connections can be destroyed with the
|
||||
.Xr ncplogout 1
|
||||
command.
|
||||
.Pp
|
||||
Upper case options described in this manual page
|
||||
are common for other
|
||||
.Pa ncp*
|
||||
programs and are referred to as
|
||||
.Dq connection options .
|
||||
Options
|
||||
.Fl U
|
||||
and
|
||||
.Fl S
|
||||
are mutually exclusive with the
|
||||
.No / Ns Ar server Ns : Ns Ar user
|
||||
syntax.
|
||||
.Pp
|
||||
The following options are available:
|
||||
.Bl -tag -width indent
|
||||
.It Fl S Ar server
|
||||
Specify the name of the
|
||||
.Tn NetWare
|
||||
server to connect to.
|
||||
This affects only
|
||||
.Tn IPX
|
||||
servers.
|
||||
For servers supporting
|
||||
.Tn IP
|
||||
natively, see the
|
||||
.Fl A
|
||||
option.
|
||||
.It Fl U Ar user
|
||||
Specify the name of the user used in the login sequence.
|
||||
.It Fl A Ar host
|
||||
Use the
|
||||
.Tn UDP
|
||||
protocol to connect to a
|
||||
.Tn NetWare
|
||||
5.x server specified by the
|
||||
.Ar host
|
||||
argument.
|
||||
.It Fl C
|
||||
Do not convert the password to uppercase.
|
||||
.It Fl D
|
||||
Mark the connection as primary.
|
||||
The option can be used to modify existing connections.
|
||||
Only the
|
||||
.Nm
|
||||
program accepts this option.
|
||||
.It Fl I Ar signature_level
|
||||
Try to use
|
||||
.Ar signature_level .
|
||||
Available values are:
|
||||
.Pp
|
||||
.Bl -tag -width ".Em Value" -offset indent -compact
|
||||
.It Em Value
|
||||
.Em Meaning
|
||||
.It 0
|
||||
disable signatures
|
||||
.It 1
|
||||
enable (use if required by server)
|
||||
.It 2
|
||||
request but do not require signing
|
||||
.It 3
|
||||
require signatures
|
||||
.El
|
||||
.Pp
|
||||
Note that only packet header signing is implemented.
|
||||
.It Fl M Ar mode
|
||||
Share this connection.
|
||||
The bits in the
|
||||
.Ar mode
|
||||
argument are similar to standard file permissions:
|
||||
.Pp
|
||||
.Bl -tag -width ".Em Mask" -offset indent -compact
|
||||
.It Em Mask
|
||||
.Em Meaning
|
||||
.It 4
|
||||
.Pq READ
|
||||
connection will be visible.
|
||||
.It 2
|
||||
.Pq WRITE
|
||||
connection can be closed/modified.
|
||||
.It 1
|
||||
.Pq EXECUTE
|
||||
user is allowed to execute requests.
|
||||
.El
|
||||
.Pp
|
||||
By default, the connection is created with
|
||||
.Ar mode
|
||||
0700
|
||||
and only the owner can use it.
|
||||
Specifying 0750 as the argument to the
|
||||
.Fl M
|
||||
option would allow read-only group access as well.
|
||||
This would allow the group to perform
|
||||
.Tn NCP
|
||||
requests,
|
||||
but not to destroy the connection.
|
||||
When a server is not explicitly specified,
|
||||
.Pa ncp*
|
||||
programs try to find a suitable connection in the following order:
|
||||
.Bl -enum -offset indent
|
||||
.It
|
||||
Try to find a connection owned by the user.
|
||||
If there is more than one such
|
||||
connection, try to determine which one is primary.
|
||||
(The primary flag is set with the
|
||||
.Fl D
|
||||
option.)
|
||||
.It
|
||||
If the primary connection could not be determined,
|
||||
the first shared connection will be used.
|
||||
.El
|
||||
.It Fl N
|
||||
Do not prompt for a password.
|
||||
At run time,
|
||||
.Nm
|
||||
reads the
|
||||
.Pa ~/.nwfsrc
|
||||
file for additional configuration parameters and a password.
|
||||
If no password is found for the specified
|
||||
.Ar server Ns : Ns Ar user
|
||||
pair,
|
||||
.Nm
|
||||
prompts for it.
|
||||
.It Fl O
|
||||
Specify the
|
||||
.Ar owner
|
||||
and
|
||||
.Ar group
|
||||
attributes for the connection.
|
||||
By default, newly created connections take the
|
||||
.Ar owner
|
||||
attribute from the creating user's username and the
|
||||
.Ar group
|
||||
attribute from the creating user's primary group.
|
||||
This option overrides that behaviour.
|
||||
Only the superuser can override the
|
||||
.Ar owner
|
||||
attribute for a connection.
|
||||
.It Fl P
|
||||
Mark the connection as permanent.
|
||||
The
|
||||
.Nm
|
||||
utility always creates permanent connections.
|
||||
This option can be useful in other
|
||||
.Pa ncp*
|
||||
programs.
|
||||
.It Fl R Ar retry_count
|
||||
Specify the number of retries to be performed
|
||||
before dropping the connection.
|
||||
The default value is 10.
|
||||
.Pp
|
||||
Note: after a connection is marked
|
||||
.Dq BAD ,
|
||||
each request will try to restore it.
|
||||
This process restores only the
|
||||
.Tn NCP
|
||||
connection;
|
||||
it does not reopen any files that were open
|
||||
at the time that the connection was marked
|
||||
.Dq BAD .
|
||||
.It Fl W Ar timeout
|
||||
Specify the server request timeout in seconds.
|
||||
The default is 5 seconds.
|
||||
.It / Ns Ar server Ns : Ns Ar user
|
||||
This syntax is provided for the sake of simplicity
|
||||
and is mutually exclusive with the
|
||||
.Fl S
|
||||
and
|
||||
.Fl U
|
||||
options.
|
||||
.El
|
||||
.Sh IMPLEMENTATION NOTES
|
||||
Low-level connection management is implemented in the
|
||||
.Pa ncp.ko
|
||||
kernel module.
|
||||
The
|
||||
.Xr IPXrouted 8
|
||||
program is also required for
|
||||
.Tn IPX
|
||||
support.
|
||||
.Sh FILES
|
||||
.Bl -tag -width ".Pa ~/.nwfsrc"
|
||||
.It Pa ~/.nwfsrc
|
||||
keeps static parameters for connections and other information;
|
||||
see
|
||||
.Pa /usr/share/examples/nwclient/dot.nwfsrc
|
||||
for details.
|
||||
.El
|
||||
.Sh HISTORY
|
||||
The
|
||||
.Nm
|
||||
command first appeared in
|
||||
.Fx 4.0 .
|
||||
.Sh AUTHORS
|
||||
.An Boris Popov Aq bp@butya.kz ,
|
||||
.Aq rbp@chat.ru
|
||||
.Sh BUGS
|
||||
Please report any bugs to the author.
|
@ -1,205 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 1999, Boris Popov
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by Boris Popov.
|
||||
* 4. Neither the name of the author nor the names of any co-contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/errno.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <err.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sysexits.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <netncp/ncp_lib.h>
|
||||
#include <netncp/ncp_rcfile.h>
|
||||
|
||||
extern char *__progname;
|
||||
|
||||
static void
|
||||
login_usage(void) {
|
||||
printf("usage: %s [-Dh] [-A host] [-BCN] [-I level] [-M mode] \n"
|
||||
" [-R retrycount] [-W timeout] /server:user\n", __progname);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
static void
|
||||
logout_usage(void) {
|
||||
printf("usage: %s [-c handle] [-h] [/server:user]\n", __progname);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
static void
|
||||
login(int argc, char *argv[], struct ncp_conn_loginfo *li) {
|
||||
int error = 0, connid, opt, setprimary = 0;
|
||||
|
||||
while ((opt = getopt(argc, argv, STDPARAM_OPT"D")) != -1) {
|
||||
switch(opt){
|
||||
case STDPARAM_ARGS:
|
||||
if (ncp_li_arg(li, opt, optarg))
|
||||
exit(1);
|
||||
break;
|
||||
case 'D':
|
||||
setprimary = 1;
|
||||
break;
|
||||
default:
|
||||
login_usage();
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
}
|
||||
if (li->access_mode == 0)
|
||||
li->access_mode = S_IRWXU;
|
||||
if (ncp_li_check(li))
|
||||
exit(1);
|
||||
li->opt |= NCP_OPT_WDOG | NCP_OPT_PERMANENT;
|
||||
/* now we can try to login, or use already established connection */
|
||||
error = ncp_li_login(li, &connid);
|
||||
if (error) {
|
||||
ncp_error("Could not login to server %s", error, li->server);
|
||||
exit(1);
|
||||
}
|
||||
error = ncp_setpermanent(connid, 1);
|
||||
if (error && errno != EACCES){
|
||||
ncp_error("Can't make connection permanent", error);
|
||||
exit(1);
|
||||
}
|
||||
if (setprimary && ncp_setprimary(connid, 1) != 0)
|
||||
ncp_error("Warning: can't make connection primary", errno);
|
||||
printf("Logged in with conn handle:%d\n", connid);
|
||||
return;
|
||||
}
|
||||
|
||||
static void
|
||||
logout(int argc, char *argv[], struct ncp_conn_loginfo *li) {
|
||||
int error = 0, connid, opt;
|
||||
|
||||
connid = -1;
|
||||
while ((opt = getopt(argc, argv, STDPARAM_OPT"c:")) != -1){
|
||||
switch (opt) {
|
||||
case 'c':
|
||||
connid = atoi(optarg);
|
||||
break;
|
||||
case STDPARAM_ARGS:
|
||||
if (ncp_li_arg(li, opt, optarg))
|
||||
exit(1);
|
||||
break;
|
||||
default:
|
||||
logout_usage();
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
}
|
||||
if (connid == -1) {
|
||||
if (li->server[0] == 0)
|
||||
errx(EX_USAGE, "no server name specified");
|
||||
if (li->user == 0)
|
||||
errx(EX_USAGE, "no user name specified");
|
||||
if (ncp_conn_scan(li, &connid))
|
||||
errx(EX_OSERR, "You are not attached to server %s",
|
||||
li->server);
|
||||
}
|
||||
if (ncp_setpermanent(connid, 0) < 0 && errno != EACCES) {
|
||||
ncp_error("Connection isn't valid", errno);
|
||||
exit(EX_OSERR);
|
||||
}
|
||||
error = ncp_disconnect(connid);
|
||||
if (error) {
|
||||
if (errno == EACCES) {
|
||||
warnx("you logged out, but connection belongs"
|
||||
"to other user and not closed");
|
||||
} else {
|
||||
ncp_error("Can't logout with connid %d", error, connid);
|
||||
error = 1;
|
||||
}
|
||||
}
|
||||
exit(error ? 1 : 0);
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char *argv[]) {
|
||||
int islogin, error;
|
||||
char *p, *p1;
|
||||
struct ncp_conn_loginfo li;
|
||||
|
||||
islogin = strcmp(__progname, "ncplogin") == 0;
|
||||
|
||||
if (argc == 2) {
|
||||
if (strcmp(argv[1], "-h") == 0) {
|
||||
if (islogin)
|
||||
login_usage();
|
||||
else
|
||||
logout_usage();
|
||||
}
|
||||
}
|
||||
|
||||
if (ncp_initlib())
|
||||
exit(1);
|
||||
if (ncp_li_init(&li, argc, argv))
|
||||
return 1;
|
||||
|
||||
if (argc >= 2 && argv[argc - 1][0] == '/') {
|
||||
p = argv[argc - 1];
|
||||
error = 1;
|
||||
do {
|
||||
if (*p++ != '/')
|
||||
break;
|
||||
p1 = strchr(p, ':');
|
||||
if (p1 == NULL)
|
||||
break;
|
||||
*p1++ = 0;
|
||||
if (ncp_li_setserver(&li, p))
|
||||
break;
|
||||
if (*p1 == 0)
|
||||
break;
|
||||
if (ncp_li_setuser(&li, p1)) break;
|
||||
error = 0;
|
||||
} while(0);
|
||||
if (error)
|
||||
errx(EX_DATAERR,
|
||||
"an error occurred while parsing '%s'",
|
||||
argv[argc - 1]);
|
||||
}
|
||||
|
||||
if (ncp_li_readrc(&li))
|
||||
return 1;
|
||||
if (ncp_rc)
|
||||
rc_close(ncp_rc);
|
||||
if (islogin)
|
||||
login(argc, argv, &li);
|
||||
else
|
||||
logout(argc, argv, &li);
|
||||
return 0;
|
||||
}
|
@ -1,56 +0,0 @@
|
||||
.\" $FreeBSD$
|
||||
.Dd September 15, 1999
|
||||
.Dt NCPLOGOUT 1
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm ncplogout
|
||||
.Nd schedule permanent connection to close
|
||||
.Sh SYNOPSIS
|
||||
.Nm
|
||||
.Op Fl S Ar server
|
||||
.Op Fl U Ar user
|
||||
.Op Fl c Ar handle
|
||||
.Nm
|
||||
.Op Fl c Ar handle
|
||||
.No / Ns Ar server Ns : Ns Ar user
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Nm
|
||||
utility will schedule a connection created by
|
||||
.Xr ncplogin 1
|
||||
command to be closed.
|
||||
If the connection is busy (i.e., used by other processes) it will
|
||||
be closed when the last process using it is terminated.
|
||||
This command is similar to the
|
||||
.Tn DOS
|
||||
.Pa logout.exe
|
||||
command.
|
||||
.Pp
|
||||
The options are:
|
||||
.Bl -tag -width indent
|
||||
.It Fl S Ar server
|
||||
Specify the name of the
|
||||
.Tn NetWare
|
||||
server to which the connection should be terminated.
|
||||
Can be omitted if there is only
|
||||
one connection active.
|
||||
.It Fl U Ar user
|
||||
Specify the name of the user to use when identifying the connection.
|
||||
Can be omitted if there is only
|
||||
one connection active.
|
||||
.It Fl c Ar handle
|
||||
Close a connection by handle.
|
||||
A list of available handles can be obtained with the following command:
|
||||
.Pp
|
||||
.Dl "ncplist c"
|
||||
.El
|
||||
.Sh HISTORY
|
||||
The
|
||||
.Nm
|
||||
utility first appeared in
|
||||
.Fx 4.0 .
|
||||
.Sh AUTHORS
|
||||
.An Boris Popov Aq bp@butya.kz ,
|
||||
.Aq bp@FreeBSD.org
|
||||
.Sh BUGS
|
||||
Please report any bugs to the author.
|
@ -1,15 +0,0 @@
|
||||
# $FreeBSD$
|
||||
|
||||
PROG= mount_nwfs
|
||||
SRCS= mount_nwfs.c getmntopts.c
|
||||
MAN= mount_nwfs.8
|
||||
|
||||
MOUNT= ${.CURDIR}/../../sbin/mount
|
||||
CFLAGS+= -DNWFS -I${MOUNT}
|
||||
|
||||
.PATH: ${MOUNT}
|
||||
|
||||
DPADD= ${LIBNCP} ${LIBIPX}
|
||||
LDADD= -lncp -lipx
|
||||
|
||||
.include <bsd.prog.mk>
|
@ -1,230 +0,0 @@
|
||||
.\" $FreeBSD$
|
||||
.Dd October 14, 1999
|
||||
.Dt MOUNT_NWFS 8
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm mount_nwfs
|
||||
.Nd mount NetWare volume from a NetWare file server
|
||||
.Sh SYNOPSIS
|
||||
.Nm
|
||||
.Op Fl Chv
|
||||
.Fl S Ar server
|
||||
.Fl U Ar user
|
||||
.Op Fl connection\ options
|
||||
.Fl V Ar volume
|
||||
.Op Fl M Ar mode
|
||||
.Op Fl c Ar case
|
||||
.Op Fl d Ar mode
|
||||
.Op Fl f Ar mode
|
||||
.Op Fl g Ar gid
|
||||
.Op Fl l Ar locale
|
||||
.Op Fl n Ar os2
|
||||
.Op Fl u Ar uid
|
||||
.Op Fl w Ar scheme
|
||||
.Ar node
|
||||
.Nm
|
||||
.Op Fl options
|
||||
.Ar /server:user/volume[/path]
|
||||
.Ar node
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Nm
|
||||
utility allows to mount volume from a NetWare server.
|
||||
It may use either
|
||||
existing connection or create new: if no usable connection was found
|
||||
it will try to establish a new one.
|
||||
Connection has count of references to it,
|
||||
so when last mount will be dismounted connection will be closed.
|
||||
It is
|
||||
possible to create connection without any mounts (but use it for them) with
|
||||
.Xr ncplogin 1 .
|
||||
.Pp
|
||||
Note two forms of command line.
|
||||
In the first form, server and user specified
|
||||
via
|
||||
.Fl S
|
||||
and
|
||||
.Fl U
|
||||
options respectively.
|
||||
In the second form server and user specified in
|
||||
.Ar special
|
||||
part of
|
||||
.Xr mount 8
|
||||
command line arguments (the
|
||||
.Fl S ,
|
||||
.Fl U
|
||||
and
|
||||
.Fl V
|
||||
options are not used in this case).
|
||||
This allows use of
|
||||
.Xr fstab 5
|
||||
file (see
|
||||
.Sx EXAMPLES
|
||||
below).
|
||||
.Pp
|
||||
The options are:
|
||||
.Bl -tag -width indent
|
||||
.It Fl S Ar server
|
||||
Name of NetWare server to connect.
|
||||
For native IP you will need also
|
||||
.Fl A
|
||||
option.
|
||||
.It Fl U Ar user
|
||||
Name of user used in login sequence.
|
||||
.It Fl connection\ options
|
||||
See
|
||||
.Xr ncplogin 1
|
||||
for details.
|
||||
.It Fl V Ar volume
|
||||
Volume name to mount.
|
||||
Volume name can also be specified after all options and
|
||||
before
|
||||
.Ar mount-point .
|
||||
.It Ar node
|
||||
Path to mount volume.
|
||||
.It Fl c Ar case
|
||||
Select a
|
||||
.Ar case
|
||||
option which affects on name representation.
|
||||
.Ar Case
|
||||
can be one of the following:
|
||||
.Bl -tag -width "ValueXX"
|
||||
.It Em Value
|
||||
.Em Meaning
|
||||
.It l
|
||||
All existing file names converted to lower case.
|
||||
Newly created file gets a lower case under OS2 name space.
|
||||
This is the default when mounting volumes with DOS name space.
|
||||
.It L
|
||||
Same as 'l' but file system tries to be case insensitive.
|
||||
May not work well.
|
||||
.It n
|
||||
No case conversion is performed.
|
||||
.Em Warning !
|
||||
Use this option with DOS name space only as a last resort,
|
||||
because creating a lower case name in the DOS name space
|
||||
can lead to unpredictable results.
|
||||
This is the default when mounting volumes with OS2 name space.
|
||||
.It u
|
||||
All existing file names converted to upper case.
|
||||
Newly created file gets an upper case under OS2 name space.
|
||||
.It U
|
||||
Same as 'u' but file system tries to be case insensitive.
|
||||
May not work well.
|
||||
.El
|
||||
.It Fl f Ar mode , Fl d Ar mode
|
||||
Specify permissions that should be assigned to files and directories.
|
||||
The values must be specified as octal numbers.
|
||||
Default value for the file mode
|
||||
is taken from mount point, default value for the dir mode adds execute
|
||||
permission where the file mode gives read permission.
|
||||
.Pp
|
||||
Note that these permissions can differ from the rights granted by NetWare
|
||||
server.
|
||||
.It Fl n Ar namespace
|
||||
Do not use
|
||||
.Ar namespace .
|
||||
Currently only
|
||||
.Ar OS2
|
||||
can be here.
|
||||
.It Fl v
|
||||
Print version number.
|
||||
.It Fl u Ar uid , Fl g Ar gid
|
||||
User id and group id assigned to files.
|
||||
The default is owner and group id from
|
||||
directory where volume is mounted.
|
||||
.It Fl l Ar locale
|
||||
Set the locale for case conversion.
|
||||
By default
|
||||
.Nm
|
||||
tries to use an environment variable
|
||||
.Ev LC_* .
|
||||
.It Fl w Ar scheme
|
||||
Select a
|
||||
.Ar scheme
|
||||
used to convert file names between NetWare and
|
||||
.Fx .
|
||||
Supported conversion schemes are:
|
||||
.Bl -tag -width ".Cm koi2cp866"
|
||||
.It Cm asis
|
||||
Characters passed as is without any alteration.
|
||||
.It Cm koi2cp866
|
||||
koi8-r <-> CP866
|
||||
.It Cm se
|
||||
Suits for setups used in Sweden.
|
||||
.El
|
||||
.It Fl M Ar mode
|
||||
See
|
||||
.Xr ncplogin 1
|
||||
for details.
|
||||
If this option is omitted, connection permissions
|
||||
assumed the same as directory mode
|
||||
.Pq Fl d
|
||||
option.
|
||||
.El
|
||||
.Sh FILES
|
||||
.Bl -tag -width /var/log/wtmp -compact
|
||||
.It Pa ~/.nwfsrc
|
||||
keeps static parameters for connections and other information.
|
||||
See
|
||||
.Pa /usr/share/examples/nwclient/dot.nwfsrc
|
||||
for details.
|
||||
.El
|
||||
.Sh NOTES
|
||||
Before any NCP connection can be established kernel must be configured
|
||||
for IPX support, IPXrouted and KLD nwfs.ko should be loaded.
|
||||
.Sh EXAMPLES
|
||||
Next examples illustrates how to connect to NetWare server
|
||||
.Em nwserv
|
||||
as user
|
||||
.Em GUEST
|
||||
and mount volumes
|
||||
.Em SYS
|
||||
and
|
||||
.Em VOL1 :
|
||||
.Bd -literal -offset indent
|
||||
mount_nwfs -S nwserv -U guest -V sys /nw/s1/sys
|
||||
mount_nwfs /nwserv:guest/sys /nw/s1/sys
|
||||
mount -t nwfs /nwserv:guest/vol1 /nw/s1/vol1
|
||||
mount -t nwfs /nwserv:boris/sys/home/boris /home/boris/nw/home
|
||||
.Ed
|
||||
.Pp
|
||||
The last example mounts only subdirectory on a volume and equivalent
|
||||
to NetWare 'map root' command.
|
||||
.Pp
|
||||
It is possible to use
|
||||
.Xr fstab 5
|
||||
for nwfs mounts:
|
||||
.Bd -literal -offset indent
|
||||
/nwserv:guest/sys /nw/s1/sys nwfs rw,noauto 0 0
|
||||
/nwserv:guest/vol1 /nw/s1/vol2 nwfs rw,noauto 0 0
|
||||
.Ed
|
||||
.Sh HISTORY
|
||||
The
|
||||
.Nm
|
||||
utility first appeared in
|
||||
.Fx 4.0 .
|
||||
.Sh CREDITS
|
||||
In development of NetWare client for
|
||||
.Fx ,
|
||||
the following sources were used:
|
||||
.Pp
|
||||
Documentation from NetWare NDK.
|
||||
.Pp
|
||||
Ncpfs for Linux - written by
|
||||
.An Volker Lendecke Aq lendecke@math.uni\-goettingen.de .
|
||||
He granted me permission to publish parts of his code under
|
||||
.Bx Ns -style
|
||||
license,
|
||||
.Pp
|
||||
"Interrupt List" from
|
||||
.An Ralf Brown ,
|
||||
.Pp
|
||||
Many files from
|
||||
.Pa /sys
|
||||
directory.
|
||||
.Sh AUTHORS
|
||||
.An Boris Popov Aq bp@butya.kz ,
|
||||
.Aq rbp@chat.ru
|
||||
.Sh BUGS
|
||||
to number a few
|
@ -1,369 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 1999, Boris Popov
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by Boris Popov.
|
||||
* 4. Neither the name of the author nor the names of any co-contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
#include <sys/param.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/errno.h>
|
||||
#include <sys/mount.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <machine/cpu.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <pwd.h>
|
||||
#include <grp.h>
|
||||
#include <unistd.h>
|
||||
#include <ctype.h>
|
||||
#include <stdlib.h>
|
||||
#include <err.h>
|
||||
#include <sysexits.h>
|
||||
#include <time.h>
|
||||
|
||||
#include <netncp/ncp_lib.h>
|
||||
#include <netncp/ncp_rcfile.h>
|
||||
#include <fs/nwfs/nwfs_mount.h>
|
||||
#include "mntopts.h"
|
||||
|
||||
#define NWFS_VFSNAME "nwfs"
|
||||
|
||||
static char mount_point[MAXPATHLEN + 1];
|
||||
static void usage(void);
|
||||
static int parsercfile(struct ncp_conn_loginfo *li, struct nwfs_args *mdata);
|
||||
|
||||
static struct mntopt mopts[] = {
|
||||
MOPT_STDOPTS,
|
||||
MOPT_END
|
||||
};
|
||||
|
||||
static int
|
||||
parsercfile(struct ncp_conn_loginfo *li __unused,
|
||||
struct nwfs_args *mdata __unused)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
NWCONN_HANDLE connHandle;
|
||||
struct nwfs_args mdata;
|
||||
struct ncp_conn_loginfo li;
|
||||
struct stat st;
|
||||
struct nw_entry_info einfo;
|
||||
struct tm *tm;
|
||||
time_t ltime;
|
||||
int opt, error, mntflags, nlsopt, wall_clock;
|
||||
int uid_set, gid_set;
|
||||
size_t len;
|
||||
char *p, *p1, tmp[1024];
|
||||
u_char *pv;
|
||||
|
||||
if (argc < 2)
|
||||
usage();
|
||||
if (argc == 2) {
|
||||
if (strcmp(argv[1], "-h") == 0) {
|
||||
usage();
|
||||
} else if (strcmp(argv[1], "-v") == 0) {
|
||||
errx(EX_OK, "version %d.%d.%d", NWFS_VERSION / 100000,
|
||||
(NWFS_VERSION % 10000) / 1000,
|
||||
(NWFS_VERSION % 1000) / 100);
|
||||
}
|
||||
}
|
||||
|
||||
if(ncp_initlib()) exit(1);
|
||||
|
||||
mntflags = error = 0;
|
||||
bzero(&mdata,sizeof(mdata));
|
||||
gid_set = uid_set = 0;
|
||||
nlsopt = 0;
|
||||
|
||||
if (ncp_li_init(&li, argc, argv)) return 1;
|
||||
/*
|
||||
* A little bit weird, but I should figure out which server/user to use
|
||||
* _before_ reading .rc file
|
||||
*/
|
||||
if (argc >= 3 && argv[argc-1][0] != '-' && argv[argc-2][0] != '-' &&
|
||||
argv[argc-2][0] == '/') {
|
||||
p = argv[argc-2];
|
||||
error = 1;
|
||||
do {
|
||||
if (*p++ != '/') break;
|
||||
p1 = tmp;
|
||||
while (*p != ':' && *p != 0) *p1++ = *p++;
|
||||
if (*p++ == 0) break;
|
||||
*p1 = 0;
|
||||
if (ncp_li_setserver(&li, tmp)) break;
|
||||
p1 = tmp;
|
||||
while (*p != '/' && *p != 0) *p1++ = *p++;
|
||||
if (*p++ == 0) break;
|
||||
*p1 = 0;
|
||||
if (ncp_li_setuser(&li, tmp)) break;
|
||||
p1 = tmp;
|
||||
while (*p != '/' && *p != 0) *p1++ = *p++;
|
||||
*p1 = 0;
|
||||
if (strlen(tmp) > NCP_VOLNAME_LEN) {
|
||||
warnx("volume name too long: %s", tmp);
|
||||
break;
|
||||
}
|
||||
ncp_str_upper(strcpy(mdata.mounted_vol,tmp));
|
||||
if (*p == '/')
|
||||
p++;
|
||||
p1 = mdata.root_path + 2;
|
||||
pv = mdata.root_path + 1;
|
||||
for(;*p;) {
|
||||
*pv = 0;
|
||||
while (*p != '/' && *p) {
|
||||
*p1++ = *p++;
|
||||
(*pv)++;
|
||||
}
|
||||
if (*pv) {
|
||||
ncp_nls_mem_u2n(pv + 1, pv + 1, *pv);
|
||||
pv += (*pv) + 1;
|
||||
mdata.root_path[0]++;
|
||||
}
|
||||
if (*p++ == 0) break;
|
||||
p1++;
|
||||
}
|
||||
error = 0;
|
||||
} while(0);
|
||||
if (error)
|
||||
errx(EX_DATAERR,
|
||||
"an error occurred while parsing '%s'",
|
||||
argv[argc - 2]);
|
||||
}
|
||||
if (ncp_li_readrc(&li)) return 1;
|
||||
if (ncp_rc) {
|
||||
parsercfile(&li,&mdata);
|
||||
rc_close(ncp_rc);
|
||||
}
|
||||
while ((opt = getopt(argc, argv, STDPARAM_OPT"V:c:d:f:g:l:n:o:u:w:")) != -1) {
|
||||
switch (opt) {
|
||||
case STDPARAM_ARGS:
|
||||
if (ncp_li_arg(&li, opt, optarg)) {
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
case 'V':
|
||||
if (strlen(optarg) > NCP_VOLNAME_LEN)
|
||||
errx(EX_DATAERR, "volume too long: %s", optarg);
|
||||
ncp_str_upper(strcpy(mdata.mounted_vol,optarg));
|
||||
break;
|
||||
case 'u': {
|
||||
struct passwd *pwd;
|
||||
|
||||
pwd = isdigit(optarg[0]) ?
|
||||
getpwuid(atoi(optarg)) : getpwnam(optarg);
|
||||
if (pwd == NULL)
|
||||
errx(EX_NOUSER, "unknown user '%s'", optarg);
|
||||
mdata.uid = pwd->pw_uid;
|
||||
uid_set = 1;
|
||||
break;
|
||||
}
|
||||
case 'g': {
|
||||
struct group *grp;
|
||||
|
||||
grp = isdigit(optarg[0]) ?
|
||||
getgrgid(atoi(optarg)) : getgrnam(optarg);
|
||||
if (grp == NULL)
|
||||
errx(EX_NOUSER, "unknown group '%s'", optarg);
|
||||
mdata.gid = grp->gr_gid;
|
||||
gid_set = 1;
|
||||
break;
|
||||
}
|
||||
case 'd':
|
||||
errno = 0;
|
||||
mdata.dir_mode = strtol(optarg, &p, 8);
|
||||
if (errno || *p != 0)
|
||||
errx(EX_DATAERR, "invalid value for directory mode");
|
||||
break;
|
||||
case 'f':
|
||||
errno = 0;
|
||||
mdata.file_mode = strtol(optarg, &p, 8);
|
||||
if (errno || *p != 0)
|
||||
errx(EX_DATAERR, "invalid value for file mode");
|
||||
break;
|
||||
case '?':
|
||||
usage();
|
||||
/*NOTREACHED*/
|
||||
case 'n': {
|
||||
char *inp, *nsp;
|
||||
|
||||
nsp = inp = optarg;
|
||||
while ((nsp = strsep(&inp, ",;:")) != NULL) {
|
||||
if (strcasecmp(nsp, "OS2") == 0)
|
||||
mdata.flags |= NWFS_MOUNT_NO_OS2;
|
||||
else if (strcasecmp(nsp, "LONG") == 0)
|
||||
mdata.flags |= NWFS_MOUNT_NO_LONG;
|
||||
else if (strcasecmp(nsp, "NFS") == 0)
|
||||
mdata.flags |= NWFS_MOUNT_NO_NFS;
|
||||
else
|
||||
errx(EX_DATAERR, "unknown namespace '%s'", nsp);
|
||||
}
|
||||
break;
|
||||
};
|
||||
case 'l':
|
||||
if (ncp_nls_setlocale(optarg) != 0) return 1;
|
||||
mdata.flags |= NWFS_MOUNT_HAVE_NLS;
|
||||
break;
|
||||
case 'o':
|
||||
getmntopts(optarg, mopts, &mntflags, 0);
|
||||
break;
|
||||
case 'c':
|
||||
switch (optarg[0]) {
|
||||
case 'l':
|
||||
nlsopt |= NWHP_LOWER;
|
||||
break;
|
||||
case 'u':
|
||||
nlsopt |= NWHP_UPPER;
|
||||
break;
|
||||
case 'n':
|
||||
nlsopt |= NWHP_LOWER | NWHP_UPPER;
|
||||
break;
|
||||
case 'L':
|
||||
nlsopt |= NWHP_LOWER | NWHP_NOSTRICT;
|
||||
break;
|
||||
case 'U':
|
||||
nlsopt |= NWHP_UPPER | NWHP_NOSTRICT;
|
||||
break;
|
||||
default:
|
||||
errx(EX_DATAERR, "invalid suboption '%c' for -c",
|
||||
optarg[0]);
|
||||
}
|
||||
break;
|
||||
case 'w':
|
||||
if (ncp_nls_setrecodebyname(optarg) != 0)
|
||||
return 1;
|
||||
mdata.flags |= NWFS_MOUNT_HAVE_NLS;
|
||||
break;
|
||||
default:
|
||||
usage();
|
||||
}
|
||||
}
|
||||
|
||||
if (optind == argc - 2) {
|
||||
optind++;
|
||||
} else if (mdata.mounted_vol[0] == 0)
|
||||
errx(EX_USAGE, "volume name should be specified");
|
||||
|
||||
if (optind != argc - 1)
|
||||
usage();
|
||||
realpath(argv[optind], mount_point);
|
||||
|
||||
if (stat(mount_point, &st) == -1)
|
||||
err(EX_OSERR, "could not find mount point %s", mount_point);
|
||||
if (!S_ISDIR(st.st_mode)) {
|
||||
errno = ENOTDIR;
|
||||
err(EX_OSERR, "can't mount on %s", mount_point);
|
||||
}
|
||||
if (ncp_geteinfo(mount_point, &einfo) == 0)
|
||||
errx(EX_OSERR, "can't mount on %s twice", mount_point);
|
||||
|
||||
if (uid_set == 0) {
|
||||
mdata.uid = st.st_uid;
|
||||
}
|
||||
if (gid_set == 0) {
|
||||
mdata.gid = st.st_gid;
|
||||
}
|
||||
if (mdata.file_mode == 0 ) {
|
||||
mdata.file_mode = st.st_mode & (S_IRWXU | S_IRWXG | S_IRWXO);
|
||||
}
|
||||
if (mdata.dir_mode == 0) {
|
||||
mdata.dir_mode = mdata.file_mode;
|
||||
if ((mdata.dir_mode & S_IRUSR) != 0)
|
||||
mdata.dir_mode |= S_IXUSR;
|
||||
if ((mdata.dir_mode & S_IRGRP) != 0)
|
||||
mdata.dir_mode |= S_IXGRP;
|
||||
if ((mdata.dir_mode & S_IROTH) != 0)
|
||||
mdata.dir_mode |= S_IXOTH;
|
||||
}
|
||||
if (li.access_mode == 0) {
|
||||
li.access_mode = mdata.dir_mode;
|
||||
}
|
||||
/* if (mdata.flags & NWFS_MOUNT_HAVE_NLS) {*/
|
||||
mdata.nls = ncp_nls;
|
||||
/* }*/
|
||||
mdata.nls.opt = nlsopt;
|
||||
|
||||
len = sizeof(wall_clock);
|
||||
if (sysctlbyname("machdep.wall_cmos_clock", &wall_clock, &len, NULL, 0) == -1)
|
||||
err(EX_OSERR, "get wall_clock");
|
||||
if (wall_clock == 0) {
|
||||
time(<ime);
|
||||
tm = localtime(<ime);
|
||||
mdata.tz = -(tm->tm_gmtoff / 60);
|
||||
}
|
||||
|
||||
error = ncp_li_check(&li);
|
||||
if (error)
|
||||
return 1;
|
||||
li.opt |= NCP_OPT_WDOG;
|
||||
/* well, now we can try to login, or use already established connection */
|
||||
error = ncp_li_login(&li, &connHandle);
|
||||
if (error) {
|
||||
ncp_error("cannot login to server %s", error, li.server);
|
||||
exit(1);
|
||||
}
|
||||
error = ncp_conn2ref(connHandle, &mdata.connRef);
|
||||
if (error) {
|
||||
ncp_error("could not convert handle to reference", error);
|
||||
ncp_disconnect(connHandle);
|
||||
exit(1);
|
||||
}
|
||||
strcpy(mdata.mount_point,mount_point);
|
||||
mdata.version = NWFS_VERSION;
|
||||
error = mount(NWFS_VFSNAME, mdata.mount_point, mntflags, (void*)&mdata);
|
||||
if (error) {
|
||||
ncp_error("mount error: %s", error, mdata.mount_point);
|
||||
ncp_disconnect(connHandle);
|
||||
exit(1);
|
||||
}
|
||||
/*
|
||||
* I'm leave along my handle, but kernel should keep own ...
|
||||
*/
|
||||
ncp_disconnect(connHandle);
|
||||
/* we are done ?, impossible ... */
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
usage(void)
|
||||
{
|
||||
fprintf(stderr, "%s\n%s\n%s\n%s\n%s\n",
|
||||
"usage: mount_nwfs [-Chv] -S server -U user [-connection options]",
|
||||
" -V volume [-M mode] [-c case] [-d mode] [-f mode]",
|
||||
" [-g gid] [-l locale] [-n os2] [-u uid] [-w scheme]",
|
||||
" node",
|
||||
" mount_nwfs [-options] /server:user/volume[/path] node");
|
||||
|
||||
exit (1);
|
||||
}
|
Loading…
Reference in New Issue
Block a user