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:
Attilio Rao 2013-03-09 12:45:36 +00:00
parent 7a61281f22
commit a92189b377
66 changed files with 37 additions and 15139 deletions

View File

@ -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

View File

@ -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>

View File

@ -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>

View File

@ -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);
}
}

View File

@ -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_ */

View File

@ -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);
}
}

View File

@ -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;
}

View File

@ -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];
}

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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;
}

View File

@ -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 *) &prop;
/* 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);
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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

View File

@ -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

View File

@ -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_ */

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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_ */

View File

@ -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;
}

View File

@ -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_ */

View File

@ -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();
}

View File

@ -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_ */

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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>

View File

@ -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>

View File

@ -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_ */

View File

@ -1,9 +0,0 @@
/*
* static configuration for libncp
*
* $FreeBSD$
*/
#define NCP_NLS_KOI2CP866
#define NCP_NLS_DEFAULT NCP_NLS_KOI_866
#define NCP_PREFIX ""

View File

@ -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);
}

View File

@ -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_ */

View File

@ -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 */

View File

@ -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_ */

View 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_ */

View File

@ -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>

View File

@ -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);

View File

@ -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);
}

View File

@ -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_ */

View File

@ -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);*/
}

View File

@ -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_ */

View File

@ -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_ */

View File

@ -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;
}

View File

@ -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_ */

View File

@ -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);
}

View File

@ -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_ */

View File

@ -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);
}

View File

@ -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_ */

View File

@ -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

View File

@ -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_ */

View File

@ -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_ */

View File

@ -1,9 +0,0 @@
# $FreeBSD$
PROG= ncplist
NO_WCAST_ALIGN=
DPADD= ${LIBNCP} ${LIBIPX}
LDADD= -lncp -lipx
.include <bsd.prog.mk>

View File

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

View File

@ -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 *) &prop;
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);
}

View File

@ -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>

View File

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

View File

@ -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;
}

View File

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

View File

@ -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>

View File

@ -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

View File

@ -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(&ltime);
tm = localtime(&ltime);
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);
}