Compare commits

...

1 Commits

Author SHA1 Message Date
ncpfs archive import
0979ae6a41 Import ncpfs 2.2.0 2026-04-28 20:39:59 +02:00
119 changed files with 12194 additions and 10043 deletions

BIN
.downloads/ncpfs-2.2.0.tgz Normal file

Binary file not shown.

19
BUGS
View File

@@ -13,9 +13,8 @@ down the complete ipx subsystem by deleting all ipx interfaces,
unmounting all ncpfs volumes (in this order!) and restarting all
again.
For the kernel hackers who want to look at the problem: The routine
ipx_sendmsg in net/ipx/af_ipx.c sometimes locks forever if called with
nonblock=0. I DO NOT KNOW WHY!!! HELP ME, PLEASE!
This problem has been solved by Martin Stover (THANKS!!)
See patches/lockup-2.0.30.diff for the fix.
-------------------------------------------------------------------------------
@@ -34,3 +33,17 @@ like
Nov 25 16:09:08 lx01 kernel: alloc_skb called nonatomically from interrupt 0000002e
These are a bit annoying, but completely harmless.
-------------------------------------------------------------------------------
Known bugs:
- It returns error 255 during bindery login on one site... I do not know why.
- If GetNearsetServer returns invalid (nonexistant, downed) server, all
utilities gives up. VLM/Client32 in this situation tries randomly choosen
server after 30 secs timeout. You have to fix your routers at this time.
Sorry.
- NFS namespace does not work on Netware Storage Services volume... Sorry,
it is not my fault and I did not found any workaround (maybe that I have
workaround for NSS from NW5Beta3)

127
Changes
View File

@@ -1,9 +1,130 @@
I only began this file with ncpfs-0.12. If you're interested in older
versions, you can find them on ftp.gwdg.de:/pub/linux/misc/ncpfs/old.
ncpfs-2.0.10 -> ncpfs-2.1.1
- Restructured the kernel part a bit, moved watchdog and message support
out of the kernel into ncpmount.
[Versions ncpfs-2.0.12.x are available at ftp://platan.vc.cvut.cz/pub/linux/ncpfs]
ncpfs-2.0.12.10 -> ncpfs-2.2.0
- VANA: minor cleanup
ncpfs-2.0.12.9 -> ncpfs-2.0.12.10
- VANA: you can now access NDS server without replica of its conteiner
(TODO: access to server if server has R/W replica of your account but
does not have replica of itself)
- VANA: Alpha still no go :-(
ncpfs-2.0.12.8 -> ncpfs-2.0.12.9
- Eloy A. Paris: Fixes in library code
ncpfs-2.0.12.7 -> ncpfs-2.0.12.8
- VANA: bugfix, now it works again without ipxripd
- VANA: still cleaning up, ncp_open() and NDS byte ordering
ncpfs-2.0.12.6 -> ncpfs-2.0.12.7
- VANA: bugfixes, nwpurge
ncpfs-2.0.12.5 -> ncpfs-2.0.12.6
- VANA: ncpmount supports NCP over IP (no incoming broadcast at this time)
ncpfs-2.0.12.4 -> ncpfs-2.0.12.5
- Eloy A. Paris: Makefile bugfix
ncpfs-2.0.12.3 -> ncpfs-2.0.12.4
- VANA: Bugfixes
- VANA: Alpha stage of native NCP over IP support (no kernel at this time)
ncpfs-2.0.12.2 -> ncpfs-2.0.12.3
- VANA: Major makefile changes, compile warning cleanup
ncpfs-2.0.12.1 -> ncpfs-2.0.12.2
- Eloy A. Paris <peloy@ven.ra.rockwell.com>: Makefile cleanup
- VANA: More merging sutil/ncplib.c and lib/ncplib.c, not fully functional yet
ncpfs-2.0.12 -> ncpfs-2.0.12.1
- Dave, VANA: Bindery logins for all utilities (-b)
- VANA: Specify signature level for ncpmount (-i number)
- VANA: Start of merging sutil/*lib* with lib/*lib*
ncpfs-2.0.11.19 -> ncpfs-2.0.12
- Polished for release 2.0.12
- Dave: pserver fixes, including addition of %d flag.
ncpfs-2.0.11.18 -> ncpfs-2.0.11.19
- Dave, VANA: new userspace utilities - pqstat and pqrm
ncpfs-2.0.11.17 -> ncpfs-2.0.11.18 (no userspace change)
- Dave: getwd() did not work on 2.1.x
- VANA: Volumes are now always listed lowercased on 2.1.x
ncpfs-2.0.11.16 -> ncpfs-2.0.11.17
- David Woodhouse <Dave@imladris.demon.co.uk>: Patch to pserver,
ncp_get_broadcast_message
- VANA & Dave: Cleanup for glibc, I hope that complete (xcpt. few warnings
about long int vs. u_int32_t)
ncpfs-2.0.11.15 -> ncpfs-2.0.11.16
- VANA: Removed symlink latest from archive :-)
- VANA: Added ncp_send_broadcast2
ncpfs-2.0.11.14 -> ncpfs-2.0.11.15
- VANA: Fixed bug: wrong completion code returned when login to server without
r/w replica of logged-in user
- VANA: It is possible to disable NFS and/or OS2 namespace support in mount
ncpfs-2.0.11.13 -> ncpfs-2.0.11.14
- VANA: One source for 2.0 and 2.1 kernels
- Chirstian Groessler <cpg@aladdin.de>: Added strong mounts
ncpfs-2.0.11.12 -> ncpfs-2.0.11.13
- Arne: Signatures added to ncpfs-nds-0.06
- VANA: Synchronized sources with Arne
ncpfs-2.0.11.11 -> ncpfs-2.0.11.12
- VANA: Fixed compilation error if compiled against kernel without signatures
even if SIGNATURES = 0 set
ncpfs-2.0.11.10 -> ncpfs-2.0.11.11
- VANA: Fixed segfault on invalid user name in NDS mode
- VANA: Added locking features (through ncpfs-specific ioctl(2))
ncpfs-2.0.11.9 -> ncpfs-2.0.11.10
- VANA: Synchronized with nds-patches-0.05 from Arne de Bruijn <Arne@knoware.nl>
ncpfs-2.0.11.8 -> ncpfs-2.0.11.9
- VANA: Added call to lock connection (dropped in 2.0.11.7, sorry)
ncpfs-2.0.11.7 -> ncpfs-2.0.11.8
- VANA: Can be correctly compiled without signatures support in kernel (I hope)
- VANA: Fix in kernel in setting task number
ncpfs-2.0.11.6 -> ncpfs-2.0.11.7
- VANA: Codebase synchronized with Arne de Bruijn <Arne@knoware.nl>
- ARNE: Gracelogins on NDS
- VANA: Removed some (one) compilation warnings
ncpfs-2.0.11.5 -> ncpfs-2.0.11.6
- VANA: Support for NDS login accross servers
ncpfs-2.0.11.4 -> ncpfs-2.0.11.5
- VANA: Cleanup in ndscrypt
- VANA: Bugfix: empty password for NDS login is now allowed & works
ncpfs-2.0.11.3 -> ncpfs-2.0.11.4
- Enabled some buffer cleaning
- Added parameter "-b" to ncpmount for bindery login to NDS server
ncpfs-2.0.11.2 -> ncpfs-2.0.11.3
- Added NDS support by Arne de Bruijn <Arne@knoware.nl>; small fixes in code;
moved sections to do same things as DOS login does.
ncpfs-2.0.11.1 -> ncpfs-2.0.11.2
- VANA: Fixed that some error conditions in LOGIN should start packet signatures
ncpfs-2.0.11 -> ncpfs-2.0.11.1
- VANA: Added packet signatures by Arne de Bruijn <Arne@knoware.nl>
ncpfs-2.0.10 -> ncpfs-2.0.11
- Added Martin's patch to Linux 2.0.30 to get rid of the lockups.
MANY thanks to Martin Stover!
ncpfs-2.0.9 -> ncpfs-2.0.10
- Made nwtrustee hopefully work ;-)

19
FAQ
View File

@@ -35,6 +35,9 @@ doing this.
A promising hint that has already helped some people is to switch off
packet signatures on the 4.1 server, as ncpfs does not support them.
Note: ncpfs, as of 2.0.12, and kernel 2.1.89, does now support packet
signatures.
-------------------------------------------------------------------------------
Q: When I re-export ncpfs-mounted directories via nfs, I get messages like
@@ -54,14 +57,10 @@ When you want to export a directory via NFS, you have to do two things:
-------------------------------------------------------------------------------
Q: When I compile ncpfs, I get a message like the following:
Q: I cannot login into server with these utilities. It was possible with an
older version.
make[1]: Entering directory `/home/me/netware/ncpfs/kernel-1.2/src'
gcc -D__KERNEL__ -I. -Wall -Wstrict-prototypes -O2 -DMODULE -fomit-frame-pointer -I/home/me/netware/ncpfs/kernel-1.2 -DNCPFS_VERSION=\"0.17\" -c dir.c
dir.c:36: warning: `struct dirent' declared inside parameter list
dir.c:36: warning: its scope is only this definition or declaration,
...
You try to compile the part of ncpfs that is meant for kernel 1.2.13 under
kernel 1.3.x. Please look at the Makefile and comment out the
corresponding lines.
A: You are probably connecting into Netware 4.x or IntraNetware. If you want a
temporary workaround, add the option "-b" to the ncpmount commandline.
For the future you should determine your Directory Services user name and
use that instead of your bindery name.

View File

@@ -2,12 +2,6 @@
# Makefile for the linux ncp-filesystem routines.
#
VERSION = 2.1.1
# If you are using kerneld to autoload ncp support,
# uncomment this (kerneld is in linux since about 1.3.57):
KERNELD = -DHAVE_KERNELD
# If your system is ELF, either also do a 'make install', or append the util/
# directory where the dynamic library resides to the environment
# variable LD_LIBRARY_PATH
@@ -15,22 +9,23 @@ HAVE_ELF=$(shell file `whereis gcc|cut -d ' ' -f 2`| \
grep ELF >/dev/null && echo -n yes )
TOPDIR = $(shell pwd)
BINDIR = /usr/bin
SBINDIR = /sbin
SUBDIRS = lib sutil util ipx-1.0 man
include ./Makeinit
KVERSION=$(shell uname -r | cut -b1-3)
EXECSUBDIRS = lib-static-su sutil util ipx-1.0
SUBDIRS := $(EXECSUBDIRS) lib-shared lib-static man
INSTALL_SUBDIRS := util sutil man ipx-1.0
ifeq ($(HAVE_ELF),yes)
EXECSUBDIRS := lib-shared $(EXECSUBDIRS)
INSTALL_SUBDIRS := lib-shared $(INSTALL_SUBDIRS)
else
EXECSUBDIRS := lib-static $(EXECSUBDIRS)
INSTALL_SUBDIRS := lib-static $(INSTALL_SUBDIRS)
endif
INCLUDES=-I$(TOPDIR)/include
COPT = -O2
COPT += -g
CFLAGS = $(COPT) -Wall $(INCLUDES) $(KERNELD) -DNCPFS_VERSION=\"$(VERSION)\"
export INCLUDES BINDIR SBINDIR KERNELD VERSION HAVE_ELF CFLAGS
export INCLUDES VERSION HAVE_ELF CFLAGS
all:
for i in $(SUBDIRS); do make -C $$i all; done
set -e; for i in $(EXECSUBDIRS); do make -C $$i all; done
@if [ "$(HAVE_ELF)" = yes ] ;\
then \
echo ; echo ; echo ;\
@@ -47,7 +42,7 @@ dep:
for i in $(SUBDIRS); do make -C $$i dep; done
install:
for i in $(SUBDIRS); do make -C $$i install; done
for i in $(INSTALL_SUBDIRS); do make -C $$i install; done
clean_me:
rm -f `find -name '*.out'`

79
Makeinit Normal file
View File

@@ -0,0 +1,79 @@
VERSION = 2.2.0
# If you want to include NDS support for ncpmount uncomment this:
# WARNING! NDS support is very beta, uncomment only if you are testing
# because anything can happen (like crashing the linux box or nw server).
NDS_SUPPORT = 1
# If you want to include packet signature support uncomment this:
# WARNING! packet signature support is in beta stage, uncomment only when you
# know what you are doing, anything can happen (like crashing the linux box or
# netware server).
# When enabling, make sure you have applied the kernel patches too,
# otherwise the packet signatures won't work.
SIGNATURES = 1
# If you want to eat only one NDS connection. Does not work at this time.
# (waiting for Novell...)
NDS_PRIVATEKEY = 1
# If you want native IP support, uncomment CONFIG_NATIVEIP
# Do not forget that it is VERY ALPHA code, with almost no support
# Enable only if you are interested in NCP over IP and you want help
# me. -A ip.address is your friend. At this time you have to silently
# ignore Login to server XXXX as YYYY - think that XXXX is ip.address and
# not one taken from .nwclient. Also, if you have not .nwclient, you have
# to add -S DUMMY on commandline.
CONFIG_NATIVE_IP = 1
# Include code for Linux2.0.x
MOUNT2 = 1
# Include code for Linux2.1.x
MOUNT3 = 1
# ########################################################
BINDIR = /usr/bin
SBINDIR = /sbin
LIBSODIR = /lib
LIBADIR = /usr/lib
MANDIR = /usr/local/man
CC = gcc
COPT = -O2
CWARN = -Wall
# CWARN = -Wall -Wstrict-prototypes -Wpointer-arith -Wcast-qual -Waggregate-return -Wnested-externs -Winline -Wbad-function-cast -W #-Werror #-Wwrite-strings -Wtraditional -Wshadow
# ########################################################
ifdef SIGNATURES
CFLAGS_DEFINES += -DSIGNATURES
endif
ifdef NDS_SUPPORT
CFLAGS_DEFINES += -DNDS_SUPPORT
endif
ifdef CONFIG_NATIVE_IP
CFLAGS_DEFINES += -DCONFIG_NATIVE_IP
endif
ifdef MOUNT2
CFLAGS_DEFINES += -DMOUNT2
endif
ifdef MOUNT3
CFLAGS_DEFINES += -DMOUNT3
endif
CFLAGS_DEFINES += -DNCPFS_VERSION=\"$(VERSION)\"
CFLAGS_OPTIONS += $(COPT)
CFLAGS_OPTIONS += $(CWARN)
CCFLAGS = $(CFLAGS_DEFINES) $(CFLAGS_OPTIONS) -I../include
# If your system is ELF, either also do a 'make install', or append the util/
# directory where the dynamic library resides to the environment
# variable LD_LIBRARY_PATH
HAVE_ELF=$(shell file `whereis gcc|cut -d ' ' -f 2`| \
grep ELF >/dev/null && echo -n yes )
#HAVE_ELF=yes
TOPDIR = $(shell pwd)
INCLUDES=-I$(TOPDIR)/include

35
README
View File

@@ -1,7 +1,7 @@
This is ncpfs, the user utilities that are needed to use the NCP kernel support
present in Linux since version 1.3.71. This version of ncpfs is only usable
with Linux 2.1.29 and later. To use it, please apply the patch contained in the
patches/ directory.
This is ncpfs, a free NetWare client filesystem for Linux. Besides
some little utilities it also contains nprint, which enables you to
print on NetWare print queues. The opposite side, pserver, is also
provided.
ncpfs works with NetWare versions 3.x and following. It does NOT work
with NetWare version 2.x. Some of the NetWare look-alikes, such as
@@ -24,11 +24,25 @@ information.
INSTALLATION
Before you start the installation of the user utilities, please make sure that
your kernel is 2.1.29 or later. If you are using 2.1.29, please apply the patch
contained in patches/linux-2.1.29.diff. You have to compile your kernel with
IPX and NCP support compiled in. But as you are using a development kernel, you
probably know what you're doing :-).
Before you start the installation, make sure that your kernel has IPX
support compiled in. When 'make config' asks you for
The IPX protocol (CONFIG_IPX) [N/y/m/?]
simply answer 'y'. Probably you do not need the full internal net that
you are asked for next.
If you are not using 2.0.x kernels, you can comment out MOUNT2=1 line
in the Makeinit.
If you are not using 2.1.x kernels, you can comment out MOUNT3=1 line
in the Makeinit.
If you are not using NDS access, you can comment out NDS_SUPPORT=1 in
the Makeinit.
If you are not using packet signatures, you can comment out SIGNATURES=1
in the Makeinit.
After you adapted your Makeinit, type 'make' and, as root, 'make install'.
HELP
@@ -110,9 +124,6 @@ limitation is the lack of uid, gid and permission information per
file. You have to assign those values once for a complete mounted
directory.
You will not be able to access servers that require packet
signatures. This seems to be one of Novell's bigger secrets :-(.
Have fun with ncpfs!
Volker

18
README.NDS Normal file
View File

@@ -0,0 +1,18 @@
The NDS login code uses the RSA public key cryptosystem. Because of a patent
right on this algorithm (U.S. patent #4,405,829, issued 20 Sep 1983), you
are probably not allowed to use this code in the U.S.A. and Canada, and
possibly neither in other countries. Check this before you use NDS logins!
The mpilib.c, mpilib.h, platform.h, and usuals.h in the lib/ directory are
taken from the PGP 2.3 source distribution (Copyright 1986-92 by Philip
Zimmermann), which is distributed under the GPL, as stated below.
Excerpt from pgpdoc2.txt (contained in pgp23src.zip):
"All the source code for PGP is available for free under the "Copyleft"
General Public License from the Free Software Foundation (FSF)."
For more details on the RSA patent see the pgp23src archive, or more recent
PGP packages.
Arne de Bruijn
arne@knoware.nl

View File

@@ -27,7 +27,8 @@ static int search_utmp(char *user, char *tty);
static char *progname;
void main(int argc, char *argv[])
void
main(int argc, char *argv[])
{
struct ncp_conn *conn;
char message[256];
@@ -50,23 +51,27 @@ void main(int argc, char *argv[])
openlog("nwmsg", LOG_PID, LOG_LPR);
if (argc != 2) {
if (argc != 2)
{
fprintf(stderr, "usage: %s mount-point\n",
progname);
exit(1);
}
mount_point = argv[1];
if ((conn = ncp_open_mount(mount_point, &err)) == NULL) {
if ((conn = ncp_open_mount(mount_point, &err)) == NULL)
{
com_err(progname, err, "in ncp_open_mount");
exit(1);
}
if (ncp_get_broadcast_message(conn, message) != 0) {
if (ncp_get_broadcast_message(conn, message) != 0)
{
fprintf(stderr, "%s: could not get broadcast message\n",
progname);
ncp_close(conn);
exit(1);
}
if (strlen(message) == 0) {
if (strlen(message) == 0)
{
syslog(LOG_DEBUG, "no message");
exit(0);
}
@@ -75,7 +80,8 @@ void main(int argc, char *argv[])
#endif
info.version = NCP_GET_FS_INFO_VERSION;
if (ioctl(conn->mount_fid, NCP_IOC_GET_FS_INFO, &info) < 0) {
if (ioctl(conn->mount_fid, NCP_IOC_GET_FS_INFO, &info) < 0)
{
fprintf(stderr, "%s: could not ioctl on connection: %s\n",
progname, strerror(errno));
ncp_close(conn);
@@ -83,30 +89,37 @@ void main(int argc, char *argv[])
}
ncp_close(conn);
if ((pwd = getpwuid(info.mounted_uid)) == NULL) {
if ((pwd = getpwuid(info.mounted_uid)) == NULL)
{
fprintf(stderr, "%s: user %d not known\n",
progname, info.mounted_uid);
exit(1);
}
if ((mtab = fopen(MOUNTED, "r")) == NULL) {
if ((mtab = fopen(MOUNTED, "r")) == NULL)
{
fprintf(stderr, "%s: can't open %s\n",
progname, MOUNTED);
exit(1);
}
while ((mnt = getmntent(mtab)) != NULL) {
if (strcmp(mnt->mnt_dir, mount_point) == 0) {
while ((mnt = getmntent(mtab)) != NULL)
{
if (strcmp(mnt->mnt_dir, mount_point) == 0)
{
break;
}
}
if (mnt == NULL) {
if (mnt == NULL)
{
syslog(LOG_DEBUG, "cannot find mtab entry\n");
}
if (search_utmp(pwd->pw_name, tty) != 0) {
if (search_utmp(pwd->pw_name, tty) != 0)
{
exit(1);
}
sprintf(tty_path, "/dev/%s", tty);
if ((tty_file = fopen(tty_path, "w")) == NULL) {
if ((tty_file = fopen(tty_path, "w")) == NULL)
{
fprintf(stderr, "%s: cannot open %s: %s\n",
progname, tty_path, strerror(errno));
exit(1);
@@ -139,16 +152,18 @@ void main(int argc, char *argv[])
* term_chk - check that a terminal exists, and get the message bit
* and the access time
*/
static int term_chk(char *tty, int *msgsokP, time_t * atimeP, int *showerror)
static int
term_chk(char *tty, int *msgsokP, time_t * atimeP, int *showerror)
{
struct stat s;
char path[MAXPATHLEN];
(void) sprintf(path, "/dev/%s", tty);
if (stat(path, &s) < 0) {
if (stat(path, &s) < 0)
{
if (showerror)
(void) fprintf(stderr,
"write: %s: %s\n", path, strerror(errno));
"write: %s: %s\n", path, strerror(errno));
return (1);
}
*msgsokP = (s.st_mode & (S_IWRITE >> 3)) != 0; /* group write bit */
@@ -167,7 +182,8 @@ static int term_chk(char *tty, int *msgsokP, time_t * atimeP, int *showerror)
* Special case for writing to yourself - ignore the terminal you're
* writing from, unless that's the only terminal with messages enabled.
*/
static int search_utmp(char *user, char *tty)
static int
search_utmp(char *user, char *tty)
{
struct utmp u;
time_t bestatime, atime;
@@ -175,7 +191,8 @@ static int search_utmp(char *user, char *tty)
char atty[sizeof(u.ut_line) + 1];
if ((ufd = open(_PATH_UTMP, O_RDONLY)) < 0) {
if ((ufd = open(_PATH_UTMP, O_RDONLY)) < 0)
{
perror("utmp");
return -1;
}
@@ -183,7 +200,8 @@ static int search_utmp(char *user, char *tty)
bestatime = 0;
user_is_me = 0;
while (read(ufd, (char *) &u, sizeof(u)) == sizeof(u))
if (strncmp(user, u.ut_name, sizeof(u.ut_name)) == 0) {
if (strncmp(user, u.ut_name, sizeof(u.ut_name)) == 0)
{
++nloggedttys;
(void) strncpy(atty, u.ut_line, sizeof(u.ut_line));
@@ -198,13 +216,15 @@ static int search_utmp(char *user, char *tty)
continue; /* it's not a valid entry */
++nttys;
if (atime > bestatime) {
if (atime > bestatime)
{
bestatime = atime;
(void) strcpy(tty, atty);
}
}
(void) close(ufd);
if (nloggedttys == 0) {
if (nloggedttys == 0)
{
(void) fprintf(stderr, "write: %s is not logged in\n", user);
return -1;
}

22
include/glibstub.h Normal file
View File

@@ -0,0 +1,22 @@
#ifndef __GLIBSTUB_H__
#define __GLIBSTUB_H__
#undef GLIBCHDR
#ifdef __GLIBC__
#if __GLIBC__ >= 2
#define GLIBCHDR
#endif
#endif
#ifdef GLIBCHDR
#define HAVE_NETIPX_IPX_H
#define HAVE_SYS_MOUNT_H
#define HAVE_NET_ROUTE_H
#define HAVE_NET_IF_H
#else
#undef HAVE_NETIPX_IPX_H
#undef HAVE_SYS_MOUNT_H
#undef HAVE_NET_ROUTE_H
#undef HAVE_NET_IF_H
#endif
#endif /* __GLIBSTUB_H__ */

View File

@@ -8,15 +8,14 @@
#ifndef _IPXLIB_H
#define _IPXLIB_H
#include <linux/types.h>
#include "kernel/types.h"
#include "ncp.h"
#include <linux/ipx.h>
#include <stdio.h>
#include "kernel/ipx.h"
typedef unsigned long IPXNet;
typedef unsigned short IPXPort;
typedef unsigned char IPXNode[IPX_NODE_LEN];
typedef u_int32_t IPXNet;
typedef u_int16_t IPXPort;
typedef u_int8_t IPXNode[IPX_NODE_LEN];
typedef const u_int8_t CIPXNode[IPX_NODE_LEN];
#define IPX_USER_PTYPE (0x00)
#define IPX_RIP_PTYPE (0x01)
@@ -32,30 +31,35 @@ typedef unsigned char IPXNode[IPX_NODE_LEN];
#define IPX_SAP_FILE_SERVER (0x0004)
struct sap_query {
unsigned short query_type; /* net order */
unsigned short server_type; /* net order */
struct sap_query
{
u_int16_t query_type; /* net order */
u_int16_t server_type; /* net order */
};
struct sap_server_ident {
unsigned short server_type __attribute__((packed));
char server_name[48] __attribute__((packed));
IPXNet server_network __attribute__((packed));
IPXNode server_node __attribute__((packed));
IPXPort server_port __attribute__((packed));
unsigned short intermediate_network __attribute__((packed));
struct sap_server_ident
{
u_int16_t server_type __attribute__((packed));
char server_name[48] __attribute__((packed));
IPXNet server_network __attribute__((packed));
IPXNode server_node __attribute__((packed));
IPXPort server_port __attribute__((packed));
u_int16_t intermediate_network __attribute__((packed));
};
#define IPX_RIP_REQUEST (0x1)
#define IPX_RIP_RESPONSE (0x2)
struct ipx_rip_packet {
__u16 operation __attribute__((packed));
struct ipx_rt_def {
__u32 network __attribute__((packed));
__u16 hops __attribute__((packed));
__u16 ticks __attribute__((packed));
} rt[1] __attribute__((packed));
struct ipx_rip_packet
{
u_int16_t operation __attribute__((packed));
struct ipx_rt_def
{
u_int32_t network __attribute__((packed));
u_int16_t hops __attribute__((packed));
u_int16_t ticks __attribute__((packed));
}
rt[1] __attribute__((packed));
};
#define IPX_BROADCAST_NODE ("\xff\xff\xff\xff\xff\xff")
@@ -85,8 +89,10 @@ void
int
ipx_sscanf_node(char *buf, unsigned char node[IPX_NODE_LEN]);
void
ipx_assign_node(IPXNode dest, IPXNode src);
ipx_assign_node(IPXNode dest, CIPXNode src);
int
ipx_node_equal(IPXNode n1, IPXNode n2);
ipx_node_equal(CIPXNode n1, CIPXNode n2);
int
ipx_sscanf_saddr(char* buf, struct sockaddr_ipx* sipx);
#endif /* _IPXLIB_H */

11
include/kernel/fs.h Normal file
View File

@@ -0,0 +1,11 @@
#ifndef _KERNEL_FS_H
#define _KERNEL_FS_H
#include "glibstub.h"
#ifdef HAVE_SYS_MOUNT_H
#include <sys/mount.h>
#else
#include <linux/fs.h>
#endif
#endif

11
include/kernel/if.h Normal file
View File

@@ -0,0 +1,11 @@
#ifndef _KERNEL_IF_H
#define _KERNEL_IF_H
#include "glibstub.h"
#ifdef HAVE_NET_IF_H
#include <net/if.h>
#else
#include <linux/if.h>
#endif
#endif

15
include/kernel/ipx.h Normal file
View File

@@ -0,0 +1,15 @@
#ifndef _KERNEL_IPX_H
#define _KERNEL_IPX_H
#include "glibstub.h"
#ifdef HAVE_NETIPX_IPX_H
#include <netipx/ipx.h>
#else
#include <linux/ipx.h>
#endif
#ifndef IPXPROTO_IPX
#define IPXPROTO_IPX (PF_IPX)
#endif
#endif

213
include/kernel/ncp.h Normal file
View File

@@ -0,0 +1,213 @@
/*
* ncp.h
*
* Copyright (C) 1995 by Volker Lendecke
* Modified for sparc by J.F. Chadima
*
*/
#ifndef _LINUX_NCP_H
#define _LINUX_NCP_H
#include "kernel/types.h"
#include "kernel/ipx.h"
#define NCP_PTYPE (0x11)
#define NCP_PORT (0x0451)
#define NCP_ALLOC_SLOT_REQUEST (0x1111)
#define NCP_REQUEST (0x2222)
#define NCP_DEALLOC_SLOT_REQUEST (0x5555)
struct ncp_request_header {
u_int16_t type __attribute__((packed));
u_int8_t sequence __attribute__((packed));
u_int8_t conn_low __attribute__((packed));
u_int8_t task __attribute__((packed));
u_int8_t conn_high __attribute__((packed));
u_int8_t function __attribute__((packed));
u_int8_t data[0] __attribute__((packed));
};
#define NCP_REPLY (0x3333)
#define NCP_POSITIVE_ACK (0x9999)
struct ncp_reply_header {
__u16 type __attribute__((packed));
__u8 sequence __attribute__((packed));
__u8 conn_low __attribute__((packed));
__u8 task __attribute__((packed));
__u8 conn_high __attribute__((packed));
__u8 completion_code __attribute__((packed));
__u8 connection_state __attribute__((packed));
__u8 data[0] __attribute__((packed));
};
#define NCP_VOLNAME_LEN (16)
#define NCP_NUMBER_OF_VOLUMES (64)
struct ncp_volume_info {
__u32 total_blocks;
__u32 free_blocks;
__u32 purgeable_blocks;
__u32 not_yet_purgeable_blocks;
__u32 total_dir_entries;
__u32 available_dir_entries;
__u8 sectors_per_block;
char volume_name[NCP_VOLNAME_LEN + 1];
};
/* these define the attribute byte as seen by NCP */
#define aRONLY (ntohl(0x01000000))
#define aHIDDEN (ntohl(0x02000000))
#define aSYSTEM (ntohl(0x04000000))
#define aEXECUTE (ntohl(0x08000000))
#define aDIR (ntohl(0x10000000))
#define aARCH (ntohl(0x20000000))
#define AR_READ (ntohs(0x0100))
#define AR_WRITE (ntohs(0x0200))
#define AR_EXCLUSIVE (ntohs(0x2000))
#define NCP_FILE_ID_LEN 6
/* Defines for Name Spaces */
#define NW_NS_DOS 0
#define NW_NS_MAC 1
#define NW_NS_NFS 2
#define NW_NS_FTAM 3
#define NW_NS_OS2 4
#if 0 /* Sorry, I do not think so... VANA */
/* Defines for ReturnInformationMask */
#define RIM_NAME (ntohl(0x01000000L))
#define RIM_SPACE_ALLOCATED (ntohl(0x02000000L))
#define RIM_ATTRIBUTES (ntohl(0x04000000L))
#define RIM_DATA_SIZE (ntohl(0x08000000L))
#define RIM_TOTAL_SIZE (ntohl(0x10000000L))
#define RIM_EXT_ATTR_INFO (ntohl(0x20000000L))
#define RIM_ARCHIVE (ntohl(0x40000000L))
#define RIM_MODIFY (ntohl(0x80000000L))
#define RIM_CREATION (ntohl(0x00010000L))
#define RIM_OWNING_NAMESPACE (ntohl(0x00020000L))
#define RIM_DIRECTORY (ntohl(0x00040000L))
#define RIM_RIGHTS (ntohl(0x00080000L))
#define RIM_ALL (ntohl(0xFF0F0000L))
#define RIM_COMPRESSED_INFO (ntohl(0x00000080L))
#else
#define RIM_NAME 0x00000001
#define RIM_SPACE_ALLOCATED 0x00000002
#define RIM_ATTRIBUTES 0x00000004
#define RIM_DATA_SIZE 0x00000008
#define RIM_TOTAL_SIZE 0x00000010
#define RIM_EXT_ATTR_INFO 0x00000020
#define RIM_ARCHIVE 0x00000040
#define RIM_MODIFY 0x00000080
#define RIM_CREATION 0x00000100
#define RIM_OWNING_NAMESPACE 0x00000200
#define RIM_DIRECTORY 0x00000400
#define RIM_RIGHTS 0x00000800
#define RIM_ALL 0x00000FFF
#define RIM_COMPRESSED_INFO 0x80000000UL
#endif
/* open/create modes */
#define OC_MODE_OPEN 0x01
#define OC_MODE_TRUNCATE 0x02
#define OC_MODE_REPLACE 0x02
#define OC_MODE_CREATE 0x08
/* open/create results */
#define OC_ACTION_NONE 0x00
#define OC_ACTION_OPEN 0x01
#define OC_ACTION_CREATE 0x02
#define OC_ACTION_TRUNCATE 0x04
#define OC_ACTION_REPLACE 0x04
/* access rights attributes */
#ifndef AR_READ_ONLY
#define AR_READ_ONLY 0x0001
#define AR_WRITE_ONLY 0x0002
#define AR_DENY_READ 0x0004
#define AR_DENY_WRITE 0x0008
#define AR_COMPATIBILITY 0x0010
#define AR_WRITE_THROUGH 0x0040
#define AR_OPEN_COMPRESSED 0x0100
#endif
struct nw_info_struct {
__u32 spaceAlloc __attribute__((packed));
__u32 attributes __attribute__((packed));
__u16 flags __attribute__((packed));
__u32 dataStreamSize __attribute__((packed));
__u32 totalStreamSize __attribute__((packed));
__u16 numberOfStreams __attribute__((packed));
__u16 creationTime __attribute__((packed));
__u16 creationDate __attribute__((packed));
__u32 creatorID __attribute__((packed));
__u16 modifyTime __attribute__((packed));
__u16 modifyDate __attribute__((packed));
__u32 modifierID __attribute__((packed));
__u16 lastAccessDate __attribute__((packed));
__u16 archiveTime __attribute__((packed));
__u16 archiveDate __attribute__((packed));
__u32 archiverID __attribute__((packed));
__u16 inheritedRightsMask __attribute__((packed));
__u32 dirEntNum __attribute__((packed));
__u32 DosDirNum __attribute__((packed));
__u32 volNumber __attribute__((packed));
__u32 EADataSize __attribute__((packed));
__u32 EAKeyCount __attribute__((packed));
__u32 EAKeySize __attribute__((packed));
__u32 NSCreator __attribute__((packed));
__u8 nameLen __attribute__((packed));
__u8 entryName[256] __attribute__((packed));
};
/* modify mask - use with MODIFY_DOS_INFO structure */
#define DM_ATTRIBUTES (ntohl(0x02000000L))
#define DM_CREATE_DATE (ntohl(0x04000000L))
#define DM_CREATE_TIME (ntohl(0x08000000L))
#define DM_CREATOR_ID (ntohl(0x10000000L))
#define DM_ARCHIVE_DATE (ntohl(0x20000000L))
#define DM_ARCHIVE_TIME (ntohl(0x40000000L))
#define DM_ARCHIVER_ID (ntohl(0x80000000L))
#define DM_MODIFY_DATE (ntohl(0x00010000L))
#define DM_MODIFY_TIME (ntohl(0x00020000L))
#define DM_MODIFIER_ID (ntohl(0x00040000L))
#define DM_LAST_ACCESS_DATE (ntohl(0x00080000L))
#define DM_INHERITED_RIGHTS_MASK (ntohl(0x00100000L))
#define DM_MAXIMUM_SPACE (ntohl(0x00200000L))
struct nw_modify_dos_info {
__u32 attributes __attribute__((packed));
__u16 creationDate __attribute__((packed));
__u16 creationTime __attribute__((packed));
__u32 creatorID __attribute__((packed));
__u16 modifyDate __attribute__((packed));
__u16 modifyTime __attribute__((packed));
__u32 modifierID __attribute__((packed));
__u16 archiveDate __attribute__((packed));
__u16 archiveTime __attribute__((packed));
__u32 archiverID __attribute__((packed));
__u16 lastAccessDate __attribute__((packed));
__u16 inheritanceGrantMask __attribute__((packed));
__u16 inheritanceRevokeMask __attribute__((packed));
__u32 maximumSpace __attribute__((packed));
};
struct nw_file_info {
struct nw_info_struct i;
int opened;
int access;
__u32 server_file_handle __attribute__((packed));
__u8 open_create_action __attribute__((packed));
__u8 file_handle[6] __attribute__((packed));
};
struct nw_search_sequence {
__u8 volNumber __attribute__((packed));
__u32 dirBase __attribute__((packed));
__u32 sequence __attribute__((packed));
};
#endif /* _LINUX_NCP_H */

110
include/kernel/ncp_fs.h Normal file
View File

@@ -0,0 +1,110 @@
/*
* ncp_fs.h
*
* Copyright (C) 1995, 1996 by Volker Lendecke
*
*/
#ifndef _KERNEL_NCP_FS_H
#define _KERNEL_NCP_FS_H
#include "kernel/fs.h"
#include <netinet/in.h>
#include <sys/types.h>
/*
* ioctl commands
*/
struct ncp_ioctl_request {
unsigned int function;
unsigned int size;
char *data;
};
struct ncp_fs_info {
int version;
struct sockaddr_ipx addr;
__kerXX_uid_t mounted_uid;
int connection; /* Connection number the server assigned us */
int buffer_size; /* The negotiated buffer size, to be
used for read/write requests! */
int volume_number;
__u32 directory_id;
};
struct ncp_sign_init
{
char sign_root[8];
char sign_last[16];
};
struct ncp_lock_ioctl
{
#define NCP_LOCK_LOG 0
#define NCP_LOCK_SH 1
#define NCP_LOCK_EX 2
#define NCP_LOCK_CLEAR 256
int cmd;
int origin;
unsigned int offset;
unsigned int length;
#define NCP_LOCK_DEFAULT_TIMEOUT 18
#define NCP_LOCK_MAX_TIMEOUT 180
int timeout;
};
struct ncp_setroot_ioctl
{
int volNumber;
int namespace;
__u32 dirEntNum;
};
struct ncp_objectname_ioctl
{
#define NCP_AUTH_NONE 0x00
#define NCP_AUTH_BIND 0x31
#define NCP_AUTH_NDS 0x32
int auth_type;
size_t object_name_len;
void* object_name;
};
struct ncp_privatedata_ioctl
{
size_t len;
void* data; /* ~1000 for NDS */
};
#define NCP_IOC_NCPREQUEST _IOR('n', 1, struct ncp_ioctl_request)
#define NCP_IOC_GETMOUNTUID _IOW('n', 2, __kernel_uid_t)
#define NCP_IOC_CONN_LOGGED_IN _IO('n', 3)
#define NCP_GET_FS_INFO_VERSION (1)
#define NCP_IOC_GET_FS_INFO _IOWR('n', 4, struct ncp_fs_info)
#define NCP_IOC_SIGN_INIT _IOR('n', 5, struct ncp_sign_init)
#define NCP_IOC_SIGN_WANTED _IOR('n', 6, int)
#define NCP_IOC_SET_SIGN_WANTED _IOW('n', 6, int)
#define NCP_IOC_LOCKUNLOCK _IOR('n', 7, struct ncp_lock_ioctl)
#define NCP_IOC_GETROOT _IOW('n', 8, struct ncp_setroot_ioctl)
#define NCP_IOC_SETROOT _IOR('n', 8, struct ncp_setroot_ioctl)
#define NCP_IOC_GETOBJECTNAME _IOWR('n', 9, struct ncp_objectname_ioctl)
#define NCP_IOC_SETOBJECTNAME _IOR('n', 9, struct ncp_objectname_ioctl)
#define NCP_IOC_GETPRIVATEDATA _IOWR('n', 10, struct ncp_privatedata_ioctl)
#define NCP_IOC_SETPRIVATEDATA _IOR('n', 10, struct ncp_privatedata_ioctl)
/*
* The packet size to allocate. One page should be enough.
*/
#define NCP_PACKET_SIZE 4070
#define NCP_MAXPATHLEN 255
#define NCP_MAXNAMELEN 14
#endif /* _LINUX_NCP_FS_H */

12
include/kernel/route.h Normal file
View File

@@ -0,0 +1,12 @@
#ifndef __KERNEL_ROUTE_H__
#define __KERNEL_ROUTE_H__
#include "glibstub.h"
#ifdef HAVE_NET_ROUTE_H
#include <net/route.h>
#else
#include <linux/route.h>
#endif
#endif /* __KERNEL_ROUTE_H__ */

40
include/kernel/types.h Normal file
View File

@@ -0,0 +1,40 @@
#ifndef __KERNEL_TYPES_H__
#define __KERNEL_TYPES_H__
#include <sys/types.h>
#undef __u8
#undef __u16
#undef __u32
#define __u8 u_int8_t
#define __u16 u_int16_t
#define __u32 u_int32_t
typedef u_int16_t __kerXX_uid_t;
#include <linux/posix_types.h>
typedef __kernel_pid_t __ker20_pid_t;
typedef __kernel_uid_t __ker20_uid_t;
typedef __kernel_gid_t __ker20_gid_t;
typedef __kernel_mode_t __ker20_mode_t;
typedef __kernel_pid_t __ker21_pid_t;
typedef __kernel_uid_t __ker21_uid_t;
typedef __kernel_gid_t __ker21_gid_t;
typedef __kernel_mode_t __ker21_mode_t;
#ifdef __GLIBC__
/* why is this defined in posix_types ???? dirty hack... */
#undef __FD_CLR
#undef __FD_SET
#undef __FD_ISSET
#undef __FD_ZERO
#ifdef _SELECTBITS_H
#undef _SELECTBITS_H
#include <selectbits.h>
#endif
#endif
#endif /* __KERNEL_TYPES_H__ */

View File

@@ -9,10 +9,10 @@
#ifndef _NCP_H
#define _NCP_H
#include <linux/types.h>
#include <linux/ipx.h>
#include <linux/ncp.h>
#include <linux/ncp_fs.h>
#include "kernel/types.h"
#include "kernel/ipx.h"
#include "kernel/ncp.h"
#include "kernel/ncp_fs.h"
#define NCP_BINDERY_USER (0x0001)
#define NCP_BINDERY_UGROUP (0x0002)
@@ -119,5 +119,4 @@ struct print_job_record {
char Path[80] __attribute__((packed));
};
#endif /* _NCP_H */

View File

@@ -8,13 +8,17 @@
#ifndef _NCPLIB_H
#define _NCPLIB_H
#include <linux/types.h>
#include "ncp.h"
#include <linux/ipx.h>
#include <sys/param.h>
#include <stdio.h>
#include <time.h>
#ifdef SIGNATURES
#ifndef NCP_IOC_SIGN_INIT
#undef SIGNATURES
#endif /* NCP_IOC_SIGN_INIT */
#endif /* SIGNATURES */
#include "ipxlib.h"
#include "com_err.h"
@@ -22,31 +26,36 @@ typedef __u8 byte;
typedef __u16 word;
typedef __u32 dword;
typedef int NWCCODE;
#ifndef memzero
#include <string.h>
#define memzero(object) memset(&(object), 0, sizeof(object))
#endif
#define BVAL(buf,pos) (((__u8 *)(buf))[pos])
#define BVAL(buf,pos) (((const __u8 *)(buf))[pos])
#define BWVAL(buf,pos) (((__u8*)(buf))[pos])
#define PVAL(buf,pos) ((unsigned)BVAL(buf,pos))
#define BSET(buf,pos,val) (BVAL(buf,pos) = (val))
#define BSET(buf,pos,val) (BWVAL(buf,pos) = (val))
static inline word
WVAL_HL(__u8 * buf, int pos)
WVAL_HL(const __u8 * buf, int pos)
{
return PVAL(buf, pos) << 8 | PVAL(buf, pos + 1);
}
static inline dword
DVAL_HL(__u8 * buf, int pos)
DVAL_HL(const __u8 * buf, int pos)
{
return WVAL_HL(buf, pos) << 16 | WVAL_HL(buf, pos + 2);
}
static inline void WSET_HL(__u8 * buf, int pos, word val)
static inline void
WSET_HL(__u8 * buf, int pos, word val)
{
BSET(buf, pos, val >> 8);
BSET(buf, pos + 1, val & 0xff);
}
static inline void DSET_HL(__u8 * buf, int pos, dword val)
static inline void
DSET_HL(__u8 * buf, int pos, dword val)
{
WSET_HL(buf, pos, val >> 16);
WSET_HL(buf, pos + 2, val & 0xffff);
@@ -58,20 +67,22 @@ static inline void DSET_HL(__u8 * buf, int pos, dword val)
#if defined(__i386__)
static inline word
WVAL_LH(__u8 * buf, int pos)
WVAL_LH(const __u8 * buf, int pos)
{
return *((word *) (buf + pos));
return *((const word *) (buf + pos));
}
static inline dword
DVAL_LH(__u8 * buf, int pos)
DVAL_LH(const __u8 * buf, int pos)
{
return *((dword *) (buf + pos));
return *((const dword *) (buf + pos));
}
static inline void WSET_LH(__u8 * buf, int pos, word val)
static inline void
WSET_LH(__u8 * buf, int pos, word val)
{
*((word *) (buf + pos)) = val;
}
static inline void DSET_LH(__u8 * buf, int pos, dword val)
static inline void
DSET_LH(__u8 * buf, int pos, dword val)
{
*((dword *) (buf + pos)) = val;
}
@@ -79,21 +90,23 @@ static inline void DSET_LH(__u8 * buf, int pos, dword val)
#else
static inline word
WVAL_LH(__u8 * buf, int pos)
WVAL_LH(const __u8 * buf, int pos)
{
return PVAL(buf, pos) | PVAL(buf, pos + 1) << 8;
}
static inline dword
DVAL_LH(__u8 * buf, int pos)
DVAL_LH(const __u8 * buf, int pos)
{
return WVAL_LH(buf, pos) | WVAL_LH(buf, pos + 2) << 16;
}
static inline void WSET_LH(__u8 * buf, int pos, word val)
static inline void
WSET_LH(__u8 * buf, int pos, word val)
{
BSET(buf, pos, val & 0xff);
BSET(buf, pos + 1, val >> 8);
}
static inline void DSET_LH(__u8 * buf, int pos, dword val)
static inline void
DSET_LH(__u8 * buf, int pos, dword val)
{
WSET_LH(buf, pos, val & 0xffff);
WSET_LH(buf, pos + 2, val >> 16);
@@ -101,19 +114,18 @@ static inline void DSET_LH(__u8 * buf, int pos, dword val)
#endif
void
str_upper(char *name);
enum connect_state {
enum connect_state
{
NOT_CONNECTED = 0,
CONN_PERMANENT,
CONN_TEMPORARY
};
struct ncp_conn {
struct ncp_conn
{
enum connect_state is_connected;
@@ -139,14 +151,22 @@ struct ncp_conn {
int current_size;
int has_subfunction;
int verbose;
int ncp_reply_size;
size_t ncp_reply_size;
int lock;
char packet[NCP_PACKET_SIZE];
#ifdef SIGNATURES
/* Field used to make packet signatures */
int sign_wanted;
int sign_active;
char sign_root[8];
char sign_last[16];
#endif
};
struct ncp_conn_spec {
struct ncp_conn_spec
{
char server[NCP_BINDERY_NAME_LEN];
char user[NCP_BINDERY_NAME_LEN];
uid_t uid;
@@ -154,12 +174,16 @@ struct ncp_conn_spec {
char password[NCP_BINDERY_NAME_LEN];
};
struct ncp_search_seq {
#ifndef __MAKE_SULIB__
struct ncp_search_seq
{
struct nw_search_sequence s;
int namespace;
};
#endif /* not __MAKE_SULIB__ */
struct ncp_property_info {
struct ncp_property_info
{
__u8 property_name[16];
__u8 property_flags;
__u8 property_security;
@@ -186,34 +210,35 @@ struct ncp_conn *
/* Open a connection */
struct ncp_conn *
ncp_open(const struct ncp_conn_spec *spec, long *err);
ncp_open(const struct ncp_conn_spec *spec, long *err);
/* Open a connection on an existing mount point */
struct ncp_conn *
ncp_open_mount(const char *mount_point, long *err);
int
ncp_open_mount(const char *mount_point, struct ncp_conn** conn);
/* Find a permanent connection that fits the spec, return NULL if
* there is none. */
char *
ncp_find_permanent(const struct ncp_conn_spec *spec);
ncp_find_permanent(const struct ncp_conn_spec *spec);
/* Find the address of a file server */
struct sockaddr_ipx *
ncp_find_fileserver(const char *server_name, long *err);
long
ncp_find_fileserver(const char *server_name, struct sockaddr* addr, size_t addrlen);
/* Find the address of a server */
struct sockaddr_ipx *
ncp_find_server(const char **server_name, int type, long *err);
long
ncp_find_server(const char **server_name, int type, struct sockaddr* addr, size_t addrlen);
/* Detach from a permanent connection or destroy a temporary
connection */
long
ncp_close(struct ncp_conn *conn);
ncp_close(struct ncp_conn *conn);
/* like getmntent, get_ncp_conn_ent scans /etc/mtab for usable
connections */
struct ncp_conn_ent {
struct ncp_conn_ent
{
char server[NCP_BINDERY_NAME_LEN];
char user[NCP_BINDERY_NAME_LEN];
uid_t uid;
@@ -221,7 +246,7 @@ struct ncp_conn_ent {
};
struct ncp_conn_ent *
ncp_get_conn_ent(FILE * filep);
ncp_get_conn_ent(FILE * filep);
#define NWCLIENT (".nwclient")
#define NWC_NOPASSWORD ("-")
@@ -232,6 +257,12 @@ struct ncp_conn_spec *
ncp_find_conn_spec(const char *server, const char *user, const char *password,
int login_necessary, uid_t uid, long *err);
#ifdef __MAKE_SULIB__
struct ncp_conn_spec *
ncp_find_conn_spec2(const char *server, const char *user, const char *password,
int login_necessary, uid_t uid, int allow_multiple_conns,
long *err);
#else /* __MAKE_SULIB__ */
long
ncp_get_file_server_description_strings(struct ncp_conn *conn,
char target[512]);
@@ -241,7 +272,8 @@ long
long
ncp_set_file_server_time(struct ncp_conn *conn, time_t * source);
struct ncp_file_server_info {
struct ncp_file_server_info
{
__u8 ServerName[48] __attribute__((packed));
__u8 FileServiceVersion __attribute__((packed));
__u8 FileServiceSubVersion __attribute__((packed));
@@ -288,9 +320,16 @@ long
__u8 no_conn, const __u8 * connections,
const char *message);
long
ncp_send_broadcast2(struct ncp_conn *conn,
unsigned int conns, const unsigned int* connlist,
const char* message);
#endif /* not __MAKE_SULIB__ */
long
ncp_get_encryption_key(struct ncp_conn *conn,
char *target);
#ifndef __MAKE_SULIB__
long
ncp_get_bindery_object_id(struct ncp_conn *conn,
__u16 object_type,
@@ -302,7 +341,7 @@ long
struct ncp_bindery_object *target);
long
ncp_scan_bindery_object(struct ncp_conn *conn,
__u32 last_id, __u16 object_type, char *search_string,
__u32 last_id, __u16 object_type, char *search_string,
struct ncp_bindery_object *target);
long
ncp_create_bindery_object(struct ncp_conn *conn,
@@ -320,14 +359,17 @@ long
__u16 object_type,
const char *object_name,
__u8 security);
#endif /* not __MAKE_SULIB__ */
struct ncp_station_addr {
struct ncp_station_addr
{
__u32 NetWork __attribute__((packed));
__u8 Node[6] __attribute__((packed));
__u16 Socket __attribute__((packed));
};
struct ncp_prop_login_control {
struct ncp_prop_login_control
{
__u8 AccountExpireDate[3] __attribute__((packed));
__u8 Disabled __attribute__((packed));
__u8 PasswordExpireDate[3] __attribute__((packed));
@@ -351,10 +393,11 @@ long
int object_type, const char *object_name,
int segment, const char *prop_name,
struct nw_property *target);
#ifndef __MAKE_SULIB__
long
ncp_scan_property(struct ncp_conn *conn,
__u16 object_type, const char *object_name,
__u32 last_id, char *search_string,
__u32 last_id, const char *search_string,
struct ncp_property_info *property_info);
long
ncp_add_object_to_set(struct ncp_conn *conn,
@@ -387,7 +430,7 @@ long
__u16 object_type, const char *object_name,
const char *property_name,
__u8 segment,
struct nw_property *property_value);
const struct nw_property *property_value);
/* Bit masks for security flag */
#define NCP_SEC_CHECKSUMMING_REQUESTED (1)
@@ -421,13 +464,24 @@ long
const unsigned char *key,
const unsigned char *oldpasswd,
const unsigned char *newpasswd);
#endif /* not __MAKE_SULIB__ */
#define NWE_SIGNATURE_LEVEL_CONFLICT (0x8861)
#define NCP_GRACE_PERIOD (0xdf)
#ifndef __MAKE_SULIB__
long
ncp_get_bindery_object_id(struct ncp_conn *conn,
__u16 object_type,
const char *object_name,
struct ncp_bindery_object *target);
#endif /* not __MAKE_SULIB__ */
long
ncp_login_user(struct ncp_conn *conn,
const unsigned char *username,
const unsigned char *password);
#ifndef __MAKE_SULIB__
long
ncp_get_volume_info_with_number(struct ncp_conn *conn, int n,
struct ncp_volume_info *target);
@@ -528,6 +582,15 @@ long
__u32 count,
__u32 * copied_count);
#define SA_NORMAL (0x0000)
#define SA_HIDDEN (0x0002)
#define SA_SYSTEM (0x0004)
#define SA_SUBDIR_ONLY (0x0010)
#define SA_SUBDIR_FILES (0x8000)
#define SA_ALL (SA_SUBDIR_FILES | SA_SYSTEM | SA_HIDDEN)
#define SA_SUBDIR_ALL (SA_SUBDIR_ONLY | SA_SYSTEM | SA_HIDDEN)
#define SA_FILES_ALL (SA_NORMAL | SA_SYSTEM | SA_HIDDEN)
long
ncp_obtain_file_or_subdir_info(struct ncp_conn *conn,
__u8 source_ns, __u8 target_ns,
@@ -555,7 +618,7 @@ long
long
ncp_do_lookup(struct ncp_conn *conn,
struct nw_info_struct *dir,
char *path, /* may only be one component */
const char *path, /* may only be one component */
struct nw_info_struct *target);
long
@@ -583,6 +646,13 @@ long
int namespace,
struct ncp_search_seq *target);
long
ncp_search_for_file_or_subdir2(struct ncp_conn *conn,
int search_attributes,
u_int32_t RIM,
struct ncp_search_seq *seq,
struct nw_info_struct *target);
long
ncp_search_for_file_or_subdir(struct ncp_conn *conn,
struct ncp_search_seq *seq,
@@ -590,14 +660,35 @@ long
long
ncp_ren_or_mov_file_or_subdir(struct ncp_conn *conn,
struct nw_info_struct *old_dir, char *old_name,
struct nw_info_struct *new_dir, char *new_name);
struct nw_info_struct *old_dir, char *old_name,
struct nw_info_struct *new_dir, char *new_name);
long
ncp_create_queue_job_and_file(struct ncp_conn *conn,
__u32 queue_id,
struct queue_job *job);
long
ncp_get_queue_length(struct ncp_conn *conn,
__u32 queue_id,
__u32 *queue_length);
long
ncp_get_queue_job_ids(struct ncp_conn *conn,
__u32 queue_id,
__u32 queue_section,
__u32 *length1,
__u32 *length2,
__u32 ids[]);
long
ncp_get_queue_job_info(struct ncp_conn *conn,
__u32 queue_id,
__u32 job_id,
struct nw_queue_job_entry *jobdata);
long
NWRemoveJobFromQueue2(struct ncp_conn* conn, __u32 queue_id, __u32 job_id);
long
ncp_close_file_and_start_job(struct ncp_conn *conn,
__u32 queue_id,
@@ -622,10 +713,12 @@ long
long
ncp_abort_servicing_job(struct ncp_conn *conn, __u32 queue_id,
__u32 job_number);
#endif /* not __MAKE_SULIB__ */
long
ncp_get_broadcast_message(struct ncp_conn *conn, char message[256]);
#ifndef __MAKE_SULIB__
long
ncp_dealloc_dir_handle(struct ncp_conn *conn, __u8 dir_handle);
@@ -644,7 +737,8 @@ long
struct nw_info_struct *file,
__u16 * target);
struct ncp_trustee_struct {
struct ncp_trustee_struct
{
__u32 object_id;
__u16 rights;
};
@@ -655,5 +749,75 @@ long
__u16 rights_mask,
int object_count, struct ncp_trustee_struct *rights);
struct ncp_deleted_file
{
int32_t seq;
__u32 vol;
__u32 base;
};
#endif /* _NCPLIB_H */
long
ncp_ns_scan_salvageable_file(struct ncp_conn* conn, __u8 src_ns,
int dirstyle, __u8 vol_num,
__u32 dir_base,
const unsigned char* encpath, int pathlen,
struct ncp_deleted_file* finfo,
char* name, int maxnamelen);
long
ncp_ns_purge_file(struct ncp_conn* conn, const struct ncp_deleted_file* finfo);
long
ncp_ns_get_full_name(struct ncp_conn* conn, __u8 src_ns, __u8 dst_ns,
int dirstyle, __u8 vol_num, __u32 dir_base,
const unsigned char* encpath, size_t pathlen,
char* name, size_t maxnamelen);
#endif /* not __MAKE_SULIB__ */
#ifdef SIGNATURES
long
ncp_sign_start(struct ncp_conn *conn, const char *sign_root);
#endif /* SIGNATURES */
#ifdef NDS_SUPPORT
long
ncp_send_nds_frag(struct ncp_conn *conn,
int ndsverb,
const char *inbuf, size_t inbuflen,
char *outbuf, size_t outbufsize, size_t *outbuflen);
long
ncp_send_nds(struct ncp_conn *conn, int fn,
const char *data_in, size_t data_in_len,
char *data_out, size_t data_out_max, size_t *data_out_len);
long
ncp_change_conn_state(struct ncp_conn *conn, int new_state);
#endif
struct ncp_conn *
ncp_open_addr(struct sockaddr *target, long *err);
#ifdef __MAKE_SULIB__
int
ncp_path_to_NW_format(const char* path, unsigned char* buff, int buffsize);
long
ncp_obtain_file_or_subdir_info2(struct ncp_conn* conn, __u8 source_ns,
__u8 target_ns, __u16 search_attribs, __u32 rim,
int dir_style, __u8 vol, __u32 dirent,
const unsigned char* path, int pathlen,
struct nw_info_struct* target);
#endif /* __MAKE_SULIB__ */
int
ncp_get_mount_uid(int fid, uid_t* uid);
#ifdef __MAKE_SULIB__
long
ncp_renegotiate_connparam(struct ncp_conn* conn, int buffsize, int options);
#endif /* __MAKE_SULIB__ */
#endif /* _NCPLIB_H */

18
include/ncpsign.h Normal file
View File

@@ -0,0 +1,18 @@
#ifdef SIGNATURES
/*
* ncpsign.h
*
* Arne de Bruijn (arne@knoware.nl), 1997
*
*/
#ifndef _NCPSIGN_H
#define _NCPSIGN_H
#include "ncplib.h"
void sign_init(const char *logindata, char *sign_root);
void sign_packet(struct ncp_conn *conn, int *size);
#endif
#endif

35
include/ndslib.h Normal file
View File

@@ -0,0 +1,35 @@
/*
NDS client for ncpfs
Copyright (C) 1997 Arne de Bruijn
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef _NDSLIB_H_
#define _NDSLIB_H_
#include "ncplib.h"
typedef unsigned short uni_char;
#define NDS_GRACE_PERIOD -223
int strlen_u(const uni_char *s);
void strcpy_uc(char *d, const uni_char *s);
void strcpy_cu(uni_char *d, const char *s);
long nds_get_server_name(struct ncp_conn *conn, uni_char **server_name);
long nds_get_tree_name(struct ncp_conn *conn, char *name, int name_buf_len);
long nds_login_auth(struct ncp_conn *conn, const char *user, const char *pwd);
#endif /* ifndef _NDSLIB_H_ */

View File

@@ -1,5 +1,8 @@
CFLAGS = -O2 -Wall
include ../Makeinit
# CFLAGS = -O2 -Wall -I../include
UTILS = ipx_configure ipx_interface ipx_internal_net ipx_route
MAN8 := $(UTILS)
CFLAGS := $(CCFLAGS)
all: $(UTILS)
@@ -17,3 +20,4 @@ install: $(UTILS)
do \
install $$i $(BINDIR); \
done
for i in $(MAN8); do install $$i.8 -m 644 $(MANDIR)/man8; done

View File

@@ -5,7 +5,8 @@
#include <sys/socket.h>
#include <errno.h>
int main(int argc, char **argv)
int
main(int argc, char **argv)
{
struct sockaddr_ipx sipx;
int s;
@@ -14,7 +15,8 @@ int main(int argc, char **argv)
int len;
s = socket(AF_IPX, SOCK_DGRAM, AF_IPX);
if (s < 0) {
if (s < 0)
{
perror("IPX: socket: ");
exit(-1);
}
@@ -24,14 +26,16 @@ int main(int argc, char **argv)
sipx.sipx_type = 17;
len = sizeof(sipx);
result = bind(s, (struct sockaddr *) &sipx, sizeof(sipx));
if (result < 0) {
if (result < 0)
{
perror("IPX: bind: ");
exit(-1);
}
msg[0] = '\0';
result = recvfrom(s, msg, sizeof(msg), 0, (struct sockaddr *) &sipx,
&len);
if (result < 0) {
if (result < 0)
{
perror("IPX: recvfrom: ");
}
printf("From %08lX:%02X%02X%02X%02X%02X%02X:%04X\n",

View File

@@ -9,7 +9,8 @@
#include <sys/socket.h>
#include <errno.h>
int main(int argc, char **argv)
int
main(int argc, char **argv)
{
struct sockaddr_ipx sipx;
int s;
@@ -18,7 +19,8 @@ int main(int argc, char **argv)
int len = sizeof(sipx);
s = socket(AF_IPX, SOCK_DGRAM, AF_IPX);
if (s < 0) {
if (s < 0)
{
perror("IPX: socket: ");
exit(-1);
}
@@ -28,7 +30,8 @@ int main(int argc, char **argv)
sipx.sipx_type = 17;
result = bind(s, (struct sockaddr *) &sipx, sizeof(sipx));
if (result < 0) {
if (result < 0)
{
perror("IPX: bind: ");
exit(-1);
}
@@ -36,7 +39,8 @@ int main(int argc, char **argv)
sipx.sipx_port = htons(0x5000);
result = sendto(s, msg, sizeof(msg), 0, (struct sockaddr *) &sipx,
sizeof(sipx));
if (result < 0) {
if (result < 0)
{
perror("IPX: send: ");
exit(-1);
}

View File

@@ -9,13 +9,15 @@
#include <sys/socket.h>
#include <errno.h>
struct rip_data {
struct rip_data
{
unsigned long rip_net;
unsigned short rip_hops __attribute__((packed));
unsigned short rip_ticks __attribute__((packed));
};
int main(int argc, char **argv)
int
main(int argc, char **argv)
{
struct sockaddr_ipx sipx;
int result;
@@ -26,7 +28,8 @@ int main(int argc, char **argv)
struct rip_data *rp;
s = socket(AF_IPX, SOCK_DGRAM, AF_IPX);
if (s < 0) {
if (s < 0)
{
perror("IPX: socket: ");
exit(-1);
}
@@ -35,15 +38,18 @@ int main(int argc, char **argv)
sipx.sipx_port = htons(0x453);
sipx.sipx_type = 17;
result = bind(s, (struct sockaddr *) &sipx, sizeof(sipx));
if (result < 0) {
if (result < 0)
{
perror("IPX: bind: ");
exit(-1);
}
while (1) {
while (1)
{
len = sizeof(sipx);
result = recvfrom(s, msg, sizeof(msg), 0,
(struct sockaddr *) &sipx, &len);
if (result < 0) {
if (result < 0)
{
perror("IPX: recvfrom");
exit(-1);
}
@@ -56,7 +62,8 @@ int main(int argc, char **argv)
sipx.sipx_node[6], sipx.sipx_node[5]);
bptr += 2;
rp = (struct rip_data *) bptr;
while (result >= sizeof(struct rip_data)) {
while (result >= sizeof(struct rip_data))
{
printf("\tNET: %08lX HOPS: %d\n", ntohl(rp->rip_net),
ntohs(rp->rip_hops));
result -= sizeof(struct rip_data);

View File

@@ -10,7 +10,8 @@
#include <errno.h>
struct sap_data {
struct sap_data
{
unsigned short sap_type __attribute__((packed));
char sap_name[48] __attribute__((packed));
unsigned long sap_net __attribute__((packed));
@@ -19,7 +20,8 @@ struct sap_data {
unsigned short sap_hops __attribute__((packed));
};
int main(int argc, char **argv)
int
main(int argc, char **argv)
{
int s;
int result;
@@ -31,12 +33,14 @@ int main(int argc, char **argv)
struct sap_data *sp;
s = socket(AF_IPX, SOCK_DGRAM, AF_IPX);
if (s < 0) {
if (s < 0)
{
perror("IPX: socket: ");
exit(-1);
}
result = setsockopt(s, SOL_SOCKET, SO_DEBUG, &val, 4);
if (result < 0) {
if (result < 0)
{
perror("IPX: setsockopt: ");
exit(-1);
}
@@ -46,15 +50,18 @@ int main(int argc, char **argv)
sipx.sipx_type = 17;
result = bind(s, (struct sockaddr *) &sipx, sizeof(sipx));
if (result < 0) {
if (result < 0)
{
perror("IPX: bind: ");
exit(-1);
}
while (1) {
while (1)
{
len = 1024;
result = recvfrom(s, msg, sizeof(msg), 0,
(struct sockaddr *) &sipx, &len);
if (result < 0) {
if (result < 0)
{
perror("IPX: recvfrom: ");
exit(-1);
}
@@ -67,7 +74,8 @@ int main(int argc, char **argv)
bptr += 2;
sp = (struct sap_data *) bptr;
while (result >= sizeof(struct sap_data)) {
while (result >= sizeof(struct sap_data))
{
int i;
sp->sap_name[32] = '\0';

View File

@@ -8,7 +8,7 @@
#include <ctype.h>
#include <getopt.h>
#include <strings.h>
#include <linux/ipx.h>
#include "kernel/ipx.h"
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
@@ -24,7 +24,8 @@ struct option options[] =
char *progname;
void usage(void)
void
usage(void)
{
fprintf(stderr,
"Usage: %s --auto_primary=[on|off]\n\
@@ -33,23 +34,27 @@ Usage: %s --help\n\
Usage: %s\n", progname, progname, progname, progname);
}
int map_string_to_bool(char *optarg)
int
map_string_to_bool(char *optarg)
{
if ((strcasecmp(optarg, "ON") == 0) ||
(strcasecmp(optarg, "TRUE") == 0) ||
(strcasecmp(optarg, "SET") == 0) ||
(strcasecmp(optarg, "YES") == 0)) {
(strcasecmp(optarg, "YES") == 0))
{
return 1;
} else if ((strcasecmp(optarg, "OFF") == 0) ||
(strcasecmp(optarg, "FALSE") == 0) ||
(strcasecmp(optarg, "CLEAR") == 0) ||
(strcasecmp(optarg, "NO") == 0)) {
(strcasecmp(optarg, "NO") == 0))
{
return 0;
}
return -1;
}
int main(int argc, char **argv)
int
main(int argc, char **argv)
{
int s;
int result;
@@ -63,11 +68,13 @@ int main(int argc, char **argv)
progname = argv[0];
s = socket(AF_IPX, SOCK_DGRAM, AF_IPX);
if (s < 0) {
if (s < 0)
{
int old_errno = errno;
sprintf(errmsg, "%s: socket", progname);
perror(errmsg);
if (old_errno == -EINVAL) {
if (old_errno == -EINVAL)
{
fprintf(stderr, "Probably you have no IPX support in "
"your kernel\n");
}
@@ -75,20 +82,24 @@ int main(int argc, char **argv)
}
sprintf(errmsg, "%s: ioctl", progname);
while ((result = getopt_long(argc, argv, "", options,
&option_index)) != -1) {
switch (result) {
&option_index)) != -1)
{
switch (result)
{
case 1:
if (got_auto_pri)
break;
got_auto_pri++;
val = map_string_to_bool(optarg);
if (val < 0) {
if (val < 0)
{
usage();
exit(-1);
}
result = ioctl(s, SIOCAIPXPRISLT, &val);
if (result < 0) {
if (result < 0)
{
perror(errmsg);
exit(-1);
}
@@ -99,12 +110,14 @@ int main(int argc, char **argv)
got_auto_itf++;
val = map_string_to_bool(optarg);
if (val < 0) {
if (val < 0)
{
usage();
exit(-1);
}
result = ioctl(s, SIOCAIPXITFCRT, &val);
if (result < 0) {
if (result < 0)
{
perror(errmsg);
exit(-1);
}
@@ -115,15 +128,17 @@ int main(int argc, char **argv)
}
}
result = ioctl(s, SIOCIPXCFGDATA, &data);
if (result < 0) {
if (result < 0)
{
perror(errmsg);
exit(-1);
}
if (argc == 1) {
if (argc == 1)
{
fprintf(stdout, "Auto Primary Select is %s\n\
Auto Interface Create is %s\n",
(data.ipxcfg_auto_select_primary) ? "ON" : "OFF",
(data.ipxcfg_auto_create_interfaces) ? "ON" : "OFF");
(data.ipxcfg_auto_create_interfaces) ? "ON" : "OFF");
}
exit(0);
}

View File

@@ -11,8 +11,8 @@
#include <stdlib.h>
#include <strings.h>
#include <netinet/in.h>
#include <linux/ipx.h>
#include <linux/if.h>
#include "kernel/ipx.h"
#include "kernel/if.h"
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
@@ -21,7 +21,8 @@
static struct ifreq id;
static char *progname;
void usage(void)
void
usage(void)
{
fprintf(stderr, "Usage: %s add [-p] device frame_type [net_number]\n\
Usage: %s del device frame_type\n\
@@ -30,11 +31,12 @@ Usage: %s check device frame_type\n", progname, progname, progname, progname);
exit(-1);
}
struct frame_type {
struct frame_type
{
char *ft_name;
unsigned char ft_val;
} frame_types[] =
}
frame_types[] =
{
{
"802.2", IPX_FRAME_8022
@@ -61,19 +63,22 @@ struct frame_type {
#define NFTYPES (sizeof(frame_types)/sizeof(struct frame_type))
int lookup_frame_type(char *frame)
int
lookup_frame_type(char *frame)
{
int j;
size_t j;
for (j = 0; (j < NFTYPES) &&
(strcasecmp(frame_types[j].ft_name, frame));
j++);
j++)
;
if (j != NFTYPES)
return j;
fprintf(stderr, "%s: Frame type must be", progname);
for (j = 0; j < NFTYPES; j++) {
for (j = 0; j < NFTYPES; j++)
{
fprintf(stderr, "%s%s",
(j == NFTYPES - 1) ? " or " : " ",
frame_types[j].ft_name);
@@ -82,7 +87,8 @@ int lookup_frame_type(char *frame)
return -1;
}
int ipx_add_interface(int argc, char **argv)
int
ipx_add_interface(int argc, char **argv)
{
struct sockaddr_ipx *sipx = (struct sockaddr_ipx *) &id.ifr_addr;
int s;
@@ -95,19 +101,24 @@ int ipx_add_interface(int argc, char **argv)
sipx->sipx_special = IPX_SPECIAL_NONE;
sipx->sipx_network = 0L;
sipx->sipx_type = IPX_FRAME_NONE;
while ((c = getopt(argc, argv, "p")) > 0) {
switch (c) {
while ((c = getopt(argc, argv, "p")) > 0)
{
switch (c)
{
case 'p':
sipx->sipx_special = IPX_PRIMARY;
break;
}
}
if (((i = (argc - optind)) < 2) || (i > 3)) {
if (((i = (argc - optind)) < 2) || (i > 3))
{
usage();
}
for (i = optind; i < argc; i++) {
switch (i - optind) {
for (i = optind; i < argc; i++)
{
switch (i - optind)
{
case 0: /* Physical Device - Required */
strcpy(id.ifr_name, argv[i]);
break;
@@ -120,9 +131,10 @@ int ipx_add_interface(int argc, char **argv)
case 2: /* Network Number - Optional */
netnum = strtoul(argv[i], (char **) NULL, 16);
if (netnum == 0xffffffffL) {
if (netnum == 0xffffffffL)
{
fprintf(stderr,
"%s: Inappropriate network number %08lX\n",
"%s: Inappropriate network number %08lX\n",
progname, netnum);
exit(-1);
}
@@ -132,11 +144,13 @@ int ipx_add_interface(int argc, char **argv)
}
s = socket(AF_IPX, SOCK_DGRAM, AF_IPX);
if (s < 0) {
if (s < 0)
{
int old_errno = errno;
sprintf(errmsg, "%s: socket", progname);
perror(errmsg);
if (old_errno == -EINVAL) {
if (old_errno == -EINVAL)
{
fprintf(stderr, "Probably you have no IPX support in "
"your kernel\n");
}
@@ -145,7 +159,8 @@ int ipx_add_interface(int argc, char **argv)
i = 0;
sipx->sipx_family = AF_IPX;
sipx->sipx_action = IPX_CRTITF;
do {
do
{
result = ioctl(s, SIOCSIFADDR, &id);
i++;
}
@@ -154,14 +169,15 @@ int ipx_add_interface(int argc, char **argv)
if (result == 0)
exit(0);
switch (errno) {
switch (errno)
{
case EEXIST:
fprintf(stderr, "%s: Primary network already selected.\n",
progname);
break;
case EADDRINUSE:
fprintf(stderr, "%s: Network number (%08lX) already in use.\n",
progname, htonl(sipx->sipx_network));
fprintf(stderr, "%s: Network number (%08X) already in use.\n",
progname, (u_int32_t)htonl(sipx->sipx_network));
break;
case EPROTONOSUPPORT:
fprintf(stderr, "%s: Invalid frame type (%s).\n",
@@ -192,7 +208,8 @@ int ipx_add_interface(int argc, char **argv)
exit(-1);
}
int ipx_delall_interface(int argc, char **argv)
int
ipx_delall_interface(int argc, char **argv)
{
struct sockaddr_ipx *sipx = (struct sockaddr_ipx *) &id.ifr_addr;
int s;
@@ -205,26 +222,31 @@ int ipx_delall_interface(int argc, char **argv)
FILE *fp;
s = socket(AF_IPX, SOCK_DGRAM, AF_IPX);
if (s < 0) {
if (s < 0)
{
sprintf(errmsg, "%s: socket", progname);
perror(errmsg);
exit(-1);
}
fp = fopen("/proc/net/ipx_interface", "r");
if (fp == NULL) {
if (fp == NULL)
{
fprintf(stderr,
"%s: Unable to open \"/proc/net/ipx_interface.\"\n",
"%s: Unable to open \"/proc/net/ipx_interface.\"\n",
progname);
exit(-1);
}
fgets(buffer, 80, fp);
while (fscanf(fp, "%s %s %s %s %s", buffer, buffer, buffer,
device, frame_type) == 5) {
device, frame_type) == 5)
{
sipx->sipx_network = 0L;
if (strcasecmp(device, "Internal") == 0) {
if (strcasecmp(device, "Internal") == 0)
{
sipx->sipx_special = IPX_INTERNAL;
} else {
} else
{
sipx->sipx_special = IPX_SPECIAL_NONE;
strcpy(id.ifr_name, device);
fti = lookup_frame_type(frame_type);
@@ -238,7 +260,8 @@ int ipx_delall_interface(int argc, char **argv)
result = ioctl(s, SIOCSIFADDR, &id);
if (result == 0)
continue;
switch (errno) {
switch (errno)
{
case EPROTONOSUPPORT:
fprintf(stderr, "%s: Invalid frame type (%s).\n",
progname, frame_type);
@@ -261,7 +284,8 @@ int ipx_delall_interface(int argc, char **argv)
exit(0);
}
int ipx_del_interface(int argc, char **argv)
int
ipx_del_interface(int argc, char **argv)
{
struct sockaddr_ipx *sipx = (struct sockaddr_ipx *) &id.ifr_addr;
int s;
@@ -269,7 +293,8 @@ int ipx_del_interface(int argc, char **argv)
char errmsg[80];
int fti;
if (argc != 3) {
if (argc != 3)
{
usage();
}
sipx->sipx_network = 0L;
@@ -281,7 +306,8 @@ int ipx_del_interface(int argc, char **argv)
sipx->sipx_type = frame_types[fti].ft_val;
s = socket(AF_IPX, SOCK_DGRAM, AF_IPX);
if (s < 0) {
if (s < 0)
{
sprintf(errmsg, "%s: socket", progname);
perror(errmsg);
exit(-1);
@@ -292,7 +318,8 @@ int ipx_del_interface(int argc, char **argv)
if (result == 0)
exit(0);
switch (errno) {
switch (errno)
{
case EPROTONOSUPPORT:
fprintf(stderr, "%s: Invalid frame type (%s).\n",
progname, frame_types[fti].ft_name);
@@ -313,7 +340,8 @@ int ipx_del_interface(int argc, char **argv)
exit(-1);
}
int ipx_check_interface(int argc, char **argv)
int
ipx_check_interface(int argc, char **argv)
{
struct sockaddr_ipx *sipx = (struct sockaddr_ipx *) &id.ifr_addr;
int s;
@@ -321,7 +349,8 @@ int ipx_check_interface(int argc, char **argv)
char errmsg[80];
int fti;
if (argc != 3) {
if (argc != 3)
{
usage();
}
sipx->sipx_network = 0L;
@@ -332,24 +361,27 @@ int ipx_check_interface(int argc, char **argv)
sipx->sipx_type = frame_types[fti].ft_val;
s = socket(AF_IPX, SOCK_DGRAM, AF_IPX);
if (s < 0) {
if (s < 0)
{
sprintf(errmsg, "%s: socket", progname);
perror(errmsg);
exit(-1);
}
sipx->sipx_family = AF_IPX;
result = ioctl(s, SIOCGIFADDR, &id);
if (result == 0) {
if (result == 0)
{
printf(
"IPX Address for (%s, %s) is %08lX:%02X%02X%02X%02X%02X%02X.\n",
"IPX Address for (%s, %s) is %08X:%02X%02X%02X%02X%02X%02X.\n",
argv[1], frame_types[fti].ft_name,
htonl(sipx->sipx_network), sipx->sipx_node[0],
(u_int32_t)htonl(sipx->sipx_network), sipx->sipx_node[0],
sipx->sipx_node[1], sipx->sipx_node[2],
sipx->sipx_node[3], sipx->sipx_node[4],
sipx->sipx_node[5]);
exit(0);
}
switch (errno) {
switch (errno)
{
case EPROTONOSUPPORT:
fprintf(stderr, "%s: Invalid frame type (%s).\n",
progname, frame_types[fti].ft_name);
@@ -370,28 +402,34 @@ int ipx_check_interface(int argc, char **argv)
exit(-1);
}
int main(int argc, char **argv)
int
main(int argc, char **argv)
{
int i;
progname = argv[0];
if (argc < 2) {
if (argc < 2)
{
usage();
exit(-1);
}
if (strncasecmp(argv[1], "add", 3) == 0) {
if (strncasecmp(argv[1], "add", 3) == 0)
{
for (i = 1; i < (argc - 1); i++)
argv[i] = argv[i + 1];
ipx_add_interface(argc - 1, argv);
} else if (strncasecmp(argv[1], "delall", 6) == 0) {
} else if (strncasecmp(argv[1], "delall", 6) == 0)
{
for (i = 1; i < (argc - 1); i++)
argv[i] = argv[i + 1];
ipx_delall_interface(argc - 1, argv);
} else if (strncasecmp(argv[1], "del", 3) == 0) {
} else if (strncasecmp(argv[1], "del", 3) == 0)
{
for (i = 1; i < (argc - 1); i++)
argv[i] = argv[i + 1];
ipx_del_interface(argc - 1, argv);
} else if (strncasecmp(argv[1], "check", 5) == 0) {
} else if (strncasecmp(argv[1], "check", 5) == 0)
{
for (i = 1; i < (argc - 1); i++)
argv[i] = argv[i + 1];
ipx_check_interface(argc - 1, argv);

View File

@@ -9,8 +9,8 @@
#include <errno.h>
#include <strings.h>
#include <netinet/in.h>
#include <linux/ipx.h>
#include <linux/if.h>
#include "kernel/ipx.h"
#include "kernel/if.h"
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
@@ -18,26 +18,32 @@
static struct ifreq id;
static char *progname;
void usage(void)
void
usage(void)
{
fprintf(stderr, "Usage: %s add net_number(hex) node(hex)\n\
Usage: %s del\n", progname, progname);
exit(-1);
}
int map_char_to_val(char dig)
int
map_char_to_val(char dig)
{
char digit = tolower(dig);
if ((digit >= '0') && (digit <= '9')) {
if ((digit >= '0') && (digit <= '9'))
{
return digit - '0';
} else if ((digit >= 'a') && (digit <= 'f')) {
} else if ((digit >= 'a') && (digit <= 'f'))
{
return (10 + (digit - 'a'));
} else {
} else
{
return 0;
}
}
int ipx_add_internal_net(int argc, char **argv)
int
ipx_add_internal_net(int argc, char **argv)
{
struct sockaddr_ipx *sipx = (struct sockaddr_ipx *) &id.ifr_addr;
int s;
@@ -51,38 +57,45 @@ int ipx_add_internal_net(int argc, char **argv)
char *tin;
int i;
if (argc != 3) {
if (argc != 3)
{
usage();
}
netnum = strtoul(argv[1], (char **) NULL, 16);
if ((netnum == 0L) || (netnum == 0xffffffffL)) {
if ((netnum == 0L) || (netnum == 0xffffffffL))
{
fprintf(stderr, "%s: Inappropriate network number %08lX\n",
progname, netnum);
exit(-1);
}
node = argv[2];
nodelen = strlen(node);
if (nodelen > 12) {
if (nodelen > 12)
{
fprintf(stderr, "%s: Node length is too long (> 12).\n", progname);
exit(-1);
}
for (i = 0; (i < nodelen) && isxdigit(node[i]); i++);
for (i = 0; (i < nodelen) && isxdigit(node[i]); i++)
;
if (i < nodelen) {
if (i < nodelen)
{
fprintf(stderr, "%s: Invalid value in node, must be hex digits.\n",
progname);
exit(-1);
}
strcpy(tmpnode, "000000000000");
memcpy(&(tmpnode[12 - nodelen]), node, nodelen);
for (tin = tmpnode, tout = sipx->sipx_node; *tin != '\0'; tin += 2, tout++) {
for (tin = tmpnode, tout = sipx->sipx_node; *tin != '\0'; tin += 2, tout++)
{
*tout = (unsigned char) map_char_to_val(*tin);
*tout <<= 4;
*tout |= (unsigned char) map_char_to_val(*(tin + 1));
}
if ((memcmp(sipx->sipx_node, "\0\0\0\0\0\0\0\0", IPX_NODE_LEN) == 0) ||
(memcmp(sipx->sipx_node, "\377\377\377\377\377\377", IPX_NODE_LEN) == 0)) {
(memcmp(sipx->sipx_node, "\377\377\377\377\377\377", IPX_NODE_LEN) == 0))
{
fprintf(stderr, "%s: Node is invalid.\n", progname);
exit(-1);
}
@@ -90,7 +103,8 @@ int ipx_add_internal_net(int argc, char **argv)
sipx->sipx_type = IPX_FRAME_NONE;
sipx->sipx_special = IPX_INTERNAL;
s = socket(AF_IPX, SOCK_DGRAM, AF_IPX);
if (s < 0) {
if (s < 0)
{
sprintf(errmsg, "%s: socket", progname);
perror(errmsg);
exit(-1);
@@ -98,7 +112,8 @@ int ipx_add_internal_net(int argc, char **argv)
sipx->sipx_family = AF_IPX;
sipx->sipx_action = IPX_CRTITF;
i = 0;
do {
do
{
result = ioctl(s, SIOCSIFADDR, &id);
i++;
}
@@ -107,18 +122,19 @@ int ipx_add_internal_net(int argc, char **argv)
if (result == 0)
exit(0);
switch (errno) {
switch (errno)
{
case EEXIST:
fprintf(stderr, "%s: Primary network already selected.\n",
progname);
break;
case EADDRINUSE:
fprintf(stderr, "%s: Network number (%08lX) already in use.\n",
progname, htonl(sipx->sipx_network));
fprintf(stderr, "%s: Network number (%08X) already in use.\n",
progname, (u_int32_t)htonl(sipx->sipx_network));
break;
case EAGAIN:
fprintf(stderr,
"%s: Insufficient memory to create internal net.\n",
"%s: Insufficient memory to create internal net.\n",
progname);
break;
default:
@@ -129,20 +145,23 @@ int ipx_add_internal_net(int argc, char **argv)
exit(-1);
}
int ipx_del_internal_net(int argc, char **argv)
int
ipx_del_internal_net(int argc, char **argv)
{
struct sockaddr_ipx *sipx = (struct sockaddr_ipx *) &id.ifr_addr;
int s;
int result;
char errmsg[80];
if (argc != 1) {
if (argc != 1)
{
usage();
}
sipx->sipx_network = 0L;
sipx->sipx_special = IPX_INTERNAL;
s = socket(AF_IPX, SOCK_DGRAM, AF_IPX);
if (s < 0) {
if (s < 0)
{
sprintf(errmsg, "%s: socket", progname);
perror(errmsg);
exit(-1);
@@ -153,7 +172,8 @@ int ipx_del_internal_net(int argc, char **argv)
if (result == 0)
exit(0);
switch (errno) {
switch (errno)
{
case ENOENT:
fprintf(stderr, "%s: No internal network configured.\n", progname);
break;
@@ -165,20 +185,24 @@ int ipx_del_internal_net(int argc, char **argv)
exit(-1);
}
int main(int argc, char **argv)
int
main(int argc, char **argv)
{
int i;
progname = argv[0];
if (argc < 2) {
if (argc < 2)
{
usage();
exit(-1);
}
if (strncasecmp(argv[1], "add", 3) == 0) {
if (strncasecmp(argv[1], "add", 3) == 0)
{
for (i = 1; i < (argc - 1); i++)
argv[i] = argv[i + 1];
ipx_add_internal_net(argc - 1, argv);
} else if (strncasecmp(argv[1], "del", 3) == 0) {
} else if (strncasecmp(argv[1], "del", 3) == 0)
{
for (i = 1; i < (argc - 1); i++)
argv[i] = argv[i + 1];
ipx_del_internal_net(argc - 1, argv);

View File

@@ -11,28 +11,33 @@
#include <errno.h>
#include <strings.h>
#include <netinet/in.h>
#include <linux/ipx.h>
#include "kernel/ipx.h"
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <linux/route.h>
#include "kernel/route.h"
static struct rtentry rd;
static char *progname;
int map_char_to_val(char dig)
int
map_char_to_val(char dig)
{
char digit = tolower(dig);
if ((digit >= '0') && (digit <= '9')) {
if ((digit >= '0') && (digit <= '9'))
{
return digit - '0';
} else if ((digit >= 'a') && (digit <= 'f')) {
} else if ((digit >= 'a') && (digit <= 'f'))
{
return (10 + (digit - 'a'));
} else {
} else
{
return 0;
}
}
void usage(void)
void
usage(void)
{
fprintf(stderr,
"Usage: %s add network(hex) router_network(hex) router_node(hex)\n\
@@ -40,7 +45,8 @@ Usage: %s del network(hex)\n", progname, progname);
exit(-1);
}
int ipx_add_route(int argc, char **argv)
int
ipx_add_route(int argc, char **argv)
{
/* Router */
struct sockaddr_ipx *sr = (struct sockaddr_ipx *) &rd.rt_gateway;
@@ -62,7 +68,8 @@ int ipx_add_route(int argc, char **argv)
/* Network Number */
netnum = strtoul(argv[1], (char **) NULL, 16);
if ((netnum == 0xffffffffL) || (netnum == 0L)) {
if ((netnum == 0xffffffffL) || (netnum == 0L))
{
fprintf(stderr, "%s: Inappropriate network number %08lX\n",
progname, netnum);
exit(-1);
@@ -72,7 +79,8 @@ int ipx_add_route(int argc, char **argv)
/* Router Network Number */
netnum = strtoul(argv[2], (char **) NULL, 16);
if ((netnum == 0xffffffffL) || (netnum == 0L)) {
if ((netnum == 0xffffffffL) || (netnum == 0L))
{
fprintf(stderr, "%s: Inappropriate network number %08lX\n",
progname, netnum);
exit(-1);
@@ -82,40 +90,47 @@ int ipx_add_route(int argc, char **argv)
/* Router Node */
node = argv[3];
nodelen = strlen(node);
if (nodelen > 12) {
if (nodelen > 12)
{
fprintf(stderr, "%s: Node length is too long (> 12).\n",
progname);
exit(-1);
}
for (i = 0; (i < nodelen) && isxdigit(node[i]); i++);
for (i = 0; (i < nodelen) && isxdigit(node[i]); i++)
;
if (i < nodelen) {
if (i < nodelen)
{
fprintf(stderr, "%s: Invalid value in node, must be hex digits.\n",
progname);
exit(-1);
}
strcpy(tmpnode, "000000000000");
memcpy(&(tmpnode[12 - nodelen]), node, nodelen);
for (tin = tmpnode, tout = sr->sipx_node; *tin != '\0'; tin += 2, tout++) {
for (tin = tmpnode, tout = sr->sipx_node; *tin != '\0'; tin += 2, tout++)
{
*tout = (unsigned char) map_char_to_val(*tin);
*tout <<= 4;
*tout |= (unsigned char) map_char_to_val(*(tin + 1));
}
if ((memcmp(sr->sipx_node, "\0\0\0\0\0\0\0\0", IPX_NODE_LEN) == 0) ||
(memcmp(sr->sipx_node, "\377\377\377\377\377\377", IPX_NODE_LEN) == 0)) {
(memcmp(sr->sipx_node, "\377\377\377\377\377\377", IPX_NODE_LEN) == 0))
{
fprintf(stderr, "%s: Node (%s) is invalid.\n", progname, tmpnode);
exit(-1);
}
s = socket(AF_IPX, SOCK_DGRAM, AF_IPX);
if (s < 0) {
if (s < 0)
{
sprintf(errmsg, "%s: socket", progname);
perror(errmsg);
exit(-1);
}
sr->sipx_family = st->sipx_family = AF_IPX;
i = 0;
do {
do
{
result = ioctl(s, SIOCADDRT, &rd);
i++;
}
@@ -124,10 +139,11 @@ int ipx_add_route(int argc, char **argv)
if (result == 0)
exit(0);
switch (errno) {
switch (errno)
{
case ENETUNREACH:
fprintf(stderr, "%s: Router network (%08lX) not reachable.\n",
progname, htonl(sr->sipx_network));
fprintf(stderr, "%s: Router network (%08X) not reachable.\n",
progname, (u_int32_t)htonl(sr->sipx_network));
break;
default:
sprintf(errmsg, "%s: ioctl", progname);
@@ -137,7 +153,8 @@ int ipx_add_route(int argc, char **argv)
exit(-1);
}
int ipx_del_route(int argc, char **argv)
int
ipx_del_route(int argc, char **argv)
{
/* Router */
struct sockaddr_ipx *sr = (struct sockaddr_ipx *) &rd.rt_gateway;
@@ -148,13 +165,15 @@ int ipx_del_route(int argc, char **argv)
unsigned long netnum;
char errmsg[80];
if (argc != 2) {
if (argc != 2)
{
usage();
}
rd.rt_flags = RTF_GATEWAY;
/* Network Number */
netnum = strtoul(argv[1], (char **) NULL, 16);
if ((netnum == 0xffffffffL) || (netnum == 0L)) {
if ((netnum == 0xffffffffL) || (netnum == 0L))
{
fprintf(stderr, "%s: Inappropriate network number %08lX.\n",
progname, netnum);
exit(-1);
@@ -163,7 +182,8 @@ int ipx_del_route(int argc, char **argv)
st->sipx_family = sr->sipx_family = AF_IPX;
s = socket(AF_IPX, SOCK_DGRAM, AF_IPX);
if (s < 0) {
if (s < 0)
{
sprintf(errmsg, "%s: socket", progname);
perror(errmsg);
exit(-1);
@@ -172,7 +192,8 @@ int ipx_del_route(int argc, char **argv)
if (result == 0)
exit(0);
switch (errno) {
switch (errno)
{
case ENOENT:
fprintf(stderr, "%s: Route not found for network %08lX.\n",
progname, netnum);
@@ -189,20 +210,24 @@ int ipx_del_route(int argc, char **argv)
exit(-1);
}
int main(int argc, char **argv)
int
main(int argc, char **argv)
{
int i;
progname = argv[0];
if (argc < 2) {
if (argc < 2)
{
usage();
exit(-1);
}
if (strncasecmp(argv[1], "add", 3) == 0) {
if (strncasecmp(argv[1], "add", 3) == 0)
{
for (i = 1; i < (argc - 1); i++)
argv[i] = argv[i + 1];
ipx_add_route(argc - 1, argv);
} else if (strncasecmp(argv[1], "del", 3) == 0) {
} else if (strncasecmp(argv[1], "del", 3) == 0)
{
for (i = 1; i < (argc - 1); i++)
argv[i] = argv[i + 1];
ipx_del_route(argc - 1, argv);

View File

@@ -1,6 +1,6 @@
EXEC= ipxdump ipxparse
CFLAGS= -Wall -O2
CFLAGS= -Wall -O2 -I../include
OBJECTS= ipxutil.o
all: $(EXEC)

View File

@@ -21,26 +21,27 @@
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <linux/if_ether.h>
#include <netinet/if_ether.h>
#include <strings.h>
#include <sys/ioctl.h>
#include <linux/if.h>
#include <net/if.h>
#include <signal.h>
#include <linux/ip.h>
#include <linux/tcp.h>
#include <netinet/protocols.h>
#include <netinet/ip.h>
#include <netinet/tcp.h>
#include <stdio.h>
#include <time.h>
#include <signal.h>
#include "ipxutil.h"
struct ipx_address {
struct ipx_address
{
unsigned long net;
unsigned char node[IPX_NODE_LEN];
unsigned short sock;
};
struct ipx_packet {
struct ipx_packet
{
unsigned short ipx_checksum;
#define IPX_NO_CHECKSUM 0xFFFF
unsigned short ipx_pktsize;
@@ -61,15 +62,18 @@ void handle_frame(unsigned char *buf, int length, struct sockaddr *saddr);
void handle_ipx(char *frame, unsigned char *buf);
static int filter = 0;
static int allframes = 0;
static IPXNode filter_node;
static int exit_request = 0;
static void int_handler()
static void
int_handler()
{
exit_request = 1;
}
void main(int argc, char *argv[])
void
main(int argc, char *argv[])
{
int sd;
struct ifreq ifr, oldifr;
@@ -81,14 +85,30 @@ void main(int argc, char *argv[])
signal(SIGINT, int_handler);
if (argc > 1) {
if (ipx_sscanf_node(argv[1], filter_node) != 0) {
fprintf(stderr, "usage: %s [node]\n", argv[0]);
while (1) {
int opt;
opt = getopt(argc, argv, "r");
if (opt == -1) break;
switch (opt) {
case 'r':allframes = 1; break;
case ':':;
case '?':break;
default: printf("?? unknown option returned by getopt\n");
break;
}
}
if (optind < argc)
{
if (ipx_sscanf_node(argv[optind], filter_node) != 0)
{
fprintf(stderr, "usage: %s [-a] [node]\n", argv[0]);
exit(1);
}
filter = 1;
}
if ((sd = socket(AF_INET, SOCK_PACKET, htons(ETH_P_ALL))) < 0) {
if ((sd = socket(AF_INET, SOCK_PACKET, htons(ETH_P_ALL))) < 0)
{
perror("Can't get socket");
fprintf(stderr, "You must run %s as root\n", argv[0]);
exit(1);
@@ -96,7 +116,8 @@ void main(int argc, char *argv[])
/* SET PROMISC */
strcpy(oldifr.ifr_name, device);
if (ioctl(sd, SIOCGIFFLAGS, &oldifr) < 0) {
if (ioctl(sd, SIOCGIFFLAGS, &oldifr) < 0)
{
close(sd);
perror("Can't get flags");
exit(2);
@@ -105,12 +126,14 @@ void main(int argc, char *argv[])
ifr = oldifr;
ifr.ifr_flags |= IFF_PROMISC;
if (ioctl(sd, SIOCSIFFLAGS, &ifr) < 0) {
if (ioctl(sd, SIOCSIFFLAGS, &ifr) < 0)
{
close(sd);
perror("Can't set flags");
exit(3);
}
while (exit_request == 0) {
while (exit_request == 0)
{
/* This is the main data-gathering loop; keep it small
and fast */
sizeaddr = sizeof(saddr);
@@ -118,11 +141,23 @@ void main(int argc, char *argv[])
&saddr, &sizeaddr);
if (length < 0)
continue;
handle_frame(buf, length, &saddr);
if (allframes) {
unsigned char* ptr = buf;
if (filter) {
if (memcmp(filter_node, buf, 6)&&memcmp(filter_node, buf+6, 6))
continue;
}
printf("raweth ");
while (length--) printf("%02X", *ptr++);
printf("\n");
} else {
handle_frame(buf, length, &saddr);
}
}
/* This should be rewritten to cooperate with other net tools */
if (ioctl(sd, SIOCSIFFLAGS, &oldifr) < 0) {
if (ioctl(sd, SIOCSIFFLAGS, &oldifr) < 0)
{
close(sd);
perror("Can't set flags");
exit(4);
@@ -131,7 +166,8 @@ void main(int argc, char *argv[])
exit(0);
}
void handle_ipx(char *frame, unsigned char *buf)
void
handle_ipx(char *frame, unsigned char *buf)
{
int i;
struct ipx_packet *h = (struct ipx_packet *) buf;
@@ -151,32 +187,38 @@ void handle_ipx(char *frame, unsigned char *buf)
d_addr.sipx_port = h->ipx_dest.sock;
d_addr.sipx_network = h->ipx_dest.net;
if (filter != 0) {
if (filter != 0)
{
if ((memcmp(filter_node, s_addr.sipx_node,
sizeof(filter_node)) != 0)
&& (memcmp(filter_node, d_addr.sipx_node,
sizeof(filter_node)) != 0)) {
sizeof(filter_node)) != 0))
{
/* Not for us */
return;
}
}
printf("%s ", frame);
for (i = 0; i < length; i++) {
for (i = 0; i < length; i++)
{
printf("%2.2X", buf[i]);
}
printf("\n");
if (!isatty(STDOUT_FILENO)) {
if (!isatty(STDOUT_FILENO))
{
fflush(stdout);
}
}
void handle_other(unsigned char *buf, int length, struct sockaddr *saddr)
void
handle_other(unsigned char *buf, int length, struct sockaddr *saddr)
{
struct ethhdr *eth = (struct ethhdr *) buf;
unsigned char *p = &(buf[sizeof(struct ethhdr)]);
if (ntohs(eth->h_proto) < 1536) {
if (ntohs(eth->h_proto) < 1536)
{
/* This is a magic hack to spot IPX packets. Older
* Novell breaks the protocol design and runs IPX over
* 802.3 without an 802.2 LLC layer. We look for FFFF
@@ -184,28 +226,33 @@ void handle_other(unsigned char *buf, int length, struct sockaddr *saddr)
* for fault tolerant netware but does for the rest.
*/
if (*(unsigned short *) p == 0xffff) {
if (*(unsigned short *) p == 0xffff)
{
handle_ipx("802.3", p);
return;
}
if ((*(unsigned short *) p == htons(0xe0e0))
&& (p[2] == 0x03)) {
&& (p[2] == 0x03))
{
handle_ipx("802.2", p + 3);
return;
}
if (memcmp(p, "\252\252\003\000\000\000\201\067", 8) == 0) {
if (memcmp(p, "\252\252\003\000\000\000\201\067", 8) == 0)
{
handle_ipx("snap", p + 8);
return;
}
}
}
void handle_frame(unsigned char *buf, int length, struct sockaddr *saddr)
void
handle_frame(unsigned char *buf, int length, struct sockaddr *saddr)
{
/* Ethernet packet type ID field */
unsigned short packet_type = ((struct ethhdr *) buf)->h_proto;
switch (packet_type) {
case __constant_ntohs(ETH_P_IPX):
switch (htons(packet_type))
{
case ETH_P_IPX:
handle_ipx("EtherII", &(buf[sizeof(struct ethhdr)]));
break;
default:

View File

@@ -21,29 +21,34 @@
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <linux/if_ether.h>
#include <netinet/if_ether.h>
#include <strings.h>
#include <sys/ioctl.h>
#include <linux/if.h>
#include <net/if.h>
#include <signal.h>
#include <linux/ip.h>
#include <linux/tcp.h>
#include <netinet/protocols.h>
#include <netinet/ip.h>
#include <netinet/tcp.h>
#include <stdio.h>
#include <time.h>
#include <signal.h>
#include <ctype.h>
#include "ipxutil.h"
#define __u8 u_int8_t
#define __u16 u_int16_t
#define __u32 u_int32_t
#define DUMPALLSAPS /* #define if you want to dump all SAP's */
struct ipx_address {
struct ipx_address
{
unsigned long net;
unsigned char node[IPX_NODE_LEN];
unsigned short sock;
};
struct ipx_packet {
struct ipx_packet
{
unsigned short ipx_checksum;
#define IPX_NO_CHECKSUM 0xFFFF
unsigned short ipx_pktsize;
@@ -63,7 +68,8 @@ struct ipx_packet {
#define NCP_REQUEST (0x2222)
#define NCP_DEALLOC_SLOT_REQUEST (0x5555)
struct ncp_request_header {
struct ncp_request_header
{
__u16 type __attribute__((packed));
__u8 sequence __attribute__((packed));
__u8 conn_low __attribute__((packed));
@@ -76,7 +82,8 @@ struct ncp_request_header {
#define NCP_REPLY (0x3333)
#define NCP_POSITIVE_ACK (0x9999)
struct ncp_reply_header {
struct ncp_reply_header
{
__u16 type __attribute__((packed));
__u8 sequence __attribute__((packed));
__u8 conn_low __attribute__((packed));
@@ -89,7 +96,8 @@ struct ncp_reply_header {
#define NCP_BURST_PACKET (0x7777)
struct ncp_burst_header {
struct ncp_burst_header
{
__u16 type __attribute__((packed));
__u8 system_flags __attribute__((packed));
__u8 stream_type __attribute__((packed));
@@ -120,29 +128,37 @@ int handle_burst(struct sockaddr_ipx *source,
/* SAP Query structure (returned in sap_packet as an array)
* NBO == Network Byte Order)
*/
typedef struct saps {
typedef struct saps
{
__u16 serverType __attribute__((packed)); /* NBO */
__u8 serverName[SAP_MAX_SERVER_NAME_LENGTH] __attribute__((packed));
struct ipx_address serverAddress __attribute__((packed));
__u16 serverHops __attribute__((packed)); /* NBO */
} SAPS;
}
SAPS;
/* General Service/Nearest Server Response SAP packet */
union sap_packet {
union sap_packet
{
unsigned short sapOperation;
struct sap_query {
struct sap_query
{
__u16 sapOperation __attribute__((packed));
__u16 serverType __attribute__((packed));
} query;
struct sap_response {
}
query;
struct sap_response
{
__u16 sapOperation __attribute__((packed));
/* each SAP can has a max of SAP_MAX_SAPS_PER_PACKET packets */
SAPS sap[SAP_MAX_SAPS_PER_PACKET] __attribute__((packed));
} response;
}
response;
};
/* print out one SAP record */
static void print_sap(FILE * file, SAPS * sapp)
static void
print_sap(FILE * file, SAPS * sapp)
{
fprintf(file, " Name:%s, serverType 0x%x, ",
sapp->serverName,
@@ -155,7 +171,8 @@ static void print_sap(FILE * file, SAPS * sapp)
fprintf(file, " (Hops %d)\n", ntohs(sapp->serverHops));
}
void handle_ipx(unsigned char *buf, int length, char *frame, int no)
void
handle_ipx(unsigned char *buf, int length, char *frame, int no)
{
struct ipx_packet *h = (struct ipx_packet *) buf;
struct sockaddr_ipx s_addr;
@@ -183,11 +200,13 @@ void handle_ipx(unsigned char *buf, int length, char *frame, int no)
printf("\n");
if (handle_burst(&s_addr, &d_addr, buf + sizeof(struct ipx_packet),
length - sizeof(struct ipx_packet), no) != 0) {
length - sizeof(struct ipx_packet), no) != 0)
{
return;
}
if ((ntohs(s_addr.sipx_port) == 0x451)
|| (ntohs(d_addr.sipx_port) == 0x451)) {
|| (ntohs(d_addr.sipx_port) == 0x451))
{
handle_ncp(&s_addr, &d_addr, buf + sizeof(struct ipx_packet),
length - sizeof(struct ipx_packet), no);
} else
@@ -198,21 +217,25 @@ void handle_ipx(unsigned char *buf, int length, char *frame, int no)
printf(" type 0x05 (SPX sequenced packet)\n");
else if (h->ipx_type == 0x14)
printf(" type 0x14 (propogated Client-NetBios)\n");
else {
else
{
hbo_dsock = ntohs(d_addr.sipx_port);
if (hbo_dsock == 0x452) { /* SAP */
if (hbo_dsock == 0x452) /* SAP */
{
sappacket = (union sap_packet *)
(buf + sizeof(struct ipx_packet));
hbo_sapop = ntohs(sappacket->sapOperation);
if ((hbo_sapop == 0x01) || (hbo_sapop == 0x03)) {
if ((hbo_sapop == 0x01) || (hbo_sapop == 0x03))
{
printf(" type 0x%x, SAP op:0x%x %s Query, "
"serverType 0x%x wanted\n",
h->ipx_type, hbo_sapop,
(hbo_sapop == 0x01) ? "General Service" :
(hbo_sapop == 0x03) ? "Nearest Server" :
(hbo_sapop == 0x01) ? "General Service" :
(hbo_sapop == 0x03) ? "Nearest Server" :
"Error",
ntohs(sappacket->query.serverType));
} else {
ntohs(sappacket->query.serverType));
} else
{
int hops;
hops = ntohs(sappacket->
@@ -228,18 +251,20 @@ void handle_ipx(unsigned char *buf, int length, char *frame, int no)
? "[Shutdown]" : "");
/* Service ending */
if (hops >= SAP_SHUTDOWN) {
if (hops >= SAP_SHUTDOWN)
{
print_sap(stdout,
sappacket->response.sap);
sappacket->response.sap);
}
#ifdef DUMPALLSAPS
/* If you want to dump all SAP's */
else {
else
{
int num_saps;
SAPS *sapp;
num_saps = (length
- sizeof(struct ipx_packet)
- sizeof(struct ipx_packet)
- 2) / sizeof(SAPS);
sapp = sappacket->response.sap;
@@ -263,13 +288,15 @@ void handle_ipx(unsigned char *buf, int length, char *frame, int no)
}
int handle_burst(struct sockaddr_ipx *source,
struct sockaddr_ipx *target,
unsigned char *buf, int length, int no)
int
handle_burst(struct sockaddr_ipx *source,
struct sockaddr_ipx *target,
unsigned char *buf, int length, int no)
{
struct ncp_burst_header *rq = (struct ncp_burst_header *) buf;
if (rq->type != NCP_BURST_PACKET) {
if (rq->type != NCP_BURST_PACKET)
{
return 0;
}
printf("Burst Packet\n");
@@ -279,22 +306,25 @@ int handle_burst(struct sockaddr_ipx *source,
rq->source_conn, rq->dest_conn,
(unsigned int) ntohl(rq->packet_sequence));
printf("Send Delay: %08X, Burst Seq: %04X, Ack Seq: %04X\n",
(unsigned int) ntohl(rq->send_delay), ntohs(rq->burst_sequence),
(unsigned int) ntohl(rq->send_delay), ntohs(rq->burst_sequence),
ntohs(rq->ack_sequence));
printf("Burst Length: %08X\n", (unsigned int) ntohl(rq->burst_length));
printf("Data Offset: %08X, Data Bytes: %04X, Missing Frags: %04X\n",
(unsigned int) ntohl(rq->data_offset), ntohs(rq->data_bytes),
(unsigned int) ntohl(rq->data_offset), ntohs(rq->data_bytes),
ntohs(rq->missing_frags));
if (ntohs(rq->data_bytes) == 24) {
struct ncp_burst_request {
if (ntohs(rq->data_bytes) == 24)
{
struct ncp_burst_request
{
struct ncp_burst_header h __attribute__((packed));
__u32 function __attribute__((packed));
__u32 file_handle __attribute__((packed));
__u8 reserved[8] __attribute__((packed));
__u32 file_offset __attribute__((packed));
__u32 number_of_bytes __attribute__((packed));
} *brq = (struct ncp_burst_request *) rq;
}
*brq = (struct ncp_burst_request *) rq;
printf("Assuming Burst Request:\n");
printf("%s: Handle %08X, Offset %08X, Bytes %08X\n",
@@ -307,9 +337,10 @@ int handle_burst(struct sockaddr_ipx *source,
return 1;
}
void handle_ncp(struct sockaddr_ipx *source,
struct sockaddr_ipx *target,
unsigned char *buf, int length, int no)
void
handle_ncp(struct sockaddr_ipx *source,
struct sockaddr_ipx *target,
unsigned char *buf, int length, int no)
{
struct ncp_request_header *rq = (struct ncp_request_header *) buf;
struct ncp_reply_header *rs = (struct ncp_reply_header *) buf;
@@ -321,7 +352,8 @@ void handle_ncp(struct sockaddr_ipx *source,
static struct ncp_request_header request_header;
static char request_data[5];
if (ntohs(rq->type) == NCP_REQUEST) {
if (ntohs(rq->type) == NCP_REQUEST)
{
/* Request */
printf("NCP request: conn: %-5d, seq: %-3d, task: %-3d, ",
rq->conn_low + 256 * rq->conn_high,
@@ -334,7 +366,8 @@ void handle_ncp(struct sockaddr_ipx *source,
data = buf + sizeof(struct ncp_request_header);
data_length = length - sizeof(struct ncp_request_header);
switch (rq->function) {
switch (rq->function)
{
case 18:
printf("fn: %-3d\n", rq->function);
printf("Get Volume Info with Number\n");
@@ -346,7 +379,8 @@ void handle_ncp(struct sockaddr_ipx *source,
case 21:
printf("fn: %-3d, subfn: %-3d\n",
rq->function, data[2]);
switch (data[2]) {
switch (data[2])
{
case 0:
printf("Send Broadcast Message\n");
break;
@@ -360,7 +394,8 @@ void handle_ncp(struct sockaddr_ipx *source,
case 22:
printf("fn: %-3d, subfn: %-3d\n",
rq->function, data[2]);
switch (data[2]) {
switch (data[2])
{
case 00:
printf("Set Directory Handle\n");
break;
@@ -404,7 +439,8 @@ void handle_ncp(struct sockaddr_ipx *source,
case 23:
printf("fn: %-3d, subfn: %-3d\n", rq->function,
data[2]);
switch (data[2]) {
switch (data[2])
{
case 17:
printf("Get Fileserver Information\n");
break;
@@ -527,7 +563,8 @@ void handle_ncp(struct sockaddr_ipx *source,
case 87:
printf("fn: %-3d, subfn: %-3d\n",
rq->function, data[0]);
switch (data[0]) {
switch (data[0])
{
case 1:
{
unsigned char *p = &(data[0]);
@@ -537,7 +574,7 @@ void handle_ncp(struct sockaddr_ipx *source,
printf("Search Attributes: %x\n",
*(__u16 *) & (p[3]));
printf("Return Information Mask: %x\n",
(unsigned int) (*(__u32 *) & (p[5])));
(unsigned int) (*(__u32 *) & (p[5])));
printf("Desired Access Rights: %x\n",
*(__u16 *) & (p[9]));
break;
@@ -564,10 +601,12 @@ void handle_ncp(struct sockaddr_ipx *source,
break;
case 97:
{
struct INPUT {
struct INPUT
{
__u16 proposed_max_size;
__u8 security_flag;
} *i = (struct INPUT *) data;
}
*i = (struct INPUT *) data;
printf("fn: %-3d\n", rq->function);
printf("Get Big Packet NCP Max Packet Size\n");
@@ -579,26 +618,28 @@ void handle_ncp(struct sockaddr_ipx *source,
}
case 101:
{
struct INPUT {
struct INPUT
{
__u32 local_conn_id;
__u32 local_max_packet_size;
__u16 local_target_socket;
__u32 local_max_send_size;
__u32 local_max_recv_size;
} *i = (struct INPUT *) data;
}
*i = (struct INPUT *) data;
printf("fn: %-3d\n", rq->function);
printf("Packet Burst Connection Request\n");
printf("local_conn_id: %lx\n",
ntohl(i->local_conn_id));
printf("local_max_packet_size: %lx\n",
ntohl(i->local_max_packet_size));
printf("local_target_socket: %lx\n",
ntohl(i->local_target_socket));
printf("local_max_send_size: %lx\n",
ntohl(i->local_max_send_size));
printf("local_max_recv_size: %lx\n",
ntohl(i->local_max_recv_size));
printf("local_conn_id: %x\n",
(u_int32_t)ntohl(i->local_conn_id));
printf("local_max_packet_size: %x\n",
(u_int32_t)ntohl(i->local_max_packet_size));
printf("local_target_socket: %x\n",
(u_int32_t)ntohl(i->local_target_socket));
printf("local_max_send_size: %x\n",
(u_int32_t)ntohl(i->local_max_send_size));
printf("local_max_recv_size: %x\n",
(u_int32_t)ntohl(i->local_max_recv_size));
}
break;
case 104:
@@ -617,20 +658,23 @@ void handle_ncp(struct sockaddr_ipx *source,
workstation, and tell me whether anything
of this makes sense at all. */
switch (data[0]) {
switch (data[0])
{
case 1:
printf("Ping for NDS\n");
break;
case 2:
{
struct INPUT {
struct INPUT
{
__u8 subfunction_code;
__u32 fragger_handle;
__u32 max_fragment_size;
__u32 message_size;
__u32 fragment_flag;
__u32 verb;
} *i = (struct INPUT *) data;
}
*i = (struct INPUT *) data;
printf("Send NDS Fragment Request/Reply\n");
printf("fragger_handle: %lx\n",
(unsigned long) i->fragger_handle);
@@ -642,7 +686,8 @@ void handle_ncp(struct sockaddr_ipx *source,
(unsigned long) i->fragment_flag);
printf("verb: %d\n", i->verb);
switch (i->verb) {
switch (i->verb)
{
case 1:
printf("Resolve Name\n");
break;
@@ -899,7 +944,8 @@ void handle_ncp(struct sockaddr_ipx *source,
printf("fn: %-3d\n", rq->function);
}
}
if (ntohs(rs->type) == NCP_REPLY) {
if (ntohs(rs->type) == NCP_REPLY)
{
printf("NCP respons: conn: %-5d, seq: %-3d, task: %-3d, ",
rs->conn_low + 256 * rs->conn_high,
rs->sequence, rs->task);
@@ -911,20 +957,25 @@ void handle_ncp(struct sockaddr_ipx *source,
if ((memcmp(&request_source, target,
sizeof(request_source)) == 0)
&& (request_header.sequence == rs->sequence)) {
switch (request_header.function) {
&& (request_header.sequence == rs->sequence))
{
switch (request_header.function)
{
case 22:
switch (request_data[2]) {
switch (request_data[2])
{
case 18:
{
struct XDATA {
struct XDATA
{
__u8 new_directory_handle;
__u8 access_rights_mask;
} *x = (struct XDATA *) data;
}
*x = (struct XDATA *) data;
printf("new_directory_handle: %x\n",
x->new_directory_handle);
x->new_directory_handle);
printf("access_rights_mask: %x\n",
x->access_rights_mask);
x->access_rights_mask);
}
break;
}
@@ -935,13 +986,15 @@ void handle_ncp(struct sockaddr_ipx *source,
break;
case 97:
{
struct XDATA {
struct XDATA
{
__u16 accepted_max_size;
__u16 echo_socket;
__u8 security_flag;
} *x = (struct XDATA *) data;
}
*x = (struct XDATA *) data;
printf("accepted_max_size: %x\n",
ntohs(x->accepted_max_size));
ntohs(x->accepted_max_size));
printf("echo_socket: %x\n",
ntohs(x->echo_socket));
printf("security_flag: %x\n",
@@ -950,44 +1003,55 @@ void handle_ncp(struct sockaddr_ipx *source,
break;
case 101:
{
struct XDATA {
struct XDATA
{
__u8 completion_code;
__u32 remote_target_id;
__u32 remote_max_packet_size;
} *x = (struct XDATA *) data;
}
*x = (struct XDATA *) data;
printf("completion_code: %x\n",
x->completion_code);
printf("remote_target_id: %lx\n",
ntohl(x->remote_target_id));
printf("remote_max_packet_size: %lx\n",
ntohl(x->remote_max_packet_size));
printf("remote_target_id: %x\n",
(u_int32_t)ntohl(x->remote_target_id));
printf("remote_max_packet_size: %x\n",
(u_int32_t)ntohl(x->remote_max_packet_size));
}
break;
}
}
}
if (data == NULL) {
if (data == NULL)
{
data = buf;
data_length = length;
}
i = 0;
while (i < data_length) {
while (i < data_length)
{
int j;
for (j = i; j < i + 16; j++) {
if (j >= data_length) {
for (j = i; j < i + 16; j++)
{
if (j >= data_length)
{
printf(" ");
} else {
} else
{
printf("%-2.2X", data[j]);
}
}
printf(" ");
for (j = i; j < i + 16; j++) {
if (j >= data_length) {
for (j = i; j < i + 16; j++)
{
if (j >= data_length)
{
break;
}
if (isprint(data[j])) {
if (isprint(data[j]))
{
printf("%c", data[j]);
} else {
} else
{
printf(".");
}
}
@@ -998,7 +1062,8 @@ void handle_ncp(struct sockaddr_ipx *source,
}
void main(int argc, char *argv[])
void
main(int argc, char *argv[])
{
unsigned char buf[16384];
unsigned char packet[8192];
@@ -1006,13 +1071,16 @@ void main(int argc, char *argv[])
int len;
int i = 1;
while (fgets(buf, sizeof(buf), stdin) != NULL) {
if (strlen(buf) == sizeof(buf) - 1) {
while (fgets(buf, sizeof(buf), stdin) != NULL)
{
if (strlen(buf) == sizeof(buf) - 1)
{
fprintf(stderr, "line too long\n");
exit(1);
}
b = strchr(buf, ' ');
if (b == NULL) {
if (b == NULL)
{
fprintf(stderr, "illegal line format\n");
exit(1);
}
@@ -1020,9 +1088,11 @@ void main(int argc, char *argv[])
b += 1;
len = 0;
while ((b[0] != '\0') && (b[1] != '\0')) {
while ((b[0] != '\0') && (b[1] != '\0'))
{
unsigned int value;
if (sscanf(b, "%2x", &value) != 1) {
if (sscanf(b, "%2x", &value) != 1)
{
fprintf(stderr, "illegal packet\n");
exit(1);
}

View File

@@ -27,7 +27,8 @@
#include <netinet/in.h>
#include "ipxutil.h"
void ipx_fprint_node(FILE * file, IPXNode node)
void
ipx_fprint_node(FILE * file, IPXNode node)
{
fprintf(file, "%02X%02X%02X%02X%02X%02X",
(unsigned char) node[0],
@@ -39,17 +40,20 @@ void ipx_fprint_node(FILE * file, IPXNode node)
);
}
void ipx_fprint_network(FILE * file, IPXNet net)
void
ipx_fprint_network(FILE * file, IPXNet net)
{
fprintf(file, "%08lX", net);
}
void ipx_fprint_port(FILE * file, IPXPort port)
void
ipx_fprint_port(FILE * file, IPXPort port)
{
fprintf(file, "%04X", port);
}
void ipx_fprint_saddr(FILE * file, struct sockaddr_ipx *sipx)
void
ipx_fprint_saddr(FILE * file, struct sockaddr_ipx *sipx)
{
ipx_fprint_network(file, ntohl(sipx->sipx_network));
fprintf(file, ":");
@@ -58,55 +62,66 @@ void ipx_fprint_saddr(FILE * file, struct sockaddr_ipx *sipx)
ipx_fprint_port(file, ntohs(sipx->sipx_port));
}
void ipx_print_node(IPXNode node)
void
ipx_print_node(IPXNode node)
{
ipx_fprint_node(stdout, node);
}
void ipx_print_network(IPXNet net)
void
ipx_print_network(IPXNet net)
{
ipx_fprint_network(stdout, net);
}
void ipx_print_port(IPXPort port)
void
ipx_print_port(IPXPort port)
{
ipx_fprint_port(stdout, port);
}
void ipx_print_saddr(struct sockaddr_ipx *sipx)
void
ipx_print_saddr(struct sockaddr_ipx *sipx)
{
ipx_fprint_saddr(stdout, sipx);
}
void ipx_assign_node(IPXNode dest, IPXNode src)
void
ipx_assign_node(IPXNode dest, IPXNode src)
{
memcpy(dest, src, sizeof(IPXNode));
}
int ipx_node_equal(IPXNode n1, IPXNode n2)
int
ipx_node_equal(IPXNode n1, IPXNode n2)
{
return memcmp(n1, n2, sizeof(IPXNode)) == 0;
}
int ipx_sscanf_node(char *buf, IPXNode node)
int
ipx_sscanf_node(char *buf, IPXNode node)
{
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) {
&(n[3]), &(n[4]), &(n[5]))) != 6)
{
return -1;
}
for (i = 0; i < 6; i++) {
for (i = 0; i < 6; i++)
{
node[i] = n[i];
}
return 0;
}
int ipx_sscanf_net(char *buf, IPXNet * target)
int
ipx_sscanf_net(char *buf, IPXNet * target)
{
if (sscanf(buf, "%8lX", target) == 1) {
if (sscanf(buf, "%8lX", target) == 1)
{
return 0;
}
return -1;

View File

@@ -25,7 +25,7 @@
#define __IPXUTIL_H__
#include <stdio.h>
#include <linux/ipx.h>
#include "kernel/ipx.h"
#define IPX_MAX_ERROR (255)
#define IPX_THIS_NET (0)

28
lib-shared/Makefile Normal file
View File

@@ -0,0 +1,28 @@
include ../Makeinit
NCPLIB = libncp.so
NCPLIB_BIN = $(NCPLIB).1.0
NCPLIB_SONAME = $(NCPLIB).1
CCFLAGS += -I../include -I.
PIC_FLAG = -fPIC
export PIC_FLAG
CCFLAGS += $(PIC_FLAG)
vpath %.c ../lib
vpath %.et ../lib
include ../lib/Makelib
install: all
rm -f $(LIBSODIR)/$(NCPLIB)
install $(NCPLIB_BIN) $(LIBSODIR)
ldconfig
ln -sf $(NCPLIB_SONAME) $(LIBSODIR)/$(NCPLIB)
$(NCPLIB): $(NCPLIB_BIN)
rm -f $@
ln -sf $< $@
$(NCPLIB_BIN): $(O_OBJ) $(O_LIB)
$(CC) -shared -o $@ -Wl,-soname=$(NCPLIB_SONAME) $(O_OBJ) -lc

17
lib-static-su/Makefile Normal file
View File

@@ -0,0 +1,17 @@
include ../Makeinit
NCPLIB = libncp.a
NCPLIB_BIN := $(NCPLIB)
CCFLAGS += -I../include -I.
CCFLAGS += -D__MAKE_SULIB__
vpath %.c ../lib
vpath %.et ../lib
include ../lib/Makelib
install:
$(NCPLIB_BIN): $(O_OBJ)
ar r $@ $(O_OBJ)

17
lib-static/Makefile Normal file
View File

@@ -0,0 +1,17 @@
include ../Makeinit
NCPLIB = libncp.a
NCPLIB_BIN = $(NCPLIB)
CCFLAGS += -I../include -I.
vpath %.c ../lib
vpath %.et ../lib
include ../lib/Makelib
install: all
install $(NCPLIB_BIN) $(LIBADIR)
$(NCPLIB_BIN): $(O_OBJ)
ar r $@ $(O_OBJ)

View File

@@ -2,70 +2,19 @@
# Makefile for the linux ncp-filesystem routines.
#
CC = gcc
ifeq ($(HAVE_ELF),yes)
PIC_FLAG = -fPIC
NCP_LIB = libncp.so.1.0
LIB_LINK_COMMAND = gcc -shared -Wl,-soname,libncp.so.1 -o $(NCP_LIB)
INSTALL_LIB = install $(NCP_LIB) -m 755 /lib; \
ln -sf $(NCP_LIB) /lib/libncp.so.1; \
ldconfig
export PIC_FLAG
else
NCP_LIB = libncp.a
LIB_LINK_COMMAND = ar r libncp.a
endif
CFLAGS += $(PIC_FLAG)
default:
make -C ..
all: libcom_err.a ncplib_err.o $(NCP_LIB)
all:
install:
$(INSTALL_LIB)
ncplib.o: ncplib.c ncplib_err.h
$(CC) $(CFLAGS) -c ncplib.c
COM_ERR_CFILES = com_err/com_err.c com_err/error_message.c com_err/et_name.c \
com_err/init_et.c
COM_ERR_OFILES = com_err/com_err.o com_err/error_message.o com_err/et_name.o \
com_err/init_et.o
libcom_err.a: $(COM_ERR_CFILES)
make -C com_err
$(NCP_LIB): ncplib.o ncplib_err.o libcom_err.a
$(LIB_LINK_COMMAND) ncplib.o ncplib_err.o $(COM_ERR_OFILES)
ln -sf libncp.so.1.0 libncp.so.1
ln -sf libncp.so.1 libncp.so
export LD_LIBRARY_PATH=`pwd`:LD_LIBRARY_PATH
ncplib_err.o: ncplib_err.h ncplib_err.c
$(CC) $(CFLAGS) -c ncplib_err.c
ncplib_err.h: ncplib_err.et
com_err/compile_et ncplib_err
ln -sf ../lib/ncplib_err.h ../include/ncplib_err.h
ncplib_err.c: ncplib_err.et
com_err/compile_et ncplib_err
dep: ncplib_err.h
make -C com_err dep
$(CPP) -M $(INCLUDES) *.c > .depend
make -C com_err install
clean:
make -C com_err clean
rm -f *.o *~ ncplib_err.[ch] ../include/ncplib_err.h
rm -f libncp.*
mrproper: clean
mrproper:
make -C com_err mrproper
rm -f $(UTILS) .depend $(DISTFILE)
#
# include a dependency file if one exists

61
lib/Makelib Normal file
View File

@@ -0,0 +1,61 @@
#
# Makefile for the linux ncp-filesystem routines.
#
BASE_OBJ = ncplib.o
ifdef NDS_SUPPORT
NDS_OBJ = ndslib.o mpilib.o
BASE_OBJ += ndscrypt.o
endif
ifdef SIGNATURES
BASE_OBJ += ncpsign.o
endif
O_OBJ := $(BASE_OBJ) $(NDS_OBJ) ncplib_err.o
all: $(NCPLIB)
$(NDS_OBJ): %.o: %.c ncplib_err.h
$(CC) $(CFLAGS) $(CCFLAGS) -DPORTABLE -DSMITH -DUNIT32 -DMUNIT16 -o $@ -c $<
$(BASE_OBJ): %.o: %.c ncplib_err.h
$(CC) $(CFLAGS) $(CCFLAGS) -o $@ -c $<
COM_ERR = ../lib/com_err
COM_ERR_CFILES = $(COM_ERR)/com_err.c $(COM_ERR)/error_message.c \
$(COM_ERR)/et_name.c $(COM_ERR)/init_et.c
COM_ERR_OFILES = $(COM_ERR)/com_err.o $(COM_ERR)/error_message.o \
$(COM_ERR)/et_name.o $(COM_ERR)/init_et.o
O_OBJ += $(COM_ERR_OFILES)
$(COM_ERR_OFILES): %.o: %.c
make -C $(COM_ERR)
ncplib_err.o: ncplib_err.h ncplib_err.c
$(CC) $(CFLAGS) $(CCFLAGS) -c ncplib_err.c
ncplib_err.h ncplib_err.c: ncplib_err.et
$(COM_ERR)/compile_et ../lib/ncplib_err
dep: ncplib_err.h
make -C $(COM_ERR) dep
$(CPP) -M $(INCLUDES) *.c > .depend
clean:
make -C $(COM_ERR) clean
rm -f *.o *~ ncplib_err.[ch] ../include/ncplib_err.h
rm -f libncp.* libcom_err.a
mrproper: clean
make -C $(COM_ERR) mrproper
rm -f $(UTILS) .depend $(DISTFILE)
#
# include a dependency file if one exists
#
ifeq (.depend,$(wildcard .depend))
include .depend
endif

View File

@@ -5,14 +5,13 @@
OBJECTS = com_err.o error_message.o et_name.o init_et.o
CFLAGS = -Wall -O2 $(PIC_FLAG)
all: ../libcom_err.a
../libcom_err.a: $(OBJECTS)
ar r ../libcom_err.a $(OBJECTS)
all: $(OBJECTS)
dep:
$(CPP) -M $(INCLUDES) *.c > .depend
install:
clean:
rm -f *.o ../libcom_err.a

View File

@@ -17,25 +17,28 @@
static void
#ifdef __STDC__
default_com_err_proc(const char *whoami, errcode_t code, const
char *fmt, va_list args)
default_com_err_proc(const char *whoami, errcode_t code, const
char *fmt, va_list args)
#else
default_com_err_proc(whoami, code, fmt, args)
default_com_err_proc(whoami, code, fmt, args)
const char *whoami;
errcode_t code;
const char *fmt;
va_list args;
#endif
{
if (whoami) {
if (whoami)
{
fputs(whoami, stderr);
fputs(": ", stderr);
}
if (code) {
if (code)
{
fputs(error_message(code), stderr);
fputs(" ", stderr);
}
if (fmt) {
if (fmt)
{
vfprintf(stderr, fmt, args);
}
/* should do this only on a tty in raw mode */
@@ -53,10 +56,12 @@ typedef void (*errf) ();
errf com_err_hook = default_com_err_proc;
#ifdef __STDC__
void com_err_va(const char *whoami, errcode_t code, const char *fmt,
va_list args)
void
com_err_va(const char *whoami, errcode_t code, const char *fmt,
va_list args)
#else
void com_err_va(whoami, code, fmt, args)
void
com_err_va(whoami, code, fmt, args)
const char *whoami;
errcode_t code;
const char *fmt;
@@ -67,12 +72,14 @@ va_list args;
}
#ifndef VARARGS
void com_err(const char *whoami,
errcode_t code,
const char *fmt,...)
void
com_err(const char *whoami,
errcode_t code,
const char *fmt,...)
{
#else
void com_err(va_alist)
void
com_err(va_alist)
va_dcl
{
const char *whoami, *fmt;

View File

@@ -2,7 +2,7 @@
#
#
AWK=/usr/bin/awk
DIR=com_err/
DIR=../lib/com_err
ROOT=`echo $1 | sed -e s/.et$//`
BASE=`basename $ROOT`

View File

@@ -24,10 +24,10 @@ struct et_list *_et_list = (struct et_list *) NULL;
#ifdef __STDC__
const char *
error_message(errcode_t code)
error_message(errcode_t code)
#else
const char *
error_message(code)
error_message(code)
errcode_t code;
#endif
{
@@ -39,7 +39,8 @@ errcode_t code;
offset = code & ((1 << ERRCODE_RANGE) - 1);
table_num = code - offset;
if (!table_num) {
if (!table_num)
{
#ifdef HAS_SYS_ERRLIST
if (offset < sys_nerr)
return (sys_errlist[offset]);
@@ -53,8 +54,10 @@ errcode_t code;
goto oops;
#endif
}
for (et = _et_list; et; et = et->next) {
if (et->table->base == table_num) {
for (et = _et_list; et; et = et->next)
{
if (et->table->base == table_num)
{
/* This is the right table */
if (et->table->n_msgs <= offset)
goto oops;
@@ -63,17 +66,21 @@ errcode_t code;
}
oops:
strcpy(buffer, "Unknown code ");
if (table_num) {
if (table_num)
{
strcat(buffer, error_table_name(table_num));
strcat(buffer, " ");
}
for (cp = buffer; *cp; cp++);
if (offset >= 100) {
for (cp = buffer; *cp; cp++)
;
if (offset >= 100)
{
*cp++ = '0' + offset / 100;
offset %= 100;
started++;
}
if (started || offset >= 10) {
if (started || offset >= 10)
{
*cp++ = '0' + offset / 10;
offset %= 10;
}

View File

@@ -11,12 +11,14 @@
#define const
#endif
struct error_table {
struct error_table
{
char const *const *msgs;
long base;
int n_msgs;
};
struct et_list {
struct et_list
{
struct et_list *next;
const struct error_table *table;
};

View File

@@ -14,7 +14,7 @@ static const char char_set[] =
static char buf[6];
const char *
error_table_name(num)
error_table_name(num)
int num;
{
int ch;
@@ -27,7 +27,8 @@ int num;
/* num = ?? ??? ??? aaa aaa bbb bbb ccc ccc ddd ddd */
num &= 077777777;
/* num = 00 000 000 aaa aaa bbb bbb ccc ccc ddd ddd */
for (i = 4; i >= 0; i--) {
for (i = 4; i >= 0; i--)
{
ch = (num >> BITS_PER_CHAR * i) & ((1 << BITS_PER_CHAR) - 1);
if (ch != 0)
*p++ = char_set[ch - 1];

View File

@@ -23,7 +23,8 @@
#define const
#endif
struct foobar {
struct foobar
{
struct et_list etl;
struct error_table et;
};
@@ -31,9 +32,11 @@ struct foobar {
extern struct et_list *_et_list;
#ifdef __STDC__
int init_error_table(const char *const *msgs, int base, int count)
int
init_error_table(const char *const *msgs, int base, int count)
#else
int init_error_table(msgs, base, count)
int
init_error_table(msgs, base, count)
const char *const *msgs;
int base;
int count;

1881
lib/mpilib.c Normal file

File diff suppressed because it is too large Load Diff

468
lib/mpilib.h Normal file
View File

@@ -0,0 +1,468 @@
/* C include file for MPI multiprecision integer math routines.
Boulder Software Engineering
3021 Eleventh Street
Boulder, CO 80304
(303) 541-0140
(c) Copyright 1986-92 by Philip Zimmermann. All rights reserved.
The author assumes no liability for damages resulting from the use
of this software, even if the damage results from defects in this
software. No warranty is expressed or implied.
These routines implement all of the multiprecision arithmetic necessary
for Rivest-Shamir-Adleman (RSA) public key cryptography, as well as
other number-theoretic algorithms such as ElGamal, Diffie-Hellman,
or Rabin.
Although originally developed in Microsoft C for the IBM PC, this code
contains few machine dependencies. It assumes 2's complement
arithmetic. It can be adapted to 8-bit, 16-bit, or 32-bit machines,
lowbyte-highbyte order or highbyte-lowbyte order. This version
has been converted to ANSI C.
Modified 8 Apr 92 - HAJK - Implement new VAX/VMS primitive support.
Modified 29 Nov 92 - Thad Smith
*/
#include <string.h>
#include "usuals.h" /* typedefs for byte, word16, boolean, etc. */
#include "platform.h" /* customization for different environments */
/* Platform customization:
* A version which runs on almost any computer can be implemented by
* defining PORTABLE and MPORTABLE, preferably as a command line
* parameter. Faster versions can be generated by specifying specific
* parameters, such as size of unit and MULTUNIT, and by supplying some
* of the critical in assembly. See the file platform.h for more
* details on customization.
*
* The symbol HIGHFIRST, designating that integers and longs are stored
* with the most significant bit in the lowest address, should be defined
* on the command line for compiling all files, since it is used by files
* other than the mpilib routines.
*/
#ifndef ALIGN
#define ALIGN
#endif
#ifndef PEASANT /* if not Russian peasant modulo multiply algorithm */
#ifndef MERRITT /* if not Merritt's modmult */
#ifndef UPTON /* if not Upton's modmult */
#ifndef SMITH
#define SMITH /* default: use Smith's modmult algorithm */
#endif
#endif
#endif
#endif
#ifdef SMITH
#define UPTON_OR_SMITH /* enable common code */
#endif
#ifdef UPTON
#define UPTON_OR_SMITH /* enable common code */
#endif
#ifndef UNIT32
#ifndef UNIT8
#define UNIT16 /* default--use 16-bit units */
#endif
#endif
/*** CAUTION: If your machine has an unusual word size that is not a
power of 2 (8, 16, 32, or 64) bits wide, then the macros here that
use the symbol "LOG_UNITSIZE" must be changed.
***/
#ifdef UNIT8
typedef unsigned char unit;
typedef signed char signedunit;
#define UNITSIZE 8 /* number of bits in a unit */
#define LOG_UNITSIZE 3
#define uppermostbit ((unit) 0x80)
#define BYTES_PER_UNIT 1 /* number of bytes in a unit */
#define units2bits(n) ((n) << 3) /* fast multiply by UNITSIZE */
#define units2bytes(n) (n)
#define bits2units(n) (((n)+7) >> 3)
#define bytes2units(n) (n)
#endif
#ifdef UNIT16
typedef word16 unit;
typedef short signedunit;
#define UNITSIZE 16 /* number of bits in a unit */
#define LOG_UNITSIZE 4
#define uppermostbit ((unit) 0x8000)
#define BYTES_PER_UNIT 2 /* number of bytes in a unit */
#define units2bits(n) ((n) << 4) /* fast multiply by UNITSIZE */
#define units2bytes(n) ((n) << 1)
#define bits2units(n) (((n)+15) >> 4)
#define bytes2units(n) (((n)+1) >> 1)
#endif
#ifdef UNIT32
typedef word32 unit;
typedef long signedunit;
#define UNITSIZE 32 /* number of bits in a unit */
#define LOG_UNITSIZE 5
#define uppermostbit ((unit) 0x80000000L)
#define BYTES_PER_UNIT 4 /* number of bytes in a unit */
#define units2bits(n) ((n) << 5) /* fast multiply by UNITSIZE */
#define units2bytes(n) ((n) << 2)
#define bits2units(n) (((n)+31) >> 5)
#define bytes2units(n) (((n)+3) >> 2)
#endif
#define power_of_2(b) ((unit) 1 << (b)) /* computes power-of-2 bit masks */
#define bits2bytes(n) (((n)+7) >> 3)
/* Some C compilers (like the ADSP2101) will not always collapse constant
expressions at compile time if the expressions contain shift operators. */
/* #define uppermostbit power_of_2(UNITSIZE-1) */
/* #define UNITSIZE units2bits(1) */ /* number of bits in a unit */
/* #define bytes2units(n) bits2units((n)<<3) */
/* #define BYTES_PER_UNIT (UNITSIZE >> 3) */
/* LOG_UNITSIZE is the log base 2 of UNITSIZE, ie: 4 for 16-bit units */
/* #define units2bits(n) ((n) << LOG_UNITSIZE) */ /* fast multiply by UNITSIZE */
/* #define units2bytes(n) ((n) << (LOG_UNITSIZE-3)) */
/* #define bits2units(n) (((n)+(UNITSIZE-1)) >> LOG_UNITSIZE) */
/* #define bytes2units(n) (((n)+(BYTES_PER_UNIT-1)) >> (LOG_UNITSIZE-3)) */
typedef unit *unitptr;
/*--------------------- Byte ordering stuff -------------------*/
#ifdef HIGHFIRST
/* these definitions assume MSB comes first */
#define tohigher(n) (-(n)) /* offset towards higher unit */
#define pre_higherunit(r) (--(r))
#define pre_lowerunit(r) (++(r))
#define post_higherunit(r) ((r)--)
#define post_lowerunit(r) ((r)++)
#define bit_index(n) (global_precision-bits2units((n)+1))
#define lsbptr(r,prec) ((r)+(prec)-1)
#define make_lsbptr(r,prec) (r) = lsbptr(r,prec)
#define unmake_lsbptr(r,prec) (r) = ((r)-(prec)+1)
#define msbptr(r,prec) (r)
#define make_msbptr(r,prec) /* (r) = msbptr(r,prec) */
/* The macro rescale(r,current_precision,new_precision) rescales
a multiprecision integer by adjusting r and its precision to new values.
It can be used to reverse the effects of the normalize
routine given above. See the comments in normalize concerning
Intel vs. Motorola LSB/MSB conventions.
WARNING: You can only safely call rescale on registers that
you have previously normalized with the above normalize routine,
or are known to be big enough for the new precision. You may
specify a new precision that is smaller than the current precision.
You must be careful not to specify a new_precision value that is
too big, or which adjusts the r pointer out of range.
*/
#define rescale(r,currentp,newp) r -= ((newp) - (currentp))
/* The macro normalize(r,precision) "normalizes" a multiprecision integer
by adjusting r and precision to new values. For Motorola-style processors
(MSB-first), r is a pointer to the MSB of the register, and must
be adjusted to point to the first nonzero unit. For Intel/VAX-style
(LSB-first) processors, r is a pointer to the LSB of the register,
and must be left unchanged. The precision counter is always adjusted,
regardless of processor type. In the case of precision = 0,
r becomes undefined.
*/
#define normalize(r,prec) \
{ prec = significance(r); r += (global_precision-(prec)); }
#else /* LOWFIRST byte order */
/* these definitions assume LSB comes first */
#define tohigher(n) (n) /* offset towards higher unit */
#define pre_higherunit(r) (++(r))
#define pre_lowerunit(r) (--(r))
#define post_higherunit(r) ((r)++)
#define post_lowerunit(r) ((r)--)
#define bit_index(n) (bits2units((n)+1)-1)
#define lsbptr(r,prec) (r)
#define make_lsbptr(r,prec) /* (r) = lsbptr(r,prec) */
#define unmake_lsbptr(r,prec) /* (r) = (r) */
#define msbptr(r,prec) ((r)+(prec)-1)
#define make_msbptr(r,prec) (r) = msbptr(r,prec)
#define rescale(r,currentp,newp) /* nil statement */
#define normalize(r,prec) prec = significance(r)
#endif /* LOWFIRST byte order */
/*------------------ End byte ordering stuff -------------------*/
/* Note that the address calculations require that lsbptr, msbptr,
make_lsbptr, make_msbptr, mp_tstbit, mp_setbit, mp_clrbit,
and bitptr all have unitptr arguments, not byte pointer arguments. */
#define bitptr(r,n) &((r)[bit_index(n)])
#define bitmsk(n) power_of_2((n) & (UNITSIZE-1))
/* bitmsk() assumes UNITSIZE is a power of 2 */
#define mp_tstbit(r,n) (*bitptr(r,n) & bitmsk(n))
#define mp_setbit(r,n) (*bitptr(r,n) |= bitmsk(n))
#define mp_clrbit(r,n) (*bitptr(r,n) &= ~bitmsk(n))
#define msunit(r) (*msbptr(r,global_precision))
#define lsunit(r) (*lsbptr(r,global_precision))
/* #define mp_tstminus(r) ((msunit(r) & uppermostbit)!=0) */
#define mp_tstminus(r) ((signedunit) msunit(r) < 0)
/* set working precision to specified number of bits. */
#ifdef mp_setp
void mp_setp(short nbits);
#define set_precision(prec) mp_setp(units2bits(global_precision=(prec)))
#else
#define set_precision(prec) (global_precision = (prec))
#endif
#ifdef PEASANT
/* Define C names for Russian peasant modmult primitives. */
#define stage_modulus stage_peasant_modulus
#define mp_modmult peasant_modmult
#define modmult_burn peasant_burn
#define SLOP_BITS PEASANT_SLOP_BITS
#else /* not PEASANT */
#ifdef MERRITT
/* Define C names for Merritt's modmult primitives. */
#define stage_modulus stage_merritt_modulus
#define mp_modmult merritt_modmult
#define modmult_burn merritt_burn
#define SLOP_BITS MERRITT_SLOP_BITS
#else /* not PEASANT, MERRITT */
#ifdef UPTON
/* Define C names for Upton's modmult primitives. */
#define stage_modulus stage_upton_modulus
#define mp_modmult upton_modmult
#define modmult_burn upton_burn
#define SLOP_BITS UPTON_SLOP_BITS
#else /* not PEASANT, MERRITT, UPTON */
#ifdef SMITH
/* Define C names for Smith's modmult primitives. */
#define stage_modulus stage_smith_modulus
#define mp_modmult smith_modmult
#define modmult_burn smith_burn
#define SLOP_BITS SMITH_SLOP_BITS
#endif /* SMITH */
#endif /* UPTON */
#endif /* MERRITT */
#endif /* PEASANT */
#define mp_shift_left(r1) mp_rotate_left(r1,(boolean)0)
/* multiprecision shift left 1 bit */
#define mp_add(r1,r2) mp_addc(r1,r2,(boolean)0)
/* multiprecision add with no carry */
#define mp_sub(r1,r2) mp_subb(r1,r2,(boolean)0)
/* multiprecision subtract with no borrow */
#define mp_abs(r) (mp_tstminus(r) ? (mp_neg(r),TRUE) : FALSE)
#define msub(r,m) if (mp_compare(r,m) >= 0) mp_sub(r,m)
/* Prevents r from getting bigger than modulus m */
#define testeq(r,i) \
( (lsunit(r)==(i)) && (significance(r)<=1) )
#define testne(r,i) \
( (lsunit(r)!=(i)) || (significance(r)>1) )
#define testge(r,i) \
( (lsunit(r)>=(i)) || (significance(r)>1) )
#define testle(r,i) \
( (lsunit(r)<=(i)) && (significance(r)<=1) )
#define mp_square(r1,r2) mp_mult(r1,r2,r2)
/* Square r2, returning product in r1 */
#define mp_modsquare(r1,r2) mp_modmult(r1,r2,r2)
/* Square r2, returning modulo'ed product in r1 */
#define countbytes(r) ((countbits(r)+7)>>3)
/* SLOP_BITS is how many "carry bits" to allow for intermediate
calculation results to exceed the size of the modulus.
It is used by modexp to give some overflow elbow room for
modmult to use to perform modulo operations with the modulus.
The number of slop bits required is determined by the modmult
algorithm. The Russian peasant modmult algorithm only requires
1 slop bit, for example. Note that if we use an external assembly
modmult routine, SLOP_BITS may be meaningless or may be defined in a
non-constant manner.
*/
#define PEASANT_SLOP_BITS 1
#define MERRITT_SLOP_BITS UNITSIZE
#define UPTON_SLOP_BITS (UNITSIZE/2)
#ifdef mp_smul /* old version requires MS word = 0 */
#define SMITH_SLOP_BITS UNITSIZE
#else /* mp_smula or C version of mp_smul */
#define SMITH_SLOP_BITS 0
#endif /* mp_smul */
/* MAX_BIT_PRECISION is upper limit that assembly primitives can handle.
It must be less than 32704 bits, or 4088 bytes. It should be an
integer multiple of UNITSIZE*2.
*/
#if (SLOP_BITS > 0)
#define MAX_BIT_PRECISION (1280+(2*UNITSIZE))
#else
#define MAX_BIT_PRECISION 1280
#endif
#define MAX_BYTE_PRECISION (MAX_BIT_PRECISION/8)
#define MAX_UNIT_PRECISION (MAX_BIT_PRECISION/UNITSIZE)
/* global_precision is the unit precision last set by set_precision */
extern short global_precision;
/* The "bit sniffer" macros all begin sniffing at the MSB.
They are used internally by all the various multiply, divide,
modulo, exponentiation, and square root functions.
*/
#define sniff_bit(bptr,bitmask) (*(bptr) & bitmask)
#define init_bitsniffer(bptr,bitmask,prec,bits) \
{ normalize(bptr,prec); \
if (!prec) \
return(0); \
bits = units2bits(prec); \
make_msbptr(bptr,prec); bitmask = uppermostbit; \
while (!sniff_bit(bptr,bitmask)) \
{ bitmask >>= 1; bits--; \
} \
}
#define bump_bitsniffer(bptr,bitmask) \
{ if (!(bitmask >>= 1)) \
{ bitmask = uppermostbit; \
post_lowerunit(bptr); \
} \
}
/* bump_2bitsniffers is used internally by mp_udiv. */
#define bump_2bitsniffers(bptr,bptr2,bitmask) \
{ if (!(bitmask >>= 1)) \
{ bitmask = uppermostbit; \
post_lowerunit(bptr); \
post_lowerunit(bptr2); \
} \
}
/* stuff_bit is used internally by mp_udiv and mp_sqrt. */
#define stuff_bit(bptr,bitmask) *(bptr) |= bitmask
boolean mp_addc
(register unitptr r1,register unitptr r2,register boolean carry);
/* multiprecision add with carry r2 to r1, result in r1 */
boolean mp_subb
(register unitptr r1,register unitptr r2,register boolean borrow);
/* multiprecision subtract with borrow, r2 from r1, result in r1 */
boolean mp_rotate_left(register unitptr r1,register boolean carry);
/* multiprecision rotate left 1 bit with carry, result in r1. */
void mp_shift_right_bits(register unitptr r1,register short bits);
/* multiprecision shift right bits, result in r1. */
short mp_compare(register unitptr r1,register unitptr r2);
/* Compares registers *r1, *r2, and returns -1, 0, or 1 */
boolean mp_inc(register unitptr r);
/* Increment multiprecision integer r. */
boolean mp_dec(register unitptr r);
/* Decrement multiprecision integer r. */
void mp_neg(register unitptr r);
/* Compute 2's complement, the arithmetic negative, of r */
#ifndef mp_move
#define mp_move(d,s) memcpy((void*)(d), (void*)(s), \
units2bytes(global_precision))
#endif
#ifndef unitfill0
#define unitfill0(r,ct) memset((void*)(r), 0, units2bytes(ct))
#endif
#ifndef mp_burn
#define mp_burn(r) mp_init(r,0) /* for burning the evidence */
#define mp_init0(r) mp_init(r,0)
#endif
#define empty_array(r) unitfill0(r, sizeof(r)/sizeof(r[0])/sizeof(unit))
void mp_init(register unitptr r, word16 value);
/* Init multiprecision register r with short value. */
short significance(register unitptr r);
/* Returns number of significant units in r */
int mp_udiv(register unitptr remainder,register unitptr quotient,
register unitptr dividend,register unitptr divisor);
/* Unsigned divide, treats both operands as positive. */
int mp_recip(register unitptr quotient,register unitptr divisor);
/* Compute reciprocal as 1/divisor. Used by faster modmult. */
int mp_div(register unitptr remainder,register unitptr quotient,
register unitptr dividend,register unitptr divisor);
/* Signed divide, either or both operands may be negative. */
word16 mp_shortdiv(register unitptr quotient,
register unitptr dividend,register word16 divisor);
/* Returns short remainder of unsigned divide. */
int mp_mod(register unitptr remainder,
register unitptr dividend,register unitptr divisor);
/* Unsigned divide, treats both operands as positive. */
word16 mp_shortmod(register unitptr dividend,register word16 divisor);
/* Just returns short remainder of unsigned divide. */
int mp_mult(register unitptr prod,
register unitptr multiplicand,register unitptr multiplier);
/* Computes multiprecision prod = multiplicand * multiplier */
int countbits(unitptr r);
/* Returns number of significant bits in r. */
int stage_peasant_modulus(unitptr n);
int stage_merritt_modulus(unitptr n);
int stage_upton_modulus(unitptr n);
int stage_smith_modulus(unitptr n);
/* Must pass modulus to stage_modulus before calling modmult. */
int peasant_modmult(register unitptr prod,
unitptr multiplicand,register unitptr multiplier);
int merritt_modmult(register unitptr prod,
unitptr multiplicand,register unitptr multiplier);
int upton_modmult(register unitptr prod,
unitptr multiplicand,register unitptr multiplier);
int smith_modmult(register unitptr prod,
unitptr multiplicand,register unitptr multiplier);
/* Performs combined multiply/modulo operation, with global modulus */
int mp_modexp(register unitptr expout,register unitptr expin,
register unitptr exponent,register unitptr modulus);
/* Combined exponentiation/modulo algorithm. */
int mp_modexp_crt(unitptr expout, unitptr expin,
unitptr p, unitptr q, unitptr ep, unitptr eq, unitptr u);
/* exponentiation and modulo using Chinese Remainder Theorem */
/****************** end of MPI library ****************************/

File diff suppressed because it is too large Load Diff

View File

@@ -42,4 +42,16 @@ ec NCPL_ET_NO_IPX,
ec NCPL_ET_NO_NCPFS_FILE,
"The file is probably not on a ncpfs mounted directory"
end
ec NCPL_ET_REPLY_FORMAT,
"The reply packet is not in the expected format"
ec NCPL_ET_REPLY_TOO_LARGE,
"The reply packet/message is too large for the allocated buffer"
ec NCPL_ET_SIGNATURE_FAILED,
"Packet signature initializing failed"
ec NCPL_ET_TRANSPORT_UNKNOWN,
"Unknown transport type"
end

103
lib/ncpsign.c Normal file
View File

@@ -0,0 +1,103 @@
#ifdef SIGNATURES
/*
* ncpsign.c
*
* Arne de Bruijn (arne@knoware.nl), 1997
*
*/
#include <string.h>
#include "ncplib.h"
#include "ncpsign.h"
#define rol32(i,c) (((((i)&0xffffffff)<<c)&0xffffffff)| \
(((i)&0xffffffff)>>(32-c)))
/* i386: 32-bit, little endian, handles mis-alignment */
#ifdef __i386__
#define GET_LE32(p) (*(const int *)(p))
#define PUT_LE32(p,v) { *(int *)(p)=v; }
#else
#define GET_LE32(p) DVAL_LH(p,0)
#define PUT_LE32(p,v) DSET_LH(p,0,v)
#endif
#define min(a,b) ((a)<(b)?(a):(b))
static void nwsign(const char *r_data1, char *r_data2, char *outdata) {
int i;
unsigned int w0,w1,w2,w3;
static int rbit[4]={0, 2, 1, 3};
#ifdef __i386__
unsigned int *data2=(int *)r_data2;
#else
unsigned int data2[16];
for (i=0;i<16;i++)
data2[i]=GET_LE32(r_data2+(i<<2));
#endif
w0=GET_LE32(r_data1);
w1=GET_LE32(r_data1+4);
w2=GET_LE32(r_data1+8);
w3=GET_LE32(r_data1+12);
for (i=0;i<16;i+=4) {
w0=rol32(w0 + ((w1 & w2) | ((~w1) & w3)) + data2[i+0],3);
w3=rol32(w3 + ((w0 & w1) | ((~w0) & w2)) + data2[i+1],7);
w2=rol32(w2 + ((w3 & w0) | ((~w3) & w1)) + data2[i+2],11);
w1=rol32(w1 + ((w2 & w3) | ((~w2) & w0)) + data2[i+3],19);
}
for (i=0;i<4;i++) {
w0=rol32(w0 + (((w2 | w3) & w1) | (w2 & w3)) + 0x5a827999 + data2[i+0],3);
w3=rol32(w3 + (((w1 | w2) & w0) | (w1 & w2)) + 0x5a827999 + data2[i+4],5);
w2=rol32(w2 + (((w0 | w1) & w3) | (w0 & w1)) + 0x5a827999 + data2[i+8],9);
w1=rol32(w1 + (((w3 | w0) & w2) | (w3 & w0)) + 0x5a827999 + data2[i+12],13);
}
for (i=0;i<4;i++) {
w0=rol32(w0 + ((w1 ^ w2) ^ w3) + 0x6ed9eba1 + data2[rbit[i]+0],3);
w3=rol32(w3 + ((w0 ^ w1) ^ w2) + 0x6ed9eba1 + data2[rbit[i]+8],9);
w2=rol32(w2 + ((w3 ^ w0) ^ w1) + 0x6ed9eba1 + data2[rbit[i]+4],11);
w1=rol32(w1 + ((w2 ^ w3) ^ w0) + 0x6ed9eba1 + data2[rbit[i]+12],15);
}
PUT_LE32(outdata,(w0+GET_LE32(r_data1)) & 0xffffffff);
PUT_LE32(outdata+4,(w1+GET_LE32(r_data1+4)) & 0xffffffff);
PUT_LE32(outdata+8,(w2+GET_LE32(r_data1+8)) & 0xffffffff);
PUT_LE32(outdata+12,(w3+GET_LE32(r_data1+12)) & 0xffffffff);
}
/*
* Initialize packet signatures
* The first 16 bytes of logindata are the shuffled password,
* the last 8 bytes the encryption key as received from the server.
*/
void sign_init(const char *logindata, char *sign_root) {
static const char initlast[16]={0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef,
0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10};
static const char *initdata="Authorized NetWare Client";
char msg[64];
char hash[16];
memset(msg, 0, 64);
memcpy(msg, logindata, 24);
memcpy(msg + 24, initdata, 25);
nwsign(initlast, msg, hash);
memcpy(sign_root, hash, 8);
}
/*
* Make a signature for the current packet and add it at the end of the
* packet.
*/
void sign_packet(struct ncp_conn *conn, int *size) {
char data[64];
memset(data,0,64);
memcpy(data,conn->sign_root,8);
PUT_LE32(data+8,(*size));
memcpy(data+12,conn->packet+sizeof(struct ncp_request_header)-1,
min((*size)-sizeof(struct ncp_request_header)+1,52));
nwsign(conn->sign_last,data,conn->sign_last);
memcpy(conn->packet+(*size),conn->sign_last,8);
(*size)+=8;
}
#endif

297
lib/ndscrypt.c Normal file
View File

@@ -0,0 +1,297 @@
/*
NDS client for ncpfs
Copyright (C) 1997 Arne de Bruijn
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <string.h>
#include "ndscrypt.h"
#include "ncplib.h"
static unsigned int rol16(unsigned int i, int c) {
return ((i << c) & 65535) | ((unsigned int)(i & 65535) >> (16 - c));
}
static unsigned int ror16(unsigned int i, int c) {
return ((unsigned int)(i & 65535) >> c) | ((i << (16 - c)) & 65535);
}
static unsigned char nwcryptdata[256]={
0xD9,0x78,0xF9,0xC4,0x19,0xDD,0xB5,0xED,0x28,0xE9,0xFD,0x79,
0x4A,0xA0,0xD8,0x9D,0xC6,0x7E,0x37,0x83,0x2B,0x76,0x53,0x8E,
0x62,0x4C,0x64,0x88,0x44,0x8B,0xFB,0xA2,0x17,0x9A,0x59,0xF5,
0x87,0xB3,0x4F,0x13,0x61,0x45,0x6D,0x8D,0x09,0x81,0x7D,0x32,
0xBD,0x8F,0x40,0xEB,0x86,0xB7,0x7B,0x0B,0xF0,0x95,0x21,0x22,
0x5C,0x6B,0x4E,0x82,0x54,0xD6,0x65,0x93,0xCE,0x60,0xB2,0x1C,
0x73,0x56,0xC0,0x14,0xA7,0x8C,0xF1,0xDC,0x12,0x75,0xCA,0x1F,
0x3B,0xBE,0xE4,0xD1,0x42,0x3D,0xD4,0x30,0xA3,0x3C,0xB6,0x26,
0x6F,0xBF,0x0E,0xDA,0x46,0x69,0x07,0x57,0x27,0xF2,0x1D,0x9B,
0xBC,0x94,0x43,0x03,0xF8,0x11,0xC7,0xF6,0x90,0xEF,0x3E,0xE7,
0x06,0xC3,0xD5,0x2F,0xC8,0x66,0x1E,0xD7,0x08,0xE8,0xEA,0xDE,
0x80,0x52,0xEE,0xF7,0x84,0xAA,0x72,0xAC,0x35,0x4D,0x6A,0x2A,
0x96,0x1A,0xD2,0x71,0x5A,0x15,0x49,0x74,0x4B,0x9F,0xD0,0x5E,
0x04,0x18,0xA4,0xEC,0xC2,0xE0,0x41,0x6E,0x0F,0x51,0xCB,0xCC,
0x24,0x91,0xAF,0x50,0xA1,0xF4,0x70,0x39,0x99,0x7C,0x3A,0x85,
0x23,0xB8,0xB4,0x7A,0xFC,0x02,0x36,0x5B,0x25,0x55,0x97,0x31,
0x2D,0x5D,0xFA,0x98,0xE3,0x8A,0x92,0xAE,0x05,0xDF,0x29,0x10,
0x67,0x6C,0xBA,0xC9,0xD3,0x00,0xE6,0xCF,0xE1,0x9E,0xA8,0x2C,
0x63,0x16,0x01,0x3F,0x58,0xE2,0x89,0xA9,0x0D,0x38,0x34,0x1B,
0xAB,0x33,0xFF,0xB0,0xBB,0x48,0x0C,0x5F,0xB9,0xB1,0xCD,0x2E,
0xC5,0xF3,0xDB,0x47,0xE5,0xA5,0x9C,0x77,0x0A,0xA6,0x20,0x68,
0xFE,0x7F,0xC1,0xAD};
#if 0
static unsigned char shuffle_table[32]=
{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};
static unsigned char shuffle_table2[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};
#endif
static unsigned char nwhashdata[256] =
{0xBD,0x56,0xEA,0xF2,0xA2,0xF1,0xAC,0x2A,0xB0,0x93,0xD1,0x9C,
0x1B,0x33,0xFD,0xD0,0x30,0x04,0xB6,0xDC,0x7D,0xDF,0x32,0x4B,
0xF7,0xCB,0x45,0x9B,0x31,0xBB,0x21,0x5A,0x41,0x9F,0xE1,0xD9,
0x4A,0x4D,0x9E,0xDA,0xA0,0x68,0x2C,0xC3,0x27,0x5F,0x80,0x36,
0x3E,0xEE,0xFB,0x95,0x1A,0xFE,0xCE,0xA8,0x34,0xA9,0x13,0xF0,
0xA6,0x3F,0xD8,0x0C,0x78,0x24,0xAF,0x23,0x52,0xC1,0x67,0x17,
0xF5,0x66,0x90,0xE7,0xE8,0x07,0xB8,0x60,0x48,0xE6,0x1E,0x53,
0xF3,0x92,0xA4,0x72,0x8C,0x08,0x15,0x6E,0x86,0x00,0x84,0xFA,
0xF4,0x7F,0x8A,0x42,0x19,0xF6,0xDB,0xCD,0x14,0x8D,0x50,0x12,
0xBA,0x3C,0x06,0x4E,0xEC,0xB3,0x35,0x11,0xA1,0x88,0x8E,0x2B,
0x94,0x99,0xB7,0x71,0x74,0xD3,0xE4,0xBF,0x3A,0xDE,0x96,0x0E,
0xBC,0x0A,0xED,0x77,0xFC,0x37,0x6B,0x03,0x79,0x89,0x62,0xC6,
0xD7,0xC0,0xD2,0x7C,0x6A,0x8B,0x22,0xA3,0x5B,0x05,0x5D,0x02,
0x75,0xD5,0x61,0xE3,0x18,0x8F,0x55,0x51,0xAD,0x1F,0x0B,0x5E,
0x85,0xE5,0xC2,0x57,0x63,0xCA,0x3D,0x6C,0xB4,0xC5,0xCC,0x70,
0xB2,0x91,0x59,0x0D,0x47,0x20,0xC8,0x4F,0x58,0xE0,0x01,0xE2,
0x16,0x38,0xC4,0x6F,0x3B,0x0F,0x65,0x46,0xBE,0x7E,0x2D,0x7B,
0x82,0xF9,0x40,0xB5,0x1D,0x73,0xF8,0xEB,0x26,0xC7,0x87,0x97,
0x25,0x54,0xB1,0x28,0xAA,0x98,0x9D,0xA5,0x64,0x6D,0x7A,0xD4,
0x10,0x81,0x44,0xEF,0x49,0xD6,0xAE,0x2E,0xDD,0x76,0x5C,0x2F,
0xA7,0x1C,0xC9,0x09,0x69,0x9A,0x83,0xCF,0x29,0x39,0xB9,0xE9,
0x4C,0xFF,0x43,0xAB};
void nwencrypt(const unsigned short *cryptbuf, const char *in, char *out) {
int i, j;
register unsigned int i1, i2, i3, i4;
const unsigned short *p;
i1 = WVAL_LH(in, 0);
i2 = WVAL_LH(in, 2);
i3 = WVAL_LH(in, 4);
i4 = WVAL_LH(in, 6);
p = cryptbuf;
for (j = 3; j; j--) {
for (i = (j == 2) ? 6 : 5; i; i--) {
i1 = rol16(i1 + (*p++) + (i4 & i3) + (~i4 & i2), 1);
i2 = rol16(i2 + (*p++) + (i1 & i4) + (~i1 & i3), 2);
i3 = rol16(i3 + (*p++) + (i2 & i1) + (~i2 & i4), 3);
i4 = rol16(i4 + (*p++) + (i3 & i2) + (~i3 & i1), 5);
}
if (j > 1) {
i1 += cryptbuf[i4 & 63];
i2 += cryptbuf[i1 & 63];
i3 += cryptbuf[i2 & 63];
i4 += cryptbuf[i3 & 63];
}
}
WSET_LH(out, 0, i1);
WSET_LH(out, 2, i2);
WSET_LH(out, 4, i3);
WSET_LH(out, 6, i4);
}
void nwdecrypt(const unsigned short *cryptbuf, const char *in, char *out) {
int i, j;
const unsigned short *p;
register unsigned int i1, i2, i3, i4;
i1 = WVAL_LH(in, 0);
i2 = WVAL_LH(in, 2);
i3 = WVAL_LH(in, 4);
i4 = WVAL_LH(in, 6);
p = cryptbuf + 64;
for (j = 3; j; j--) {
for (i = (j == 2) ? 6 : 5; i; i--) {
i4 = ror16(i4, 5) - (~i3 & i1) - (i3 & i2) - (*--p);
i3 = ror16(i3, 3) - (~i2 & i4) - (i2 & i1) - (*--p);
i2 = ror16(i2, 2) - (~i1 & i3) - (i1 & i4) - (*--p);
i1 = ror16(i1, 1) - (~i4 & i2) - (i4 & i3) - (*--p);
}
if (j > 1) {
i4 -= cryptbuf[i3 & 63];
i3 -= cryptbuf[i2 & 63];
i2 -= cryptbuf[i1 & 63];
i1 -= cryptbuf[i4 & 63];
}
}
WSET_LH(out, 0, i1);
WSET_LH(out, 2, i2);
WSET_LH(out, 4, i3);
WSET_LH(out, 6, i4);
}
void nwcryptinit(unsigned short *scryptbuf, const char *key) {
int i;
unsigned char cryptbuf[128], *p;
memcpy(cryptbuf, key, 8);
for (i = 0; i < 120; i++)
cryptbuf[i + 8] =
nwcryptdata[(unsigned char)(cryptbuf[i] + cryptbuf[i + 7]) & 255];
cryptbuf[128 - 8] = nwcryptdata[(unsigned char)cryptbuf[128 - 8] & 255];
for (i = 127 - 8; i >= 0; i--)
cryptbuf[i] = nwcryptdata[(unsigned char)cryptbuf[i + 1] ^
(unsigned char)cryptbuf[i + 8]];
for (i = 0, p = cryptbuf; i < 64; i++, p += 2)
scryptbuf[i] = (*p) | (*(p+1)) << 8;
}
void nwencryptblock(const char *cryptkey, const char *buf, int buflen,
char *outbuf) {
int i;
char nhash[8];
unsigned short cryptbuf[64];
nwcryptinit(cryptbuf, cryptkey);
memset(nhash, 0, 8);
while (buflen >= 8) {
for (i = 0; i < 8; i++, buf++)
nhash[i] ^= *buf;
nwencrypt(cryptbuf, nhash, nhash);
memcpy(outbuf, nhash, 8);
outbuf += 8;
buflen -= 8;
}
memset(cryptbuf, 0, sizeof(cryptbuf));
}
void nwdecryptblock(const char *cryptkey, const char *buf, int buflen,
char *outbuf) {
int i;
char nhash[16], *p;
unsigned short cryptbuf[64];
nwcryptinit(cryptbuf, cryptkey);
memset(nhash, 0, 16);
p = nhash;
while (buflen >= 8) {
memcpy(p, buf, 8);
p = nhash + 8 - (p - nhash);
nwdecrypt(cryptbuf, buf, outbuf);
for (i = 0; i < 8; i++, outbuf++)
*outbuf ^= p[i];
buf += 8;
buflen -= 8;
}
memset(cryptbuf, 0, sizeof(cryptbuf));
}
void nwhash1(char *hash, int hashlen, const char *data, int datalen) {
unsigned char *hp, *hp1, *hend, c;
const unsigned char *dp;
hp1 = (hp = (unsigned char *)hash) + 1;
hend = hp + hashlen;
dp = (const unsigned char *)data;
while (datalen--) {
*hp = nwhashdata[*hp1 ^ *hp] ^ *dp++;
hp = hp1++;
if (hp1 == hend)
hp1 = (unsigned char *)hash;
}
while (hp-- > (unsigned char *)hash) {
hp1 = (unsigned char *)hash;
c = *hp1++;
while (*(hp1 - 1) = *hp1, ++hp1 < (unsigned char *)hash + hashlen);
*(hp1 - 1) = c;
}
}
void nwhash2(char *hashbuf, char c) {
int i, j;
char *p = hashbuf + hashbuf[0x40];
p[0x20] = p[0x00] ^ (p[0x10] = c);
hashbuf[0x41] = (p[0x30] ^= nwhashdata[(unsigned char)(c ^ hashbuf[0x41])]);
if (!(hashbuf[0x40] = (hashbuf[0x40] + 1) & 15)) {
c = 0;
for (i = 18; i; i--)
for (j = 48, p = hashbuf; j; j--)
c = (*(p++) ^= nwhashdata[((unsigned char)c + j) & 255]);
}
}
void nwhash2block(char *hashbuf, const char *data, int datalen) {
while (datalen--)
nwhash2(hashbuf, *data++);
}
void nwhash2end(char *hashbuf) {
int i, j;
for(j = i = 16 - hashbuf[0x40]; j; j--)
nwhash2(hashbuf, i);
for(i = 0x30; i < 0x40; i++)
nwhash2(hashbuf, hashbuf[i]);
}
#if 0
void shuffle(const char *objid, const char *pwd, char *out) {
unsigned char temp[32];
int i, j, k;
i = strlen(pwd);
memset(temp, 0, 32);
for (j = 0; j < i; j++)
temp[j & 31] ^= pwd[j];
if (i)
for (j = i; j < 32; j += i) {
temp[j++] = shuffle_table[j];
k = 32 - j;
memcpy(temp + j, pwd, (k > i) ? i : k);
}
for (i = 0; i < 32; i++)
temp[i] ^= objid[i & 3];
j = 0;
for (k = 0; k < 2; k++)
for (i = 0; i < 32; i++)
(char)j += temp[i] = (temp[i] + j) ^
(temp[(i + j) & 31] - shuffle_table[i]);
for (i = 0; i < 16; i++)
out[i] = shuffle_table2[temp[i * 2]] |
(shuffle_table2[temp[i * 2 + 1]] << 4);
}
#endif

47
lib/ndscrypt.h Normal file
View File

@@ -0,0 +1,47 @@
/*
NDS client for ncpfs
Copyright (C) 1997 Arne de Bruijn
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef _NDSCRYPT_H
#define _NDSCRYPT_H
#include <string.h>
void nwencrypt(const unsigned short *cryptbuf, const char *in, char *out);
void nwdecrypt(const unsigned short *cryptbuf, const char *in, char *out);
void nwcryptinit(unsigned short *scryptbuf, const char *key);
void nwencryptblock(const char *cryptkey, const char *buf, int buflen,
char *outbuf);
void nwdecryptblock(const char *cryptkey, const char *buf, int buflen,
char *outbuf);
#define nwhash1init(hash, hashlen) memset(hash, 0, hashlen)
void nwhash1(char *hash, int hashlen, const char *data, int datalen);
#define nwhash2init(hashbuf) memset(hashbuf, 0, 0x42)
void nwhash2(char *hashbuf, char c);
void nwhash2block(char *hashbuf, const char *data, int datalen);
void nwhash2end(char *hashbuf);
#if 0
void shuffle(const char *objid, const char *pwd, char *out);
#else
void shuffle(const char *objid, const char *pwd, int buflen, char *out);
#endif
#endif /* _NDSCRYPT_H */

1253
lib/ndslib.c Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -92,20 +92,20 @@ typedef unsigned char buf4[4];
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,
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 =
@@ -115,7 +115,8 @@ static buf32 encryptkeys =
0xF4, 0x47, 0xDC, 0xA7, 0xEC, 0xCF, 0x50, 0xC0};
static void shuffle1(buf32 temp, unsigned char *target)
static void
shuffle1(buf32 temp, unsigned char *target)
{
short b4;
unsigned char b3;
@@ -123,51 +124,63 @@ static void shuffle1(buf32 temp, unsigned char *target)
b4 = 0;
for (b2 = 0; b2 <= 1; ++b2) {
for (s = 0; s <= 31; ++s) {
for (b2 = 0; b2 <= 1; ++b2)
{
for (s = 0; s <= 31; ++s)
{
b3 = (temp[s] + b4) ^ (temp[(s + b4) & 31] - encryptkeys[s]);
b4 = b4 + b3;
temp[s] = b3;
}
}
for (i = 0; i <= 15; ++i) {
for (i = 0; i <= 15; ++i)
{
target[i] = encrypttable[temp[2 * i]]
| (encrypttable[temp[2 * i + 1]] << 4);
}
}
static void shuffle(const unsigned char *lon, const unsigned char *buf, int buflen,
unsigned char *target)
void
shuffle(const unsigned char *lon, const unsigned char *buf, int buflen,
unsigned char *target)
{
int b2, d, s;
buf32 temp;
while ((buflen > 0)
&& (buf[buflen - 1] == 0)) {
&& (buf[buflen - 1] == 0))
{
buflen = buflen - 1;
}
for (s = 0; s < 32; s++) {
for (s = 0; s < 32; s++)
{
temp[s] = 0;
}
d = 0;
while (buflen >= 32) {
for (s = 0; s <= 31; ++s) {
while (buflen >= 32)
{
for (s = 0; s <= 31; ++s)
{
temp[s] = temp[s] ^ buf[d];
d = d + 1;
}
buflen = buflen - 32;
}
b2 = d;
if (buflen > 0) {
for (s = 0; s <= 31; ++s) {
if (d + buflen == b2) {
if (buflen > 0)
{
for (s = 0; s <= 31; ++s)
{
if (d + buflen == b2)
{
b2 = d;
temp[s] = temp[s] ^ encryptkeys[s];
} else {
} else
{
temp[s] = temp[s] ^ buf[b2];
b2 = b2 + 1;
}
@@ -180,9 +193,10 @@ static void shuffle(const unsigned char *lon, const unsigned char *buf, int bufl
}
static void nw_encrypt(const unsigned char *fra,
const unsigned char *buf,
unsigned char *til)
static void
nw_encrypt(const unsigned char *fra,
const unsigned char *buf,
unsigned char *til)
{
buf32 k;
int s;
@@ -197,6 +211,7 @@ static void nw_encrypt(const unsigned char *fra,
til[s] = k[s] ^ k[15 - s];
}
#ifndef __MAKE_SULIB__
/*****************************************************************************/
/* */
@@ -288,7 +303,8 @@ static char
* in ncplib.c.
*/
static void newpassencrypt(char *old, char *new, char *out)
static void
newpassencrypt(char *old, char *new, char *out)
{
char *p, *bx;
char copy[8];
@@ -297,22 +313,26 @@ static void newpassencrypt(char *old, char *new, char *out)
memcpy(copy, new, 8);
for (i = 0; i < 16; i++) {
for (di = 0, ax = 0, p = old; di < 8; di++, ax += 0x20, p++) {
for (i = 0; i < 16; i++)
{
for (di = 0, ax = 0, p = old; di < 8; di++, ax += 0x20, p++)
{
cl = newshuffle[(((copy[di] ^ *p) >> 4) & 0x0f) + ax + 0x10] << 4;
dl = newshuffle[((copy[di] ^ *p) & 0xf) + ax];
copy[di] = cl | dl;
}
ch = old[7];
for (bx = old + 7; bx > old; bx--) {
for (bx = old + 7; bx > old; bx--)
{
*bx = ((bx[-1] >> 4) & 0x0f) | ((*bx) << 4);
}
*old = ((ch >> 4) & 0x0f) | (*old) << 4;
memset(out, '\0', 8);
for (di = 0; di < 16; di++) {
for (di = 0; di < 16; di++)
{
if (newshuffle[di + 0x100] & 1)
ch = ((copy[newshuffle[di + 0x100] / 2] >> 4) & 0x0f);
else
@@ -322,3 +342,5 @@ static void newpassencrypt(char *old, char *new, char *out)
memcpy(copy, out, 8);
}
}
#endif /* __MAKE_SULIB__ */

218
lib/platform.h Normal file
View File

@@ -0,0 +1,218 @@
/* platform.h - computer platform customization for PGP
multiprecision math package. #Included in mpilib.h.
*/
#ifndef PLATFORM_H
#define PLATFORM_H
/* Platform customization:
* A version which runs on almost any computer can be implemented by
* defining PORTABLE and MPORTABLE, preferably as a command line
* parameter. Faster versions can be generated by specifying specific
* parameters, such as size of unit and MULTUNIT, and by supplying some
* of the critical in assembly.
*
* This file holds customizations for different environments.
* This is done in one of two ways:
* 1. A symbol is defined on the command line which designates a
* particular environment, such as MSDOS. This file detects the
* environment symbol and sets the appropriate low-level defines.
*
* 2. If no environment is named, the low-level defines are set in
* the same manner as for PGP 2.0, thereby providing an easy upgrade.
*
* Following are a description of the low-level definition symbols:
*
* The following preprocessor symbols should be conditionally set to
* optimize for a particular environment.
*
* Define one of the following:
* UNIT8, UNIT16, or UNIT32 - specifies size of operands for
* multiprecision add, subtract, shift, and initialization operations.
* Define one of the following:
* MUNIT8, MUNIT16, MUNIT32 - specified size of operands for
* multiprecision multiply and mod_mult. This must be less than or
* equal to unit size. It should be the word size for the native
* atomic multiply instruction. For a 16x16 bit multiply yielding a
* 32-bit product, MUNIT16 should be set.
* Define one (or more) of the following:
* PEASANT, MERRITT, UPTON, SMITH -algorithm used for modmult. All defined
* algorithms are compiled, but the first defined name listed will be
* assigned to the generic entry point symbols. Multiple algorithms are
* used primarily for testing.
* HIGHFIRST - specified if longs are stored with the most significant
* bit at the lowest address (Motorola), undefined otherwise. This should
* be defined on the command line, normally in the makefile.
*
* The following symbol, if initialized, is set to specific values:
* ALIGN - variable declaration attribute which forces optimum alignment
* of words, e.g. for VAX C: ALIGN=_align(quadword)
*
* The following symbols correspond to individual multiprecision routines
* that may be implemented with assembly language. If they are implemented
* in assembly, the symbols should be defined with the name of the
* corresponding external entry points, e.g., mp_addc=P_ADDC
* mp_setp - set precision for external routines
* mp_addc - add with carry
* mp_subb - subtract with borrow
* mp_rotate_left - rotate left
* mp_compare - compare
* mp_move - move
* unitfill0 - zero fill
* mp_smul - multiply vector by single word *
* mp_smula - multiply vector by single word and accumulate *
* mp_dmul - full multiply
* mp_set_recip - setup for mp_quo_digit
* mp_quo_digit - quotient digit for modulus reduction
*
* Either mp_smul or mp_smula should be defined. mp_smula provides
* for accumulation to an existing value, while mp_smul is for use of the
* older definition of mp_smul, used in PGP 2.0, which assumed that the high
* order accumulator word is zero. Use of mp_smula causes one less word of
* precision to be used, thereby slightly increasing speed.
*/
/********************************************************************
* Environment customization. Please send any additions or corrections
* to Philip Zimmermann.
*/
#ifndef PORTABLE
#ifdef MSDOS
#ifndef i386 /* gcc */
#define UNIT16
#define MUNIT16
#define mp_setp P_SETP
#define mp_addc P_ADDC
#define mp_subb P_SUBB
#define mp_rotate_left P_ROTL
#define mp_smula P_SMULA
#define mp_quo_digit P_QUO_DIGIT
#define mp_set_recip P_SETRECIP
#define SMITH
#define PLATFORM_SPECIFIED
#endif /* i386 */
#endif /* MSDOS */
#ifdef VMS
#define UNIT32 /* use 32-bit units */
#define MUNIT32 /* not used in C code, only in assembler */
#define UPTON
#define mp_setp p_setp
#define mp_addc p_addc
#define mp_subb p_subb
#define mp_rotate_left p_rotl
#define mp_smul p_smul
#define mp_dmul p_dmul
#define mp_compare p_cmp
#define ALIGN _align(quadword)
#ifdef VAXC
/*
* A VAX is a CISC machine. Unfortunately C is at to low a level to use
* many of the instruction set enhancements so we define some macros
* here that implement fast moves and fast zero fills with single
* instructions.
*/
#pragma builtins
#define mp_move( dst, src) _MOVC3( global_precision*4, (char *) src, (char *) dst)
#define unitfill0( r, unitcount) _MOVC5( 0, (char *) 0, 0, unitcount*4, (char *) r)
#define mp_burn(r) _MOVC5(0, (char *) 0, 0, global_precision*4, (char *) r)
#define mp_init0(r) mp_burn(r) /* Just for documentation purposes */
#endif /* VAXC */
#define PLATFORM_SPECIFIED
#endif /* VMS */
#ifdef mips
/*
* Needs r3kd.s and r3000.s (or r3000.c)
*/
#define UNIT32
#define MUNIT32
#define SMITH
#define mp_dmul p_dmul
#define mp_setp p_setp
#define mp_addc p_addc
#define mp_subb p_subb
#define mp_rotate_left p_rotl
#define mp_smula p_smula
#define mp_quo_digit p_quo_digit
#define mp_set_recip p_setrecip
#define PLATFORM_SPECIFIED
#endif /* mips */
#ifdef i386
/*
* Needs 80386.S
*/
#define UNIT32
#define MUNIT32
#define SMITH
#define mp_setp P_SETP
#define mp_addc P_ADDC
#define mp_subb P_SUBB
#define mp_rotate_left P_ROTL
#define unitfill0(r,ct) memset((void*)r, 0, (ct)*sizeof(unit))
#define mp_smula P_SMULA
#define mp_quo_digit p_quo_digit
#define mp_set_recip p_setrecip
#define PLATFORM_SPECIFIED
#endif /* i386 */
#ifdef sparc
/*
* Needs sparc.s
*/
#define UNIT32
#define MERRITT
#define mp_setp P_SETP
#define mp_addc P_ADDC
#define mp_subb P_SUBB
#define mp_rotate_left P_ROTL
#define unitfill0(r,ct) memset((void*)r, 0, (ct)*sizeof(unit))
#define PLATFORM_SPECIFIED
#endif /* sparc */
#if defined(mc68000) || defined(mc68020)
/*
* Needs mc68020.S
*/
#define UNIT32
#define mp_setp P_SETP
#define mp_addc P_ADDC
#define mp_subb P_SUBB
#define mp_rotate_left P_ROTL
#define unitfill0(r,ct) memset((void*)r, 0, (ct)*sizeof(unit))
#if defined(sun3) || defined(mc68020)
# define UPTON
# define MUNIT32
# define mp_smul P_SMUL
/* # define mp_dmul P_DMUL */ /* mc68020.s has a bug in P_DMUL */
#else
# define SMITH
# define MUNIT16
#endif
#define PLATFORM_SPECIFIED
#endif /* mc68000 */
/* Add additional platforms here ... */
/**************** End of system specification ************************/
#ifndef PLATFORM_SPECIFIED
/* No platform explicitly selected. Customization is controlled by
* PORTABLE and MPORTABLE.
*/
#define mp_setp P_SETP
#define mp_addc P_ADDC
#define mp_subb P_SUBB
#define mp_rotate_left P_ROTL
#define UPTON
#define unitfill0(r,ct) memset((void*)r, 0, (ct)*sizeof(unit))
#ifndef MPORTABLE
#define mp_smul P_SMUL
#endif /* MPORTABLE */
#endif /* PLATFORM_SPECIFIED */
#endif /* PORTABLE */
#endif /* PLATFORM_H */

39
lib/usuals.h Normal file
View File

@@ -0,0 +1,39 @@
/* usuals.h - The usual typedefs, etc.
*/
#ifndef USUALS /* Assures no redefinitions of usual types...*/
#define USUALS
#include <sys/types.h>
typedef unsigned char boolean; /* values are TRUE or FALSE */
typedef u_int8_t byte; /* values are 0-255 */
typedef byte *byteptr; /* pointer to byte */
typedef char *string; /* pointer to ASCII character string */
typedef u_int16_t word16; /* values are 0-65535 */
typedef u_int32_t word32; /* values are 0-4294967295 */
#ifndef TRUE
#define FALSE 0
#define TRUE (!FALSE)
#endif /* if TRUE not already defined */
#ifndef min /* if min macro not already defined */
#define min(a,b) (((a)<(b)) ? (a) : (b) )
#define max(a,b) (((a)>(b)) ? (a) : (b) )
#endif /* if min macro not already defined */
/* void for use in pointers */
#ifndef NO_VOID_STAR
#define VOID void
#else
#define VOID char
#endif
/* Zero-fill the byte buffer. */
#define fill0(buffer,count) memset( buffer, 0, count )
/* This macro is for burning sensitive data. Many of the
file I/O routines use it for zapping buffers */
#define burn(x) fill0((VOID *)&(x),sizeof(x))
#endif /* if USUALS not already defined */

View File

@@ -1,12 +1,22 @@
include ../Makeinit
MAN1 = ncopy nwbols nwfsinfo nwsfind pqlist nprint nwboprops nwfstime \
nwtrustee pserver nsend nwbpset nwpasswd nwuserlist slist \
nwauth nwbpvalues nwrights nwvolinfo pqrm pqstat nwpurge
MAN5 = nwclient
MAN8 = ncpmount nwbpadd nwmsg ncpumount nwbpcreate nwrevoke nwbocreate \
nwbprm nwborm nwgrant
all:
dep:
install:
for i in *.1; do install $$i -m 755 /usr/local/man/man1; done
for i in *.5; do install $$i -m 755 /usr/local/man/man5; done
for i in *.8; do install $$i -m 755 /usr/local/man/man8; done
for i in $(MAN1); do install $$i.1 -m 644 $(MANDIR)/man1; done
for i in $(MAN5); do install $$i.5 -m 644 $(MANDIR)/man5; done
for i in $(MAN8); do install $$i.8 -m 644 $(MANDIR)/man8; done
clean:
rm -f *~
rm -f *~
mrproper: clean

33
man/nwmsg.8 Normal file
View File

@@ -0,0 +1,33 @@
.TH NWMSG 8 02/29/1996 nwmsg nwmsg
.SH NAME
nwmsg \- Deliver NetWare user broadcast messages
.SH SYNOPSIS
.B nwmsg
.I mount-point
.SH DESCRIPTION
.B nwmsg
is called by kerneld when a broadcast message arrives from a NetWare
server.
.B nwmsg
fetches this message via the mount point and delivers it to
the user using the same way write(1) uses.
Please note that
.I kerneld
must run when broadcast messages should be delivered to users.
NetWare servers can send asynchronous broadcast messages to users,
either on explicit request by another user, or when the server is
shutdown. The client workstation is informed about this event by an
IPX packet on a special socket, the message socket.
This can happen at any time, so the user has to be informed about this
event whenever it appears. I chose to use the kerneld feature of the
Linux kernel to call the program nwmsg. For nwmsg, I used the relevant
parts of the
.I write
program, so you can expect the NetWare broadcast
messages to appear where user messages would appear.
.SH SEE ALSO
ncpmount(8), kerneld(8), write(1)

65
man/nwpurge.1 Normal file
View File

@@ -0,0 +1,65 @@
.TH NWPURGE 1 4/2/1998 nwpurge nwpurge
.SH NAME
nwpurge \- Permanently delete previously erased files
.SH SYNOPSIS
.B nwpurge
[
.B -h
] [
.B -a
] [
.B -l
] [
.B -s
] [
.B directory
]
.SH DESCRIPTION
.B nwpurge
purges files from specified NetWare directory.
.SH OPTIONS
.B -h
.RS 3
.B -h
is used to print out a short help text.
.RE
.B -a
.RS 3
.B -a
is used to specify that not only specified directory, but also its
subdirectories have to be purged.
.RE
.B -l
.RS 3
.B -l
is used to disable purge. Files are only printed out.
.RE
.B -s
.RS 3
.B -s
specifies silent mode (no print output, only total is printed).
.RE
.B directory
.RS 3
You can specify the directory in which you want to purge files. Current
working directory is used by default. You have to specify path in
Linux format, not in NetWare format.
.SH EXAMPLES
nwpurge -a /NetWare/server/sys
With this example, all files from directory /NetWare/server/sys and from
all its subdirectories are purged.
.SH AUTHORS
nwpurge was written by Petr Vandrovec with the corresponding NetWare
utility in mind. See the Changes file of ncpfs for other contributors.

105
man/pqrm.1 Normal file
View File

@@ -0,0 +1,105 @@
.TH PQRM 1 03/03/1998 pqrm pqrm
.SH NAME
pqrm \- Remove job from NetWare print queue
.SH SYNOPSIS
.B pqrm
[
.B -h
] [
.B -S
.I server
] [
.B -U
.I user name
] [
.B -P
.I password
|
.B -n
] [
.B -C
]
.I queue_name
.I job_ID
[
.I another_job_ID
... ]
.SH DESCRIPTION
.B pqrm
remove specified jobs from the NetWare print queue available
to you on some server. If you are already connected to some server, this one
is used.
.B pqrm
looks up the file
.I $HOME/.nwclient
to find a file server, a user name and possibly a password. See
nwclient(5) for more information. Please note that the access
permissions of .nwclient MUST be 600, for security reasons.
.SH OPTIONS
.B queue_name
.RS 3
.B queue_name
is used to specify queue. You can not use wildcards in the name.
.RE
.B job_ID
,
.B another_job_ID
.RS 3
.B job_ID
is used to specify which job has to be deleted.
.RE
.B -S
.I server
.RS 3
.B server
is the name of the server you want to use.
.RE
.B -U
.I user name
.RS 3
If the user name your NetWare administrator gave to you differs
from your unix user-id, you should use
.B -U
to tell the server about your NetWare user name.
.RE
.B -P
.I password
.RS 3
You may want to give the password required by the server on the
command line. You should be careful about using passwords in scripts.
.RE
.B -n
.RS 3
.B -n
should be given to mount shares which do not require a password to log in.
If neither
.B -n
nor
.B -P
are given, pqstat prompts for a password.
.RE
.B -C
.RS 3
By default, passwords are converted to uppercase before they are sent
to the server, because most servers require this. You can turn off
this conversion by
.B -C.
.RE
.SH SEE ALSO
.B nwclient(5), nprint(1), slist(1), ncpmount(8), ncpumount(8), pqlist(1), pqstat(1)
.SH CREDITS
pqrm was written by Petr Vandrovec (vandrove@vc.cvut.cz)

107
man/pqstat.1 Normal file
View File

@@ -0,0 +1,107 @@
.TH PQSTAT 1 03/03/1998 pqstat pqstat
.SH NAME
pqstat \- List jobs in NetWare print queue
.SH SYNOPSIS
.B pqstat
[
.B -h
] [
.B -S
.I server
] [
.B -U
.I user name
] [
.B -P
.I password
|
.B -n
] [
.B -C
]
.I queue name
[
.I job count
]
.SH DESCRIPTION
.B pqstat
lists specified number of jobs from the specified NetWare print queue available
to you on some server. If you are already connected to some server, this one
is used.
If pqstat does not print to a tty, the decorative header line is
not printed, so that you can count the jobs in print queue by doing
pqstat -S server queue | wc -l
.B pqstat
looks up the file
.I $HOME/.nwclient
to find a file server, a user name and possibly a password. See
nwclient(5) for more information. Please note that the access
permissions of .nwclient MUST be 600, for security reasons.
.SH OPTIONS
.B queue name
.RS 3
.B queue name
is used to specify queue. You can not use wildcards in the name.
.RE
.B job count
.RS 3
.B job count
is used to specify how much entries will be shown. Default is to show all
entries.
.RE
.B -S
.I server
.RS 3
.B server
is the name of the server you want to use.
.RE
.B -U
.I user name
.RS 3
If the user name your NetWare administrator gave to you differs
from your unix user-id, you should use
.B -U
to tell the server about your NetWare user name.
.RE
.B -P
.I password
.RS 3
You may want to give the password required by the server on the
command line. You should be careful about using passwords in scripts.
.RE
.B -n
.RS 3
.B -n
should be given to mount shares which do not require a password to log in.
If neither
.B -n
nor
.B -P
are given, pqstat prompts for a password.
.RE
.B -C
.RS 3
By default, passwords are converted to uppercase before they are sent
to the server, because most servers require this. You can turn off
this conversion by
.B -C.
.RE
.SH SEE ALSO
.B nwclient(5), nprint(1), slist(1), ncpmount(8), ncpumount(8), pqlist(1), pqrm(1)
.SH CREDITS
pqstat was written by David Woodhouse (dave@imladris.demon.co.uk)

View File

@@ -108,6 +108,9 @@ print job.
%u: This field will be replaced by the name of the user who posted
this print job.
%d: This field will be replaced by the job description field of
this print job.
.RE
.B -j

View File

@@ -1,19 +1,19 @@
Begin3
Title: ncpfs
Version: 2.1.1
Entered-date: 23. March 1997
Version: 2.2.0
Entered-date: May 1, 1998
Description: With ncpfs you can mount volumes of your netware
server under Linux. You can also print to netware
print queues and spool netware print queues to the
Linux printing system. You need kernel 1.2.x or
1.3.71 and above. ncpfs does NOT work with any 1.3.x
kernel below 1.3.71.
Linux printing system.
Keywords: filesystem ncp novell netware printing
Author: lendecke@namu01.Num.Math.Uni-Goettingen.de (Volker Lendecke)
Maintained-by: lendecke@namu01.Num.Math.Uni-Goettingen.de (Volker Lendecke)
Author: lendecke@Math.Uni-Goettingen.de (Volker Lendecke)
Maintained-by: lendecke@Math.Uni-Goettingen.de (Volker Lendecke),
vandrove@vc.cvut.cz (Petr Vandrovec)
Primary-site: ftp.gwdg.de:/pub/linux/misc/ncpfs
Alternate-site: sunsite.unc.edu:/pub/Linux/system/Filesystems/ncpfs
~177k ncpfs-2.1.1.tgz
~ 1k ncpfs-2.1.1.lsm
platan.vc.cvut.cz:/pub/linux/ncpfs
~190k ncpfs-2.2.0.tgz
~ 1k ncpfs-2.2.0.lsm
Copying-policy: GPL
End

96
ncpfs-nds-0.06.CHANGES Normal file
View File

@@ -0,0 +1,96 @@
Release 0.06, January 20, 1998
* Signature support (re)included. Because of this the name has changed
and the kernel patch is added.
* Fixed segfault in nds_login_auth when trying server context.
(with thanks to K J MacDonald, kenny@holyrood.ed.ac.uk)
Release 0.05, November 7, 1997
* Added include errno.h to ndslib.c (needed for glibc)
* Modified nwsfind to accept -a parameter that causes nwsfind to
interpret the server name as an address.
* Fixed segfault in ncp_open_addr
* Modified lib/ncplib.c:ncp_open_addr to call nwsfind with the address
(creates a route to the address if necessary).
Release 0.04, November 5, 1997
Changes since 0.03:
* Added support for NDS login/authenticate to a read-only replica
(untested)
* ncpmount has new option -b to use bindery logins to NDS servers
(actually since 0.01)
(Again with thanks to Petr Vandrovec, vandrove@vc.cvut.cz)
Release 0.03, November 2, 1997
Changes since 0.02:
* (Hopefully temporarily) removed signature support, it seems to be
legally protected. Because of this the name has changed and the
kernel patch is removed.
Release 0.02, October 15, 1997
Changes since 0.01:
* Fixed bug with empty passwords
* Fixed bug with beginlogin id != user id
* Fixed bug with fragger handle != 0
* Removed ncpsign.* from ./sutil, moved ncpsign.h to ./include
* Reorganized packet signature initializing
* Added support for NDS grace logins
(With thanks to Petr Vandrovec, vandrove@vc.cvut.cz)
Changes made by ncpfs-nds-sign-0.01.patch:
* Adds NDS_SUPPORT conditional variable to main Makefile
* Puts set -e; ahead of the SUBDIRS loop in the main Makefile to abort
the loop if compilation in a subdir fails
* Adds README.NDS file
* Adds fields for packet signatures to struct ncp_conn
* Adds the following functions to the lib/ncplib.c
ncp_negotiate_size_and_options Negotiate packet size and options
ncp_get_bindery_access_level Get bindery access level
ncp_init_pb_conn Initialize packet burst connection
ncp_send_nds_frag Send message with NDS fragger protocol
ncp_sign_start Initialize internal signing structures
ncp_send_nds Send request for NDS function
ncp_change_conn_state Change NW 4 connection state
* Modifies ncp_open_temporary in lib/ncplib.c to use NDS login if
compiled with -DNDS_SUPPORT and server has NDS.
* Adds two error messages to ncplib_err.et
* Modifies lib/ncplib.c to generate packet signatures when wanted.
* Adds lib/ndslib.c with the following external used functions:
strlen_u Get length of unicode string
strcpy_uc Copy unicode string to normal string
strcpy_cu Copy normal string to unicode string
nds_get_server_name Get name and domain of current server
nds_get_tree_name Get current NDS tree name
nds_login_auth NDS login and authenticate to current server
* Adds mpilib.c, mpilib.h, usuals.h and platform.h from the PGP 2.3
source to lib/ for the RSA encryption, which is necessary for NDS
login/authenticate.
* Adds lib/ndscrypt.c with hash and encrypt functions for NDS login.
* Adds lib/ncpsign.c with a MD4 hash function for packet signatures.
* Modifies lib/Makefile to add ncpsign.o, ndslib.o, mpilib.o and
ndscrypt.o to libncp.
* Modifies sutil/Makefile to add ndslib.o,mpilib.o,ndscrypt.o to libncp.
* Adds ncp_send_nds_frag, ncp_send_nds, ncp_change_conn_state to
sutil/ncplib.c
* Modifies sutil/ncpmount.c to:
give more verbose error message if mount(2) fails;
use NDS login if compiled with -DNDS_SUPPORT and server has NDS;
start packet signature generation.
(See below for changes to kernel-1.2/*)
Changes made by ncpfs-nds-sign-0.01.kernel.patch:
* Modifies Makefile to add ncpsign_kernel.o to ncpfs.o
* Modifies inode.c to query whether the server wants packet signatures.
* Adds ioctls to start packet signature generation and to query
whether the server wants packet signing.
* Adds ncp_negotiate_size_and_options to ncplib_kernel.c.
* Modifies sock.c to sign packets when enabled.
* Adds ncpsign_kernel.c to generatie packet signatures.
Arne de Bruijn, October 4, 1997

42
ncpfs-nds-0.06.README Normal file
View File

@@ -0,0 +1,42 @@
NDS support for ncpfs (linux)
ncpfs is a NetWare client for the Linux operating system, maintained
by Volker Lendecke (lendecke@namu01.gwdg.de). I have written
support for NDS logins to NetWare 4 servers.
Warning! NDS logins require the RSA public key algorithm, which is
patented in the U.S.A. and Canada, and possibly in other countries.
Because of this you may not be allowed to use this code. Check this
before you use NDS logins!
Warning! The NDS support for ncpfs is in early beta stage, currently
I have only tested it on my own test NW 4.10 server. The NDS support
may not work for you, or even give problems like crashing your linux
box, or the NetWare server! Please apply the patch only if you know
what you are doing. Note that this version of the patch is not
little-endian free, so it won't work on big-endian architectures.
THIS PATCH IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER
EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS
WITH YOU. SHOULD THE PATCH PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL
NECESSARY SERVICING, REPAIR OR CORRECTION.
This file contains a patch for the non-kernel part of ncpfs:
ncpfs-nds-0.05.patch. This is against ncpfs 2.0.11, but works the same
for ncpfs 2.0.10.
Apply the patches by cd'ing into the appropriate source directory (e.g
/usr/local/src/ncpfs-2.0.11) and do:
patch < patch-file
You can disable NDS support after applying the patch by uncommenting
the line NDS_SUPPORT = 1 in the main Makefile from ncpfs.
If you have comments or suggestinons about this patch please mail them
to me.
Arne de Bruijn
arne@knoware.nl

View File

@@ -4,10 +4,11 @@ and do:
patch -p1 < patch-file
lockup-2.0.28.diff:
An *extremely* dirty fix to the lockup bug mentioned in the BUGS
file. Please only apply it if you experience the problem. Should apply
to 2.0.28 and above in the 2.0.x series. NOT TESTED with 2.1.x.
lockup-2.0.30.diff:
Please apply this patch to your 2.0.30 kernel to get rid of the ncpfs
lockups. See ../BUGS for the symptoms.
linux-2.1.26.diff:
Development version of ncpfs
Patches for other kernels to support new features must be downloaded
separately because of kernel changes have no relations to ncpfs changes.
Kernel patches should be available on same place as this package or
at ftp://platan.vc.cvut.cz/pub/linux/ncpfs/latest.

View File

@@ -1,35 +0,0 @@
--- 2.1.26/fs/ncpfs/sock.c Sun Jan 26 11:07:44 1997
+++ 2.1.26-patched/fs/ncpfs/sock.c Sun Feb 16 17:05:13 1997
@@ -24,6 +24,7 @@
#include <linux/ncp.h>
#include <linux/ncp_fs.h>
#include <linux/ncp_fs_sb.h>
+#include <linux/poll.h>
#include <net/sock.h>
@@ -343,7 +344,6 @@
char *start = server->packet;
poll_table wait_table;
struct poll_table_entry entry;
- int (*select) (struct inode *, poll_table *);
int init_timeout, max_timeout;
int timeout;
int retrans;
@@ -362,7 +362,6 @@
file = server->ncp_filp;
inode = file->f_inode;
- select = file->f_op->poll;
sock = &inode->u.socket_i;
if (!sock)
{
@@ -418,7 +417,7 @@
wait_table.nr = 0;
wait_table.entry = &entry;
current->state = TASK_INTERRUPTIBLE;
- if (!select(inode, &wait_table))
+ if (!(file->f_op->poll(file, &wait_table) & POLLIN))
{
if (timeout > max_timeout)
{

File diff suppressed because it is too large Load Diff

View File

@@ -1,44 +0,0 @@
diff -urN 2.0.11/fs/ncpfs/sock.c linux/fs/ncpfs/sock.c
--- 2.0.28/fs/ncpfs/sock.c Fri Jul 12 08:14:53 1996
+++ linux/fs/ncpfs/sock.c Thu Aug 8 19:27:26 1996
@@ -55,7 +55,8 @@
{
struct iovec iov;
struct msghdr msg;
-
+ int result;
+
iov.iov_base = (void *)buff;
iov.iov_len = len;
@@ -65,7 +66,29 @@
msg.msg_iov = &iov;
msg.msg_iovlen = 1;
- return sock->ops->sendmsg(sock, &msg, len, nonblock, flags);
+ result = sock->ops->sendmsg(sock, &msg, len, 1, flags);
+
+ if ((result != -EAGAIN) || (nonblock != 0))
+ {
+ return result;
+ }
+
+ /* The following is probably one of the worst sins you can do
+ to a multitasking kernel: active polling. But when you call
+ ipx_sendmsg with nonblock==0, then it will block forever
+ from time to time. I really do not know why. To work around
+ this, I try to send the packet with nonblock=1 and retry
+ it. */
+
+ do {
+ /* Before retrying, give others a chance */
+ current->state = TASK_INTERRUPTIBLE;
+ current->timeout = jiffies + HZ/10;
+ schedule();
+ result = sock->ops->sendmsg(sock, &msg, len, 1, flags);
+ } while (result == -EAGAIN);
+
+ return result;
}

View File

@@ -0,0 +1,12 @@
diff -u -urN 2.0.30/net/ipx/af_ipx.c 2.0.30-patched/net/ipx/af_ipx.c
--- 2.0.30/net/ipx/af_ipx.c Wed Nov 27 08:44:21 1996
+++ 2.0.30-patched/net/ipx/af_ipx.c Mon Jul 14 17:25:12 1997
@@ -1723,6 +1723,7 @@
}
sk->rcvbuf=SK_RMEM_MAX;
sk->sndbuf=SK_WMEM_MAX;
+ sk->allocation=GFP_KERNEL;
sk->prot=NULL; /* So we use default free mechanisms */
skb_queue_head_init(&sk->receive_queue);
skb_queue_head_init(&sk->write_queue);

View File

@@ -2,9 +2,17 @@
# Makefile for the linux ncp-filesystem routines.
#
UTILS = ncpmount ncpumount nwsfind
include ../Makeinit
CC = gcc
ifdef MOUNT3
# environ in ncpmount
CCFLAGS += -D_GNU_SOURCE
endif
O_UTILS = ncpmount.o ncpumount.o nwsfind.o
UTILS = $(O_UTILS:%.o=%)
CCFLAGS += -D__MAKE_SULIB__
default:
make -C ..
@@ -15,20 +23,20 @@ install: all
for i in $(UTILS); \
do install $$i -m 4755 $(BINDIR); done
$(UTILS): %: %.o libncp.a
$(CC) -o $@ $(addsuffix .o,$@) -L. -lncp -L../lib -lcom_err
$(O_UTILS): %.o: %.c ../lib-static-su/ncplib_err.h
$(CC) $(CFLAGS) $(CCFLAGS) -I../lib-static-su -o $@ -c $<
ncplib.o: ncplib.c ncplib.h
$(CC) $(CFLAGS) -finline-functions -c ncplib.c
$(UTILS): %: %.o ../lib-static-su/libncp.a
$(CC) -o $@ $(addsuffix .o,$@) -L../lib-static-su -lncp
libncp.a: ncplib.o ../lib/ncplib_err.o
ar r libncp.a ncplib.o ../lib/ncplib_err.o
../lib-static-su/libncp.a ../lib-static-su/ncplib_err.h:
make -C ../lib-static-su libncp.a
dep:
$(CPP) -M $(INCLUDES) *.c > .depend
clean:
rm -f *.o *~ libncp.a $(UTILS)
rm -f *.o *~ $(UTILS)
mrproper: clean
rm -f .depend

View File

@@ -1,93 +0,0 @@
/*
* ipxlib.h
*
* Copyright (C) 1995 by Volker Lendecke
*
*/
#ifndef _IPXLIB_H
#define _IPXLIB_H
#include <linux/types.h>
#include <linux/ncp.h>
#include <linux/ncp_fs.h>
#include <linux/ipx.h>
#include <stdio.h>
typedef unsigned long IPXNet;
typedef unsigned short IPXPort;
typedef unsigned char IPXNode[IPX_NODE_LEN];
#define IPX_USER_PTYPE (0x00)
#define IPX_RIP_PTYPE (0x01)
#define IPX_SAP_PTYPE (0x04)
#define IPX_AUTO_PORT (0x0000)
#define IPX_SAP_PORT (0x0452)
#define IPX_RIP_PORT (0x0453)
#define IPX_SAP_GENERAL_QUERY (0x0001)
#define IPX_SAP_GENERAL_RESPONSE (0x0002)
#define IPX_SAP_NEAREST_QUERY (0x0003)
#define IPX_SAP_NEAREST_RESPONSE (0x0004)
#define IPX_SAP_FILE_SERVER (0x0004)
struct sap_query {
unsigned short query_type; /* net order */
unsigned short server_type; /* net order */
};
struct sap_server_ident {
unsigned short server_type __attribute__((packed));
char server_name[48] __attribute__((packed));
IPXNet server_network __attribute__((packed));
IPXNode server_node __attribute__((packed));
IPXPort server_port __attribute__((packed));
unsigned short intermediate_network __attribute__((packed));
};
#define IPX_RIP_REQUEST (0x1)
#define IPX_RIP_RESPONSE (0x2)
struct ipx_rip_packet {
__u16 operation __attribute__((packed));
struct ipx_rt_def {
__u32 network __attribute__((packed));
__u16 hops __attribute__((packed));
__u16 ticks __attribute__((packed));
} rt[1] __attribute__((packed));
};
#define IPX_BROADCAST_NODE ("\xff\xff\xff\xff\xff\xff")
#define IPX_THIS_NODE ("\0\0\0\0\0\0")
#define IPX_THIS_NET (0)
#ifndef IPX_NODE_LEN
#define IPX_NODE_LEN (6)
#endif
void
ipx_print_node(IPXNode node);
void
ipx_print_network(IPXNet net);
void
ipx_print_port(IPXPort port);
void
ipx_print_saddr(struct sockaddr_ipx *sipx);
void
ipx_fprint_node(FILE * file, IPXNode node);
void
ipx_fprint_network(FILE * file, IPXNet net);
void
ipx_fprint_port(FILE * file, IPXPort port);
void
ipx_fprint_saddr(FILE * file, struct sockaddr_ipx *sipx);
int
ipx_sscanf_node(char *buf, unsigned char node[IPX_NODE_LEN]);
void
ipx_assign_node(IPXNode dest, IPXNode src);
int
ipx_node_equal(IPXNode n1, IPXNode n2);
#endif /* _IPXLIB_H */

File diff suppressed because it is too large Load Diff

View File

@@ -1,280 +0,0 @@
/*
* ncplib.h
*
* Copyright (C) 1995, 1996 by Volker Lendecke
*
*/
#ifndef _NCPLIB_H
#define _NCPLIB_H
#include <linux/types.h>
#include "ncp.h"
#include <linux/ncp_fs.h>
#include <sys/param.h>
#include <stdio.h>
#include <time.h>
#include "ipxlib.h"
#include "com_err.h"
#ifndef memzero
#include <string.h>
#define memzero(object) memset(&(object), 0, sizeof(object))
#endif
typedef __u8 byte;
typedef __u16 word;
typedef __u32 dword;
#define BVAL(buf,pos) (((__u8 *)(buf))[pos])
#define PVAL(buf,pos) ((unsigned)BVAL(buf,pos))
#define BSET(buf,pos,val) (BVAL(buf,pos) = (val))
static inline word
WVAL_HL(__u8 * buf, int pos)
{
return PVAL(buf, pos) << 8 | PVAL(buf, pos + 1);
}
static inline dword
DVAL_HL(__u8 * buf, int pos)
{
return WVAL_HL(buf, pos) << 16 | WVAL_HL(buf, pos + 2);
}
static inline void WSET_HL(__u8 * buf, int pos, word val)
{
BSET(buf, pos, val >> 8);
BSET(buf, pos + 1, val & 0xff);
}
static inline void DSET_HL(__u8 * buf, int pos, dword val)
{
WSET_HL(buf, pos, val >> 16);
WSET_HL(buf, pos + 2, val & 0xffff);
}
/* we know that the 386 can handle misalignment and has the "right"
byteorder */
#if defined(__i386__)
static inline word
WVAL_LH(__u8 * buf, int pos)
{
return *((word *) (buf + pos));
}
static inline dword
DVAL_LH(__u8 * buf, int pos)
{
return *((dword *) (buf + pos));
}
static inline void WSET_LH(__u8 * buf, int pos, word val)
{
*((word *) (buf + pos)) = val;
}
static inline void DSET_LH(__u8 * buf, int pos, dword val)
{
*((dword *) (buf + pos)) = val;
}
#else
static inline word
WVAL_LH(__u8 * buf, int pos)
{
return PVAL(buf, pos) | PVAL(buf, pos + 1) << 8;
}
static inline dword
DVAL_LH(__u8 * buf, int pos)
{
return WVAL_LH(buf, pos) | WVAL_LH(buf, pos + 2) << 16;
}
static inline void WSET_LH(__u8 * buf, int pos, word val)
{
BSET(buf, pos, val & 0xff);
BSET(buf, pos + 1, val >> 8);
}
static inline void DSET_LH(__u8 * buf, int pos, dword val)
{
WSET_LH(buf, pos, val & 0xffff);
WSET_LH(buf, pos + 2, val >> 16);
}
#endif
void
str_upper(char *name);
enum connect_state {
NOT_CONNECTED = 0,
CONN_PERMANENT,
CONN_TEMPORARY
};
struct ncp_conn {
enum connect_state is_connected;
char server[NCP_BINDERY_NAME_LEN];
char user[NCP_BINDERY_NAME_LEN];
struct ncp_fs_info i;
/* Fields for use with permanent connections */
int mount_fid;
char mount_point[MAXPATHLEN];
/* Fields for use with temporary connections */
int ncp_sock;
int wdog_sock;
int wdog_pid;
__u8 sequence;
int completion;
int conn_status;
int reply_size;
/* Fields used to setup ncp requests */
int current_size;
int has_subfunction;
int verbose;
int ncp_reply_size;
int lock;
char packet[NCP_PACKET_SIZE];
};
struct ncp_conn_spec {
char server[NCP_BINDERY_NAME_LEN];
char user[NCP_BINDERY_NAME_LEN];
uid_t uid;
int login_type; /* NCP_BINDERY_USER / NCP_BINDERY_PSERVER */
char password[NCP_BINDERY_NAME_LEN];
};
struct ncp_property_info {
__u8 property_name[16];
__u8 property_flags;
__u8 property_security;
__u32 search_instance;
__u8 value_available_flag;
__u8 more_properties_flag;
};
/* ncp_initialize is the main entry point for user programs which want
to connect to a NetWare Server. It looks for -S, -U, -P and -n in
the argument list, opens the connection and removes the arguments
from the list. It was designed after the X Windows init
functions. */
struct ncp_conn *
ncp_initialize(int *argc, char **argv,
int login_necessary, long *err);
/* You can login as another object by this procedure. As a first use
pserver comes to mind. */
struct ncp_conn *
ncp_initialize_as(int *argc, char **argv,
int login_necessary, int login_type, long *err);
/* Open a connection */
struct ncp_conn *
ncp_open(struct ncp_conn_spec *spec, long *err);
/* Open a connection on an existing mount point */
struct ncp_conn *
ncp_open_mount(const char *mount_point, long *err);
/* Find a permanent connection that fits the spec, return NULL if
* there is none. */
char *
ncp_find_permanent(const struct ncp_conn_spec *spec);
/* Find the address of a file server */
struct sockaddr_ipx *
ncp_find_fileserver(char *server_name, long *err);
/* Find the address of a server */
struct sockaddr_ipx *
ncp_find_server(char **server_name, int type, long *err);
/* Detach from a permanent connection or destroy a temporary
connection */
long
ncp_close(struct ncp_conn *conn);
/* like getmntent, get_ncp_conn_ent scans /etc/mtab for usable
connections */
struct ncp_conn_ent {
char server[NCP_BINDERY_NAME_LEN];
char user[NCP_BINDERY_NAME_LEN];
uid_t uid;
char mount_point[MAXPATHLEN];
};
struct ncp_conn_ent *
ncp_get_conn_ent(FILE * filep);
#define NWCLIENT (".nwclient")
#define NWC_NOPASSWORD ("-")
/* find an appropriate connection */
struct ncp_conn_spec *
ncp_find_conn_spec(const char *server, const char *user, const char *password,
int login_necessary, uid_t uid, long *err);
long
ncp_get_encryption_key(struct ncp_conn *conn,
char *target);
struct ncp_station_addr {
__u32 NetWork __attribute__((packed));
__u8 Node[6] __attribute__((packed));
__u16 Socket __attribute__((packed));
};
struct ncp_prop_login_control {
__u8 AccountExpireDate[3] __attribute__((packed));
__u8 Disabled __attribute__((packed));
__u8 PasswordExpireDate[3] __attribute__((packed));
__u8 GraceLogins __attribute__((packed));
__u16 PasswordExpireInterval __attribute__((packed));
__u8 MaxGraceLogins __attribute__((packed));
__u8 MinPasswordLength __attribute__((packed));
__u16 MaxConnections __attribute__((packed));
__u8 ConnectionTimeMask[42] __attribute__((packed));
__u8 LastLogin[6] __attribute__((packed));
__u8 RestrictionMask __attribute__((packed));
__u8 reserved __attribute__((packed));
__u32 MaxDiskUsage __attribute__((packed));
__u16 BadLoginCount __attribute__((packed));
__u32 BadLoginCountDown __attribute__((packed));
struct ncp_station_addr LastIntruder __attribute__((packed));
};
long
ncp_read_property_value(struct ncp_conn *conn,
int object_type, const char *object_name,
int segment, const char *prop_name,
struct nw_property *target);
#define NCP_GRACE_PERIOD (0xdf)
long
ncp_get_bindery_object_id(struct ncp_conn *conn,
__u16 object_type,
const char *object_name,
struct ncp_bindery_object *target);
long
ncp_login_user(struct ncp_conn *conn,
const unsigned char *username,
const unsigned char *password);
long
ncp_get_broadcast_message(struct ncp_conn *conn, char message[256]);
#endif /* _NCPLIB_H */

File diff suppressed because it is too large Load Diff

76
sutil/ncpmount.h Normal file
View File

@@ -0,0 +1,76 @@
/*
* ncp_mount.h
*
* Copyright (C) 1995, 1996 by Volker Lendecke
*
*/
#ifndef __NCPMOUNT_H__
#define __NCPMOUNT_H__
#include "ncp.h"
#define NCP_MOUNT_VERSION_V2 2
/* Values for flags */
#define NCP_MOUNT2_SOFT 0x0001
#define NCP_MOUNT2_INTR 0x0002
#define NCP_MOUNT2_STRONG 0x0004
#define NCP_MOUNT2_NO_OS2 0x0008
#define NCP_MOUNT2_NO_NFS 0x0010
#define PATH_MAX_V20 1024 /* PATH_MAX for 2.0 kernel */
struct ncp_mount_data_v2 {
int version;
unsigned int ncp_fd; /* The socket to the ncp port */
unsigned int wdog_fd; /* Watchdog packets come here */
unsigned int message_fd; /* Message notifications come here */
__ker20_uid_t mounted_uid; /* Who may umount() this filesystem? */
struct sockaddr_ipx serv_addr;
unsigned char server_name[NCP_BINDERY_NAME_LEN];
unsigned char mount_point[PATH_MAX_V20+1];
unsigned char mounted_vol[NCP_VOLNAME_LEN+1];
unsigned int time_out; /* How long should I wait after
sending a NCP request? */
unsigned int retry_count; /* And how often should I retry? */
unsigned int flags;
__ker20_uid_t uid;
__ker20_gid_t gid;
__ker20_mode_t file_mode;
__ker20_mode_t dir_mode;
};
#define NCP_MOUNT_VERSION_V3 3
/* Values for flags */
#define NCP_MOUNT3_SOFT 0x0001
#define NCP_MOUNT3_INTR 0x0002
#define NCP_MOUNT3_STRONG 0x0004
#define NCP_MOUNT3_NO_OS2 0x0008
#define NCP_MOUNT3_NO_NFS 0x0010
struct ncp_mount_data_v3 {
int version;
unsigned int ncp_fd; /* The socket to the ncp port */
__ker21_uid_t mounted_uid; /* Who may umount() this filesystem? */
__ker21_pid_t wdog_pid; /* Who cares for our watchdog packets? */
unsigned char mounted_vol[NCP_VOLNAME_LEN + 1];
unsigned int time_out; /* How long should I wait after
sending a NCP request? */
unsigned int retry_count; /* And how often should I retry? */
unsigned int flags;
__ker21_uid_t uid;
__ker21_gid_t gid;
__ker21_mode_t file_mode;
__ker21_mode_t dir_mode;
};
#endif /* __NCPMOUNT_H__ */

View File

@@ -16,7 +16,7 @@
#include <netdb.h>
#include <sys/stat.h>
#include <sys/types.h>
/* #include <sys/wait.h> *//* generates a warning here */
/* #include <sys/wait.h> */ /* generates a warning here */
extern pid_t waitpid(pid_t, int *, int);
#include <sys/errno.h>
#include <unistd.h>
@@ -27,36 +27,37 @@ extern pid_t waitpid(pid_t, int *, int);
#include <sys/mount.h>
#include <mntent.h>
#include <sys/ioctl.h>
#include <linux/fs.h>
#include <linux/ncp.h>
#include <linux/ncp_mount.h>
#include <linux/ncp_fs.h>
#include "ncplib.h"
static char *progname;
static void usage(void)
static void
usage(void)
{
printf("usage: %s mount-point\n", progname);
}
static int umount_ok(const char *mount_point)
static int
umount_ok(const char *mount_point)
{
int fid = open(mount_point, O_RDONLY, 0);
uid_t mount_uid;
if (fid == -1) {
if (fid == -1)
{
fprintf(stderr, "Could not open %s: %s\n",
mount_point, strerror(errno));
return -1;
}
if (ioctl(fid, NCP_IOC_GETMOUNTUID, &mount_uid) != 0) {
if (ncp_get_mount_uid(fid, &mount_uid) != 0)
{
fprintf(stderr, "%s probably not ncp-filesystem\n",
mount_point);
return -1;
}
if ((getuid() != 0)
&& (mount_uid != getuid())) {
&& (mount_uid != getuid()))
{
fprintf(stderr, "You are not allowed to umount %s\n",
mount_point);
return -1;
@@ -71,7 +72,7 @@ static int umount_ok(const char *mount_point)
is not a legal pathname for ``/dev/fd0.'' Anything we cannot parse
we return unmodified. */
char *
canonicalize(const char *path)
canonicalize(const char *path)
{
char *canonical = malloc(PATH_MAX + 1);
@@ -81,7 +82,8 @@ char *
if (realpath(path, canonical))
return canonical;
if (strlen(path) > PATH_MAX) {
if (strlen(path) > PATH_MAX)
{
return NULL;
}
strcpy(canonical, path);
@@ -89,7 +91,8 @@ char *
}
int main(int argc, char *argv[])
int
main(int argc, char *argv[])
{
int fd;
@@ -101,70 +104,83 @@ int main(int argc, char *argv[])
progname = argv[0];
if (geteuid() != 0) {
if (geteuid() != 0)
{
fprintf(stderr, "%s must be installed suid root\n", progname);
exit(1);
}
if (argc != 2) {
if (argc != 2)
{
usage();
exit(1);
}
mount_point = canonicalize(argv[1]);
if (mount_point == NULL) {
if (mount_point == NULL)
{
fprintf(stderr, "Invalid mount point: %s\n", argv[1]);
exit(1);
}
if (umount_ok(mount_point) != 0) {
if (umount_ok(mount_point) != 0)
{
fprintf(stderr, "You are not allowed to umount %s\n",
mount_point);
exit(1);
}
if (umount(mount_point) != 0) {
if (umount(mount_point) != 0)
{
fprintf(stderr, "Could not umount %s: %s\n",
mount_point, strerror(errno));
exit(1);
}
if ((fd = open(MOUNTED "~", O_RDWR | O_CREAT | O_EXCL, 0600)) == -1) {
if ((fd = open(MOUNTED "~", O_RDWR | O_CREAT | O_EXCL, 0600)) == -1)
{
fprintf(stderr, "Can't get " MOUNTED "~ lock file");
return 1;
}
close(fd);
if ((mtab = setmntent(MOUNTED, "r")) == NULL) {
if ((mtab = setmntent(MOUNTED, "r")) == NULL)
{
fprintf(stderr, "Can't open " MOUNTED ": %s\n",
strerror(errno));
return 1;
}
#define MOUNTED_TMP MOUNTED".tmp"
if ((new_mtab = setmntent(MOUNTED_TMP, "w")) == NULL) {
if ((new_mtab = setmntent(MOUNTED_TMP, "w")) == NULL)
{
fprintf(stderr, "Can't open " MOUNTED_TMP ": %s\n",
strerror(errno));
endmntent(mtab);
return 1;
}
while ((mnt = getmntent(mtab)) != NULL) {
if (strcmp(mnt->mnt_dir, mount_point) != 0) {
while ((mnt = getmntent(mtab)) != NULL)
{
if (strcmp(mnt->mnt_dir, mount_point) != 0)
{
addmntent(new_mtab, mnt);
}
}
endmntent(mtab);
if (fchmod(fileno(new_mtab), S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH) < 0) {
if (fchmod(fileno(new_mtab), S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH) < 0)
{
fprintf(stderr, "Error changing mode of %s: %s\n",
MOUNTED_TMP, strerror(errno));
exit(1);
}
endmntent(new_mtab);
if (rename(MOUNTED_TMP, MOUNTED) < 0) {
if (rename(MOUNTED_TMP, MOUNTED) < 0)
{
fprintf(stderr, "Cannot rename %s to %s: %s\n",
MOUNTED, MOUNTED_TMP, strerror(errno));
exit(1);
}
if (unlink(MOUNTED "~") == -1) {
if (unlink(MOUNTED "~") == -1)
{
fprintf(stderr, "Can't remove " MOUNTED "~");
return 1;
}

View File

@@ -1,198 +0,0 @@
/*$*********************************************************
$*
$* 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.
$*
$********************************************************* */
/****************************************************************************
I read that Novell is not very open when it comes to technical details
of the Netware Core Protocol. This might be especially true for the
encryption stuff. I took the necessary code from Dr. Dobb's Journal
11/93, Undocumented Corner. I asked Jon Erickson <jon@ddj.com> about
the legal status of this piece of code:
---
Date: Thu, 12 Oct 1995 13:44:18 +0100
From: Volker Lendecke <lendecke>
To: jon@ddj.com
Subject: legal status of your source code?
Hello!
I hope that you're the right one to write to, you are the first on your WWW
server. If you are not, could you please forward this message to the right
person? Thanks.
I'm currently exploring the possibility to write a free (in the GNU GPL
sense) NCP filesystem, which would allow me to access a novell server
transparently. For that I would like to use the encryption functions you
published in DDJ 11/93, Undocumented Corner. I would make some cosmetic
changes, such as other indentations, minor code changes and so on. But I do
not know if that allows me to publish this code under GPL. One alternative
would be to publish a diff against your listing, but that would probably
contain much of your code as well, and it would be very inconvenient for
the average user.
I think that you have some kind of standard procedure for such a
case. Please tell me what I should do.
Many thanks in advance,
Volker
+=================================================================+
! Volker Lendecke Internet: lendecke@namu01.gwdg.de !
! D-37081 Goettingen, Germany !
+=================================================================+
--
I got the following answer:
---
From: Jon Erickson <jon@ddj.com>
X-Mailer: SCO System V Mail (version 3.2)
To: lendecke@namu01.gwdg.de
Subject: Re: legal status of your source code?
Date: Thu, 12 Oct 95 5:42:56 PDT
Volker,
Code from Dr. Dobb's Journal related articles is provided for
anyone to use. Clearly, the author of the article should be
given credit.
Jon Erickson
---
With this answer in mind, I took the code and made it a bit more
C-like. The original seemed to be translated by a mechanical pascal->c
translator. Jon's answer encouraged me to publish nwcrypt.c under the
GPL. If anybody who knows more about copyright and sees any problems
with this, please tell me.
****************************************************************************/
/******************* Data types ***************************/
typedef unsigned char buf32[32];
typedef unsigned char buf16[16];
typedef unsigned char buf8[8];
typedef unsigned char buf4[4];
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};
static void shuffle1(buf32 temp, unsigned char *target)
{
short b4;
unsigned char b3;
int s, b2, i;
b4 = 0;
for (b2 = 0; b2 <= 1; ++b2) {
for (s = 0; s <= 31; ++s) {
b3 = (temp[s] + b4) ^ (temp[(s + b4) & 31] - encryptkeys[s]);
b4 = b4 + b3;
temp[s] = b3;
}
}
for (i = 0; i <= 15; ++i) {
target[i] = encrypttable[temp[2 * i]]
| (encrypttable[temp[2 * i + 1]] << 4);
}
}
static void shuffle(const unsigned char *lon, const unsigned char *buf, int buflen,
unsigned char *target)
{
int b2, d, s;
buf32 temp;
while ((buflen > 0)
&& (buf[buflen - 1] == 0)) {
buflen = buflen - 1;
}
for (s = 0; s < 32; s++) {
temp[s] = 0;
}
d = 0;
while (buflen >= 32) {
for (s = 0; s <= 31; ++s) {
temp[s] = temp[s] ^ buf[d];
d = d + 1;
}
buflen = buflen - 32;
}
b2 = d;
if (buflen > 0) {
for (s = 0; s <= 31; ++s) {
if (d + buflen == b2) {
b2 = d;
temp[s] = temp[s] ^ encryptkeys[s];
} else {
temp[s] = temp[s] ^ buf[b2];
b2 = b2 + 1;
}
}
}
for (s = 0; s <= 31; ++s)
temp[s] = temp[s] ^ lon[s & 3];
shuffle1(temp, target);
}
static void nw_encrypt(const unsigned char *fra,
const unsigned char *buf,
unsigned char *til)
{
buf32 k;
int s;
shuffle(&(fra[0]), buf, 16, &(k[0]));
shuffle(&(fra[4]), buf, 16, &(k[16]));
for (s = 0; s <= 15; ++s)
k[s] = k[s] ^ k[31 - s];
for (s = 0; s <= 7; ++s)
til[s] = k[s] ^ k[15 - s];
}

View File

@@ -13,25 +13,30 @@
#include <unistd.h>
#include <stdlib.h>
#include <stdarg.h>
#include <errno.h>
static char *progname;
static void usage(void)
static void
usage(void)
{
fprintf(stderr, "usage: %s [server]\n", progname);
}
static void help(void)
static void
help(void)
{
printf("\n");
printf("usage: %s [server]\n", progname);
printf("\n"
"-t Server type, default: File server\n"
"-a server is in form <net>:<node>:<socket>\n"
"-h Print this help text\n"
"\n");
}
static void swallow_error(const char *name, long code, const char *format, va_list arg)
static void
swallow_error(const char *name, long code, const char *format, va_list arg)
{
printf("%s ", error_message(code));
vfprintf(stdout, format, arg);
@@ -39,12 +44,15 @@ static void swallow_error(const char *name, long code, const char *format, va_li
return;
}
int main(int argc, char *argv[])
int
main(int argc, char *argv[])
{
char *server = NULL;
const char *server = NULL;
int object_type = NCP_BINDERY_FSERVER;
struct sockaddr_ipx *result;
struct sockaddr_ipx addr;
struct ncp_conn *conn;
long err;
int is_address = 0;
int opt;
@@ -52,11 +60,16 @@ int main(int argc, char *argv[])
set_com_err_hook(swallow_error);
while ((opt = getopt(argc, argv, "t:")) != EOF) {
switch (opt) {
while ((opt = getopt(argc, argv, "at:")) != EOF)
{
switch (opt)
{
case 't':
object_type = atoi(optarg);
break;
case 'a':
is_address = 1;
break;
case 'h':
case '?':
help();
@@ -67,24 +80,47 @@ int main(int argc, char *argv[])
}
}
if (optind < argc - 1) {
if (optind < argc - 1)
{
usage();
exit(1);
}
if (optind == argc - 1) {
server = argv[optind];
if (strlen(server) >= NCP_BINDERY_NAME_LEN) {
com_err(argv[0], ENAMETOOLONG, "server name too long");
if (is_address)
{
if ((optind > argc - 1) ||
ipx_sscanf_saddr(argv[optind], &addr))
{
usage();
exit(1);
}
if ((!(conn = ncp_open_addr((struct sockaddr*)&addr, &err))) ||
(err = ncp_close(conn))) {;
}
else
{
server = argv[optind];
}
}
else
{
if (optind == argc - 1)
{
server = argv[optind];
if (strlen(server) >= NCP_BINDERY_NAME_LEN)
{
com_err(argv[0], ENAMETOOLONG, "server name too long");
exit(1);
}
}
err = ncp_find_server(&server, object_type, (struct sockaddr*)&addr, sizeof(addr));
}
result = ncp_find_server(&server, object_type, &err);
if (result == NULL) {
if (err != 0)
{
com_err(argv[0], err, "when trying to find server");
exit(1);
}
ipx_print_saddr(result);
ipx_print_saddr(&addr);
printf(" %s\n", server);
return 0;
}

View File

@@ -2,21 +2,30 @@
# Makefile for the linux ncp-filesystem routines.
#
USERUTILS = slist pqlist nwfsinfo pserver nprint nsend ncopy nwpasswd
USERUTILS += nwbols nwbocreate nwborm nwboprops
USERUTILS += nwbpcreate nwbprm nwbpvalues nwbpadd nwbpset
USERUTILS += nwgrant nwrevoke nwuserlist nwrights nwauth
USERUTILS += nwfstime nwvolinfo nwtrustee
include ../Makeinit
O_USERUTILS = slist.o pqlist.o nwfsinfo.o pserver.o nprint.o nsend.o \
ncopy.o nwpasswd.o nwbols.o nwbocreate.o nwborm.o nwboprops.o \
pqstat.o pqrm.o nwbpcreate.o nwbprm.o nwbpvalues.o nwbpadd.o \
nwbpset.o nwgrant.o nwrevoke.o nwuserlist.o nwrights.o nwauth.o \
nwfstime.o nwvolinfo.o nwtrustee.o nwpurge.o
ifdef MOUNT2
O_SBINUTILS = nwmsg.o
endif
USERUTILS = $(O_USERUTILS:%.o=%)
SBINUTILS = $(O_SBINUTILS:%.o=%)
UTILS = $(USERUTILS) $(SBINUTILS) ncptest
CC = gcc
ifeq ($(HAVE_ELF),yes)
NCP_LIB = libncp.so.1.0
NCP_LIB = libncp.so
NCPLIB_DIR = ../lib-shared
LIBDEP = $(NCPLIB_DIR)/$(NCP_LIB)
else
NCP_LIB = libncp.a
LIBDEP = ../lib/libncp.a
NCPLIB_DIR = ../lib-static
LIBDEP = $(NCPLIB_DIR)/$(NCP_LIB)
endif
default:
@@ -30,11 +39,20 @@ install: all
for i in $(SBINUTILS); \
do install $$i -m 755 $(SBINDIR); done
../lib-static/libncp.a:
make -C ../lib-static libncp.a
../lib-shared/libncp.so:
make -C ../lib-shared libncp.so
$(O_USERUTILS) $(O_SBINUTILS) ncptest.o: %.o: %.c
$(CC) $(CFLAGS) $(CCFLAGS) -o $@ -c $<
$(UTILS): %: %.o $(LIBDEP)
$(CC) -o $@ $(addsuffix .o,$@) -L../lib -lncp
$(CC) $(CFLAGS) -o $@ $(addsuffix .o,$@) -L$(NCPLIB_DIR) -lncp
ipx_probe: ipx_probe.c
$(CC) $(CFLAGS) -o ipx_probe ipx_probe.c
$(CC) $(CFLAGS) $(CCFLAGS) -o ipx_probe ipx_probe.c
dep:
$(CPP) -M $(INCLUDES) *.c > .depend

Binary file not shown.

View File

@@ -22,23 +22,25 @@
static char *progname;
int verbose = 0;
static void usage()
static void
usage ()
{
fprintf(stderr, "usage: %s [options]\n", progname);
fprintf(stderr, "type '%s -h' for help\n", progname);
fprintf (stderr, "usage: %s [options]\n", progname);
fprintf (stderr, "type '%s -h' for help\n", progname);
}
static void help()
static void
help ()
{
printf("\n"
"Probe an interface for ipx networks\n"
"\n");
printf("usage: %s [options]\n", progname);
printf("\n"
"-v Verbose output\n"
"-i interface Interface to probe, default: eth0\n"
"-t timeout Seconds to wait for answer, default: 3\n"
"-h Print this help text\n\n");
printf ("\n"
"Probe an interface for ipx networks\n"
"\n");
printf ("usage: %s [options]\n", progname);
printf ("\n"
"-v Verbose output\n"
"-i interface Interface to probe, default: eth0\n"
"-t timeout Seconds to wait for answer, default: 3\n"
"-h Print this help text\n\n");
}
#define IPX_SAP_PTYPE (0x04)
@@ -48,360 +50,407 @@ static void help()
#define BVAL(buf,pos) (((__u8 *)(buf))[pos])
#define BSET(buf,pos,val) (BVAL(buf,pos) = (val))
static inline void WSET_HL(__u8 * buf, int pos, __u16 val)
static inline void
WSET_HL (__u8 * buf, int pos, __u16 val)
{
BSET(buf, pos, val >> 8);
BSET(buf, pos + 1, val & 0xff);
BSET (buf, pos, val >> 8);
BSET (buf, pos + 1, val & 0xff);
}
struct frame_type {
char *ft_name;
unsigned char ft_val;
struct frame_type
{
char *ft_name;
unsigned char ft_val;
};
static struct frame_type frame_types[] =
{
{
"802.2", IPX_FRAME_8022
}
,
{
"802.2", IPX_FRAME_8022
}
,
#ifdef IPX_FRAME_TR_8022
{
"802.2TR", IPX_FRAME_TR_8022
}
,
{
"802.2TR", IPX_FRAME_TR_8022
}
,
#endif
{
"802.3", IPX_FRAME_8023
}
,
{
"SNAP", IPX_FRAME_SNAP
}
,
{
"EtherII", IPX_FRAME_ETHERII
}
{
"802.3", IPX_FRAME_8023
}
,
{
"SNAP", IPX_FRAME_SNAP
}
,
{
"EtherII", IPX_FRAME_ETHERII
}
};
#define NFTYPES (sizeof(frame_types)/sizeof(struct frame_type))
static char *
frame_name(int frame_type)
frame_name (int frame_type)
{
int i;
for (i = 0; i < NFTYPES; i++) {
if (frame_types[i].ft_val == frame_type) {
return frame_types[i].ft_name;
}
int i;
for (i = 0; i < NFTYPES; i++)
{
if (frame_types[i].ft_val == frame_type)
{
return frame_types[i].ft_name;
}
return NULL;
}
return NULL;
}
static int ipx_recvfrom(int sock, void *buf, int len, unsigned int flags,
struct sockaddr_ipx *sender, int *addrlen, int timeout,
long *err)
static int
ipx_recvfrom (int sock, void *buf, int len, unsigned int flags,
struct sockaddr_ipx *sender, int *addrlen, int timeout,
long *err)
{
fd_set rd, wr, ex;
struct timeval tv;
int result;
fd_set rd, wr, ex;
struct timeval tv;
int result;
FD_ZERO(&rd);
FD_ZERO(&wr);
FD_ZERO(&ex);
FD_SET(sock, &rd);
FD_ZERO (&rd);
FD_ZERO (&wr);
FD_ZERO (&ex);
FD_SET (sock, &rd);
tv.tv_sec = timeout;
tv.tv_usec = 0;
tv.tv_sec = timeout;
tv.tv_usec = 0;
if ((result = select(sock + 1, &rd, &wr, &ex, &tv)) == -1) {
*err = errno;
return -1;
}
if (FD_ISSET(sock, &rd)) {
result = recvfrom(sock, buf, len, flags,
(struct sockaddr *) sender, addrlen);
} else {
result = -1;
errno = ETIMEDOUT;
}
if (result < 0) {
*err = errno;
}
return result;
if ((result = select (sock + 1, &rd, &wr, &ex, &tv)) == -1)
{
*err = errno;
return -1;
}
if (FD_ISSET (sock, &rd))
{
result = recvfrom (sock, buf, len, flags,
(struct sockaddr *) sender, addrlen);
}
else
{
result = -1;
errno = ETIMEDOUT;
}
if (result < 0)
{
*err = errno;
}
return result;
}
static int ipx_recv(int sock, void *buf, int len, unsigned int flags, int timeout,
long *err)
static int
ipx_recv (int sock, void *buf, int len, unsigned int flags, int timeout,
long *err)
{
struct sockaddr_ipx sender;
int addrlen = sizeof(sender);
struct sockaddr_ipx sender;
int addrlen = sizeof (sender);
return ipx_recvfrom(sock, buf, len, flags, &sender, &addrlen,
timeout, err);
return ipx_recvfrom (sock, buf, len, flags, &sender, &addrlen,
timeout, err);
}
static int probe_frame(char *interface, int frame_type, int timeout, unsigned long *net)
static int
probe_frame (char *interface, int frame_type, int timeout, unsigned long *net)
{
int i, sock, opt;
int result;
long err;
char errmsg[strlen(progname) + 20];
char data[1024];
int i, sock, opt;
int result;
long err;
char errmsg[strlen (progname) + 20];
char data[1024];
static struct ifreq id;
struct sockaddr_ipx *sipx = (struct sockaddr_ipx *) &id.ifr_addr;
static struct ifreq id;
struct sockaddr_ipx *sipx = (struct sockaddr_ipx *) &id.ifr_addr;
if (verbose != 0) {
printf("probing %s on %s -- ", frame_name(frame_type),
interface);
fflush(stdout);
if (verbose != 0)
{
printf ("probing %s on %s -- ", frame_name (frame_type),
interface);
fflush (stdout);
}
sock = socket (AF_IPX, SOCK_DGRAM, AF_IPX);
if (sock < 0)
{
int old_errno = errno;
sprintf (errmsg, "%s: socket", progname);
perror (errmsg);
if (old_errno == -EINVAL)
{
fprintf (stderr, "Probably you have no IPX support in "
"your kernel\n");
}
sock = socket(AF_IPX, SOCK_DGRAM, AF_IPX);
if (sock < 0) {
int old_errno = errno;
close (sock);
return -1;
}
memset (&id, 0, sizeof (id));
strncpy (id.ifr_name, interface, sizeof (id.ifr_name) - 1);
sipx->sipx_family = AF_IPX;
sipx->sipx_action = IPX_CRTITF;
sipx->sipx_special = IPX_PRIMARY;
sipx->sipx_network = 0L;
sipx->sipx_type = frame_type;
sprintf(errmsg, "%s: socket", progname);
perror(errmsg);
if (old_errno == -EINVAL) {
fprintf(stderr, "Probably you have no IPX support in "
"your kernel\n");
}
close(sock);
return -1;
}
memset(&id, 0, sizeof(id));
strncpy(id.ifr_name, interface, sizeof(id.ifr_name) - 1);
sipx->sipx_family = AF_IPX;
sipx->sipx_action = IPX_CRTITF;
sipx->sipx_special = IPX_PRIMARY;
sipx->sipx_network = 0L;
sipx->sipx_type = frame_type;
i = 0;
do
{
result = ioctl (sock, SIOCSIFADDR, &id);
i++;
}
while ((i < 5) && (result < 0) && (errno == EAGAIN));
i = 0;
do {
result = ioctl(sock, SIOCSIFADDR, &id);
i++;
}
while ((i < 5) && (result < 0) && (errno == EAGAIN));
if (result < 0)
{
int old_errno = errno;
close (sock);
errno = old_errno;
return result;
}
/* We do a GNS request on the new socket. If something comes
back, we assume that the frame type is valid. */
if (result < 0) {
int old_errno = errno;
close(sock);
errno = old_errno;
return result;
}
/* We do a GNS request on the new socket. If something comes
back, we assume that the frame type is valid. */
opt = 1;
if ((result = setsockopt (sock, SOL_SOCKET,
SO_BROADCAST, &opt, sizeof (opt))) < 0)
{
int old_errno = errno;
close (sock);
errno = old_errno;
return result;
}
memset (&id, 0, sizeof (id));
sipx->sipx_family = AF_IPX;
sipx->sipx_network = htonl (0x0);
sipx->sipx_port = htons (0x0);
sipx->sipx_type = IPX_SAP_PTYPE;
opt = 1;
if ((result = setsockopt(sock, SOL_SOCKET,
SO_BROADCAST, &opt, sizeof(opt))) < 0) {
int old_errno = errno;
close(sock);
errno = old_errno;
return result;
}
memset(&id, 0, sizeof(id));
sipx->sipx_family = AF_IPX;
sipx->sipx_network = htonl(0x0);
sipx->sipx_port = htons(0x0);
sipx->sipx_type = IPX_SAP_PTYPE;
if ((result = bind (sock, (struct sockaddr *) sipx,
sizeof (*sipx))) < 0 - 1)
{
int old_errno = errno;
close (sock);
errno = old_errno;
return result;
}
WSET_HL (data, 0, IPX_SAP_NEAREST_QUERY);
WSET_HL (data, 2, 4);
if ((result = bind(sock, (struct sockaddr *) sipx,
sizeof(*sipx))) < 0 - 1) {
int old_errno = errno;
close(sock);
errno = old_errno;
return result;
}
WSET_HL(data, 0, IPX_SAP_NEAREST_QUERY);
WSET_HL(data, 2, 4);
memset (&id, 0, sizeof (id));
sipx->sipx_family = AF_IPX;
sipx->sipx_port = htons (IPX_SAP_PORT);
sipx->sipx_type = IPX_SAP_PTYPE;
sipx->sipx_network = htonl (0x0);
memcpy (sipx->sipx_node, IPX_BROADCAST_NODE, 6);
memset(&id, 0, sizeof(id));
sipx->sipx_family = AF_IPX;
sipx->sipx_port = htons(IPX_SAP_PORT);
sipx->sipx_type = IPX_SAP_PTYPE;
sipx->sipx_network = htonl(0x0);
memcpy(sipx->sipx_node, IPX_BROADCAST_NODE, 6);
if ((result = sendto (sock, data, 4, 0, (struct sockaddr *) sipx,
sizeof (*sipx))) < 0)
{
int old_errno = errno;
close (sock);
errno = old_errno;
return result;
}
result = ipx_recv (sock, data, 1024, 0, timeout, &err);
if ((result = sendto(sock, data, 4, 0, (struct sockaddr *) sipx,
sizeof(*sipx))) < 0) {
int old_errno = errno;
close(sock);
errno = old_errno;
return result;
}
result = ipx_recv(sock, data, 1024, 0, timeout, &err);
if (result > 0)
{
struct sockaddr_ipx sipx;
int namelen = sizeof (sipx);
if (result > 0) {
struct sockaddr_ipx sipx;
int namelen = sizeof(sipx);
if (getsockname (sock, (struct sockaddr *) &sipx,
&namelen) < 0)
{
fprintf (stderr, "%s: Could not find socket address\n",
progname);
exit (1);
}
*net = ntohl (sipx.sipx_network);
}
memset (&id, 0, sizeof (id));
strncpy (id.ifr_name, interface, sizeof (id.ifr_name) - 1);
sipx->sipx_family = AF_IPX;
sipx->sipx_action = IPX_DLTITF;
sipx->sipx_network = 0L;
sipx->sipx_type = frame_type;
result = ioctl (sock, SIOCSIFADDR, &id);
close (sock);
if (getsockname(sock, (struct sockaddr *) &sipx,
&namelen) < 0) {
fprintf(stderr, "%s: Could not find socket address\n",
progname);
exit(1);
}
*net = ntohl(sipx.sipx_network);
if (result < 0)
{
fprintf (stderr, "%s: could not delete interface\n",
progname);
exit (1);
}
if (err == ETIMEDOUT)
{
if (verbose != 0)
{
printf ("no network found\n");
}
memset(&id, 0, sizeof(id));
strncpy(id.ifr_name, interface, sizeof(id.ifr_name) - 1);
sipx->sipx_family = AF_IPX;
sipx->sipx_action = IPX_DLTITF;
sipx->sipx_network = 0L;
sipx->sipx_type = frame_type;
result = ioctl(sock, SIOCSIFADDR, &id);
close(sock);
if (result < 0) {
fprintf(stderr, "%s: could not delete interface\n",
progname);
exit(1);
}
if (err == ETIMEDOUT) {
if (verbose != 0) {
printf("no network found\n");
}
return -1;
}
if (verbose != 0) {
printf("found IPX network %8.8lX\n", *net);
}
return 0;
return -1;
}
if (verbose != 0)
{
printf ("found IPX network %8.8lX\n", *net);
}
return 0;
}
static int file_lines(char *name)
static int
file_lines (char *name)
{
FILE *f = fopen(name, "r");
char buf[100];
int lines = 0;
FILE *f = fopen (name, "r");
char buf[100];
int lines = 0;
if (f == NULL) {
return -errno;
}
while (fgets(buf, sizeof(buf), f) != NULL) {
lines += 1;
}
fclose(f);
return lines;
if (f == NULL)
{
return -errno;
}
while (fgets (buf, sizeof (buf), f) != NULL)
{
lines += 1;
}
fclose (f);
return lines;
}
static int ipx_interfaces(void)
static int
ipx_interfaces (void)
{
int result = file_lines("/proc/net/ipx_interface");
if (result == 0) {
result = -EIO;
}
return result - 1;
int result = file_lines ("/proc/net/ipx_interface");
if (result == 0)
{
result = -EIO;
}
return result - 1;
}
static int ipx_auto_off(void)
static int
ipx_auto_off (void)
{
int s;
char errmsg[strlen(progname) + 20];
int val = 0;
int s;
char errmsg[strlen (progname) + 20];
int val = 0;
s = socket(AF_IPX, SOCK_DGRAM, AF_IPX);
if (s < 0) {
int old_errno = errno;
s = socket (AF_IPX, SOCK_DGRAM, AF_IPX);
if (s < 0)
{
int old_errno = errno;
sprintf(errmsg, "%s: socket", progname);
perror(errmsg);
if (old_errno == -EINVAL) {
fprintf(stderr, "Probably you have no IPX support in "
"your kernel\n");
}
close(s);
return -1;
sprintf (errmsg, "%s: socket", progname);
perror (errmsg);
if (old_errno == -EINVAL)
{
fprintf (stderr, "Probably you have no IPX support in "
"your kernel\n");
}
sprintf(errmsg, "%s: ioctl", progname);
close (s);
return -1;
}
sprintf (errmsg, "%s: ioctl", progname);
if (ioctl(s, SIOCAIPXPRISLT, &val) < 0) {
perror(errmsg);
close(s);
return -1;
}
if (ioctl(s, SIOCAIPXITFCRT, &val) < 0) {
perror(errmsg);
close(s);
return -1;
}
close(s);
return 0;
if (ioctl (s, SIOCAIPXPRISLT, &val) < 0)
{
perror (errmsg);
close (s);
return -1;
}
if (ioctl (s, SIOCAIPXITFCRT, &val) < 0)
{
perror (errmsg);
close (s);
return -1;
}
close (s);
return 0;
}
int main(int argc, char *argv[])
int
main (int argc, char *argv[])
{
int interfaces;
char *interface = "eth0";
int opt;
int timeout = 3;
int interfaces;
char *interface = "eth0";
int opt;
int timeout = 3;
unsigned long network[5] =
{0,};
unsigned long network[5] =
{0,};
progname = argv[0];
progname = argv[0];
while ((opt = getopt(argc, argv, "vi:ht:")) != EOF) {
switch (opt) {
case 'v':
verbose = 1;
break;
case 'i':
interface = optarg;
break;
case 't':
timeout = atoi(optarg);
break;
case 'h':
help();
exit(1);
default:
usage();
exit(1);
}
while ((opt = getopt (argc, argv, "vi:ht:")) != EOF)
{
switch (opt)
{
case 'v':
verbose = 1;
break;
case 'i':
interface = optarg;
break;
case 't':
timeout = atoi (optarg);
break;
case 'h':
help ();
exit (1);
default:
usage ();
exit (1);
}
}
if (ipx_auto_off() < 0) {
exit(1);
}
interfaces = ipx_interfaces();
if (interfaces > 0) {
fprintf(stderr, "%s must be run with no interfaces configured."
" Found %d interface%s.\n",
progname, interfaces,
interfaces == 1 ? "" : "s");
exit(1);
}
if (interfaces < 0) {
fprintf(stderr, "%s: %s\n", progname, strerror(interfaces));
exit(1);
}
probe_frame(interface, IPX_FRAME_8022, timeout, &(network[0]));
probe_frame(interface, IPX_FRAME_8023, timeout, &(network[1]));
probe_frame(interface, IPX_FRAME_SNAP, timeout, &(network[2]));
probe_frame(interface, IPX_FRAME_ETHERII, timeout, &(network[3]));
if (ipx_auto_off () < 0)
{
exit (1);
}
interfaces = ipx_interfaces ();
if (interfaces > 0)
{
fprintf (stderr, "%s must be run with no interfaces configured."
" Found %d interface%s.\n",
progname, interfaces,
interfaces == 1 ? "" : "s");
exit (1);
}
if (interfaces < 0)
{
fprintf (stderr, "%s: %s\n", progname, strerror (interfaces));
exit (1);
}
probe_frame (interface, IPX_FRAME_8022, timeout, &(network[0]));
probe_frame (interface, IPX_FRAME_8023, timeout, &(network[1]));
probe_frame (interface, IPX_FRAME_SNAP, timeout, &(network[2]));
probe_frame (interface, IPX_FRAME_ETHERII, timeout, &(network[3]));
if (verbose == 0) {
if (network[0] != 0) {
printf("%s %8.8lX\n",
frame_name(IPX_FRAME_8022), network[0]);
}
if (network[1] != 0) {
printf("%s %8.8lX\n",
frame_name(IPX_FRAME_8023), network[1]);
}
if (network[2] != 0) {
printf("%s %8.8lX\n",
frame_name(IPX_FRAME_SNAP), network[2]);
}
if (network[3] != 0) {
printf("%s %8.8lX\n",
frame_name(IPX_FRAME_ETHERII), network[3]);
}
if (verbose == 0)
{
if (network[0] != 0)
{
printf ("%s %8.8lX\n",
frame_name (IPX_FRAME_8022), network[0]);
}
return 0;
if (network[1] != 0)
{
printf ("%s %8.8lX\n",
frame_name (IPX_FRAME_8023), network[1]);
}
if (network[2] != 0)
{
printf ("%s %8.8lX\n",
frame_name (IPX_FRAME_SNAP), network[2]);
}
if (network[3] != 0)
{
printf ("%s %8.8lX\n",
frame_name (IPX_FRAME_ETHERII), network[3]);
}
}
return 0;
}

View File

@@ -23,9 +23,10 @@
#include <fcntl.h>
#include <signal.h>
#include "ncplib.h"
#include <errno.h>
struct NCPMountRec {
struct NCPMountRec
{
char *mountDir;
char *server;
struct ncp_conn *conn;
@@ -70,7 +71,8 @@ static struct sigaction sTermSig;
/****************************************************************************
*
*/
static void usage()
static void
usage(void)
{
fprintf(stderr, "usage: %s [-V]\n", ProgramName);
fprintf(stderr, " %s [-vn] [-s amt] sourcefile destinationfile|directory\n", ProgramName);
@@ -84,17 +86,19 @@ static void usage()
* Return pointer to original string if no "/" in string. (except at end)
*/
static const char *
myBaseName(const char *path)
myBaseName(const char *path)
{
const char *p;
for (p = &path[strlen(path)]; p != path; p--) { /* skip ENDING "/" chars */
for (p = &path[strlen(path)]; p != path; p--)
{ /* skip ENDING "/" chars */
if (*p && *p != '/')
break;
}
if (p == path)
return p;
for (; p != path || *p == '/'; p--) {
for (; p != path || *p == '/'; p--)
{
if (*p == '/')
return ++p;
}
@@ -105,7 +109,7 @@ static const char *
*
*/
static const char *
notDir(const char *path)
notDir(const char *path)
{
struct stat buf;
static const char *notDirectory = "not a directory";
@@ -120,12 +124,15 @@ static const char *
/****************************************************************************
*
*/
static int handleOptions(const int argc, char *const argv[])
static int
handleOptions(const int argc, char *const argv[])
{
int opt;
while ((opt = getopt(argc, argv, "vVns:")) != EOF) {
switch (opt) {
while ((opt = getopt(argc, argv, "vVns:")) != EOF)
{
switch (opt)
{
case 'V': /* Version */
optVersion = 1;
@@ -142,7 +149,8 @@ static int handleOptions(const int argc, char *const argv[])
case 's': /* Nice Factor */
optNiceFactorSel = 1;
optNiceFactor = atoi(optarg);
if (optNiceFactor < 1) {
if (optNiceFactor < 1)
{
fprintf(stderr, "%s: -s option requires positive numeric argument > 0\n",
ProgramName);
return 1;
@@ -160,18 +168,22 @@ static int handleOptions(const int argc, char *const argv[])
/****************************************************************************
* TODO: if recursive flag last MUST be a directory, even if only 2 args.
*/
static int validateFileArgs(const int argc, char *const argv[])
static int
validateFileArgs(const int argc, char *const argv[])
{
const char *p;
if (argc == 0) {
if (argc == 0)
{
fprintf(stderr, "%s: No arguments specified.\n", ProgramName);
return 1;
}
if (argc == 1) {
if (argc == 1)
{
fprintf(stderr, "%s: No destination specified.\n", ProgramName);
return 1;
}
if ((argc > 2) && (p = notDir(argv[argc - 1]))) { /* last arg MUST be dir */
if ((argc > 2) && (p = notDir(argv[argc - 1])))
{ /* last arg MUST be dir */
fprintf(stderr, "%s: %s: %s\n", ProgramName, argv[argc - 1], p);
return 1;
}
@@ -182,7 +194,7 @@ static int validateFileArgs(const int argc, char *const argv[])
* Duplicate a string.
*/
char *
duplicateStr(const char *InStr)
duplicateStr(const char *InStr)
{
char *dup;
if (!InStr)
@@ -196,31 +208,38 @@ char *
/****************************************************************************
* load a table of ncpfs mount points.
*/
int loadMountTable()
int
loadMountTable(void)
{
FILE *mountedFile;
struct mntent *mountEntry = NULL;
ncpCount = 0;
if ((mountedFile = fopen(MOUNTED, "r")) == NULL) {
if ((mountedFile = fopen(MOUNTED, "r")) == NULL)
{
fprintf(stderr, "ncopy: cannot open %s, %s\n", MOUNTED, strerror(errno));
return 1;
}
while ((mountEntry = getmntent(mountedFile)) != NULL) {
while ((mountEntry = getmntent(mountedFile)) != NULL)
{
if (!strcmp(mountEntry->mnt_type, "ncpfs"))
ncpCount++;
}
if (ncpCount) {
if (ncpCount)
{
NcpMountTable = (struct NCPMountRec *)
malloc(ncpCount * sizeof(struct NCPMountRec));
if (!NcpMountTable) {
if (!NcpMountTable)
{
fprintf(stderr, "Out of memory\n");
fclose(mountedFile);
return 1;
}
fseek(mountedFile, 0, SEEK_SET);
ncpCount = 0;
while ((mountEntry = getmntent(mountedFile)) != NULL) {
if (!strcmp(mountEntry->mnt_type, "ncpfs")) {
while ((mountEntry = getmntent(mountedFile)) != NULL)
{
if (!strcmp(mountEntry->mnt_type, "ncpfs"))
{
NcpMountTable[ncpCount].mountDir = duplicateStr(mountEntry->mnt_dir);
NcpMountTable[ncpCount].server =
duplicateStr(mountEntry->mnt_fsname);
@@ -236,13 +255,16 @@ int loadMountTable()
/****************************************************************************
* Releases the table of ncpfs mount points.
*/
void releaseMountTable()
void
releaseMountTable(void)
{
int loop;
if (!ncpCount)
return;
for (loop = ncpCount; loop; loop--, ncpCount--) {
if (NcpMountTable[loop - 1].conn) {
for (loop = ncpCount; loop; loop--, ncpCount--)
{
if (NcpMountTable[loop - 1].conn)
{
ncp_close(NcpMountTable[loop - 1].conn);
NcpMountTable[loop - 1].conn = NULL;
}
@@ -257,14 +279,16 @@ void releaseMountTable()
* the file.
* Returns -1 if the files do not reference the same server.
*/
int ncpIndex(const char *InputFile, const char *OutputFile)
int
ncpIndex(const char *InputFile, const char *OutputFile)
{
int loop;
char *mountDir;
if (!ncpCount)
return -1;
for (loop = 0; loop < ncpCount; loop++) {
for (loop = 0; loop < ncpCount; loop++)
{
mountDir = NcpMountTable[loop].mountDir;
if (!strncmp(mountDir, InputFile, strlen(mountDir)) &&
!strncmp(mountDir, OutputFile, strlen(mountDir)))
@@ -278,40 +302,46 @@ int ncpIndex(const char *InputFile, const char *OutputFile)
* Does a regular buffered file copy.
* This is used if we cannot use the Netware file copy.
*/
int normalFileCopy(const char *InputFile, const char *OutputFile,
char *Buffer, int BufferSize,
const char *paramInputFile,
const char *paramOutputFile)
int
normalFileCopy(const char *InputFile, const char *OutputFile,
char *Buffer, int BufferSize,
const char *paramInputFile,
const char *paramOutputFile)
{
int fdIn, fdOut;
long fileSize, totalSize;
struct stat statBuf;
fdIn = open(InputFile, O_RDONLY);
if (fdIn == -1) {
if (fdIn == -1)
{
fprintf(stderr, "%s: Cannot open %s, %s\n", ProgramName, paramInputFile,
strerror(errno));
return 1;
}
if (fstat(fdIn, &statBuf)) {
if (fstat(fdIn, &statBuf))
{
fprintf(stderr, "%s: Cannot stat %s, %s\n", ProgramName, paramInputFile,
strerror(errno));
close(fdIn);
return 1;
}
if (S_ISDIR(statBuf.st_mode)) {
if (S_ISDIR(statBuf.st_mode))
{
close(fdIn);
fprintf(stderr, "%s: %s: omitting directory\n", ProgramName, paramInputFile);
return 0; /* At this point, don't consider this a fatal error */
}
fdOut = open(OutputFile, O_CREAT | O_TRUNC | O_WRONLY, statBuf.st_mode);
if (fdOut == -1) {
if (fdOut == -1)
{
fprintf(stderr, "%s: Cannot create %s, %s\n", ProgramName, paramOutputFile,
strerror(errno));
close(fdIn);
return 1;
}
fileSize = lseek(fdIn, 0, SEEK_END);
if (fileSize < 0) {
if (fileSize < 0)
{
fprintf(stderr, "%s: lseek error on %s, %s\n", ProgramName, paramInputFile,
strerror(errno));
close(fdOut);
@@ -319,16 +349,19 @@ int normalFileCopy(const char *InputFile, const char *OutputFile,
return 1;
}
lseek(fdIn, 0, SEEK_SET);
if (optVerbose) {
if (optVerbose)
{
printf("Normal copy: %s -> %s 0%%", paramInputFile, paramOutputFile);
fflush(stdout);
}
totalSize = fileSize;
while (fileSize) {
while (fileSize)
{
int currentMove;
int writeAmt;
currentMove = (fileSize > BufferSize) ? BufferSize : fileSize;
if (read(fdIn, Buffer, currentMove) != currentMove) {
if (read(fdIn, Buffer, currentMove) != currentMove)
{
fprintf(stderr, "%s: Error reading %s, %s\n", ProgramName, paramInputFile,
strerror(errno));
close(fdIn);
@@ -336,13 +369,15 @@ int normalFileCopy(const char *InputFile, const char *OutputFile,
return 1;
}
writeAmt = write(fdOut, Buffer, currentMove);
if (writeAmt < 0) {
if (writeAmt < 0)
{
fprintf(stderr, "%s: Error writing %s, %s\n", ProgramName, paramOutputFile,
strerror(errno));
close(fdIn);
close(fdOut);
return 1;
} else if (writeAmt == 0) {
} else if (writeAmt == 0)
{
fprintf(stderr, "%s: Out of space on destination device writing %s\n",
ProgramName, OutputFile);
close(fdIn);
@@ -350,7 +385,8 @@ int normalFileCopy(const char *InputFile, const char *OutputFile,
return 1;
}
fileSize -= currentMove;
if (optVerbose) {
if (optVerbose)
{
printf("\rNormal copy: %s -> %s %ld%%", paramInputFile, paramOutputFile, (100 - (fileSize * 100 / totalSize)));
fflush(stdout);
}
@@ -367,10 +403,11 @@ int normalFileCopy(const char *InputFile, const char *OutputFile,
* Netware file names need to be all upper case.
*/
char *
upString(char *str)
upString(char *str)
{
char *alias = str;
while (*alias) {
while (*alias)
{
*alias = toupper(*alias);
++alias;
}
@@ -381,10 +418,12 @@ char *
* Locates the first occurrance of a single character in the input string.
* returns -1 if the character is not found.
*/
int stringPosition(const char *str, char token)
int
stringPosition(const char *str, char token)
{
const char *alias = str;
while (*alias) {
while (*alias)
{
if (*alias == token)
return alias - str;
alias++;
@@ -398,7 +437,8 @@ int stringPosition(const char *str, char token)
* This will mangle the input "FileString", leaving just the file name
* component in it when it is finished.
*/
int getDirHandle(struct ncp_conn *conn, char *FileString, __u8 * NewDirHandle)
int
getDirHandle(struct ncp_conn *conn, char *FileString, __u8 * NewDirHandle)
{
struct nw_info_struct info1, info2;
int currentLevel = 0;
@@ -406,20 +446,25 @@ int getDirHandle(struct ncp_conn *conn, char *FileString, __u8 * NewDirHandle)
struct nw_info_struct *parentInfo = NULL;
struct nw_info_struct *currentInfo = NULL;
while ((k = stringPosition(FileString, '/')) >= 0) {
while ((k = stringPosition(FileString, '/')) >= 0)
{
FileString[k] = 0;
if (!currentLevel) {
if (!currentLevel)
{
parentInfo = NULL;
currentInfo = &info1;
} else if (currentLevel % 2) {
} else if (currentLevel % 2)
{
parentInfo = &info1;
currentInfo = &info2;
} else {
} else
{
parentInfo = &info2;
currentInfo = &info1;
}
if (ncp_do_lookup(conn, parentInfo, FileString,
currentInfo) != 0) {
currentInfo) != 0)
{
fprintf(stderr, "%s: Ncp lookup failed on directory %s--%s\n",
ProgramName, FileString, strerror(errno));
return 1;
@@ -429,7 +474,8 @@ int getDirHandle(struct ncp_conn *conn, char *FileString, __u8 * NewDirHandle)
}
if (ncp_alloc_short_dir_handle(conn, currentInfo, NCP_ALLOC_TEMPORARY,
NewDirHandle) != 0) {
NewDirHandle) != 0)
{
fprintf(stderr, "%s: Ncp alloc dir handle failed--%s\n",
ProgramName, strerror(errno));
return 1;
@@ -441,10 +487,11 @@ int getDirHandle(struct ncp_conn *conn, char *FileString, __u8 * NewDirHandle)
/****************************************************************************
* Interfaces with the ncplib to do the netware copy of the file.
*/
int netwareCopyFile(int ncpMountIndex, const char *sourcefile,
const char *destfile,
const char *paramInputFile,
const char *paramOutputFile)
int
netwareCopyFile(int ncpMountIndex, const char *sourcefile,
const char *destfile,
const char *paramInputFile,
const char *paramOutputFile)
{
__u8 source_dir_handle;
__u8 dest_dir_handle;
@@ -465,10 +512,12 @@ int netwareCopyFile(int ncpMountIndex, const char *sourcefile,
/* Establish a connection to a Netware mount point if
one is not already established. */
if (!NcpMountTable[ncpMountIndex].conn) {
NcpMountTable[ncpMountIndex].conn =
ncp_open_mount(NcpMountTable[ncpMountIndex].mountDir, &err);
if (err) {
if (!NcpMountTable[ncpMountIndex].conn)
{
err = ncp_open_mount(NcpMountTable[ncpMountIndex].mountDir,
&NcpMountTable[ncpMountIndex].conn);
if (err)
{
com_err(ProgramName, err, "opening ncp connection on mount point %s",
NcpMountTable[ncpMountIndex].mountDir);
return 2;
@@ -481,7 +530,8 @@ int netwareCopyFile(int ncpMountIndex, const char *sourcefile,
stroffset = strlen(NcpMountTable[ncpMountIndex].mountDir) + 1;
sourceDup = duplicateStr(sourcefile + stroffset);
destDup = duplicateStr(destfile + stroffset);
if (!sourceDup || !destDup) {
if (!sourceDup || !destDup)
{
fprintf(stderr, "%s: Malloc failed duplicating file names\n",
ProgramName);
return 2;
@@ -491,14 +541,16 @@ int netwareCopyFile(int ncpMountIndex, const char *sourcefile,
/* Get Handles to the input and output directories */
if (getDirHandle(sourceconn, sourceDup, &source_dir_handle) ||
getDirHandle(sourceconn, destDup, &dest_dir_handle)) {
getDirHandle(sourceconn, destDup, &dest_dir_handle))
{
free(sourceDup);
free(destDup);
return 1;
}
/* Open the input and output files. */
if (ncp_open_file(sourceconn, source_dir_handle, sourceDup, 0, AR_READ,
&source_file) != 0) {
&source_file) != 0)
{
fprintf(stderr, "%s: Cannot open %s--%s\n",
ProgramName, paramInputFile, strerror(errno));
free(sourceDup);
@@ -506,7 +558,8 @@ int netwareCopyFile(int ncpMountIndex, const char *sourcefile,
return 1;
}
if (ncp_create_file(sourceconn, dest_dir_handle, destDup,
source_file.file_attributes, &dest_file) != 0) {
source_file.file_attributes, &dest_file) != 0)
{
fprintf(stderr, "%s: Cannot create %s--%s\n", ProgramName, paramOutputFile,
strerror(errno));
ncp_close_file(sourceconn, source_file.file_id);
@@ -523,7 +576,8 @@ int netwareCopyFile(int ncpMountIndex, const char *sourcefile,
free(destDup);
retValue = 0;
if (optVerbose) {
if (optVerbose)
{
printf("NetWare copy: %s -> %s 0%%", paramInputFile, paramOutputFile);
fflush(stdout);
}
@@ -533,24 +587,28 @@ int netwareCopyFile(int ncpMountIndex, const char *sourcefile,
sourceOff = 0;
retryCount = 0;
while (amtLeft && retryCount < MaxNcopyRetries) {
while (amtLeft && retryCount < MaxNcopyRetries)
{
int ncopyRetValue;
if (amtLeft > CopyBlockSize)
thisMove = CopyBlockSize;
else
thisMove = amtLeft;
/* If we are being nice and we've copied enough blocks, go to sleep */
if (optNice) {
if (BlocksCopied == optNiceFactor) {
if (optNice)
{
if (BlocksCopied == optNiceFactor)
{
sleep(NiceSleepTime);
BlocksCopied = 0;
} else
++BlocksCopied;
}
ncopyRetValue = ncp_copy_file(sourceconn, source_file.file_id,
dest_file.file_id, sourceOff, sourceOff,
dest_file.file_id, sourceOff, sourceOff,
thisMove, &amountCopied);
if (ncopyRetValue != 0) {
if (ncopyRetValue != 0)
{
/* In my testing this only happens when you run out of space
on the server.
Netware seems to wait a bit before reporting space recently
@@ -559,7 +617,8 @@ int netwareCopyFile(int ncpMountIndex, const char *sourcefile,
retryCount++;
amountCopied = thisMove = 0;
}
if (amountCopied != thisMove) {
if (amountCopied != thisMove)
{
fprintf(stderr, "%s: Warning, amountCopied (%u) != thisMove (%u)\n",
ProgramName, (unsigned int) amountCopied, (unsigned int) thisMove);
}
@@ -569,7 +628,8 @@ int netwareCopyFile(int ncpMountIndex, const char *sourcefile,
#endif
amtLeft -= amountCopied;
sourceOff += amountCopied;
if (optVerbose) {
if (optVerbose)
{
printf("\rNetWare copy: %s -> %s %ld%%", paramInputFile, paramOutputFile,
(100 - (long) ((float) amtLeft / (float) totalSize * 100.0)));
if (retryCount)
@@ -581,7 +641,8 @@ int netwareCopyFile(int ncpMountIndex, const char *sourcefile,
retValue = 1;
if (optVerbose)
printf("\n");
if (ncp_close_file(sourceconn, dest_file.file_id) != 0) {
if (ncp_close_file(sourceconn, dest_file.file_id) != 0)
{
fprintf(stderr, "%s: Close failed for %s\n", ProgramName, paramOutputFile);
retValue = 1;
}
@@ -590,16 +651,19 @@ int netwareCopyFile(int ncpMountIndex, const char *sourcefile,
CurrentConn = NULL;
CurrentFile = NULL;
if (ncp_close_file(sourceconn, source_file.file_id) != 0) {
if (ncp_close_file(sourceconn, source_file.file_id) != 0)
{
fprintf(stderr, "%s: Close failed for %s\n", ProgramName, paramInputFile);
retValue = 1;
}
if (ncp_dealloc_dir_handle(sourceconn, dest_dir_handle) != 0) {
if (ncp_dealloc_dir_handle(sourceconn, dest_dir_handle) != 0)
{
fprintf(stderr, "%s: Dealloc dir handle error for %s\n", ProgramName,
paramOutputFile);
retValue = 1;
}
if (ncp_dealloc_dir_handle(sourceconn, source_dir_handle) != 0) {
if (ncp_dealloc_dir_handle(sourceconn, source_dir_handle) != 0)
{
fprintf(stderr, "%s: Dealloc dir handle error for %s\n", ProgramName,
paramInputFile);
retValue = 1;
@@ -612,8 +676,9 @@ int netwareCopyFile(int ncpMountIndex, const char *sourcefile,
* Decides whether to use the traditional file copy or the netware remote
* file copy.
*/
int copyFiles(const char *realsource, const char *realdestination,
const char *paraminputfile, const char *paramoutputfile)
int
copyFiles(const char *realsource, const char *realdestination,
const char *paraminputfile, const char *paramoutputfile)
{
int oldUMask;
char fileBuffer[24000];
@@ -623,7 +688,7 @@ int copyFiles(const char *realsource, const char *realdestination,
printf("Real Source '%s'\n"
"Real Dest '%s'\n"
"Param Src '%s'\n"
"Param Dest '%s'\n", realsource, realdestination, paraminputfile,
"Param Dest '%s'\n", realsource, realdestination, paraminputfile,
paramoutputfile);
#endif
@@ -657,7 +722,8 @@ int copyFiles(const char *realsource, const char *realdestination,
* Is it failure if destination fails?
* Do we Stay in the loop?
*/
static int copyRealPaths(const char *source, const char *destination)
static int
copyRealPaths(const char *source, const char *destination)
{
char realsource[MAXPATHLEN * 2];
char realdestination[MAXPATHLEN * 2];
@@ -665,18 +731,21 @@ static int copyRealPaths(const char *source, const char *destination)
char filePart[MAXPATHLEN + 1];
const char *p;
if (realpath(source, realsource) == 0) { /* the source must at least exist */
if (realpath(source, realsource) == 0)
{ /* the source must at least exist */
fprintf(stderr, "%s: %s: %s\n",
ProgramName, source, strerror(errno));
return 1; /* indicate a "source" problem */
}
if (realpath(destination, realdestination) == 0) { /* dest file missing? OK */
if (realpath(destination, realdestination) == 0)
{ /* dest file missing? OK */
strncpy(dirPart, destination, MAXPATHLEN); /* but "dirpart" must work */
dirPart[MAXPATHLEN] = 0;
p = myBaseName(dirPart);
strcpy(filePart, p);
dirPart[p - dirPart] = 0; /* isolates "directory" part from "file part" */
if (realpath(dirPart, realdestination) == 0) {
if (realpath(dirPart, realdestination) == 0)
{
fprintf(stderr, "%s: %s: %s\n",
ProgramName, dirPart, strerror(errno));
return 2; /* indicate a "destination" problem */
@@ -701,7 +770,8 @@ static int copyRealPaths(const char *source, const char *destination)
* if argc > 2 last parameter is a directory
* by validateFileArgs()
*/
static int handleFileArgs(int argc, char *const argv[])
static int
handleFileArgs(int argc, char *const argv[])
{
int loop;
const char *destination;
@@ -711,10 +781,12 @@ static int handleFileArgs(int argc, char *const argv[])
char destinationfile[MAXPATHLEN * 2];
destination = argv[argc - 1]; /* get LAST argument */
for (loop = 0; loop < (argc - 1); loop++) { /* all file arguments, but last */
for (loop = 0; loop < (argc - 1); loop++)
{ /* all file arguments, but last */
strncpy(destinationfile, destination, MAXPATHLEN);
destinationfile[MAXPATHLEN] = 0;
if ((argc > 2) || (!notDir(argv[argc - 1]))) { /* destination is a dir */
if ((argc > 2) || (!notDir(argv[argc - 1])))
{ /* destination is a dir */
if (*destinationfile != '/' || *(destinationfile + 1))
strcat(destinationfile, "/");
baseNamePtr = myBaseName(argv[loop]); /* get the file name */
@@ -731,41 +803,48 @@ static int handleFileArgs(int argc, char *const argv[])
/****************************************************************************
*
*/
static void handleSignals(int sigNumber)
static void
handleSignals(int sigNumber)
{
/* Ignore Signal Handling while cleaning up */
/* SIGHUP */
sHangupSig.sa_handler = SIG_IGN;
if (sigaction(SIGHUP, &sHangupSig, NULL) == -1) {
if (sigaction(SIGHUP, &sHangupSig, NULL) == -1)
{
fprintf(stderr, "%s: Reset to ignore SIGHUP signal failed: %s",
ProgramName, strerror(errno));
}
/* SIGINT */
sInterruptSig.sa_handler = SIG_IGN;
if (sigaction(SIGINT, &sInterruptSig, NULL) == -1) {
if (sigaction(SIGINT, &sInterruptSig, NULL) == -1)
{
fprintf(stderr, "%s: Reset to ignore SIGINT signal failed: %s",
ProgramName, strerror(errno));
}
/* SIGQUIT */
sQuitSig.sa_handler = SIG_IGN;
if (sigaction(SIGQUIT, &sQuitSig, NULL) == -1) {
if (sigaction(SIGQUIT, &sQuitSig, NULL) == -1)
{
fprintf(stderr, "%s: Reset to ignore SIGQUIT signal failed: %s",
ProgramName, strerror(errno));
}
/* SIGTERM */
sTermSig.sa_handler = SIG_IGN;
if (sigaction(SIGTERM, &sTermSig, NULL) == -1) {
if (sigaction(SIGTERM, &sTermSig, NULL) == -1)
{
fprintf(stderr, "%s: Reset to ignore SIGTERM signal failed: %s",
ProgramName, strerror(errno));
}
/* If we don't close the ncp output file, we have to ncpumount and
ncpmount before we can get rid of it. */
if (OutputOpen) {
if (OutputOpen)
{
/* Issue a warning if we cannot close the file */
/* If an error occurs we probably have to umount/mount to
remove the file */
if (ncp_close_file(CurrentConn, CurrentFile->file_id) != 0) {
if (ncp_close_file(CurrentConn, CurrentFile->file_id) != 0)
{
fprintf(stderr, "%s: unclean close of output file", ProgramName);
}
OutputOpen = 0;
@@ -776,48 +855,57 @@ static void handleSignals(int sigNumber)
/****************************************************************************
* We'll trap Hangup, Interrupt, Quit or Terminate
*/
static int trapSignals()
static int
trapSignals(void)
{
if (sigaction(SIGHUP, NULL, &sHangupSig)) { /* init structure fields */
if (sigaction(SIGHUP, NULL, &sHangupSig))
{ /* init structure fields */
fprintf(stderr, "%s: Get HANGUP signal action failed: %s",
ProgramName, strerror(errno));
return 1;
}
sHangupSig.sa_handler = handleSignals;
if (sigaction(SIGHUP, &sHangupSig, NULL) == -1) {
if (sigaction(SIGHUP, &sHangupSig, NULL) == -1)
{
fprintf(stderr, "%s: Reset HANGUP signal action failed: %s",
ProgramName, strerror(errno));
return 1;
}
if (sigaction(SIGINT, NULL, &sInterruptSig)) { /* init structure fields */
if (sigaction(SIGINT, NULL, &sInterruptSig))
{ /* init structure fields */
fprintf(stderr, "%s: Get INTERRUPT signal action failed: %s",
ProgramName, strerror(errno));
return 1;
}
sInterruptSig.sa_handler = handleSignals;
if (sigaction(SIGINT, &sInterruptSig, NULL) == -1) {
if (sigaction(SIGINT, &sInterruptSig, NULL) == -1)
{
fprintf(stderr, "%s: Reset INTERRUPT signal action failed: %s",
ProgramName, strerror(errno));
return 1;
}
if (sigaction(SIGQUIT, NULL, &sQuitSig)) { /* init structure fields */
if (sigaction(SIGQUIT, NULL, &sQuitSig))
{ /* init structure fields */
fprintf(stderr, "%s: Get QUIT signal action failed: %s",
ProgramName, strerror(errno));
return 1;
}
sQuitSig.sa_handler = handleSignals;
if (sigaction(SIGQUIT, &sQuitSig, NULL) == -1) {
if (sigaction(SIGQUIT, &sQuitSig, NULL) == -1)
{
fprintf(stderr, "%s: Reset QUIT signal action failed: %s",
ProgramName, strerror(errno));
return 1;
}
if (sigaction(SIGTERM, NULL, &sTermSig)) { /* init structure fields */
if (sigaction(SIGTERM, NULL, &sTermSig))
{ /* init structure fields */
fprintf(stderr, "%s: Get TERMINATE signal action failed: %s",
ProgramName, strerror(errno));
return 1;
}
sTermSig.sa_handler = handleSignals;
if (sigaction(SIGTERM, &sTermSig, NULL) == -1) {
if (sigaction(SIGTERM, &sTermSig, NULL) == -1)
{
fprintf(stderr, "%s: Reset TERMINATE signal action failed: %s",
ProgramName, strerror(errno));
return 1;
@@ -828,20 +916,24 @@ static int trapSignals()
/****************************************************************************
*
*/
int main(int argc, char *const argv[])
int
main(int argc, char *const argv[])
{
int returnCode;
ProgramName = argv[0];
if (handleOptions(argc, argv)) { /* bad option, missing option parameter */
if (handleOptions(argc, argv))
{ /* bad option, missing option parameter */
usage();
return 1;
}
if (optVersion) { /* only option not requiring any arguments */
if (optVersion)
{ /* only option not requiring any arguments */
printf("%s version %s\n", ProgramName, VersionStr);
return 0;
}
if (validateFileArgs(argc - optind, argv + optind)) {
if (validateFileArgs(argc - optind, argv + optind))
{
usage();
return 1;
}

View File

@@ -1,4 +1,3 @@
/*
* ncptest.c
*
@@ -20,7 +19,7 @@
#include <unistd.h>
#include <sys/types.h>
#include <sys/ioctl.h>
/* #include <sys/wait.h> *//* generates a warning here */
/* #include <sys/wait.h> *//* generates a warning here */
extern pid_t waitpid(pid_t, int *, int);
#include <sys/errno.h>
#include <unistd.h>
@@ -30,16 +29,16 @@ extern pid_t waitpid(pid_t, int *, int);
#include <stdlib.h>
#include <sys/mount.h>
#include <mntent.h>
#include <linux/ipx.h>
#include "kernel/ipx.h"
#include <linux/fs.h>
#include <linux/ncp.h>
#include <linux/ncp_fs.h>
#include <linux/ncp_mount.h>
#include "kernel/fs.h"
#include "kernel/ncp.h"
#include "kernel/ncp_fs.h"
#include "ncplib.h"
void test_connlist(struct ncp_conn *conn)
void
test_connlist(struct ncp_conn *conn)
{
__u8 conn_list[256] =
{0,};
@@ -50,92 +49,110 @@ void test_connlist(struct ncp_conn *conn)
return;
}
void test_send(struct ncp_conn *conn)
void
test_send(struct ncp_conn *conn)
{
__u8 conn_list[256] =
{0,};
int no;
if (ncp_get_connlist(conn, NCP_BINDERY_USER, "ME", &no,
conn_list) != 0) {
conn_list) != 0)
{
no = 0;
}
if (no > 0) {
if (no > 0)
{
ncp_send_broadcast(conn, no, conn_list, "Hallo");
}
return;
}
void test_create(struct ncp_conn *conn)
void
test_create(struct ncp_conn *conn)
{
struct nw_info_struct sys;
struct nw_info_struct me;
__u8 dir_handle;
struct ncp_file_info new_file;
if (ncp_do_lookup(conn, NULL, "SYS", &sys) != 0) {
if (ncp_do_lookup(conn, NULL, "SYS", &sys) != 0)
{
printf("lookup error\n");
return;
}
if (ncp_do_lookup(conn, &sys, "ME", &me) != 0) {
if (ncp_do_lookup(conn, &sys, "ME", &me) != 0)
{
printf("lookup public error\n");
return;
}
if (ncp_alloc_short_dir_handle(conn, &me, NCP_ALLOC_TEMPORARY,
&dir_handle) != 0) {
&dir_handle) != 0)
{
printf("alloc_dir_handle error\n");
return;
}
if (ncp_create_file(conn, dir_handle, "BLUB.TXT", 0,
&new_file) != 0) {
&new_file) != 0)
{
printf("create error\n");
return;
}
if (ncp_dealloc_dir_handle(conn, dir_handle) != 0) {
if (ncp_dealloc_dir_handle(conn, dir_handle) != 0)
{
printf("dealloc error\n");
return;
}
}
int test_change(struct ncp_conn *conn)
int
test_change(struct ncp_conn *conn)
{
long result;
unsigned char ncp_key[8];
struct ncp_bindery_object user;
if ((result = ncp_get_encryption_key(conn, ncp_key)) != 0) {
if ((result = ncp_get_encryption_key(conn, ncp_key)) != 0)
{
return result;
}
if ((result = ncp_get_bindery_object_id(conn, 1,
"ME", &user)) != 0) {
"ME", &user)) != 0)
{
return result;
}
if ((result = ncp_change_login_passwd(conn, &user, ncp_key,
"MEE", "ME")) != 0) {
"MEE", "ME")) != 0)
{
return result;
}
return 0;
}
void test_readdir(struct ncp_conn *conn)
void
test_readdir(struct ncp_conn *conn)
{
struct nw_info_struct sys;
struct nw_info_struct blub;
struct ncp_search_seq seq;
struct nw_info_struct entry;
if (ncp_do_lookup(conn, NULL, "SYS", &sys) != 0) {
if (ncp_do_lookup(conn, NULL, "SYS", &sys) != 0)
{
printf("lookup error\n");
return;
}
if (ncp_do_lookup(conn, &sys, "BLUB", &blub) != 0) {
if (ncp_do_lookup(conn, &sys, "BLUB", &blub) != 0)
{
printf("lookup blub error\n");
return;
}
if (ncp_initialize_search(conn, &sys, 0, &seq) != 0) {
if (ncp_initialize_search(conn, &sys, 0, &seq) != 0)
{
printf("init error\n");
return;
}
while (ncp_search_for_file_or_subdir(conn, &seq, &entry) == 0) {
while (ncp_search_for_file_or_subdir(conn, &seq, &entry) == 0)
{
struct nw_info_struct nfs;
printf("found: %s\n", entry.entryName);
if (ncp_obtain_file_or_subdir_info(conn, NW_NS_DOS, NW_NS_NFS,
@@ -143,7 +160,8 @@ void test_readdir(struct ncp_conn *conn)
entry.volNumber,
entry.DosDirNum,
NULL,
&nfs) == 0) {
&nfs) == 0)
{
printf("nfs name: %s\n", nfs.entryName);
}
if (ncp_obtain_file_or_subdir_info(conn, NW_NS_DOS, NW_NS_OS2,
@@ -151,30 +169,35 @@ void test_readdir(struct ncp_conn *conn)
entry.volNumber,
entry.DosDirNum,
NULL,
&nfs) == 0) {
&nfs) == 0)
{
printf("os2 name: %s\n", nfs.entryName);
}
}
}
void test_rights(struct ncp_conn *conn)
void
test_rights(struct ncp_conn *conn)
{
struct nw_info_struct sys;
struct nw_info_struct me;
__u16 rights;
if (ncp_do_lookup(conn, NULL, "SYS", &sys) != 0) {
if (ncp_do_lookup(conn, NULL, "SYS", &sys) != 0)
{
printf("lookup error\n");
return;
}
if (ncp_do_lookup(conn, &sys, "ME", &me) != 0) {
if (ncp_do_lookup(conn, &sys, "ME", &me) != 0)
{
printf("lookup me error\n");
return;
}
if (ncp_get_eff_directory_rights(conn, 0, 0, 0x8006,
sys.volNumber, sys.DosDirNum, NULL,
&rights) != 0) {
sys.volNumber, sys.DosDirNum, NULL,
&rights) != 0)
{
printf("get sys rights error\n");
return;
}
@@ -182,7 +205,8 @@ void test_rights(struct ncp_conn *conn)
if (ncp_get_eff_directory_rights(conn, 0, 0, 0x8006,
me.volNumber, me.DosDirNum, NULL,
&rights) != 0) {
&rights) != 0)
{
printf("get me rights error\n");
return;
}
@@ -190,12 +214,14 @@ void test_rights(struct ncp_conn *conn)
return;
}
int main(int argc, char *argv[])
int
main(int argc, char *argv[])
{
struct ncp_conn *conn;
long err;
if ((conn = ncp_initialize(&argc, argv, 1, &err)) == NULL) {
if ((conn = ncp_initialize(&argc, argv, 1, &err)) == NULL)
{
com_err(argv[0], err, "in ncp_initialize");
return 1;
}

View File

@@ -22,7 +22,8 @@ static void
usage(void);
static void help(void);
void main(int argc, char *argv[])
int
main(int argc, char *argv[])
{
struct ncp_conn *conn;
@@ -50,11 +51,13 @@ void main(int argc, char *argv[])
memzero(q);
if ((argc == 2)
&& (strcmp(argv[1], "-h") == 0)) {
&& (strcmp(argv[1], "-h") == 0))
{
help();
exit(0);
}
if ((conn = ncp_initialize(&argc, argv, 1, &err)) == NULL) {
if ((conn = ncp_initialize(&argc, argv, 1, &err)) == NULL)
{
com_err(argv[0], err, "when initializing connection");
exit(1);
}
@@ -75,8 +78,10 @@ void main(int argc, char *argv[])
pj.Rows = htons(80);
strcpy(pj.FnameHeader, "stdin");
while ((opt = getopt(argc, argv, "h?q:d:p:b:f:l:r:c:t:F:TN")) != EOF) {
switch (opt) {
while ((opt = getopt(argc, argv, "h?q:d:p:b:f:l:r:c:t:F:TN")) != EOF)
{
switch (opt)
{
case 'h':
case '?':
help();
@@ -85,38 +90,45 @@ void main(int argc, char *argv[])
case 'p':
/* Path */
pj.CtrlFlags |= PRINT_BANNER;
if (strlen(optarg) >= sizeof(pj.Path)) {
if (strlen(optarg) >= sizeof(pj.Path))
{
strncpy(pj.Path, optarg,
sizeof(pj.Path));
} else {
} else
{
strcpy(pj.Path, optarg);
}
break;
case 'b':
/* Banner Name */
pj.CtrlFlags |= PRINT_BANNER;
if (strlen(optarg) >= sizeof(pj.BannerName)) {
if (strlen(optarg) >= sizeof(pj.BannerName))
{
strncpy(pj.BannerName, optarg,
sizeof(pj.BannerName));
} else {
} else
{
strcpy(pj.BannerName, optarg);
}
break;
case 'f':
/* File Name in Banner */
pj.CtrlFlags |= PRINT_BANNER;
if (strlen(optarg) >= sizeof(pj.FnameBanner)) {
if (strlen(optarg) >= sizeof(pj.FnameBanner))
{
strncpy(pj.FnameBanner, optarg,
sizeof(pj.FnameBanner));
} else {
} else
{
strcpy(pj.FnameBanner, optarg);
}
break;
case 'l':
/* lines, default: 66 */
if ((atoi(optarg) < 0) || (atoi(optarg) > 65535)) {
if ((atoi(optarg) < 0) || (atoi(optarg) > 65535))
{
fprintf(stderr,
"invalid line number: %s\n", optarg);
"invalid line number: %s\n", optarg);
break;
}
pj.Lines = htons(atoi(optarg));
@@ -124,9 +136,10 @@ void main(int argc, char *argv[])
break;
case 'r':
/* rows, default: 80 */
if ((atoi(optarg) < 0) || (atoi(optarg) > 65535)) {
if ((atoi(optarg) < 0) || (atoi(optarg) > 65535))
{
fprintf(stderr,
"invalid row number: %s\n", optarg);
"invalid row number: %s\n", optarg);
break;
}
pj.Rows = htons(atoi(optarg));
@@ -134,7 +147,8 @@ void main(int argc, char *argv[])
break;
case 'c':
/* copies, default: 1 */
if ((atoi(optarg) < 0) || (atoi(optarg) > 65000)) {
if ((atoi(optarg) < 0) || (atoi(optarg) > 65000))
{
fprintf(stderr,
"invalid copies: %s\n", optarg);
break;
@@ -144,7 +158,8 @@ void main(int argc, char *argv[])
break;
case 't':
/* tab size, default: 8 */
if ((atoi(optarg) < 0) || (atoi(optarg) > 255)) {
if ((atoi(optarg) < 0) || (atoi(optarg) > 255))
{
fprintf(stderr,
"invalid tab size: %s\n", optarg);
break;
@@ -162,16 +177,18 @@ void main(int argc, char *argv[])
break;
case 'F':
/* Form number, default: 0 */
if ((atoi(optarg) < 0) || (atoi(optarg) > 255)) {
if ((atoi(optarg) < 0) || (atoi(optarg) > 255))
{
fprintf(stderr,
"invalid form number: %s\n", optarg);
"invalid form number: %s\n", optarg);
break;
}
j.j.JobType = htons(atoi(optarg));
break;
case 'q':
/* Queue name to print on, default: '*' */
if (strlen(optarg) >= NCP_BINDERY_NAME_LEN) {
if (strlen(optarg) >= NCP_BINDERY_NAME_LEN)
{
printf("queue name too long: %s\n",
optarg);
ncp_close(conn);
@@ -182,10 +199,12 @@ void main(int argc, char *argv[])
case 'd':
/* Job Description */
pj.CtrlFlags |= PRINT_BANNER;
if (strlen(optarg) >= sizeof(j.j.JobTextDescription)) {
if (strlen(optarg) >= sizeof(j.j.JobTextDescription))
{
strncpy(j.j.JobTextDescription, optarg,
sizeof(j.j.JobTextDescription));
} else {
} else
{
strcpy(j.j.JobTextDescription, optarg);
}
break;
@@ -197,34 +216,43 @@ void main(int argc, char *argv[])
}
}
if (optind != argc - 1) {
if (optind != argc - 1)
{
usage();
ncp_close(conn);
exit(1);
}
file_name = argv[optind];
if (strcmp(file_name, "-") == 0) {
if (strcmp(file_name, "-") == 0)
{
file = 0; /* stdin */
} else {
} else
{
file = open(file_name, O_RDONLY, 0);
if (file < 0) {
if (file < 0)
{
perror("could not open file");
ncp_close(conn);
exit(1);
}
if (strlen(file_name) >= sizeof(pj.FnameHeader)) {
if (strlen(file_name) >= sizeof(pj.FnameHeader))
{
strncpy(pj.FnameHeader, file_name,
sizeof(pj.FnameHeader));
} else {
} else
{
strcpy(pj.FnameHeader, file_name);
}
if (strlen(pj.FnameBanner) == 0) {
if (strlen(file_name) >= sizeof(pj.FnameBanner)) {
if (strlen(pj.FnameBanner) == 0)
{
if (strlen(file_name) >= sizeof(pj.FnameBanner))
{
strncpy(pj.FnameBanner, file_name,
sizeof(pj.FnameBanner));
} else {
} else
{
strcpy(pj.FnameBanner, file_name);
}
}
@@ -235,24 +263,29 @@ void main(int argc, char *argv[])
str_upper(queue);
if (ncp_scan_bindery_object(conn, 0xffffffff, NCP_BINDERY_PQUEUE,
queue, &q) != 0) {
queue, &q) != 0)
{
printf("could not find queue %s\n", queue);
ncp_close(conn);
exit(1);
}
if (ncp_create_queue_job_and_file(conn, q.object_id, &j) != 0) {
if (ncp_create_queue_job_and_file(conn, q.object_id, &j) != 0)
{
printf("create error\n");
ncp_close(conn);
exit(1);
}
written = 0;
do {
do
{
read_this_time = read(file, buf, sizeof(buf));
if (read_this_time < 0) {
if (read_this_time < 0)
{
break;
}
if (ncp_write(conn, j.file_handle,
written, read_this_time, buf) < read_this_time) {
written, read_this_time, buf) < read_this_time)
{
break;
}
written += read_this_time;
@@ -261,19 +294,22 @@ void main(int argc, char *argv[])
close(file);
if (ncp_close_file_and_start_job(conn, q.object_id, &j) != 0) {
if (ncp_close_file_and_start_job(conn, q.object_id, &j) != 0)
{
printf("close error\n");
}
ncp_close(conn);
return;
return 0;
}
static void usage(void)
static void
usage(void)
{
fprintf(stderr, "usage: %s [options] file\n", progname);
}
static void help(void)
static void
help(void)
{
printf("\n");
printf("usage: %s [options] file\n", progname);

View File

@@ -12,22 +12,27 @@
#include <ctype.h>
#include "ncplib.h"
int main(int argc, char **argv)
int
main(int argc, char **argv)
{
struct ncp_conn *conn;
__u8 conn_list[256] =
{0,};
int no_conn;
int conn_list2[256];
int i;
char *message = NULL;
char *user = NULL;
long err;
if ((conn = ncp_initialize(&argc, argv, 1, &err)) == NULL) {
if ((conn = ncp_initialize(&argc, argv, 1, &err)) == NULL)
{
com_err(argv[0], err, "when initializing");
exit(1);
}
if (argc != 3) {
if (argc != 3)
{
fprintf(stderr, "usage: %s [options] user message\n", argv[0]);
ncp_close(conn);
exit(1);
@@ -36,20 +41,31 @@ int main(int argc, char **argv)
message = argv[2];
if ((err = ncp_get_connlist(conn, NCP_BINDERY_USER, user, &no_conn,
conn_list)) != 0) {
conn_list)) != 0)
{
com_err(argv[0], err, "in get_connlist");
ncp_close(conn);
exit(1);
}
if (no_conn == 0) {
if (no_conn == 0)
{
fprintf(stderr, "No connection found for %s\n", user);
ncp_close(conn);
exit(1);
}
if ((err = ncp_send_broadcast(conn, no_conn, conn_list, message)) != 0) {
com_err(argv[0], err, "in send_broadcast");
ncp_close(conn);
exit(1);
for (i=0; i<no_conn; i++)
conn_list2[i] = conn_list[i];
if ((err = ncp_send_broadcast2(conn, no_conn, conn_list2, message)) != 0)
{
/* NetWare 2.x returns error code 0x89FB - function not implemented */
if (conn->completion == 0xFB)
err = ncp_send_broadcast(conn, no_conn, conn_list, message);
if (err)
{
com_err(argv[0], err, "in send_broadcast");
ncp_close(conn);
exit(1);
}
}
ncp_close(conn);
return 0;

View File

@@ -14,12 +14,14 @@
static char *progname;
static void usage(void)
static void
usage(void)
{
fprintf(stderr, "usage: %s [options]\n", progname);
}
static void help(void)
static void
help(void)
{
printf("\n");
printf("usage: %s [options]\n", progname);
@@ -31,18 +33,21 @@ static void help(void)
"\n");
}
static void swallow_error(const char *s, long x, const char *t, va_list arg)
static void
swallow_error(const char *s, long x, const char *t, va_list arg)
{
return;
}
int main(int argc, char *argv[])
int
main(int argc, char *argv[])
{
struct ncp_conn_spec *spec;
struct ncp_conn *conn;
char *server = NULL;
char *object_name = NULL;
int object_type = NCP_BINDERY_USER;
struct sockaddr_ipx addr;
long err;
char *str;
@@ -51,11 +56,14 @@ int main(int argc, char *argv[])
progname = argv[0];
if (!isatty(0)) {
if (!isatty(0))
{
set_com_err_hook(swallow_error);
}
while ((opt = getopt(argc, argv, "h?S:U:t:")) != EOF) {
switch (opt) {
while ((opt = getopt(argc, argv, "h?S:U:t:")) != EOF)
{
switch (opt)
{
case 'S':
server = optarg;
break;
@@ -78,31 +86,37 @@ int main(int argc, char *argv[])
spec = ncp_find_conn_spec(server, object_name, "",
1, getuid(), &err);
if (spec == NULL) {
if (spec == NULL)
{
com_err(argv[0], err, "when trying to find server");
exit(1);
}
if (ncp_find_fileserver(spec->server, &err) == NULL) {
if ((err = ncp_find_fileserver(spec->server, (struct sockaddr*)&addr, sizeof(addr))) != 0)
{
com_err(argv[0], err, "when trying to find server");
exit(1);
}
spec->login_type = object_type;
memset(spec->password, 0, sizeof(spec->password));
if (isatty(0)) {
if (isatty(0))
{
str = getpass("Enter password: ");
if (strlen(str) >= sizeof(spec->password)) {
if (strlen(str) >= sizeof(spec->password))
{
printf("Password too long\n");
exit(1);
}
strcpy(spec->password, str);
} else {
} else
{
fgets(spec->password, sizeof(spec->password), stdin);
}
str_upper(spec->password);
if ((conn = ncp_open(spec, &err)) == NULL) {
if ((conn = ncp_open(spec, &err)) == NULL)
{
com_err(argv[0], err, "when trying to open connection");
exit(1);
}

View File

@@ -13,12 +13,14 @@
static char *progname;
static void usage(void)
static void
usage(void)
{
fprintf(stderr, "usage: %s [options]\n", progname);
}
static void help(void)
static void
help(void)
{
printf("\n");
printf("usage: %s [options]\n", progname);
@@ -37,27 +39,34 @@ static void help(void)
"\n");
}
static int parse_security(const char *security)
static int
parse_security(const char *security)
{
if (strcasecmp(security, "anyone") == 0) {
if (strcasecmp(security, "anyone") == 0)
{
return 0;
}
if (strcasecmp(security, "logged") == 0) {
if (strcasecmp(security, "logged") == 0)
{
return 1;
}
if (strcasecmp(security, "object") == 0) {
if (strcasecmp(security, "object") == 0)
{
return 2;
}
if (strcasecmp(security, "supervisor") == 0) {
if (strcasecmp(security, "supervisor") == 0)
{
return 3;
}
if (strcasecmp(security, "netware") == 0) {
if (strcasecmp(security, "netware") == 0)
{
return 4;
}
return -1;
}
int main(int argc, char *argv[])
int
main(int argc, char *argv[])
{
struct ncp_conn *conn;
char *object_name = NULL;
@@ -72,12 +81,15 @@ int main(int argc, char *argv[])
progname = argv[0];
if ((conn = ncp_initialize(&argc, argv, 1, &err)) == NULL) {
if ((conn = ncp_initialize(&argc, argv, 1, &err)) == NULL)
{
com_err(argv[0], err, "when initializing");
goto finished;
}
while ((opt = getopt(argc, argv, "h?o:t:r:w:")) != EOF) {
switch (opt) {
while ((opt = getopt(argc, argv, "h?o:t:r:w:")) != EOF)
{
switch (opt)
{
case 'o':
object_name = optarg;
str_upper(object_name);
@@ -87,7 +99,8 @@ int main(int argc, char *argv[])
break;
case 'r':
read_sec = parse_security(optarg);
if (read_sec < 0) {
if (read_sec < 0)
{
fprintf(stderr,
"%s: Wrong read security\n"
"Must be one of anyone, logged, "
@@ -98,7 +111,8 @@ int main(int argc, char *argv[])
break;
case 'w':
write_sec = parse_security(optarg);
if (write_sec < 0) {
if (write_sec < 0)
{
fprintf(stderr,
"%s: Wrong write security\n"
"Must be one of anyone, logged, "
@@ -117,20 +131,24 @@ int main(int argc, char *argv[])
}
}
if (object_type < 0) {
if (object_type < 0)
{
fprintf(stderr, "%s: You must specify an object type\n",
argv[0]);
goto finished;
}
if (object_name == NULL) {
if (object_name == NULL)
{
fprintf(stderr, "%s: You must specify an object name\n",
argv[0]);
goto finished;
}
if (ncp_create_bindery_object(conn, object_type, object_name,
(write_sec << 4) + read_sec, 0) != 0) {
(write_sec << 4) + read_sec, 0) != 0)
{
fprintf(stderr, "%s: Could not create the object\n", argv[0]);
} else {
} else
{
result = 0;
}

View File

@@ -15,13 +15,15 @@
static char *progname;
static void usage(void)
static void
usage(void)
{
fprintf(stderr, "usage: %s [options] pattern\n", progname);
return;
}
static void help(void)
static void
help(void)
{
printf("\n");
printf("usage: %s [options]\n", progname);
@@ -39,7 +41,8 @@ static void help(void)
"\n");
}
int main(int argc, char **argv)
int
main(int argc, char **argv)
{
struct ncp_conn *conn;
struct ncp_bindery_object o;
@@ -55,12 +58,15 @@ int main(int argc, char **argv)
progname = argv[0];
if ((conn = ncp_initialize(&argc, argv, 1, &err)) == NULL) {
if ((conn = ncp_initialize(&argc, argv, 1, &err)) == NULL)
{
com_err(argv[0], err, "when initializing");
return 1;
}
while ((opt = getopt(argc, argv, "h?vt:o:")) != EOF) {
switch (opt) {
while ((opt = getopt(argc, argv, "h?vt:o:")) != EOF)
{
switch (opt)
{
case 'h':
case '?':
help();
@@ -80,26 +86,31 @@ int main(int argc, char **argv)
}
}
if (optind < argc) {
if (optind < argc)
{
usage();
exit(1);
}
for (p = pattern; *p != '\0'; p++) {
for (p = pattern; *p != '\0'; p++)
{
*p = toupper(*p);
}
o.object_id = 0xffffffff;
while (ncp_scan_bindery_object(conn, o.object_id,
type, pattern, &o) == 0) {
type, pattern, &o) == 0)
{
found = 1;
if (verbose != 0) {
if (verbose != 0)
{
printf("%s %08X %04X %d %02X %d\n",
o.object_name, (unsigned int) o.object_id,
(unsigned int) o.object_type,
o.object_flags, o.object_security,
o.object_has_prop);
} else {
} else
{
printf("%s %08X %04X\n",
o.object_name, (unsigned int) o.object_id,
(unsigned int) o.object_type);

View File

@@ -13,12 +13,14 @@
static char *progname;
static void usage(void)
static void
usage(void)
{
fprintf(stderr, "usage: %s [options]\n", progname);
}
static void help(void)
static void
help(void)
{
printf("\n");
printf("usage: %s [options]\n", progname);
@@ -36,7 +38,8 @@ static void help(void)
"\n");
}
int main(int argc, char *argv[])
int
main(int argc, char *argv[])
{
struct ncp_conn *conn;
char *object_name = NULL;
@@ -51,12 +54,15 @@ int main(int argc, char *argv[])
progname = argv[0];
if ((conn = ncp_initialize(&argc, argv, 1, &err)) == NULL) {
if ((conn = ncp_initialize(&argc, argv, 1, &err)) == NULL)
{
com_err(argv[0], err, "when initializing");
goto finished;
}
while ((opt = getopt(argc, argv, "h?o:t:v")) != EOF) {
switch (opt) {
while ((opt = getopt(argc, argv, "h?o:t:v")) != EOF)
{
switch (opt)
{
case 'o':
object_name = optarg;
str_upper(object_name);
@@ -77,12 +83,14 @@ int main(int argc, char *argv[])
}
}
if (object_type < 0) {
if (object_type < 0)
{
fprintf(stderr, "%s: You must specify an object type\n",
argv[0]);
goto finished;
}
if (object_name == NULL) {
if (object_name == NULL)
{
fprintf(stderr, "%s: You must specify an object name\n",
argv[0]);
goto finished;
@@ -90,13 +98,16 @@ int main(int argc, char *argv[])
info.search_instance = 0xffffffff;
while (ncp_scan_property(conn, object_type, object_name,
info.search_instance, "*", &info) == 0) {
if (verbose != 0) {
info.search_instance, "*", &info) == 0)
{
if (verbose != 0)
{
printf("%s %d %02x %d\n",
info.property_name, info.property_flags,
info.property_security,
info.value_available_flag);
} else {
} else
{
printf("%s\n", info.property_name);
}
}

View File

@@ -13,12 +13,14 @@
static char *progname;
static void usage(void)
static void
usage(void)
{
fprintf(stderr, "usage: %s [options]\n", progname);
}
static void help(void)
static void
help(void)
{
printf("\n");
printf("usage: %s [options]\n", progname);
@@ -35,7 +37,8 @@ static void help(void)
"\n");
}
int main(int argc, char *argv[])
int
main(int argc, char *argv[])
{
struct ncp_conn *conn;
char *object_name = NULL;
@@ -48,12 +51,15 @@ int main(int argc, char *argv[])
progname = argv[0];
if ((conn = ncp_initialize(&argc, argv, 1, &err)) == NULL) {
if ((conn = ncp_initialize(&argc, argv, 1, &err)) == NULL)
{
com_err(argv[0], err, "when initializing");
goto finished;
}
while ((opt = getopt(argc, argv, "h?o:t:")) != EOF) {
switch (opt) {
while ((opt = getopt(argc, argv, "h?o:t:")) != EOF)
{
switch (opt)
{
case 'o':
object_name = optarg;
str_upper(object_name);
@@ -71,19 +77,23 @@ int main(int argc, char *argv[])
}
}
if (object_type < 0) {
if (object_type < 0)
{
fprintf(stderr, "%s: You must specify an object type\n",
argv[0]);
goto finished;
}
if (object_name == NULL) {
if (object_name == NULL)
{
fprintf(stderr, "%s: You must specify an object name\n",
argv[0]);
goto finished;
}
if (ncp_delete_bindery_object(conn, object_type, object_name) != 0) {
if (ncp_delete_bindery_object(conn, object_type, object_name) != 0)
{
fprintf(stderr, "%s: Could not delete the object\n", argv[0]);
} else {
} else
{
result = 0;
}

View File

@@ -13,12 +13,14 @@
static char *progname;
static void usage(void)
static void
usage(void)
{
fprintf(stderr, "usage: %s [options]\n", progname);
}
static void help(void)
static void
help(void)
{
printf("\n");
printf("usage: %s [options] [values]\n", progname);
@@ -36,15 +38,16 @@ static void help(void)
"value value to be added\n"
"\n"
"If property is of type SET, value is an object id (hex)\n"
"Otherwise, value is either a string value to be written, or\n"
"a count of bytes to be written. The latter is assumed if\n"
"more than one value argument is given. The count is decimal,\n"
"Otherwise, value is either a string value to be written, or\n"
"a count of bytes to be written. The latter is assumed if\n"
"more than one value argument is given. The count is decimal,\n"
"and the following arguments are interpreted as bytes in\n"
"hexadecimal notation.\n"
"\n");
}
int main(int argc, char *argv[])
int
main(int argc, char *argv[])
{
struct ncp_conn *conn;
char *object_name = NULL;
@@ -58,12 +61,15 @@ int main(int argc, char *argv[])
progname = argv[0];
if ((conn = ncp_initialize(&argc, argv, 1, &err)) == NULL) {
if ((conn = ncp_initialize(&argc, argv, 1, &err)) == NULL)
{
com_err(argv[0], err, "when initializing");
goto finished;
}
while ((opt = getopt(argc, argv, "h?o:t:p:v:")) != EOF) {
switch (opt) {
while ((opt = getopt(argc, argv, "h?o:t:p:v:")) != EOF)
{
switch (opt)
{
case 'o':
object_name = optarg;
str_upper(object_name);
@@ -73,7 +79,8 @@ int main(int argc, char *argv[])
break;
case 'p':
property_name = optarg;
if (strlen(property_name) > 15) {
if (strlen(property_name) > 15)
{
fprintf(stderr, "%s: Property Name too long\n",
argv[0]);
exit(1);
@@ -93,22 +100,26 @@ int main(int argc, char *argv[])
}
}
if (object_type < 0) {
if (object_type < 0)
{
fprintf(stderr, "%s: You must specify an object type\n",
argv[0]);
goto finished;
}
if (object_name == NULL) {
if (object_name == NULL)
{
fprintf(stderr, "%s: You must specify an object name\n",
argv[0]);
goto finished;
}
if (property_name == NULL) {
if (property_name == NULL)
{
fprintf(stderr, "%s: You must specify a property name\n",
argv[0]);
goto finished;
}
if (optind > argc - 1) {
if (optind > argc - 1)
{
fprintf(stderr, "%s: You must specify a property value\n",
argv[0]);
goto finished;
@@ -117,35 +128,41 @@ int main(int argc, char *argv[])
optind += 1;
if (ncp_scan_property(conn, object_type, object_name,
0xffffffff, property_name, &info) != 0) {
0xffffffff, property_name, &info) != 0)
{
fprintf(stderr, "%s: Could not find property\n", argv[0]);
goto finished;
}
if ((info.property_flags & 2) != 0) {
if ((info.property_flags & 2) != 0)
{
/* Property is of type SET */
struct ncp_bindery_object o;
if (optind != argc) {
if (optind != argc)
{
fprintf(stderr, "%s: For the SET property %s, you must"
" specify an object id as value\n",
progname, property_name);
goto finished;
}
if (ncp_get_bindery_object_name(conn,
ntohl(strtol(value, NULL, 16)),
&o) != 0) {
ntohl(strtol(value, NULL, 16)),
&o) != 0)
{
fprintf(stderr, "%s: %s is not a valid object id\n",
progname, value);
goto finished;
}
if (ncp_add_object_to_set(conn, object_type, object_name,
property_name,
o.object_type, o.object_name) != 0) {
o.object_type, o.object_name) != 0)
{
fprintf(stderr, "%s: could not add object %s\n",
progname, o.object_name);
goto finished;
}
} else {
} else
{
/* Property is of type ITEM */
char contents[255 * 128];
int segno = 1;
@@ -153,42 +170,50 @@ int main(int argc, char *argv[])
memset(contents, 0, sizeof(contents));
if (optind == argc) {
if (optind == argc)
{
/* value is the string to add */
length = strlen(value);
if (length >= sizeof(contents)) {
if (length >= sizeof(contents))
{
fprintf(stderr, "%s: Value too long\n",
progname);
goto finished;
}
strcpy(contents, value);
} else {
} else
{
/* value is the byte count */
int i;
length = atoi(value);
if (length >= sizeof(contents)) {
if (length >= sizeof(contents))
{
fprintf(stderr, "%s: Value too long\n",
progname);
goto finished;
}
if (optind != argc - length) {
if (optind != argc - length)
{
fprintf(stderr, "%s: Byte count does not match"
" number of bytes\n", progname);
goto finished;
}
i = 0;
while (optind < argc) {
while (optind < argc)
{
contents[i] = strtol(argv[optind], NULL, 16);
i += 1;
optind += 1;
}
}
for (segno = 1; segno <= 255; segno++) {
for (segno = 1; segno <= 255; segno++)
{
struct nw_property segment;
int offset = (segno - 1) * 128;
if (offset > length) {
if (offset > length)
{
/* everything written */
break;
}
@@ -197,7 +222,8 @@ int main(int argc, char *argv[])
if (ncp_write_property_value(conn, object_type,
object_name,
property_name,
segno, &segment) != 0) {
segno, &segment) != 0)
{
fprintf(stderr, "%s: Could not write "
"property\n", progname);
goto finished;

View File

@@ -13,12 +13,14 @@
static char *progname;
static void usage(void)
static void
usage(void)
{
fprintf(stderr, "usage: %s [options]\n", progname);
}
static void help(void)
static void
help(void)
{
printf("\n");
printf("usage: %s [options]\n", progname);
@@ -39,27 +41,34 @@ static void help(void)
"\n");
}
static int parse_security(const char *security)
static int
parse_security(const char *security)
{
if (strcasecmp(security, "anyone") == 0) {
if (strcasecmp(security, "anyone") == 0)
{
return 0;
}
if (strcasecmp(security, "logged") == 0) {
if (strcasecmp(security, "logged") == 0)
{
return 1;
}
if (strcasecmp(security, "object") == 0) {
if (strcasecmp(security, "object") == 0)
{
return 2;
}
if (strcasecmp(security, "supervisor") == 0) {
if (strcasecmp(security, "supervisor") == 0)
{
return 3;
}
if (strcasecmp(security, "netware") == 0) {
if (strcasecmp(security, "netware") == 0)
{
return 4;
}
return -1;
}
int main(int argc, char *argv[])
int
main(int argc, char *argv[])
{
struct ncp_conn *conn;
char *object_name = NULL;
@@ -76,12 +85,15 @@ int main(int argc, char *argv[])
progname = argv[0];
if ((conn = ncp_initialize(&argc, argv, 1, &err)) == NULL) {
if ((conn = ncp_initialize(&argc, argv, 1, &err)) == NULL)
{
com_err(argv[0], err, "when initializing");
goto finished;
}
while ((opt = getopt(argc, argv, "h?o:t:p:sr:w:")) != EOF) {
switch (opt) {
while ((opt = getopt(argc, argv, "h?o:t:p:sr:w:")) != EOF)
{
switch (opt)
{
case 'o':
object_name = optarg;
str_upper(object_name);
@@ -91,7 +103,8 @@ int main(int argc, char *argv[])
break;
case 'p':
property_name = optarg;
if (strlen(property_name) > 15) {
if (strlen(property_name) > 15)
{
fprintf(stderr, "%s: Property Name too long\n",
argv[0]);
exit(1);
@@ -103,7 +116,8 @@ int main(int argc, char *argv[])
break;
case 'r':
read_sec = parse_security(optarg);
if (read_sec < 0) {
if (read_sec < 0)
{
fprintf(stderr,
"%s: Wrong read security\n"
"Must be one of anyone, logged, "
@@ -114,7 +128,8 @@ int main(int argc, char *argv[])
break;
case 'w':
write_sec = parse_security(optarg);
if (write_sec < 0) {
if (write_sec < 0)
{
fprintf(stderr,
"%s: Wrong write security\n"
"Must be one of anyone, logged, "
@@ -133,17 +148,20 @@ int main(int argc, char *argv[])
}
}
if (object_type < 0) {
if (object_type < 0)
{
fprintf(stderr, "%s: You must specify an object type\n",
argv[0]);
goto finished;
}
if (object_name == NULL) {
if (object_name == NULL)
{
fprintf(stderr, "%s: You must specify an object name\n",
argv[0]);
goto finished;
}
if (property_name == NULL) {
if (property_name == NULL)
{
fprintf(stderr, "%s: You must specify a property name\n",
argv[0]);
goto finished;
@@ -151,9 +169,11 @@ int main(int argc, char *argv[])
if (ncp_create_property(conn, object_type, object_name,
property_name,
property_is_set ? 2 : 0,
(write_sec << 4) + read_sec) != 0) {
(write_sec << 4) + read_sec) != 0)
{
fprintf(stderr, "%s: Could not create the property\n", argv[0]);
} else {
} else
{
result = 0;
}

Some files were not shown because too many files have changed in this diff Show More