diff options
| author | Boris Popov <bp@FreeBSD.org> | 1999-10-12 11:56:41 +0000 | 
|---|---|---|
| committer | Boris Popov <bp@FreeBSD.org> | 1999-10-12 11:56:41 +0000 | 
| commit | efef966da8db50f4da90b4bed651b4421d6c82f5 (patch) | |
| tree | 5df7367bbf1788b36cc6e008c01b2b3fe1e5f0e9 | |
| parent | cff51c813aa71405702445d52489e82674d59f08 (diff) | |
Notes
| -rw-r--r-- | lib/libncp/CREDITS | 27 | ||||
| -rw-r--r-- | lib/libncp/Makefile | 24 | ||||
| -rw-r--r-- | lib/libncp/ipx.c | 351 | ||||
| -rw-r--r-- | lib/libncp/ipxsap.h | 95 | ||||
| -rw-r--r-- | lib/libncp/ncp_cfg.h | 9 | ||||
| -rw-r--r-- | lib/libncp/ncp_file.h | 92 | ||||
| -rw-r--r-- | lib/libncp/ncp_lib.h | 258 | ||||
| -rw-r--r-- | lib/libncp/ncp_mod.h | 16 | ||||
| -rw-r--r-- | lib/libncp/ncp_rcfile.h | 64 | ||||
| -rw-r--r-- | lib/libncp/ncpl_bind.c | 263 | ||||
| -rw-r--r-- | lib/libncp/ncpl_conn.c | 517 | ||||
| -rw-r--r-- | lib/libncp/ncpl_crypt.c | 137 | ||||
| -rw-r--r-- | lib/libncp/ncpl_file.c | 263 | ||||
| -rw-r--r-- | lib/libncp/ncpl_misc.c | 289 | ||||
| -rw-r--r-- | lib/libncp/ncpl_msg.c | 131 | ||||
| -rw-r--r-- | lib/libncp/ncpl_net.c | 150 | ||||
| -rw-r--r-- | lib/libncp/ncpl_nls.c | 272 | ||||
| -rw-r--r-- | lib/libncp/ncpl_queue.c | 214 | ||||
| -rw-r--r-- | lib/libncp/ncpl_rcfile.c | 407 | ||||
| -rw-r--r-- | lib/libncp/ncpl_rpc.c | 136 | ||||
| -rw-r--r-- | lib/libncp/ncpl_subr.c | 470 | ||||
| -rw-r--r-- | lib/libncp/sap.c | 302 | ||||
| -rw-r--r-- | sys/netncp/ncp_cfg.h | 9 | ||||
| -rw-r--r-- | sys/netncp/ncp_file.h | 92 | ||||
| -rw-r--r-- | sys/netncp/ncp_lib.h | 258 | ||||
| -rw-r--r-- | sys/netncp/ncp_rcfile.h | 64 | 
26 files changed, 4910 insertions, 0 deletions
diff --git a/lib/libncp/CREDITS b/lib/libncp/CREDITS new file mode 100644 index 0000000000000..43380553e8f90 --- /dev/null +++ b/lib/libncp/CREDITS @@ -0,0 +1,27 @@ +# $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> diff --git a/lib/libncp/Makefile b/lib/libncp/Makefile new file mode 100644 index 0000000000000..b1170ba02cf9b --- /dev/null +++ b/lib/libncp/Makefile @@ -0,0 +1,24 @@ +#	$FreeBSD$ + +NCPLIB=${.CURDIR} + +LIB=		ncp + +SHLIB_MAJOR=	1 +SHLIB_MINOR=	0 + +NOMAN= + +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 + +HEADERS=ncp_cfg.h ncp_lib.h ncp_file.h ncp_rcfile.h + +beforeinstall: +.for hdr in ${HEADERS} +	install -c -o ${BINOWN} -g ${BINGRP} -m 0444 \ +	     ${.CURDIR}/${hdr} ${DESTDIR}/usr/include/netncp +.endfor + +.include <bsd.lib.mk> diff --git a/lib/libncp/ipx.c b/lib/libncp/ipx.c new file mode 100644 index 0000000000000..9284d08469b6b --- /dev/null +++ b/lib/libncp/ipx.c @@ -0,0 +1,351 @@ +/* + * 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/ioctl.h> +#include <sys/socket.h> +#include <sys/sysctl.h> +#include <sys/time.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 __P((caddr_t, caddr_t, struct rt_addrinfo *)); +static int	if_ipxscan __P((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); +	} +} + diff --git a/lib/libncp/ipxsap.h b/lib/libncp/ipxsap.h new file mode 100644 index 0000000000000..2d8d7f039ec65 --- /dev/null +++ b/lib/libncp/ipxsap.h @@ -0,0 +1,95 @@ +/* + * 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$ + */ +#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 */ +}; + +struct sap_entry { +	u_short		server_type; +	u_char		server_name[IPX_SAP_SERVER_NAME_LEN]; +	struct ipx_addr	ipx; +	u_short		hops; +}; + +struct sap_packet { +	u_short		operation; +	struct sap_entry sap_entries[1]; +}; + +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_ */ diff --git a/lib/libncp/ncp_cfg.h b/lib/libncp/ncp_cfg.h new file mode 100644 index 0000000000000..82a30d748d5d2 --- /dev/null +++ b/lib/libncp/ncp_cfg.h @@ -0,0 +1,9 @@ +/*  + * static configuration for libncp + * + * $FreeBSD$ + */ + +#define NCP_NLS_KOI2CP866 +#define NCP_NLS_DEFAULT NCP_NLS_KOI_866 +#define NCP_PREFIX	"" diff --git a/lib/libncp/ncp_file.h b/lib/libncp/ncp_file.h new file mode 100644 index 0000000000000..17b5bd5f8aeca --- /dev/null +++ b/lib/libncp/ncp_file.h @@ -0,0 +1,92 @@ +/* + * 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$ + */ + +#ifndef _NCP_NCP_FILE_H_ +#define _NCP_NCP_FILE_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +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]; +} __attribute__((packed)) NWDELETED_INFO; + +int	ncp_AllocTempDirHandle(char *path, NWDIR_HANDLE *pdh); +int	ncp_DeallocateDirHandle(NWDIR_HANDLE dh); +int	ncp_GetNSEntryInfo(NWDIR_HANDLE dh, struct nw_entry_info *fi, int *ns); + +NWCCODE	ncp_ScanNSEntryInfo(NWCONN_HANDLE cH, nuint8 namSpc, nuint16 attrs, +	SEARCH_SEQUENCE *seq, pnstr8 searchPattern, nuint32 retInfoMask,  +	NW_ENTRY_INFO *entryInfo); + +NWCCODE ncp_PurgeDeletedFile(NWCONN_HANDLE cH, nuint32 iterHandle,  +	nuint32 volNum, nuint32 dirBase, nuint8 ns); + +NWCCODE NWRecoverDeletedFile(NWCONN_HANDLE conn, NWDIR_HANDLE dirHandle, +	nuint32 iterHandle,  +	nuint32 volNum, nuint32 dirBase,  +	pnstr8  delFileName, pnstr8 rcvrFileName); + +NWCCODE ncp_ScanForDeletedFiles(NWCONN_HANDLE cH, pnuint32 iterHandle,  +	pnuint32 volNum, pnuint32 dirBase, nuint8 ns, +	NWDELETED_INFO *entryInfo); + + +#ifdef __cplusplus +} +#endif + +#endif /* _NCP_NCP_FILE_ */ diff --git a/lib/libncp/ncp_lib.h b/lib/libncp/ncp_lib.h new file mode 100644 index 0000000000000..bff63390017a6 --- /dev/null +++ b/lib/libncp/ncp_lib.h @@ -0,0 +1,258 @@ +/* + * 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$ + */ + +#ifndef _NCP_LIB_H_ +#define _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:N:O: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; +	char	*bn_name; +}; + +int ncp_args_parserc(struct ncp_args *na, char *sect, ncp_setopt_t *set_callback); +int ncp_args_parseopt(struct ncp_args *na, int opt, char *optarg, ncp_setopt_t *set_callback); + + +struct sockaddr_ipx; +struct ipx_addr; +struct sockaddr; +struct ncp_buf; +struct rcfile; + +int  ncp_initlib(void); +int  ncp_connect(struct ncp_conn_args *li, int *connHandle); +int  ncp_connect_addr(struct sockaddr *sa, NWCONN_HANDLE *chp); +int  ncp_disconnect(int connHandle); +int  ncp_request(int connHandle,int function, struct ncp_buf *ncpbuf); +int  ncp_conn_request(int connHandle, struct ncp_buf *ncpbuf); +int  ncp_login(int connHandle, const char *user, int objtype, const char *password); +int  ncp_conn_scan(struct ncp_conn_loginfo *li, int *connHandle); +int  ncp_conn_cnt(void); +void *ncp_conn_list(void); +int  ncp_conn_getinfo(int connHandle, struct ncp_conn_stat *ps); +int  ncp_conn_getuser(int connHandle, char **user); +int  ncp_conn2ref(int connHandle, int *connRef); +int  ncp_conn_dup(NWCONN_HANDLE org, NWCONN_HANDLE *res); +int  ncp_path2conn(char *path, int *connHandle); +int  ncp_li_init(struct ncp_conn_loginfo *li, int argc, char *argv[]); +void ncp_li_done(struct ncp_conn_loginfo *li); +int  ncp_li_login(struct ncp_conn_loginfo *li, int *aconnHandle); +int  ncp_li_readrc(struct ncp_conn_loginfo *li); +int  ncp_li_check(struct ncp_conn_loginfo *li); +int  ncp_li_arg(struct ncp_conn_loginfo *li, int opt, char *arg); +int  ncp_li_setserver(struct ncp_conn_loginfo *li, const char *arg); +int  ncp_li_setuser(struct ncp_conn_loginfo *li, char *arg); +int  ncp_li_setpassword(struct ncp_conn_loginfo *li, const char *passwd); +int  ncp_conn_setflags(int connHandle, u_int16_t mask, u_int16_t flags); +int  ncp_conn_find(char *server, char *user); +NWCCODE NWRequest(NWCONN_HANDLE cH, nuint16 fn, +	nuint16 nrq, NW_FRAGMENT* rq,  +	nuint16 nrp, NW_FRAGMENT* rp) ; + +#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 *li, int af,char *name); +int  ncp_find_server(struct ncp_conn_loginfo *li, int type, int af,char *name); + +/* misc rotines */ +char* ncp_str_upper(char *name); +int  ncp_open_rcfile(void); +int  ncp_getopt(int nargc, char * const *nargv, const char *ostr); +void NWUnpackDateTime(nuint32 dateTime, NW_DATE *sDate, NW_TIME *sTime); +void NWUnpackDate(nuint16 date, NW_DATE *sDate); +void NWUnpackTime(nuint16 time, NW_TIME *sTime); +time_t ncp_UnpackDateTime(nuint32 dateTime); +int  ncp_GetFileServerDateAndTime(NWCONN_HANDLE cH, time_t *target); +int  ncp_SetFileServerDateAndTime(NWCONN_HANDLE cH, time_t * source); +NWCCODE NWDownFileServer(NWCONN_HANDLE cH, int force); +NWCCODE NWCloseBindery(NWCONN_HANDLE cH); +NWCCODE NWOpenBindery(NWCONN_HANDLE cH); +NWCCODE NWDisableTTS(NWCONN_HANDLE cH); +NWCCODE NWEnableTTS(NWCONN_HANDLE cH); +NWCCODE NWDisableFileServerLogin(NWCONN_HANDLE cH); +NWCCODE NWEnableFileServerLogin(NWCONN_HANDLE cH); +void ncp_error(char *fmt, int error,...); +char *ncp_printb(char *dest, int flags, const struct ncp_bitname *bnp); +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 ipx_print_addr(struct ipx_addr *ipx); + +/* bindery calls */ +int  ncp_get_bindery_object_id(int connHandle, u_int16_t object_type, const char *object_name, +		struct ncp_bindery_object *target); +int  ncp_get_bindery_object_name(int connHandle, u_int32_t object_id,  +		struct ncp_bindery_object *target); +int  ncp_scan_bindery_object(int connHandle, u_int32_t last_id, u_int16_t object_type,  +		char *search_string, struct ncp_bindery_object *target); +int  ncp_read_property_value(int connHandle,int object_type, const char *object_name, +		int segment, const char *prop_name, struct nw_property *target); +void shuffle(const u_char *lon, const u_char *buf, int buflen, u_char *target); +int  ncp_get_encryption_key(NWCONN_HANDLE cH, char *target); +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); +int  ncp_keyed_verify_password(NWCONN_HANDLE cH, char *key, char *passwd, +			    struct ncp_bindery_object *objinfo); + +/* queue calls */ +int  ncp_create_queue_job_and_file(int connHandle, u_int32_t queue_id, struct queue_job *job); +int  ncp_close_file_and_start_job(int connHandle, u_int32_t queue_id,  struct queue_job *job); +int  ncp_attach_to_queue(int connHandle, u_int32_t queue_id); +int  ncp_detach_from_queue(int connHandle, u_int32_t queue_id); +int  ncp_service_queue_job(int connHandle, u_int32_t queue_id, u_int16_t job_type, +		struct queue_job *job); +int  ncp_finish_servicing_job(int connHandle, u_int32_t queue_id, u_int32_t job_number, +	u_int32_t charge_info); +int  ncp_abort_servicing_job(int connHandle, u_int32_t queue_id, u_int32_t job_number); +int  ncp_get_queue_length(int connHandle, u_int32_t queue_id, u_int32_t *queue_length); +int  ncp_get_queue_job_ids(int connHandle, u_int32_t queue_id, u_int32_t queue_section, +                       u_int32_t *length1, u_int32_t *length2, u_int32_t ids[]); +int  ncp_get_queue_job_info(int connHandle, u_int32_t queue_id, u_int32_t job_id, +                        struct nw_queue_job_entry *jobdata); +/* + * file system and volume calls  + */ +int  ncp_read(int connHandle, ncp_fh *fh, off_t offset, size_t count, char *target); +int  ncp_write(int connHandle, ncp_fh *fh, off_t offset, size_t count, char *source); +int  ncp_geteinfo(char *path, struct nw_entry_info *fi); +int  ncp_NSEntryInfo(NWCONN_HANDLE cH, nuint8 ns, nuint8 vol, nuint32 dirent, +	    NW_ENTRY_INFO *entryInfo); + +NWCCODE NWGetVolumeName(NWCONN_HANDLE cH, u_char volume, char *name); + +/* misc ncp calls */ +int  ncp_get_file_server_information(int connHandle, struct ncp_file_server_info *target); +int  ncp_get_stations_logged_info(int connHandle, u_int32_t connection, +		struct ncp_bindery_object *target, time_t *login_time); +int  ncp_get_internet_address(int connHandle, u_int32_t connection, struct ipx_addr *target, +			 u_int8_t * conn_type); +NWCCODE NWGetObjectConnectionNumbers(NWCONN_HANDLE connHandle, +		pnstr8 pObjName, nuint16 objType, +		pnuint16 pNumConns, pnuint16 pConnHandleList, +		nuint16 maxConns); +/* + * Message broadcast + */ +NWCCODE NWDisableBroadcasts(NWCONN_HANDLE connHandle); +NWCCODE	NWEnableBroadcasts(NWCONN_HANDLE connHandle); +NWCCODE	NWBroadcastToConsole(NWCONN_HANDLE  connHandle, pnstr8 message); +NWCCODE NWSendBroadcastMessage(NWCONN_HANDLE  connHandle, pnstr8 message, +	    nuint16 connCount, pnuint16 connList, pnuint8 resultList); +NWCCODE NWGetBroadcastMessage(NWCONN_HANDLE connHandle, pnstr8 message); + +/* + * RPC calls + */ +NWCCODE	NWSMExecuteNCFFile(NWCONN_HANDLE cH, pnstr8 NCFFileName); +NWCCODE	NWSMLoadNLM(NWCONN_HANDLE cH, pnstr8 cmd); +NWCCODE NWSMUnloadNLM(NWCONN_HANDLE cH, pnstr8 cmd); +NWCCODE NWSMMountVolume(NWCONN_HANDLE cH, pnstr8 volName, nuint32* volnum); +NWCCODE NWSMDismountVolumeByName(NWCONN_HANDLE cH, pnstr8 vol); +NWCCODE NWSMSetDynamicCmdIntValue(NWCONN_HANDLE cH, pnstr8 setCommandName, nuint32 cmdValue); +NWCCODE NWSMSetDynamicCmdStrValue(NWCONN_HANDLE cH, pnstr8 setCommandName, pnstr8 cmdValue); + +int dostat(int modnum, char *modname, int *offset); + +extern int  ncp_opterr, ncp_optind, ncp_optopt, ncp_optreset; +extern char *ncp_optarg; + +extern struct rcfile *ncp_rc; +extern int sysentoffset; +#endif /* _NCP_LIB_H_ */ diff --git a/lib/libncp/ncp_mod.h b/lib/libncp/ncp_mod.h new file mode 100644 index 0000000000000..4bdc39af3d07f --- /dev/null +++ b/lib/libncp/ncp_mod.h @@ -0,0 +1,16 @@ +/* + * Describes all ncp_lib kernel functions + * + * $FreeBSD$ + */ +#ifndef _NCP_MOD_H_ +#define _NCP_MOD_H_ + +/* order of calls in syscall table relative to offset in system table */ +#define	NCP_SE(callno)		(callno+sysentoffset) +#define	NCP_CONNSCAN		NCP_SE(0) +#define	NCP_CONNECT		NCP_SE(1) +#define	NCP_INTFN		NCP_SE(2) +#define	SNCP_REQUEST		NCP_SE(3) + +#endif /* !_NCP_MOD_H_ */
\ No newline at end of file diff --git a/lib/libncp/ncp_rcfile.h b/lib/libncp/ncp_rcfile.h new file mode 100644 index 0000000000000..bbdf8eb3dfe4a --- /dev/null +++ b/lib/libncp/ncp_rcfile.h @@ -0,0 +1,64 @@ +/* + * 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$ + */ +#ifndef _NCP_RCFILE_H_ +#define _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; +}; + +int  rc_open(char *filename,char *mode,struct rcfile **rcfile); +int  rc_close(struct rcfile *rcp); +int  rc_getstringptr(struct rcfile *rcp,char *section, char *key,char **dest); +int  rc_getstring(struct rcfile *rcp,char *section, char *key,int maxlen,char *dest); +int  rc_getint(struct rcfile *rcp,char *section, char *key,int *value); +int  rc_getbool(struct rcfile *rcp,char *section, char *key,int *value); + +#endif	/* _NCP_RCFILE_H_ */ diff --git a/lib/libncp/ncpl_bind.c b/lib/libncp/ncpl_bind.c new file mode 100644 index 0000000000000..40d0b7358eac5 --- /dev/null +++ b/lib/libncp/ncpl_bind.c @@ -0,0 +1,263 @@ +/* + * 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/types.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(int 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(int 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(int connid, u_int32_t last_id, u_int16_t object_type,  +	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(int 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); +	} +} diff --git a/lib/libncp/ncpl_conn.c b/lib/libncp/ncpl_conn.c new file mode 100644 index 0000000000000..df9580733169e --- /dev/null +++ b/lib/libncp/ncpl_conn.c @@ -0,0 +1,517 @@ +/* + * 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$ + */ + +/* + * + * 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 <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) { +		fprintf(stderr, "Server name too long:%s\n", 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) { +		fprintf(stderr, "User name too long:%s\n", 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) { +		fprintf(stderr, "Password too long:%s\n", passwd); +		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 ((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) { +			fprintf(stderr, "no default connection found: %s\n",strerror(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) { +			fprintf(stderr, "no server name specified\n"); +			error = 1; +			break; +		} +		error = ncp_find_fileserver(li, +		    (server_name==NULL) ? AF_IPX : AF_INET, server_name); +		if (error) { +			fprintf(stderr,"Can't find server %s, error=%s\n",li->server,strerror(errno)); +			break; +		} +		if (li->user == NULL || li->user[0] == 0) { +			fprintf(stderr, "no user name specified for server %s\n",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, len = sizeof(cnt); +	 +#if __FreeBSD_version < 400001 +	error = sysctlbyname("net.ipx.ncp.conn_cnt", &cnt, &len, NULL, 0); +#else +	error = sysctlbyname("net.ncp.conn_cnt", &cnt, &len, NULL, 0); +#endif +	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) { +			fprintf(stderr, "Invalid NCP signature level option `%s' (must be number between 0 and 3)\n", 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, 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; +#if __FreeBSD_version < 400001 +	error = sysctlbyname("net.ipx.ncp.conn_stat", p, &len, NULL, 0); +#else +	error = sysctlbyname("net.ncp.conn_stat", p, &len, NULL, 0); +#endif +	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]; +	(const char*)p->username = user; +	p->objtype = objtype; +	(const char*)p->password = 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; +} diff --git a/lib/libncp/ncpl_crypt.c b/lib/libncp/ncpl_crypt.c new file mode 100644 index 0000000000000..00ce9bfd9a112 --- /dev/null +++ b/lib/libncp/ncpl_crypt.c @@ -0,0 +1,137 @@ +/*  + *  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 + * + * $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]; +} + + diff --git a/lib/libncp/ncpl_file.c b/lib/libncp/ncpl_file.c new file mode 100644 index 0000000000000..e305bc0b0999f --- /dev/null +++ b/lib/libncp/ncpl_file.c @@ -0,0 +1,263 @@ +/* + * 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/ioctl.h> +#include <errno.h> +#include <stdio.h> +#include <fcntl.h> +#include <unistd.h> +#include <strings.h> + +#include <netncp/ncp_lib.h> +#include <netncp/ncp_file.h> +#include <nwfs/nwfs.h> + +int +ncp_read(int 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(int 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; +} diff --git a/lib/libncp/ncpl_misc.c b/lib/libncp/ncpl_misc.c new file mode 100644 index 0000000000000..7f7a67a8a368c --- /dev/null +++ b/lib/libncp/ncpl_misc.c @@ -0,0 +1,289 @@ +/* + * 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$ + * + * calls that don't fit to any other category + * + */ +#include <sys/types.h> +#include <sys/time.h> +#include <errno.h> +#include <stdio.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(int 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(int 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(int 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; +	DECLARE_RQ; +	ncp_init_request_s(conn, 21); +	ncp_add_word_hl(conn, objType); +	ncp_add_pstring(conn, pObjName); +	if ((error = ncp_request(connHandle, 23, conn)) != 0) return error; +	i = ncp_reply_byte(conn,0); +	*pNumConns = i; +	for (i = min(i, maxConns); i; i--) { +		pConnHandleList[i-1] = ncp_reply_byte(conn, i); +	} +	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); +} diff --git a/lib/libncp/ncpl_msg.c b/lib/libncp/ncpl_msg.c new file mode 100644 index 0000000000000..a65131bd14fbe --- /dev/null +++ b/lib/libncp/ncpl_msg.c @@ -0,0 +1,131 @@ +/* + * 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/types.h> +#include <errno.h> +#include <stdio.h> +#include <strings.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; +} diff --git a/lib/libncp/ncpl_net.c b/lib/libncp/ncpl_net.c new file mode 100644 index 0000000000000..da21b663de51c --- /dev/null +++ b/lib/libncp/ncpl_net.c @@ -0,0 +1,150 @@ +/* + * 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/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> +#include "ncp_mod.h" + +static int ncp_find_server_in(struct ncp_conn_loginfo *li, int type, char *server_name); + +static int +ncp_find_server_ipx(struct ncp_conn_loginfo *li, int type) { +	char server[NCP_BINDERY_NAME_LEN + 1]; +	int error; +	char nearest[NCP_BINDERY_NAME_LEN + 1]; +	struct nw_property prop; +	struct ipx_addr *n_addr = (struct ipx_addr *) ∝ +/*	struct ncp_conn_loginfo ltmp;*/ +	int connid; + +	bzero(server, sizeof(server)); +	bzero(nearest, sizeof(nearest)); + +	strcpy(server, li->server); +	ncp_str_upper(server); + +	if ((error = sap_find_nearest(type, &li->ipxaddr, nearest)) != 0) { +		return error; +	} +	/* if no server specified return info about nearest */ +	if (!li->server[0]) { +		strcpy(li->server, nearest); +		return 0; +	} +/*	printf("%s\n",ipx_ntoa(li->ipxaddr.sipx_addr));*/ +	if (strcmp(server, nearest) == 0) { +		return 0; +	} +	/* We have to ask the nearest server for our wanted server */ +	li->opt=0; +	if ((error = ncp_connect(li, &connid)) != 0) { +		return error; +	} +	if (ncp_read_property_value(connid, type, server, 1, "NET_ADDRESS", &prop) != 0) { +		ncp_disconnect(connid); +		return EHOSTUNREACH; +	} +	if ((error = ncp_disconnect(connid)) != 0) { +		return error; +	} +	li->ipxaddr.sipx_family = AF_IPX; +	li->ipxaddr.sipx_addr.x_net = n_addr->x_net; +	li->ipxaddr.sipx_port = n_addr->x_port; +	li->ipxaddr.sipx_addr.x_host = n_addr->x_host; +	return 0; +} + +static int +ncp_find_server_in(struct ncp_conn_loginfo *li, int type, char *server_name) { +	struct hostent* h; +	int l; + +	h = gethostbyname(server_name); +	if (!h) { +		fprintf(stderr, "Get host address `%s': ", server_name); +		herror(NULL); +		return 1; +	} +	if (h->h_addrtype != AF_INET) { +		fprintf(stderr, "Get host address `%s': Not AF_INET\n", server_name); +		return 1; +	} +	if (h->h_length != 4) { +		fprintf(stderr, "Get host address `%s': Bad address length\n", server_name); +		return 1; +	} +	l = sizeof(struct sockaddr_in); +	bzero(&li->inaddr, l); +	li->inaddr.sin_len = l; +	li->inaddr.sin_family = h->h_addrtype; +	memcpy(&li->inaddr.sin_addr.s_addr, h->h_addr, 4); +	li->inaddr.sin_port = htons(524); /* ncp */ +	return 0; +} + +int  +ncp_find_server(struct ncp_conn_loginfo *li, int type, int af, char *name) { +	int error = EHOSTUNREACH; + +	switch(af) { +	    case AF_IPX: +		error = ncp_find_server_ipx(li, type); +		break; +	    case AF_INET: +		if (name) +			error = ncp_find_server_in(li, type, name); +		break; +	    default: +		error = EPROTONOSUPPORT; +	} +	return error; +} + +int +ncp_find_fileserver(struct ncp_conn_loginfo *li, int af, char *name) { +	return ncp_find_server(li, NCP_BINDERY_FSERVER, af, name); +} diff --git a/lib/libncp/ncpl_nls.c b/lib/libncp/ncpl_nls.c new file mode 100644 index 0000000000000..92bc013c6103d --- /dev/null +++ b/lib/libncp/ncpl_nls.c @@ -0,0 +1,272 @@ +/* + * 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$ + */ + +/* + * Languages support. Currently is very primitive. + */ +#include <sys/types.h> +#include <ctype.h> +#include <errno.h> +#include <stdio.h> +#include <strings.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 + +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 +	{NULL, 0} +}; + +struct ncp_nlstables ncp_nls; + +int +ncp_nls_setlocale(char *name) { +	int i; + +	ncp_nls.tolower = def2lower; +	ncp_nls.toupper = 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.tolower[i] = tolower(i); +		ncp_nls.toupper[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; +} diff --git a/lib/libncp/ncpl_queue.c b/lib/libncp/ncpl_queue.c new file mode 100644 index 0000000000000..beb34c7bd1556 --- /dev/null +++ b/lib/libncp/ncpl_queue.c @@ -0,0 +1,214 @@ +/* + * 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$ + * + * NetWare queue interface + * + */ +#include <sys/types.h> +#include <errno.h> +#include <stdio.h> +#include <netncp/ncp_lib.h> + +int +ncp_create_queue_job_and_file(int 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(int 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(int 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(int 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(int 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(int 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(int 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(int 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(int 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(int 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; +} diff --git a/lib/libncp/ncpl_rcfile.c b/lib/libncp/ncpl_rcfile.c new file mode 100644 index 0000000000000..7a69071be7521 --- /dev/null +++ b/lib/libncp/ncpl_rcfile.c @@ -0,0 +1,407 @@ +/* + * 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/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; +} + diff --git a/lib/libncp/ncpl_rpc.c b/lib/libncp/ncpl_rpc.c new file mode 100644 index 0000000000000..f2f9e54425e47 --- /dev/null +++ b/lib/libncp/ncpl_rpc.c @@ -0,0 +1,136 @@ +/* + * 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. + * NetWare RPCs + * + * $FreeBSD$ + */ +#include <sys/types.h> +#include <sys/time.h> +#include <errno.h> +#include <stdio.h> +#include <strings.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); +} diff --git a/lib/libncp/ncpl_subr.c b/lib/libncp/ncpl_subr.c new file mode 100644 index 0000000000000..c7606c72abe8b --- /dev/null +++ b/lib/libncp/ncpl_subr.c @@ -0,0 +1,470 @@ +/* + * 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/types.h> +#include <sys/errno.h> +#include <sys/sysctl.h> +#include <sys/syscall.h> +#include <unistd.h> +#include <ctype.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 "ncp_mod.h" + +int sysentoffset; + +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) { +	return syscall(NCP_CONNECT,li,connHandle); +} + +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){ +	int err = syscall(SNCP_REQUEST,connHandle,function,ncpbuf); +	return (err<0) ? errno : 0; +} + +int +ncp_conn_request(int connHandle, struct ncp_buf *ncpbuf){ +	return syscall(SNCP_REQUEST, connHandle, NCP_CONN, ncpbuf); +} + +int +ncp_conn_scan(struct ncp_conn_loginfo *li, int *connid) { +	return syscall(NCP_CONNSCAN,li, connid); +} + +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 len = sizeof(sysentoffset); +	int kv, kvlen = sizeof(kv); +	static int ncp_initialized; + +	if (ncp_initialized) +		return 0; +#if __FreeBSD_version < 400001 +	error = sysctlbyname("net.ipx.ncp.sysent", &sysentoffset, &len, NULL, 0); +#else +	error = sysctlbyname("net.ncp.sysent", &sysentoffset, &len, NULL, 0); +#endif +	if (error) { +		fprintf(stderr, "%s: can't find kernel module\n", __FUNCTION__); +		return error; +	} +#if __FreeBSD_version < 400001 +	error = sysctlbyname("net.ipx.ncp.version", &kv, &kvlen, NULL, 0); +#else +	error = sysctlbyname("net.ncp.version", &kv, &kvlen, NULL, 0); +#endif +	if (error) { +		fprintf(stderr, "%s: kernel module is old, please recompile it.\n", __FUNCTION__); +		return error; +	} +	if (NCP_VERSION != kv) { +		fprintf(stderr, "%s: kernel module version(%d) don't match library(%d).\n", __FUNCTION__, kv, NCP_VERSION); +		return EINVAL; +	} +	if ((error = ncp_nls_setrecode(0)) != 0) { +		fprintf(stderr, "%s: can't initialise recode\n", __FUNCTION__); +		return error; +	} +	if ((error = ncp_nls_setlocale("")) != 0) { +		fprintf(stderr, "%s: can't initialise locale\n", __FUNCTION__); +		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; +{ +	extern char *__progname; +	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", __progname, 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", +				    __progname, 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(char *fmt, int error,...) { +	va_list ap; + +	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; +} diff --git a/lib/libncp/sap.c b/lib/libncp/sap.c new file mode 100644 index 0000000000000..32e0ab2171113 --- /dev/null +++ b/lib/libncp/sap.c @@ -0,0 +1,302 @@ +/* + * 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 <stdlib.h> +#include <string.h> +#include <sys/types.h> +#include <sys/socket.h> +#include <sys/time.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) { +			packets++; +			continue; +		} +	} while (ntohs(reply->operation) != IPX_SAP_NEAREST_RESPONSE && +		 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; +} diff --git a/sys/netncp/ncp_cfg.h b/sys/netncp/ncp_cfg.h new file mode 100644 index 0000000000000..82a30d748d5d2 --- /dev/null +++ b/sys/netncp/ncp_cfg.h @@ -0,0 +1,9 @@ +/*  + * static configuration for libncp + * + * $FreeBSD$ + */ + +#define NCP_NLS_KOI2CP866 +#define NCP_NLS_DEFAULT NCP_NLS_KOI_866 +#define NCP_PREFIX	"" diff --git a/sys/netncp/ncp_file.h b/sys/netncp/ncp_file.h new file mode 100644 index 0000000000000..17b5bd5f8aeca --- /dev/null +++ b/sys/netncp/ncp_file.h @@ -0,0 +1,92 @@ +/* + * 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$ + */ + +#ifndef _NCP_NCP_FILE_H_ +#define _NCP_NCP_FILE_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +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]; +} __attribute__((packed)) NWDELETED_INFO; + +int	ncp_AllocTempDirHandle(char *path, NWDIR_HANDLE *pdh); +int	ncp_DeallocateDirHandle(NWDIR_HANDLE dh); +int	ncp_GetNSEntryInfo(NWDIR_HANDLE dh, struct nw_entry_info *fi, int *ns); + +NWCCODE	ncp_ScanNSEntryInfo(NWCONN_HANDLE cH, nuint8 namSpc, nuint16 attrs, +	SEARCH_SEQUENCE *seq, pnstr8 searchPattern, nuint32 retInfoMask,  +	NW_ENTRY_INFO *entryInfo); + +NWCCODE ncp_PurgeDeletedFile(NWCONN_HANDLE cH, nuint32 iterHandle,  +	nuint32 volNum, nuint32 dirBase, nuint8 ns); + +NWCCODE NWRecoverDeletedFile(NWCONN_HANDLE conn, NWDIR_HANDLE dirHandle, +	nuint32 iterHandle,  +	nuint32 volNum, nuint32 dirBase,  +	pnstr8  delFileName, pnstr8 rcvrFileName); + +NWCCODE ncp_ScanForDeletedFiles(NWCONN_HANDLE cH, pnuint32 iterHandle,  +	pnuint32 volNum, pnuint32 dirBase, nuint8 ns, +	NWDELETED_INFO *entryInfo); + + +#ifdef __cplusplus +} +#endif + +#endif /* _NCP_NCP_FILE_ */ diff --git a/sys/netncp/ncp_lib.h b/sys/netncp/ncp_lib.h new file mode 100644 index 0000000000000..bff63390017a6 --- /dev/null +++ b/sys/netncp/ncp_lib.h @@ -0,0 +1,258 @@ +/* + * 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$ + */ + +#ifndef _NCP_LIB_H_ +#define _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:N:O: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; +	char	*bn_name; +}; + +int ncp_args_parserc(struct ncp_args *na, char *sect, ncp_setopt_t *set_callback); +int ncp_args_parseopt(struct ncp_args *na, int opt, char *optarg, ncp_setopt_t *set_callback); + + +struct sockaddr_ipx; +struct ipx_addr; +struct sockaddr; +struct ncp_buf; +struct rcfile; + +int  ncp_initlib(void); +int  ncp_connect(struct ncp_conn_args *li, int *connHandle); +int  ncp_connect_addr(struct sockaddr *sa, NWCONN_HANDLE *chp); +int  ncp_disconnect(int connHandle); +int  ncp_request(int connHandle,int function, struct ncp_buf *ncpbuf); +int  ncp_conn_request(int connHandle, struct ncp_buf *ncpbuf); +int  ncp_login(int connHandle, const char *user, int objtype, const char *password); +int  ncp_conn_scan(struct ncp_conn_loginfo *li, int *connHandle); +int  ncp_conn_cnt(void); +void *ncp_conn_list(void); +int  ncp_conn_getinfo(int connHandle, struct ncp_conn_stat *ps); +int  ncp_conn_getuser(int connHandle, char **user); +int  ncp_conn2ref(int connHandle, int *connRef); +int  ncp_conn_dup(NWCONN_HANDLE org, NWCONN_HANDLE *res); +int  ncp_path2conn(char *path, int *connHandle); +int  ncp_li_init(struct ncp_conn_loginfo *li, int argc, char *argv[]); +void ncp_li_done(struct ncp_conn_loginfo *li); +int  ncp_li_login(struct ncp_conn_loginfo *li, int *aconnHandle); +int  ncp_li_readrc(struct ncp_conn_loginfo *li); +int  ncp_li_check(struct ncp_conn_loginfo *li); +int  ncp_li_arg(struct ncp_conn_loginfo *li, int opt, char *arg); +int  ncp_li_setserver(struct ncp_conn_loginfo *li, const char *arg); +int  ncp_li_setuser(struct ncp_conn_loginfo *li, char *arg); +int  ncp_li_setpassword(struct ncp_conn_loginfo *li, const char *passwd); +int  ncp_conn_setflags(int connHandle, u_int16_t mask, u_int16_t flags); +int  ncp_conn_find(char *server, char *user); +NWCCODE NWRequest(NWCONN_HANDLE cH, nuint16 fn, +	nuint16 nrq, NW_FRAGMENT* rq,  +	nuint16 nrp, NW_FRAGMENT* rp) ; + +#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 *li, int af,char *name); +int  ncp_find_server(struct ncp_conn_loginfo *li, int type, int af,char *name); + +/* misc rotines */ +char* ncp_str_upper(char *name); +int  ncp_open_rcfile(void); +int  ncp_getopt(int nargc, char * const *nargv, const char *ostr); +void NWUnpackDateTime(nuint32 dateTime, NW_DATE *sDate, NW_TIME *sTime); +void NWUnpackDate(nuint16 date, NW_DATE *sDate); +void NWUnpackTime(nuint16 time, NW_TIME *sTime); +time_t ncp_UnpackDateTime(nuint32 dateTime); +int  ncp_GetFileServerDateAndTime(NWCONN_HANDLE cH, time_t *target); +int  ncp_SetFileServerDateAndTime(NWCONN_HANDLE cH, time_t * source); +NWCCODE NWDownFileServer(NWCONN_HANDLE cH, int force); +NWCCODE NWCloseBindery(NWCONN_HANDLE cH); +NWCCODE NWOpenBindery(NWCONN_HANDLE cH); +NWCCODE NWDisableTTS(NWCONN_HANDLE cH); +NWCCODE NWEnableTTS(NWCONN_HANDLE cH); +NWCCODE NWDisableFileServerLogin(NWCONN_HANDLE cH); +NWCCODE NWEnableFileServerLogin(NWCONN_HANDLE cH); +void ncp_error(char *fmt, int error,...); +char *ncp_printb(char *dest, int flags, const struct ncp_bitname *bnp); +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 ipx_print_addr(struct ipx_addr *ipx); + +/* bindery calls */ +int  ncp_get_bindery_object_id(int connHandle, u_int16_t object_type, const char *object_name, +		struct ncp_bindery_object *target); +int  ncp_get_bindery_object_name(int connHandle, u_int32_t object_id,  +		struct ncp_bindery_object *target); +int  ncp_scan_bindery_object(int connHandle, u_int32_t last_id, u_int16_t object_type,  +		char *search_string, struct ncp_bindery_object *target); +int  ncp_read_property_value(int connHandle,int object_type, const char *object_name, +		int segment, const char *prop_name, struct nw_property *target); +void shuffle(const u_char *lon, const u_char *buf, int buflen, u_char *target); +int  ncp_get_encryption_key(NWCONN_HANDLE cH, char *target); +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); +int  ncp_keyed_verify_password(NWCONN_HANDLE cH, char *key, char *passwd, +			    struct ncp_bindery_object *objinfo); + +/* queue calls */ +int  ncp_create_queue_job_and_file(int connHandle, u_int32_t queue_id, struct queue_job *job); +int  ncp_close_file_and_start_job(int connHandle, u_int32_t queue_id,  struct queue_job *job); +int  ncp_attach_to_queue(int connHandle, u_int32_t queue_id); +int  ncp_detach_from_queue(int connHandle, u_int32_t queue_id); +int  ncp_service_queue_job(int connHandle, u_int32_t queue_id, u_int16_t job_type, +		struct queue_job *job); +int  ncp_finish_servicing_job(int connHandle, u_int32_t queue_id, u_int32_t job_number, +	u_int32_t charge_info); +int  ncp_abort_servicing_job(int connHandle, u_int32_t queue_id, u_int32_t job_number); +int  ncp_get_queue_length(int connHandle, u_int32_t queue_id, u_int32_t *queue_length); +int  ncp_get_queue_job_ids(int connHandle, u_int32_t queue_id, u_int32_t queue_section, +                       u_int32_t *length1, u_int32_t *length2, u_int32_t ids[]); +int  ncp_get_queue_job_info(int connHandle, u_int32_t queue_id, u_int32_t job_id, +                        struct nw_queue_job_entry *jobdata); +/* + * file system and volume calls  + */ +int  ncp_read(int connHandle, ncp_fh *fh, off_t offset, size_t count, char *target); +int  ncp_write(int connHandle, ncp_fh *fh, off_t offset, size_t count, char *source); +int  ncp_geteinfo(char *path, struct nw_entry_info *fi); +int  ncp_NSEntryInfo(NWCONN_HANDLE cH, nuint8 ns, nuint8 vol, nuint32 dirent, +	    NW_ENTRY_INFO *entryInfo); + +NWCCODE NWGetVolumeName(NWCONN_HANDLE cH, u_char volume, char *name); + +/* misc ncp calls */ +int  ncp_get_file_server_information(int connHandle, struct ncp_file_server_info *target); +int  ncp_get_stations_logged_info(int connHandle, u_int32_t connection, +		struct ncp_bindery_object *target, time_t *login_time); +int  ncp_get_internet_address(int connHandle, u_int32_t connection, struct ipx_addr *target, +			 u_int8_t * conn_type); +NWCCODE NWGetObjectConnectionNumbers(NWCONN_HANDLE connHandle, +		pnstr8 pObjName, nuint16 objType, +		pnuint16 pNumConns, pnuint16 pConnHandleList, +		nuint16 maxConns); +/* + * Message broadcast + */ +NWCCODE NWDisableBroadcasts(NWCONN_HANDLE connHandle); +NWCCODE	NWEnableBroadcasts(NWCONN_HANDLE connHandle); +NWCCODE	NWBroadcastToConsole(NWCONN_HANDLE  connHandle, pnstr8 message); +NWCCODE NWSendBroadcastMessage(NWCONN_HANDLE  connHandle, pnstr8 message, +	    nuint16 connCount, pnuint16 connList, pnuint8 resultList); +NWCCODE NWGetBroadcastMessage(NWCONN_HANDLE connHandle, pnstr8 message); + +/* + * RPC calls + */ +NWCCODE	NWSMExecuteNCFFile(NWCONN_HANDLE cH, pnstr8 NCFFileName); +NWCCODE	NWSMLoadNLM(NWCONN_HANDLE cH, pnstr8 cmd); +NWCCODE NWSMUnloadNLM(NWCONN_HANDLE cH, pnstr8 cmd); +NWCCODE NWSMMountVolume(NWCONN_HANDLE cH, pnstr8 volName, nuint32* volnum); +NWCCODE NWSMDismountVolumeByName(NWCONN_HANDLE cH, pnstr8 vol); +NWCCODE NWSMSetDynamicCmdIntValue(NWCONN_HANDLE cH, pnstr8 setCommandName, nuint32 cmdValue); +NWCCODE NWSMSetDynamicCmdStrValue(NWCONN_HANDLE cH, pnstr8 setCommandName, pnstr8 cmdValue); + +int dostat(int modnum, char *modname, int *offset); + +extern int  ncp_opterr, ncp_optind, ncp_optopt, ncp_optreset; +extern char *ncp_optarg; + +extern struct rcfile *ncp_rc; +extern int sysentoffset; +#endif /* _NCP_LIB_H_ */ diff --git a/sys/netncp/ncp_rcfile.h b/sys/netncp/ncp_rcfile.h new file mode 100644 index 0000000000000..bbdf8eb3dfe4a --- /dev/null +++ b/sys/netncp/ncp_rcfile.h @@ -0,0 +1,64 @@ +/* + * 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$ + */ +#ifndef _NCP_RCFILE_H_ +#define _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; +}; + +int  rc_open(char *filename,char *mode,struct rcfile **rcfile); +int  rc_close(struct rcfile *rcp); +int  rc_getstringptr(struct rcfile *rcp,char *section, char *key,char **dest); +int  rc_getstring(struct rcfile *rcp,char *section, char *key,int maxlen,char *dest); +int  rc_getint(struct rcfile *rcp,char *section, char *key,int *value); +int  rc_getbool(struct rcfile *rcp,char *section, char *key,int *value); + +#endif	/* _NCP_RCFILE_H_ */  | 
