Initial import of ncp library sources.

Reviewed by:	jdp, mdodd
This commit is contained in:
Boris Popov 1999-10-12 11:56:41 +00:00
parent cff51c813a
commit efef966da8
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=52153
26 changed files with 4910 additions and 0 deletions

27
lib/libncp/CREDITS Normal file
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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 *) &prop;
/* struct ncp_conn_loginfo ltmp;*/
int connid;
bzero(server, sizeof(server));
bzero(nearest, sizeof(nearest));
strcpy(server, li->server);
ncp_str_upper(server);
if ((error = sap_find_nearest(type, &li->ipxaddr, nearest)) != 0) {
return error;
}
/* if no server specified return info about nearest */
if (!li->server[0]) {
strcpy(li->server, nearest);
return 0;
}
/* printf("%s\n",ipx_ntoa(li->ipxaddr.sipx_addr));*/
if (strcmp(server, nearest) == 0) {
return 0;
}
/* We have to ask the nearest server for our wanted server */
li->opt=0;
if ((error = ncp_connect(li, &connid)) != 0) {
return error;
}
if (ncp_read_property_value(connid, type, server, 1, "NET_ADDRESS", &prop) != 0) {
ncp_disconnect(connid);
return EHOSTUNREACH;
}
if ((error = ncp_disconnect(connid)) != 0) {
return error;
}
li->ipxaddr.sipx_family = AF_IPX;
li->ipxaddr.sipx_addr.x_net = n_addr->x_net;
li->ipxaddr.sipx_port = n_addr->x_port;
li->ipxaddr.sipx_addr.x_host = n_addr->x_host;
return 0;
}
static int
ncp_find_server_in(struct ncp_conn_loginfo *li, int type, char *server_name) {
struct hostent* h;
int l;
h = gethostbyname(server_name);
if (!h) {
fprintf(stderr, "Get host address `%s': ", server_name);
herror(NULL);
return 1;
}
if (h->h_addrtype != AF_INET) {
fprintf(stderr, "Get host address `%s': Not AF_INET\n", server_name);
return 1;
}
if (h->h_length != 4) {
fprintf(stderr, "Get host address `%s': Bad address length\n", server_name);
return 1;
}
l = sizeof(struct sockaddr_in);
bzero(&li->inaddr, l);
li->inaddr.sin_len = l;
li->inaddr.sin_family = h->h_addrtype;
memcpy(&li->inaddr.sin_addr.s_addr, h->h_addr, 4);
li->inaddr.sin_port = htons(524); /* ncp */
return 0;
}
int
ncp_find_server(struct ncp_conn_loginfo *li, int type, int af, char *name) {
int error = EHOSTUNREACH;
switch(af) {
case AF_IPX:
error = ncp_find_server_ipx(li, type);
break;
case AF_INET:
if (name)
error = ncp_find_server_in(li, type, name);
break;
default:
error = EPROTONOSUPPORT;
}
return error;
}
int
ncp_find_fileserver(struct ncp_conn_loginfo *li, int af, char *name) {
return ncp_find_server(li, NCP_BINDERY_FSERVER, af, name);
}

272
lib/libncp/ncpl_nls.c Normal file
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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_ */