Initial import of ncp library sources.
Reviewed by: jdp, mdodd
This commit is contained in:
parent
cff51c813a
commit
efef966da8
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=52153
27
lib/libncp/CREDITS
Normal file
27
lib/libncp/CREDITS
Normal file
@ -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>
|
24
lib/libncp/Makefile
Normal file
24
lib/libncp/Makefile
Normal file
@ -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>
|
351
lib/libncp/ipx.c
Normal file
351
lib/libncp/ipx.c
Normal file
@ -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);
|
||||
}
|
||||
}
|
||||
|
95
lib/libncp/ipxsap.h
Normal file
95
lib/libncp/ipxsap.h
Normal file
@ -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_ */
|
9
lib/libncp/ncp_cfg.h
Normal file
9
lib/libncp/ncp_cfg.h
Normal file
@ -0,0 +1,9 @@
|
||||
/*
|
||||
* static configuration for libncp
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#define NCP_NLS_KOI2CP866
|
||||
#define NCP_NLS_DEFAULT NCP_NLS_KOI_866
|
||||
#define NCP_PREFIX ""
|
92
lib/libncp/ncp_file.h
Normal file
92
lib/libncp/ncp_file.h
Normal file
@ -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_ */
|
258
lib/libncp/ncp_lib.h
Normal file
258
lib/libncp/ncp_lib.h
Normal file
@ -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_ */
|
16
lib/libncp/ncp_mod.h
Normal file
16
lib/libncp/ncp_mod.h
Normal file
@ -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_ */
|
64
lib/libncp/ncp_rcfile.h
Normal file
64
lib/libncp/ncp_rcfile.h
Normal file
@ -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_ */
|
263
lib/libncp/ncpl_bind.c
Normal file
263
lib/libncp/ncpl_bind.c
Normal file
@ -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);
|
||||
}
|
||||
}
|
517
lib/libncp/ncpl_conn.c
Normal file
517
lib/libncp/ncpl_conn.c
Normal file
@ -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;
|
||||
}
|
137
lib/libncp/ncpl_crypt.c
Normal file
137
lib/libncp/ncpl_crypt.c
Normal file
@ -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];
|
||||
}
|
||||
|
||||
|
263
lib/libncp/ncpl_file.c
Normal file
263
lib/libncp/ncpl_file.c
Normal file
@ -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;
|
||||
}
|
289
lib/libncp/ncpl_misc.c
Normal file
289
lib/libncp/ncpl_misc.c
Normal file
@ -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);
|
||||
}
|
131
lib/libncp/ncpl_msg.c
Normal file
131
lib/libncp/ncpl_msg.c
Normal file
@ -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;
|
||||
}
|
150
lib/libncp/ncpl_net.c
Normal file
150
lib/libncp/ncpl_net.c
Normal file
@ -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);
|
||||
}
|
272
lib/libncp/ncpl_nls.c
Normal file
272
lib/libncp/ncpl_nls.c
Normal file
@ -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;
|
||||
}
|
214
lib/libncp/ncpl_queue.c
Normal file
214
lib/libncp/ncpl_queue.c
Normal file
@ -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;
|
||||
}
|
407
lib/libncp/ncpl_rcfile.c
Normal file
407
lib/libncp/ncpl_rcfile.c
Normal file
@ -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;
|
||||
}
|
||||
|
136
lib/libncp/ncpl_rpc.c
Normal file
136
lib/libncp/ncpl_rpc.c
Normal file
@ -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);
|
||||
}
|
470
lib/libncp/ncpl_subr.c
Normal file
470
lib/libncp/ncpl_subr.c
Normal file
@ -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;
|
||||
}
|
302
lib/libncp/sap.c
Normal file
302
lib/libncp/sap.c
Normal file
@ -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;
|
||||
}
|
9
sys/netncp/ncp_cfg.h
Normal file
9
sys/netncp/ncp_cfg.h
Normal file
@ -0,0 +1,9 @@
|
||||
/*
|
||||
* static configuration for libncp
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#define NCP_NLS_KOI2CP866
|
||||
#define NCP_NLS_DEFAULT NCP_NLS_KOI_866
|
||||
#define NCP_PREFIX ""
|
92
sys/netncp/ncp_file.h
Normal file
92
sys/netncp/ncp_file.h
Normal file
@ -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_ */
|
258
sys/netncp/ncp_lib.h
Normal file
258
sys/netncp/ncp_lib.h
Normal file
@ -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_ */
|
64
sys/netncp/ncp_rcfile.h
Normal file
64
sys/netncp/ncp_rcfile.h
Normal file
@ -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_ */
|
Loading…
Reference in New Issue
Block a user