Compare commits

..

5 Commits

Author SHA1 Message Date
ncpfs archive import
f813517d69 Import ncpfs 2.0.12 2026-04-28 20:39:59 +02:00
ncpfs archive import
915f560f85 Import ncpfs 2.0.11 2026-04-28 20:39:59 +02:00
ncpfs archive import
1a5653d403 Import ncpfs 2.0.10 2026-04-28 20:39:58 +02:00
ncpfs archive import
f88460b2e6 Import ncpfs 2.0.9 2026-04-28 20:39:58 +02:00
ncpfs archive import
fff159f2db Import ncpfs 2.0.8 2026-04-28 20:39:58 +02:00
141 changed files with 13745 additions and 9179 deletions

BIN
.downloads/ncpfs-2.0.10.tgz Normal file

Binary file not shown.

BIN
.downloads/ncpfs-2.0.11.tgz Normal file

Binary file not shown.

BIN
.downloads/ncpfs-2.0.12.tgz Normal file

Binary file not shown.

BIN
.downloads/ncpfs-2.0.8.tgz Normal file

Binary file not shown.

BIN
.downloads/ncpfs-2.0.9.tgz Normal file

Binary file not shown.

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

98
Changes
View File

@@ -1,6 +1,104 @@
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.
[Versions ncpfs-2.0.11.x are available at ftp://platan.vc.cvut.cz/pub/linux/ncpfs]
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 allways listed lowercased on 2.1.x
ncpfs-2.0.11.16 -> ncpfs-2.0.11.17
- 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: 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@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@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@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?)
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 ;-)
- Made the manpages a little bit prettier
ncpfs-2.0.8 -> ncpfs-2.0.9
- Added patches directory
- Added nwvolinfo and nwtrustee. Thanks to Jacek Stepniewski <cunio@gazeta.pl>
- nwpasswd can change other's passwords. Thanks to Martin Stover.
ncpfs-2.0.7 -> ncpfs-2.0.8
- Fixed util/Makefile for easier optimization handling. Thanks to Rik
Faith <faith@cs.unc.edu> for this one
- added nwfstime. You can now set the file server date and time from Linux.
- added the contrib directory. Feel free to add more!
ncpfs-2.0.6 -> ncpfs-2.0.7
- Hopefully removed one security problem in ncpumount.
- Added command line flag to pserver.c

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,11 +2,11 @@
# Makefile for the linux ncp-filesystem routines.
#
VERSION = 2.0.7
VERSION = 2.0.12
# If you are using kerneld to autoload ncp support,
# uncomment this (kerneld is in linux since about 1.3.57):
#KERNELD = -DHAVE_KERNELD
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
@@ -14,6 +14,24 @@ VERSION = 2.0.7
HAVE_ELF=$(shell file `whereis gcc|cut -d ' ' -f 2`| \
grep ELF >/dev/null && echo -n yes )
# 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
# Include code for Linux2.0.x
MOUNT2 = 1
# Include code for Linux2.1.x
MOUNT3 = 1
TOPDIR = $(shell pwd)
BINDIR = /usr/bin
SBINDIR = /sbin
@@ -23,20 +41,15 @@ KVERSION=$(shell uname -r | cut -b1-3)
INCLUDES=-I$(TOPDIR)/include
ifeq ($(KVERSION),1.2)
SUBDIRS += kernel-1.2/src
INCLUDES += -I$(TOPDIR)/kernel-1.2
endif
COPT = -O2
# COPT += -g
CFLAGS = $(COPT) -Wall $(INCLUDES) $(KERNELD) -DNCPFS_VERSION=\"$(VERSION)\"
CFLAGS = -Wall $(INCLUDES) $(KERNELD) -DNCPFS_VERSION=\"$(VERSION)\"
#CFLAGS += -g
CFLAGS += -O2
export INCLUDES BINDIR SBINDIR KERNELD VERSION HAVE_ELF CFLAGS
export INCLUDES BINDIR SBINDIR KERNELD VERSION HAVE_ELF CFLAGS NDS_SUPPORT \
SIGNATURES MOUNT2 MOUNT3
all:
for i in $(SUBDIRS); do make -C $$i all; done
set -e; for i in $(SUBDIRS); do make -C $$i all; done
@if [ "$(HAVE_ELF)" = yes ] ;\
then \
echo ; echo ; echo ;\
@@ -58,7 +71,7 @@ install:
clean_me:
rm -f `find -name '*.out'`
rm -f `find -name '*~'`
rm -f ncpfs.tgz
rm -f *.tgz
clean: clean_me
for i in $(SUBDIRS); do make -C $$i clean; done
@@ -72,15 +85,13 @@ SRCPATH=$(shell pwd)
SRCDIR=$(shell basename $(SRCPATH))
DISTFILE=$(SRCDIR).tgz
dist: mrproper
(cd ..; \
tar cvf - $(SRCDIR) | \
gzip -9 > $(DISTFILE); \
mv $(DISTFILE) $(SRCDIR))
dist: tgz
make dep
make all
tgz: mrproper
tgz:
indent -kr -i8 `find . -name '*.[ch]'`
make mrproper
(cd ..; \
tar cvf - $(SRCDIR) | \
gzip -9 > $(DISTFILE); \

30
README
View File

@@ -32,28 +32,18 @@ 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.
The installation of ncpfs depends on the kernel version you are
using. For kernel 1.2, you should simply type 'make' and look at
what's in the bin/ directory after that. Please be sure that your
kernel resides in /usr/src/linux, because the file
kernel-1.2/src/sock.c has to refer directly to it.
If you use Kernel 1.3, please be sure that you use at least
1.3.71. ncpfs does NOT work with any earlier 1.3.x kernel.
If you use Kernel 1.3.71 or later, you might have to recompile your
kernel. With these kernels, the kernel part of ncpfs is already
included in the main source tree. If you want to use ncpfs, you should
say 'y' to 'make config' when you are asked for IPX, and again when it
asks for ncpfs. After you have rebooted with the new kernel, 'cat
/proc/filesystems' should show you a line saying that the kernel knows
ncpfs.
If you are running kerneld, please uncomment the corresponding line in
If you are not running kerneld, please comment the corresponding line in
the Makefile to reflect this.
If your system is ELF, please enable the use of the shared ncp-library
in the Makefile. This will save at least 1MB of disk space.
If you are not using 2.0.x kernels, you can comment out MOUNT2=1 line
in the Makefile.
If you are not using 2.1.x kernels, you can comment out MOUNT3=1 line
in the Makefile.
If you are not using NDS access, you can comment out NDS_SUPPORT=1 in
the Makefile.
If you are not using packet signatures, you can comment out SIGNATURES=1
in the Makefile.
After you adapted your Makefile, type 'make' and, as root, 'make install'.

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

12
TODO
View File

@@ -1,12 +0,0 @@
Here's a list of things I want to do. Feel free to send suggestions,
or even help me ;-).
- do rtt estimation, like tcp does.
- Do better connection management. I imagine to create a ncpd.
- When ncpd is done, one can think about mounting several volumes over
a single NCP connection. This should make the trade-off mentioned in
ncpmount.8 unnecessary.
- Do some kind of mapping of NCP uid's to unix uid's

232
contrib/tknwmsg/nwmsg.c Normal file
View File

@@ -0,0 +1,232 @@
/*
* nwmsg.c
*
* Fetch NetWare broadcast messages and write to the user
*
* Copyright (C) 1996 by Volker Lendecke
*
*/
#include <pwd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/ioctl.h>
#include <sys/wait.h>
#include <unistd.h>
#include <syslog.h>
#include <signal.h>
#include <paths.h>
#include <utmp.h>
#include <mntent.h>
#include "ncplib.h"
static int search_utmp(char *user, char *tty);
static char *progname;
void
main(int argc, char *argv[])
{
struct ncp_conn *conn;
char message[256];
char *mount_point;
struct ncp_fs_info info;
struct passwd *pwd;
char tty[256];
char tty_path[256];
FILE *tty_file;
FILE *mtab;
struct mntent *mnt;
long err;
char tknwmsg_command[256];
int error_level;
progname = argv[0];
openlog("nwmsg", LOG_PID, LOG_LPR);
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)
{
com_err(progname, err, "in ncp_open_mount");
exit(1);
}
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)
{
syslog(LOG_DEBUG, "no message");
exit(0);
}
#if 0
syslog(LOG_DEBUG, "message: %s", message);
#endif
info.version = NCP_GET_FS_INFO_VERSION;
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);
exit(1);
}
ncp_close(conn);
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)
{
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)
{
break;
}
}
if (mnt == NULL)
{
syslog(LOG_DEBUG, "cannot find mtab entry\n");
}
if (search_utmp(pwd->pw_name, tty) != 0)
{
exit(1);
}
sprintf(tty_path, "/dev/%s", tty);
if ((tty_file = fopen(tty_path, "w")) == NULL)
{
fprintf(stderr, "%s: cannot open %s: %s\n",
progname, tty_path, strerror(errno));
exit(1);
}
fprintf(tty_file, "\r\n\007\007\007Message from NetWare Server: %s\r\n",
mnt->mnt_fsname);
fprintf(tty_file, "%s\r\n", message);
//formulate the full system command for the X notice...
strcat(tknwmsg_command, "/usr/bin/tknwmsg -display :0 ");
strcat(tknwmsg_command, "Message from NetWare Server: ");
strcat(tknwmsg_command, mnt->mnt_fsname);
strcat(tknwmsg_command, " ");
strcat(tknwmsg_command, message);
strcat(tknwmsg_command, " &");
//execute this system command...
error_level = system(tknwmsg_command);
fclose(tty_file);
fclose(mtab);
return;
}
/* The following routines have been taken from util-linux-2.5's write.c */
/*
* 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)
{
struct stat s;
char path[MAXPATHLEN];
(void) sprintf(path, "/dev/%s", tty);
if (stat(path, &s) < 0)
{
if (showerror)
(void) fprintf(stderr,
"write: %s: %s\n", path, strerror(errno));
return (1);
}
*msgsokP = (s.st_mode & (S_IWRITE >> 3)) != 0; /* group write bit */
*atimeP = s.st_atime;
return (0);
}
/*
* search_utmp - search utmp for the "best" terminal to write to
*
* Ignores terminals with messages disabled, and of the rest, returns
* the one with the most recent access time. Returns as value the number
* of the user's terminals with messages enabled, or -1 if the user is
* not logged in at all.
*
* 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)
{
struct utmp u;
time_t bestatime, atime;
int ufd, nloggedttys, nttys, msgsok, user_is_me;
char atty[sizeof(u.ut_line) + 1];
if ((ufd = open(_PATH_UTMP, O_RDONLY)) < 0)
{
perror("utmp");
return -1;
}
nloggedttys = nttys = 0;
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)
{
++nloggedttys;
(void) strncpy(atty, u.ut_line, sizeof(u.ut_line));
atty[sizeof(u.ut_line)] = '\0';
if (term_chk(atty, &msgsok, &atime, 0))
continue; /* bad term? skip */
if (!msgsok)
continue; /* skip ttys with msgs off */
if (u.ut_type != USER_PROCESS)
continue; /* it's not a valid entry */
++nttys;
if (atime > bestatime)
{
bestatime = atime;
(void) strcpy(tty, atty);
}
}
(void) close(ufd);
if (nloggedttys == 0)
{
(void) fprintf(stderr, "write: %s is not logged in\n", user);
return -1;
}
return 0;
}

57
contrib/tknwmsg/tknwmsg Executable file
View File

@@ -0,0 +1,57 @@
#!/usr/bin/wish
#This is a procedure for centering windows...
#
#
proc center {window_to_center} {
update idletasks
set width [expr [winfo reqwidth $window_to_center]]
set height [expr [winfo reqheight $window_to_center]]
if {$width < 400} {set width 400}
set x [expr [winfo screenwidth $window_to_center]/2 - $width/2]
set y [expr [winfo screenheight $window_to_center]/2 - $height/2]
wm geometry $window_to_center $width\x$height+$x+$y
#update idletasks
wm deiconify $window_to_center
}
#
#
#
#
#This is the main() proc...
set argv_exist [string length $argv]
if {$argv_exist <= 0} {puts "syntax: tkmesg string\a";exit}
wm withdraw .
wm title . "Netware Client for Linux"
wm resizable . 0 0
puts "\a"
label .mesg -text $argv
pack .mesg -padx 5 -pady 5
button .ok -text "Ok" -command exit -width 5
pack .ok -padx 5 -pady 5
focus .ok
bind .ok <Return> exit
center .
#beep the users console after the window appears...
set ofd [open /dev/console w]
puts $ofd "\a"
close $ofd

BIN
contrib/tknwmsg/tknwmsg.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

View File

@@ -0,0 +1,29 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
<HTML>
<HEAD>
<TITLE></TITLE>
<META NAME="GENERATOR" CONTENT="Mozilla/3.01Gold (X11; I; Linux 2.0.25 i586) [Netscape]">
</HEAD>
<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#0000EF" VLINK="#51188E" ALINK="#FF0000">
<CENTER><P><FONT SIZE=+3>Tknwmsg</FONT></P></CENTER>
<P>Recieve NetWare broadcasts in a dialog under Linux.</P>
<P>The original source was included in the ncpfs package distributed on
sunsite.unc.edu. The modified source to nwmsg.c and a tcl/tk script can
be downloaded here. The <A HREF="tknwmsg_README">tknwmsg_README</A> is
also available for download.</P>
<P>The only requirements for installation are a system with tcl/tk installed
and X running. The system()&nbsp;command will fail if X is not running.</P>
<P>
<HR WIDTH="100%"></P>
<P><A HREF="mailto:kburto1@umbc.edu">Kevin Burton</A></P>
<P><A HREF="http://www.gl.umbc.edu/~kburto1/kburto1.html">http://www.gl.umbc.edu/~kburto1/kburto1.html</A></P>
</BODY>
</HTML>

View File

@@ -0,0 +1,40 @@
Tknwmsg 1.0 for NCPFS.
Kevin Burton (kburto1@umbc.edu), Copyright 1996
Distributed under GPL (GNU Public License)
-- INTRO --
Tknwmesg is a extension for ncpfs for linux that allows users to recived messages
while under an X console.
Essentially it is an extension for nwmsg that comes with ncpfs. The only
changes are a system() call to a tk script that will run a dialog with an "ok"
button under X.
-- INSTALLATION --
TCL/TK must be installed on your system. If they are not then you will have to
get the source for their installation if you want to run tkmesg.
- Download ncpfs from sunsite.unc.edu
- Run "su" to become root if you are not already root.
- Unpack ncpfs in a temporary directory.
- copy the Tknwmsg nwmsg.c to util/nwmsg.c in your ncpfs directory.
- copy tknwmsg to /usr/bin
- change to your nwmsg directory.
- run "make all;make install" and the new version of tknwmsg will be
installed.
-- USE --
- At least 1 terminal on the local system must be have "mesg y". Else
no GUI dialog will be displayed.
Using mesg y in a .bashrc will not work. The only way that I have
found to do this is to have chmod a+w /dev/ttyp? in Xsession or
$HOME/.xsession. Also it may be necessary to have .bashrc do the
same thing if users are starting and stopping xterms.

View File

@@ -16,25 +16,25 @@ typedef long errcode_t;
#include <stdarg.h>
/* ANSI C -- use prototypes etc */
void com_err (const char *, long, const char *, ...);
void com_err_va (const char *whoami, errcode_t code, const char *fmt,
va_list args);
char const *error_message (long);
void com_err(const char *, long, const char *,...);
void com_err_va(const char *whoami, errcode_t code, const char *fmt,
va_list args);
char const *error_message(long);
extern void (*com_err_hook) (const char *, long, const char *, va_list);
void (*set_com_err_hook (void (*) (const char *, long, const char *, va_list)))
(const char *, long, const char *, va_list);
void (*reset_com_err_hook (void)) (const char *, long, const char *, va_list);
int init_error_table(const char * const *msgs, int base, int count);
void (*set_com_err_hook(void (*)(const char *, long, const char *, va_list)))
(const char *, long, const char *, va_list);
void (*reset_com_err_hook(void)) (const char *, long, const char *, va_list);
int init_error_table(const char *const *msgs, int base, int count);
#else
/* no prototypes */
void com_err ();
void com_err_va ();
char *error_message ();
void com_err();
void com_err_va();
char *error_message();
extern void (*com_err_hook) ();
void (*set_com_err_hook ()) ();
void (*reset_com_err_hook ()) ();
void (*set_com_err_hook()) ();
void (*reset_com_err_hook()) ();
int init_error_table();
#endif
#define __COM_ERR_H
#endif /* ! defined(__COM_ERR_H) */
#endif /* ! defined(__COM_ERR_H) */

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,16 +8,13 @@
#ifndef _IPXLIB_H
#define _IPXLIB_H
#include "kernel/types.h"
#include "ncp.h"
#include "kernel/ipx.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];
typedef u_int32_t IPXNet;
typedef u_int16_t IPXPort;
typedef u_int8_t IPXNode[IPX_NODE_LEN];
#define IPX_USER_PTYPE (0x00)
#define IPX_RIP_PTYPE (0x01)
@@ -33,30 +30,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_int16_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")
@@ -68,26 +70,31 @@ struct ipx_rip_packet {
#endif
void
ipx_print_node(IPXNode node);
ipx_print_node(IPXNode node);
void
ipx_print_network(IPXNet net);
ipx_print_network(IPXNet net);
void
ipx_print_port(IPXPort port);
ipx_print_port(IPXPort port);
void
ipx_print_saddr(struct sockaddr_ipx* sipx);
ipx_print_saddr(struct sockaddr_ipx *sipx);
void
ipx_fprint_node(FILE *file, IPXNode node);
ipx_fprint_node(FILE * file, IPXNode node);
void
ipx_fprint_network(FILE *file, IPXNet net);
ipx_fprint_network(FILE * file, IPXNet net);
void
ipx_fprint_port(FILE *file, IPXPort port);
ipx_fprint_port(FILE * file, IPXPort port);
void
ipx_fprint_saddr(FILE *file, struct sockaddr_ipx* sipx);
ipx_fprint_saddr(FILE * file, struct sockaddr_ipx *sipx);
int
ipx_sscanf_node(char *buf, unsigned char node[IPX_NODE_LEN]);
ipx_sscanf_node(char *buf, unsigned char node[IPX_NODE_LEN]);
void
ipx_assign_node(IPXNode dest, IPXNode src);
ipx_assign_node(IPXNode dest, IPXNode src);
int
ipx_node_equal(IPXNode n1,IPXNode n2);
ipx_node_equal(IPXNode n1, IPXNode n2);
#endif /* _IPXLIB_H */
#ifdef __MAKE_NCPMOUNT__
int
ipx_sscanf_saddr(char* buf, struct sockaddr_ipx* sipx);
#endif
#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

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

@@ -0,0 +1,11 @@
#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
#endif

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

@@ -0,0 +1,196 @@
/*
* 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
/* 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))
/* 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 */

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

@@ -0,0 +1,88 @@
/*
* 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;
};
#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)
/*
* 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 <asm/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__ */

122
include/ncp.h Normal file
View File

@@ -0,0 +1,122 @@
/*
* ncp.h
*
* Copyright (C) 1995 by Volker Lendecke
* Modified for sparc by J.F. Chadima
*
*/
#ifndef _NCP_H
#define _NCP_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)
#define NCP_BINDERY_PQUEUE (0x0003)
#define NCP_BINDERY_FSERVER (0x0004)
#define NCP_BINDERY_NAME_LEN (48)
struct ncp_bindery_object {
__u32 object_id;
__u16 object_type;
__u8 object_name[NCP_BINDERY_NAME_LEN];
__u8 object_flags;
__u8 object_security;
__u8 object_has_prop;
};
struct nw_property {
__u8 value[128];
__u8 more_flag;
__u8 property_flag;
};
struct prop_net_address {
__u32 network __attribute__((packed));
__u8 node[IPX_NODE_LEN] __attribute__((packed));
__u16 port __attribute__((packed));
};
struct ncp_filesearch_info {
__u8 volume_number;
__u16 directory_id;
__u16 sequence_no;
__u8 access_rights;
};
#define NCP_MAX_FILENAME (14)
struct ncp_file_info {
__u8 file_id[NCP_FILE_ID_LEN];
char file_name[NCP_MAX_FILENAME + 1];
__u8 file_attributes;
__u8 file_mode;
__u32 file_length;
__u16 creation_date;
__u16 access_date;
__u16 update_date;
__u16 update_time;
};
struct nw_queue_job_entry {
__u16 InUse __attribute__((packed));
__u32 prev __attribute__((packed));
__u32 next __attribute__((packed));
__u32 ClientStation __attribute__((packed));
__u32 ClientTask __attribute__((packed));
__u32 ClientObjectID __attribute__((packed));
__u32 TargetServerID __attribute__((packed));
__u8 TargetExecTime[6] __attribute__((packed));
__u8 JobEntryTime[6] __attribute__((packed));
__u32 JobNumber __attribute__((packed));
__u16 JobType __attribute__((packed));
__u16 JobPosition __attribute__((packed));
__u16 JobControlFlags __attribute__((packed));
__u8 FileNameLen __attribute__((packed));
char JobFileName[13] __attribute__((packed));
__u32 JobFileHandle __attribute__((packed));
__u32 ServerStation __attribute__((packed));
__u32 ServerTaskNumber __attribute__((packed));
__u32 ServerObjectID __attribute__((packed));
char JobTextDescription[50] __attribute__((packed));
char ClientRecordArea[152] __attribute__((packed));
};
struct queue_job {
struct nw_queue_job_entry j;
__u8 file_handle[6];
};
#define QJE_OPER_HOLD 0x80
#define QJE_USER_HOLD 0x40
#define QJE_ENTRYOPEN 0x20
#define QJE_SERV_RESTART 0x10
#define QJE_SERV_AUTO 0x08
/* ClientRecordArea for print jobs */
#define KEEP_ON 0x0400
#define NO_FORM_FEED 0x0800
#define NOTIFICATION 0x1000
#define DELETE_FILE 0x2000
#define EXPAND_TABS 0x4000
#define PRINT_BANNER 0x8000
struct print_job_record {
__u8 Version __attribute__((packed));
__u8 TabSize __attribute__((packed));
__u16 Copies __attribute__((packed));
__u16 CtrlFlags __attribute__((packed));
__u16 Lines __attribute__((packed));
__u16 Rows __attribute__((packed));
char FormName[16] __attribute__((packed));
__u8 Reserved[6] __attribute__((packed));
char BannerName[13] __attribute__((packed));
char FnameBanner[13] __attribute__((packed));
char FnameHeader[14] __attribute__((packed));
char Path[80] __attribute__((packed));
};
#endif /* _NCP_H */

View File

@@ -8,37 +8,129 @@
#ifndef _NCPLIB_H
#define _NCPLIB_H
#include <linux/types.h>
#include <linux/ncp.h>
#include <linux/ncp_fs.h>
#include <linux/ipx.h>
#include "ncp.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"
typedef __u8 byte;
typedef __u16 word;
typedef __u32 dword;
#ifndef memzero
#include <string.h>
#define memzero(object) memset(&(object), 0, sizeof(object))
#endif
void
str_upper(char *name);
#define BVAL(buf,pos) (((__u8 *)(buf))[pos])
#define PVAL(buf,pos) ((unsigned)BVAL(buf,pos))
#define BSET(buf,pos,val) (BVAL(buf,pos) = (val))
enum connect_state {
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 {
struct ncp_conn
{
enum connect_state is_connected;
char server[NCP_BINDERY_NAME_LEN];
char user [NCP_BINDERY_NAME_LEN];
char user[NCP_BINDERY_NAME_LEN];
struct ncp_fs_info i;
@@ -64,9 +156,17 @@ struct ncp_conn {
int lock;
char packet[NCP_PACKET_SIZE];
#ifdef SIGNATURES
/* Fields 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;
@@ -74,12 +174,14 @@ struct ncp_conn_spec {
char password[NCP_BINDERY_NAME_LEN];
};
struct ncp_search_seq {
struct ncp_search_seq
{
struct nw_search_sequence s;
int namespace;
};
struct ncp_property_info {
struct ncp_property_info
{
__u8 property_name[16];
__u8 property_flags;
__u8 property_security;
@@ -94,46 +196,47 @@ struct ncp_property_info {
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);
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);
ncp_initialize_as(int *argc, char **argv,
int login_necessary, int login_type, long *err);
/* 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);
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);
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);
ncp_find_fileserver(const char *server_name, long *err);
/* Find the address of a server */
struct sockaddr_ipx *
ncp_find_server(const char **server_name, int type, long *err);
ncp_find_server(const char **server_name, int type, long *err);
/* 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;
@@ -141,7 +244,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 ("-")
@@ -149,163 +252,173 @@ ncp_get_conn_ent(FILE *filep);
/* 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);
ncp_find_conn_spec(const char *server, const char *user, const char *password,
int login_necessary, uid_t uid, long *err);
long
ncp_get_file_server_description_strings(struct ncp_conn *conn,
char target[512]);
ncp_get_file_server_description_strings(struct ncp_conn *conn,
char target[512]);
long
ncp_get_file_server_time(struct ncp_conn *conn, time_t *target);
ncp_get_file_server_time(struct ncp_conn *conn, time_t * target);
long
ncp_set_file_server_time(struct ncp_conn *conn, time_t * source);
struct ncp_file_server_info {
__u8 ServerName[48] __attribute__ ((packed));
__u8 FileServiceVersion __attribute__ ((packed));
__u8 FileServiceSubVersion __attribute__ ((packed));
__u16 MaximumServiceConnections __attribute__ ((packed));
__u16 ConnectionsInUse __attribute__ ((packed));
__u16 NumberMountedVolumes __attribute__ ((packed));
__u8 Revision __attribute__ ((packed));
__u8 SFTLevel __attribute__ ((packed));
__u8 TTSLevel __attribute__ ((packed));
__u16 MaxConnectionsEverUsed __attribute__ ((packed));
__u8 AccountVersion __attribute__ ((packed));
__u8 VAPVersion __attribute__ ((packed));
__u8 QueueVersion __attribute__ ((packed));
__u8 PrintVersion __attribute__ ((packed));
__u8 VirtualConsoleVersion __attribute__ ((packed));
__u8 RestrictionLevel __attribute__ ((packed));
__u8 InternetBridge __attribute__ ((packed));
__u8 Reserved[60] __attribute__ ((packed));
struct ncp_file_server_info
{
__u8 ServerName[48] __attribute__((packed));
__u8 FileServiceVersion __attribute__((packed));
__u8 FileServiceSubVersion __attribute__((packed));
__u16 MaximumServiceConnections __attribute__((packed));
__u16 ConnectionsInUse __attribute__((packed));
__u16 NumberMountedVolumes __attribute__((packed));
__u8 Revision __attribute__((packed));
__u8 SFTLevel __attribute__((packed));
__u8 TTSLevel __attribute__((packed));
__u16 MaxConnectionsEverUsed __attribute__((packed));
__u8 AccountVersion __attribute__((packed));
__u8 VAPVersion __attribute__((packed));
__u8 QueueVersion __attribute__((packed));
__u8 PrintVersion __attribute__((packed));
__u8 VirtualConsoleVersion __attribute__((packed));
__u8 RestrictionLevel __attribute__((packed));
__u8 InternetBridge __attribute__((packed));
__u8 Reserved[60] __attribute__((packed));
};
long
ncp_get_file_server_information(struct ncp_conn *conn,
struct ncp_file_server_info *target);
ncp_get_file_server_information(struct ncp_conn *conn,
struct ncp_file_server_info *target);
long
ncp_get_connlist(struct ncp_conn *conn,
__u16 object_type, const char *object_name,
int *returned_no, __u8 conn_numbers[256]);
ncp_get_connlist(struct ncp_conn *conn,
__u16 object_type, const char *object_name,
int *returned_no, __u8 conn_numbers[256]);
long
ncp_get_stations_logged_info(struct ncp_conn *conn,
__u32 connection,
struct ncp_bindery_object *target,
time_t *login_time);
ncp_get_stations_logged_info(struct ncp_conn *conn,
__u32 connection,
struct ncp_bindery_object *target,
time_t * login_time);
long
ncp_get_internet_address(struct ncp_conn *conn,
__u32 connection,
struct sockaddr_ipx *target,
__u8 *conn_type);
ncp_get_internet_address(struct ncp_conn *conn,
__u32 connection,
struct sockaddr_ipx *target,
__u8 * conn_type);
long
ncp_send_broadcast(struct ncp_conn *conn,
__u8 no_conn, const __u8 *connections,
const char *message);
ncp_send_broadcast(struct ncp_conn *conn,
__u8 no_conn, const __u8 * connections,
const char *message);
long
ncp_get_encryption_key(struct ncp_conn *conn,
char *target);
long
ncp_get_bindery_object_id(struct ncp_conn *conn,
__u16 object_type,
const char *object_name,
struct ncp_bindery_object *target);
long
ncp_get_bindery_object_name(struct ncp_conn *conn,
__u32 object_id,
struct ncp_bindery_object *target);
long
ncp_scan_bindery_object(struct ncp_conn *conn,
__u32 last_id, __u16 object_type, char *search_string,
struct ncp_bindery_object *target);
long
ncp_create_bindery_object(struct ncp_conn *conn,
__u16 object_type,
const char *object_name,
__u8 object_security,
__u8 object_status);
long
ncp_delete_bindery_object(struct ncp_conn *conn,
__u16 object_type,
const char *object_name);
ncp_send_broadcast2(struct ncp_conn *conn,
unsigned int conns, const unsigned int* connlist,
const char* message);
long
ncp_change_object_security(struct ncp_conn *conn,
ncp_get_encryption_key(struct ncp_conn *conn,
char *target);
long
ncp_get_bindery_object_id(struct ncp_conn *conn,
__u16 object_type,
const char *object_name,
__u8 security);
struct ncp_bindery_object *target);
long
ncp_get_bindery_object_name(struct ncp_conn *conn,
__u32 object_id,
struct ncp_bindery_object *target);
long
ncp_scan_bindery_object(struct ncp_conn *conn,
__u32 last_id, __u16 object_type, char *search_string,
struct ncp_bindery_object *target);
long
ncp_create_bindery_object(struct ncp_conn *conn,
__u16 object_type,
const char *object_name,
__u8 object_security,
__u8 object_status);
long
ncp_delete_bindery_object(struct ncp_conn *conn,
__u16 object_type,
const char *object_name);
struct ncp_station_addr {
__u32 NetWork __attribute__ ((packed));
__u8 Node[6] __attribute__ ((packed));
__u16 Socket __attribute__ ((packed));
long
ncp_change_object_security(struct ncp_conn *conn,
__u16 object_type,
const char *object_name,
__u8 security);
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));
};
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);
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);
long
ncp_scan_property(struct ncp_conn *conn,
__u16 object_type, const char *object_name,
__u32 last_id, char *search_string,
struct ncp_property_info *property_info);
ncp_scan_property(struct ncp_conn *conn,
__u16 object_type, const char *object_name,
__u32 last_id, char *search_string,
struct ncp_property_info *property_info);
long
ncp_add_object_to_set(struct ncp_conn *conn,
__u16 object_type, const char *object_name,
const char *property_name,
__u16 member_type,
const char *member_name);
ncp_add_object_to_set(struct ncp_conn *conn,
__u16 object_type, const char *object_name,
const char *property_name,
__u16 member_type,
const char *member_name);
long
ncp_change_property_security(struct ncp_conn *conn,
__u16 object_type, const char *object_name,
const char *property_name,
__u8 property_security);
ncp_change_property_security(struct ncp_conn *conn,
__u16 object_type, const char *object_name,
const char *property_name,
__u8 property_security);
long
ncp_create_property(struct ncp_conn *conn,
ncp_create_property(struct ncp_conn *conn,
__u16 object_type, const char *object_name,
const char *property_name,
const char *property_name,
__u8 property_flags, __u8 property_security);
long
ncp_delete_object_from_set(struct ncp_conn *conn,
__u16 object_type, const char *object_name,
const char *property_name,
__u16 member_type,
const char *member_name);
long
ncp_delete_property(struct ncp_conn *conn,
__u16 object_type, const char *object_name,
const char *property_name);
ncp_delete_object_from_set(struct ncp_conn *conn,
__u16 object_type, const char *object_name,
const char *property_name,
__u16 member_type,
const char *member_name);
long
ncp_write_property_value(struct ncp_conn *conn,
__u16 object_type, const char *object_name,
const char *property_name,
__u8 segment,
struct nw_property *property_value);
ncp_delete_property(struct ncp_conn *conn,
__u16 object_type, const char *object_name,
const char *property_name);
long
ncp_write_property_value(struct ncp_conn *conn,
__u16 object_type, const char *object_name,
const char *property_name,
__u8 segment,
struct nw_property *property_value);
/* Bit masks for security flag */
#define NCP_SEC_CHECKSUMMING_REQUESTED (1)
@@ -315,138 +428,144 @@ ncp_write_property_value(struct ncp_conn *conn,
#define NCP_SEC_LIP_DISABLED (128)
long
ncp_get_big_ncp_max_packet_size(struct ncp_conn *conn,
__u16 proposed_max_size,
__u8 proposed_security_flag,
__u16 *accepted_max_size,
__u16 *echo_socket,
__u8 *accepted_security_flag);
ncp_get_big_ncp_max_packet_size(struct ncp_conn *conn,
__u16 proposed_max_size,
__u8 proposed_security_flag,
__u16 * accepted_max_size,
__u16 * echo_socket,
__u8 * accepted_security_flag);
long
ncp_login_encrypted(struct ncp_conn *conn,
const struct ncp_bindery_object *object,
const unsigned char *key,
const unsigned char *passwd);
ncp_login_encrypted(struct ncp_conn *conn,
const struct ncp_bindery_object *object,
const unsigned char *key,
const unsigned char *passwd);
long
ncp_login_unencrypted(struct ncp_conn *conn,
__u16 object_type, const char *object_name,
const unsigned char *passwd);
ncp_login_unencrypted(struct ncp_conn *conn,
__u16 object_type, const char *object_name,
const unsigned char *passwd);
long
ncp_change_login_passwd(struct ncp_conn *conn,
const struct ncp_bindery_object *object,
const unsigned char *key,
const unsigned char *oldpasswd,
const unsigned char *newpasswd);
ncp_change_login_passwd(struct ncp_conn *conn,
const struct ncp_bindery_object *object,
const unsigned char *key,
const unsigned char *oldpasswd,
const unsigned char *newpasswd);
#define NWE_SIGNATURE_LEVEL_CONFLICT (0x8861)
#define NCP_GRACE_PERIOD (0xdf)
long
ncp_login_user(struct ncp_conn *conn,
const unsigned char *username,
const unsigned char *password);
ncp_login_user(struct ncp_conn *conn,
const unsigned char *username,
const unsigned char *password);
long
ncp_get_volume_info_with_number(struct ncp_conn *conn, int n,
struct ncp_volume_info *target);
ncp_get_volume_info_with_number(struct ncp_conn *conn, int n,
struct ncp_volume_info *target);
long
ncp_get_volume_number(struct ncp_conn *conn, const char *name,
int *target);
ncp_get_volume_number(struct ncp_conn *conn, const char *name,
int *target);
long
ncp_file_search_init(struct ncp_conn *conn,
int dir_handle, const char *path,
struct ncp_filesearch_info *target);
ncp_file_search_init(struct ncp_conn *conn,
int dir_handle, const char *path,
struct ncp_filesearch_info *target);
long
ncp_file_search_continue(struct ncp_conn *conn,
struct ncp_filesearch_info *fsinfo,
int attributes, const char *path,
struct ncp_file_info *target);
ncp_file_search_continue(struct ncp_conn *conn,
struct ncp_filesearch_info *fsinfo,
int attributes, const char *path,
struct ncp_file_info *target);
long
ncp_get_finfo(struct ncp_conn *conn,
int dir_handle, const char *path, const char *name,
struct ncp_file_info *target);
ncp_get_finfo(struct ncp_conn *conn,
int dir_handle, const char *path, const char *name,
struct ncp_file_info *target);
long
ncp_open_file(struct ncp_conn *conn,
int dir_handle, const char *path,
int attr, int access,
struct ncp_file_info *target);
long
ncp_close_file(struct ncp_conn *conn, const char *file_id);
long
ncp_create_newfile(struct ncp_conn *conn,
int dir_handle, const char *path,
int attr,
struct ncp_file_info *target);
long
ncp_create_file(struct ncp_conn *conn,
int dir_handle, const char *path,
int attr,
struct ncp_file_info *target);
long
ncp_erase_file(struct ncp_conn *conn,
ncp_open_file(struct ncp_conn *conn,
int dir_handle, const char *path,
int attr);
int attr, int access,
struct ncp_file_info *target);
long
ncp_close_file(struct ncp_conn *conn, const char *file_id);
long
ncp_rename_file(struct ncp_conn *conn,
int old_handle, const char *old_path,
int attr,
int new_handle, const char *new_path);
ncp_create_newfile(struct ncp_conn *conn,
int dir_handle, const char *path,
int attr,
struct ncp_file_info *target);
long
ncp_create_directory(struct ncp_conn *conn,
int dir_handle, const char *path,
int inherit_mask);
ncp_create_file(struct ncp_conn *conn,
int dir_handle, const char *path,
int attr,
struct ncp_file_info *target);
long
ncp_delete_directory(struct ncp_conn *conn,
int dir_handle, const char *path);
long
ncp_rename_directory(struct ncp_conn *conn,
int dir_handle,
const char *old_path, const char *new_path);
long
ncp_add_trustee(struct ncp_conn *conn,
ncp_erase_file(struct ncp_conn *conn,
int dir_handle, const char *path,
__u32 object_id, __u8 rights);
int attr);
long
ncp_delete_trustee(struct ncp_conn *conn,
int dir_handle, const char *path, __u32 object_id);
ncp_rename_file(struct ncp_conn *conn,
int old_handle, const char *old_path,
int attr,
int new_handle, const char *new_path);
long
ncp_read(struct ncp_conn *conn, const char *file_id,
off_t offset, size_t count, char *target);
ncp_create_directory(struct ncp_conn *conn,
int dir_handle, const char *path,
int inherit_mask);
long
ncp_write(struct ncp_conn *conn, const char *file_id,
off_t offset, size_t count, const char *source);
ncp_delete_directory(struct ncp_conn *conn,
int dir_handle, const char *path);
long
ncp_copy_file(struct ncp_conn *conn,
const char source_file[6],
const char target_file[6],
__u32 source_offset,
__u32 target_offset,
__u32 count,
__u32 *copied_count);
ncp_rename_directory(struct ncp_conn *conn,
int dir_handle,
const char *old_path, const char *new_path);
long
ncp_obtain_file_or_subdir_info(struct ncp_conn *conn,
__u8 source_ns, __u8 target_ns,
__u16 search_attribs, __u32 rim,
__u8 vol, __u32 dirent, const char *path,
struct nw_info_struct *target);
ncp_get_trustee(struct ncp_conn *conn, __u32 object_id,
__u8 vol, char *path,
__u16 * trustee, __u16 * contin);
long
ncp_add_trustee(struct ncp_conn *conn,
int dir_handle, const char *path,
__u32 object_id, __u8 rights);
long
ncp_delete_trustee(struct ncp_conn *conn,
int dir_handle, const char *path, __u32 object_id);
long
ncp_read(struct ncp_conn *conn, const char *file_id,
off_t offset, size_t count, char *target);
long
ncp_write(struct ncp_conn *conn, const char *file_id,
off_t offset, size_t count, const char *source);
long
ncp_copy_file(struct ncp_conn *conn,
const char source_file[6],
const char target_file[6],
__u32 source_offset,
__u32 target_offset,
__u32 count,
__u32 * copied_count);
long
ncp_obtain_file_or_subdir_info(struct ncp_conn *conn,
__u8 source_ns, __u8 target_ns,
__u16 search_attribs, __u32 rim,
__u8 vol, __u32 dirent, const char *path,
struct nw_info_struct *target);
#define NCP_PERM_READ (0x001)
#define NCP_PERM_WRITE (0x002)
@@ -459,103 +578,124 @@ ncp_obtain_file_or_subdir_info(struct ncp_conn *conn,
#define NCP_PERM_SUPER (0x100)
long
ncp_get_eff_directory_rights(struct ncp_conn *conn,
__u8 source_ns, __u8 target_ns,
__u16 search_attribs,
__u8 vol, __u32 dirent, const char *path,
__u16 *my_effective_rights);
ncp_get_eff_directory_rights(struct ncp_conn *conn,
__u8 source_ns, __u8 target_ns,
__u16 search_attribs,
__u8 vol, __u32 dirent, const char *path,
__u16 * my_effective_rights);
long
ncp_do_lookup(struct ncp_conn *conn,
struct nw_info_struct *dir,
char *path, /* may only be one component */
struct nw_info_struct *target);
ncp_do_lookup(struct ncp_conn *conn,
struct nw_info_struct *dir,
char *path, /* may only be one component */
struct nw_info_struct *target);
long
ncp_modify_file_or_subdir_dos_info(struct ncp_conn *conn,
struct nw_info_struct *file,
__u32 info_mask,
struct nw_modify_dos_info *info);
ncp_modify_file_or_subdir_dos_info(struct ncp_conn *conn,
struct nw_info_struct *file,
__u32 info_mask,
struct nw_modify_dos_info *info);
long
ncp_del_file_or_subdir(struct ncp_conn *conn,
struct nw_info_struct *dir, char *name);
ncp_del_file_or_subdir(struct ncp_conn *conn,
struct nw_info_struct *dir, char *name);
long
ncp_open_create_file_or_subdir(struct ncp_conn *conn,
struct nw_info_struct *dir, char *name,
int open_create_mode,
__u32 create_attributes,
int desired_acc_rights,
struct nw_file_info *target);
ncp_open_create_file_or_subdir(struct ncp_conn *conn,
struct nw_info_struct *dir, char *name,
int open_create_mode,
__u32 create_attributes,
int desired_acc_rights,
struct nw_file_info *target);
long
ncp_initialize_search(struct ncp_conn *conn,
const struct nw_info_struct *dir,
int namespace,
struct ncp_search_seq *target);
ncp_initialize_search(struct ncp_conn *conn,
const struct nw_info_struct *dir,
int namespace,
struct ncp_search_seq *target);
long
ncp_search_for_file_or_subdir(struct ncp_conn *conn,
struct ncp_search_seq *seq,
struct nw_info_struct *target);
ncp_search_for_file_or_subdir(struct ncp_conn *conn,
struct ncp_search_seq *seq,
struct nw_info_struct *target);
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);
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);
long
ncp_create_queue_job_and_file(struct ncp_conn *conn,
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,
struct queue_job *job);
long
ncp_close_file_and_start_job(struct ncp_conn *conn,
__u32 queue_id,
struct queue_job *job);
ncp_attach_to_queue(struct ncp_conn *conn,
__u32 queue_id);
long
ncp_attach_to_queue(struct ncp_conn *conn,
__u32 queue_id);
ncp_detach_from_queue(struct ncp_conn *conn,
__u32 queue_id);
long
ncp_detach_from_queue(struct ncp_conn *conn,
__u32 queue_id);
ncp_service_queue_job(struct ncp_conn *conn, __u32 queue_id, __u16 job_type,
struct queue_job *job);
long
ncp_service_queue_job(struct ncp_conn *conn, __u32 queue_id, __u16 job_type,
struct queue_job *job);
ncp_finish_servicing_job(struct ncp_conn *conn, __u32 queue_id,
__u32 job_number, __u32 charge_info);
long
ncp_finish_servicing_job(struct ncp_conn *conn, __u32 queue_id,
__u32 job_number, __u32 charge_info);
ncp_abort_servicing_job(struct ncp_conn *conn, __u32 queue_id,
__u32 job_number);
long
ncp_abort_servicing_job(struct ncp_conn *conn, __u32 queue_id,
__u32 job_number);
ncp_get_broadcast_message(struct ncp_conn *conn, char message[256]);
long
ncp_get_broadcast_message(struct ncp_conn *conn, char message[256]);
long
ncp_dealloc_dir_handle(struct ncp_conn *conn, __u8 dir_handle);
ncp_dealloc_dir_handle(struct ncp_conn *conn, __u8 dir_handle);
#define NCP_ALLOC_PERMANENT (0x0000)
#define NCP_ALLOC_TEMPORARY (0x0001)
#define NCP_ALLOC_SPECIAL (0x0002)
long
ncp_alloc_short_dir_handle(struct ncp_conn *conn,
struct nw_info_struct *dir,
__u16 alloc_mode,
__u8 *target);
ncp_alloc_short_dir_handle(struct ncp_conn *conn,
struct nw_info_struct *dir,
__u16 alloc_mode,
__u8 * target);
long
ncp_get_effective_dir_rights(struct ncp_conn *conn,
struct nw_info_struct *file,
__u16 *target);
ncp_get_effective_dir_rights(struct ncp_conn *conn,
struct nw_info_struct *file,
__u16 * target);
struct ncp_trustee_struct
{
@@ -564,10 +704,35 @@ struct ncp_trustee_struct
};
long
ncp_add_trustee_set(struct ncp_conn *conn,
__u8 volume_number, __u32 dir_entry,
__u16 rights_mask,
int object_count, struct ncp_trustee_struct *rights);
ncp_add_trustee_set(struct ncp_conn *conn,
__u8 volume_number, __u32 dir_entry,
__u16 rights_mask,
int object_count, struct ncp_trustee_struct *rights);
#ifdef SIGNATURES
long
ncp_sign_start(struct ncp_conn *conn, const char *sign_root);
#endif
#ifdef NDS_SUPPORT
long
ncp_send_nds_frag(struct ncp_conn *conn,
int ndsverb,
char *inbuf, int inbuflen,
char *outbuf, int outbufsize, int *outbuflen);
#endif /* _NCPLIB_H */
long
ncp_send_nds(struct ncp_conn *conn, int fn,
char *data_in, int data_in_len,
char *data_out, int data_out_max, int *data_out_len);
long
ncp_change_conn_state(struct ncp_conn *conn, int new_state);
struct ncp_conn *
ncp_open_addr(struct sockaddr_ipx *target, long *err);
int
ncp_get_mount_uid(int fid, uid_t* uid);
#endif
#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,4 +1,4 @@
CFLAGS = -O2 -Wall
CFLAGS = -O2 -Wall -I../include
UTILS = ipx_configure ipx_interface ipx_internal_net ipx_route
all: $(UTILS)

View File

@@ -8,14 +8,15 @@
int
main(int argc, char **argv)
{
struct sockaddr_ipx sipx;
int s;
int result;
char msg[100];
int len;
struct sockaddr_ipx sipx;
int s;
int result;
char msg[100];
int len;
s = socket(AF_IPX, SOCK_DGRAM, AF_IPX);
if (s < 0) {
if (s < 0)
{
perror("IPX: socket: ");
exit(-1);
}
@@ -24,29 +25,25 @@ main(int argc, char **argv)
sipx.sipx_port = htons(0x5000);
sipx.sipx_type = 17;
len = sizeof(sipx);
result = bind(s, (struct sockaddr *)&sipx, sizeof(sipx));
if (result < 0) {
result = bind(s, (struct sockaddr *) &sipx, sizeof(sipx));
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) {
result = recvfrom(s, msg, sizeof(msg), 0, (struct sockaddr *) &sipx,
&len);
if (result < 0)
{
perror("IPX: recvfrom: ");
}
printf("From %08lX:%02X%02X%02X%02X%02X%02X:%04X\n",
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],
htons(sipx.sipx_port));
printf("From %08lX:%02X%02X%02X%02X%02X%02X:%04X\n",
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],
htons(sipx.sipx_port));
printf("\tGot \"%s\"\n", msg);
return 0;
}

View File

@@ -1,3 +1,7 @@
#include <stdio.h>
#include <sys/types.h>
#include <linux/ipx.h>
@@ -8,14 +12,15 @@
int
main(int argc, char **argv)
{
struct sockaddr_ipx sipx;
int s;
int result;
char msg[100] = "Hi Mom";
int len = sizeof(sipx);
struct sockaddr_ipx sipx;
int s;
int result;
char msg[100] = "Hi Mom";
int len = sizeof(sipx);
s = socket(AF_IPX, SOCK_DGRAM, AF_IPX);
if (s < 0) {
if (s < 0)
{
perror("IPX: socket: ");
exit(-1);
}
@@ -24,23 +29,20 @@ main(int argc, char **argv)
sipx.sipx_port = 0;
sipx.sipx_type = 17;
result = bind(s, (struct sockaddr *)&sipx, sizeof(sipx));
if (result < 0) {
result = bind(s, (struct sockaddr *) &sipx, sizeof(sipx));
if (result < 0)
{
perror("IPX: bind: ");
exit(-1);
}
result = getsockname(s, (struct sockaddr *)&sipx, &len);
result = getsockname(s, (struct sockaddr *) &sipx, &len);
sipx.sipx_port = htons(0x5000);
result = sendto(s, msg, sizeof(msg), 0, (struct sockaddr *)&sipx,
result = sendto(s, msg, sizeof(msg), 0, (struct sockaddr *) &sipx,
sizeof(sipx));
if (result < 0) {
if (result < 0)
{
perror("IPX: send: ");
exit(-1);
}
return 0;
}

View File

@@ -1,3 +1,7 @@
#include <stdio.h>
#include <sys/types.h>
#include <linux/ipx.h>
@@ -5,25 +9,27 @@
#include <sys/socket.h>
#include <errno.h>
struct rip_data {
unsigned long rip_net;
unsigned short rip_hops __attribute__ ((packed));
unsigned short rip_ticks __attribute__ ((packed));
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)
{
struct sockaddr_ipx sipx;
int result;
int s;
char msg[1024];
int len;
char *bptr;
struct rip_data *rp;
struct sockaddr_ipx sipx;
int result;
int s;
char msg[1024];
int len;
char *bptr;
struct rip_data *rp;
s = socket(AF_IPX, SOCK_DGRAM, AF_IPX);
if (s < 0) {
if (s < 0)
{
perror("IPX: socket: ");
exit(-1);
}
@@ -31,38 +37,37 @@ main(int argc, char **argv)
sipx.sipx_network = 0;
sipx.sipx_port = htons(0x453);
sipx.sipx_type = 17;
result = bind(s, (struct sockaddr *)&sipx, sizeof(sipx));
if (result < 0) {
result = bind(s, (struct sockaddr *) &sipx, sizeof(sipx));
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) {
result = recvfrom(s, msg, sizeof(msg), 0,
(struct sockaddr *) &sipx, &len);
if (result < 0)
{
perror("IPX: recvfrom");
exit(-1);
}
bptr = msg;
result -= 2;
printf("RIP packet from: %08lX:%02X%02X%02X%02X%02X%02X\n",
htonl(sipx.sipx_network),
sipx.sipx_node[0], sipx.sipx_node[1],
sipx.sipx_node[2], sipx.sipx_node[3],
sipx.sipx_node[6], sipx.sipx_node[5]);
htonl(sipx.sipx_network),
sipx.sipx_node[0], sipx.sipx_node[1],
sipx.sipx_node[2], sipx.sipx_node[3],
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));
ntohs(rp->rip_hops));
result -= sizeof(struct rip_data);
rp++;
}
}
}

View File

@@ -1,3 +1,7 @@
#include <stdio.h>
#include <sys/types.h>
#include <linux/ipx.h>
@@ -6,55 +10,58 @@
#include <errno.h>
struct sap_data {
unsigned short sap_type __attribute__ ((packed));
char sap_name[48] __attribute__ ((packed));
unsigned long sap_net __attribute__ ((packed));
unsigned char sap_node[6] __attribute__ ((packed));
unsigned short sap_sock __attribute__ ((packed));
unsigned short sap_hops __attribute__ ((packed));
struct sap_data
{
unsigned short sap_type __attribute__((packed));
char sap_name[48] __attribute__((packed));
unsigned long sap_net __attribute__((packed));
unsigned char sap_node[6] __attribute__((packed));
unsigned short sap_sock __attribute__((packed));
unsigned short sap_hops __attribute__((packed));
};
int
main(int argc, char **argv)
{
int s;
int result;
struct sockaddr_ipx sipx;
char msg[1024];
long val = 0;
int len;
char *bptr;
struct sap_data *sp;
int s;
int result;
struct sockaddr_ipx sipx;
char msg[1024];
long val = 0;
int len;
char *bptr;
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);
}
sipx.sipx_family = PF_IPX;
sipx.sipx_network = 0L;
sipx.sipx_port = htons(0x452);
sipx.sipx_type = 17;
result = bind(s, (struct sockaddr *)&sipx, sizeof(sipx));
if (result < 0) {
result = bind(s, (struct sockaddr *) &sipx, sizeof(sipx));
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) {
result = recvfrom(s, msg, sizeof(msg), 0,
(struct sockaddr *) &sipx, &len);
if (result < 0)
{
perror("IPX: recvfrom: ");
exit(-1);
}
@@ -67,30 +74,27 @@ main(int argc, char **argv)
bptr += 2;
sp = (struct sap_data *) bptr;
while (result >= sizeof(struct sap_data)) {
int i;
while (result >= sizeof(struct sap_data))
{
int i;
sp->sap_name[32] = '\0';
for (i = 31; (i > 0) && (sp->sap_name[i] == '_'); i--);
i++;
sp->sap_name[i] = '\0';
printf("NAME: %s TYPE: %x HOPS: %x\n", sp->sap_name,
ntohs(sp->sap_type), ntohs(sp->sap_hops));
printf("%lx:%x %x %x %x %x %x: %x\n",
ntohl(sp->sap_net),
sp->sap_node[0],
sp->sap_node[1],
sp->sap_node[2],
sp->sap_node[3],
sp->sap_node[4],
sp->sap_node[5],
ntohs(sp->sap_sock));
ntohs(sp->sap_type), ntohs(sp->sap_hops));
printf("%lx:%x %x %x %x %x %x: %x\n",
ntohl(sp->sap_net),
sp->sap_node[0],
sp->sap_node[1],
sp->sap_node[2],
sp->sap_node[3],
sp->sap_node[4],
sp->sap_node[5],
ntohs(sp->sap_sock));
result -= sizeof(struct sap_data);
sp++;
}
}
}

View File

@@ -1,5 +1,5 @@
/* Copyright (c) 1995-1996 Caldera, Inc. All Rights Reserved.
*
* See file COPYING for details.
*/
@@ -8,26 +8,27 @@
#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>
#include <errno.h>
struct option options[] = {
{ "auto_primary", required_argument, NULL, 1 },
{ "auto_interface", required_argument, NULL, 2 },
{ "help", no_argument, NULL, 3},
{ NULL, 0, NULL, 0 }
struct option options[] =
{
{"auto_primary", required_argument, NULL, 1},
{"auto_interface", required_argument, NULL, 2},
{"help", no_argument, NULL, 3},
{NULL, 0, NULL, 0}
};
char *progname;
char *progname;
void
usage(void)
{
fprintf(stderr,
"Usage: %s --auto_primary=[on|off]\n\
fprintf(stderr,
"Usage: %s --auto_primary=[on|off]\n\
Usage: %s --auto_interface=[on|off]\n\
Usage: %s --help\n\
Usage: %s\n", progname, progname, progname, progname);
@@ -37,36 +38,38 @@ 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, "TRUE") == 0) ||
(strcasecmp(optarg, "SET") == 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, "FALSE") == 0) ||
(strcasecmp(optarg, "CLEAR") == 0) ||
(strcasecmp(optarg, "NO") == 0))
{
return 0;
}
}
return -1;
}
int
main(int argc, char **argv)
{
int s;
int result;
char errmsg[80];
char val;
int option_index = 0;
int got_auto_pri = 0;
int got_auto_itf = 0;
ipx_config_data data;
int s;
int result;
char errmsg[80];
char val;
int option_index = 0;
int got_auto_pri = 0;
int got_auto_itf = 0;
ipx_config_data data;
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);
@@ -77,41 +80,44 @@ main(int argc, char **argv)
}
exit(-1);
}
sprintf(errmsg, "%s: ioctl", progname);
while ((result = getopt_long(argc, argv, "", options,
&option_index)) != -1) {
switch (result) {
case 1:
while ((result = getopt_long(argc, argv, "", options,
&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);
}
break;
case 2:
if (got_auto_itf)
if (got_auto_itf)
break;
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);
}
@@ -122,16 +128,17 @@ 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",
Auto Interface Create is %s\n",
(data.ipxcfg_auto_select_primary) ? "ON" : "OFF",
(data.ipxcfg_auto_create_interfaces) ? "ON" : "OFF");
}
exit(0);
}

View File

@@ -1,5 +1,6 @@
/* Copyright (c) 1995-1996 Caldera, Inc. All Rights Reserved.
*
* See file COPYING for details.
*/
@@ -10,15 +11,15 @@
#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>
#include <errno.h>
static struct ifreq id;
static char *progname;
static struct ifreq id;
static char *progname;
void
usage(void)
@@ -30,17 +31,34 @@ Usage: %s check device frame_type\n", progname, progname, progname, progname);
exit(-1);
}
struct frame_type {
char *ft_name;
unsigned char ft_val;
} frame_types[] = {
{"802.2", IPX_FRAME_8022},
struct frame_type
{
char *ft_name;
unsigned char ft_val;
}
frame_types[] =
{
{
"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))
@@ -48,20 +66,21 @@ struct frame_type {
int
lookup_frame_type(char *frame)
{
int j;
int j;
for (j = 0; (j < NFTYPES) &&
(strcasecmp(frame_types[j].ft_name, frame));
j++)
for (j = 0; (j < NFTYPES) &&
(strcasecmp(frame_types[j].ft_name, frame));
j++)
;
if (j != NFTYPES)
return j;
fprintf(stderr, "%s: Frame type must be", progname);
for (j = 0; j < NFTYPES; j++) {
fprintf(stderr, "%s%s",
(j == NFTYPES-1) ? " or " : " ",
for (j = 0; j < NFTYPES; j++)
{
fprintf(stderr, "%s%s",
(j == NFTYPES - 1) ? " or " : " ",
frame_types[j].ft_name);
}
fprintf(stderr, ".\n");
@@ -71,44 +90,51 @@ lookup_frame_type(char *frame)
int
ipx_add_interface(int argc, char **argv)
{
struct sockaddr_ipx *sipx = (struct sockaddr_ipx *)&id.ifr_addr;
int s;
int result;
unsigned long netnum;
char errmsg[80];
int i, fti = 0;
char c;
struct sockaddr_ipx *sipx = (struct sockaddr_ipx *) &id.ifr_addr;
int s;
int result;
unsigned long netnum;
char errmsg[80];
int i, fti = 0;
char c;
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) {
case 'p': sipx->sipx_special = IPX_PRIMARY; break;
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;
case 1: /* Frame Type - Required */
case 1: /* Frame Type - Required */
fti = lookup_frame_type(argv[i]);
if (fti < 0)
exit(-1);
sipx->sipx_type = frame_types[fti].ft_val;
break;
case 2: /* Network Number - Optional */
netnum = strtoul(argv[i], (char **)NULL, 16);
if (netnum == 0xffffffffL) {
fprintf(stderr,
"%s: Inappropriate network number %08lX\n",
case 2: /* Network Number - Optional */
netnum = strtoul(argv[i], (char **) NULL, 16);
if (netnum == 0xffffffffL)
{
fprintf(stderr,
"%s: Inappropriate network number %08lX\n",
progname, netnum);
exit(-1);
}
@@ -116,9 +142,10 @@ ipx_add_interface(int argc, char **argv)
break;
}
}
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);
@@ -129,25 +156,28 @@ ipx_add_interface(int argc, char **argv)
}
exit(-1);
}
i = 0;
sipx->sipx_family = AF_IPX;
sipx->sipx_action = IPX_CRTITF;
do {
do
{
result = ioctl(s, SIOCSIFADDR, &id);
i++;
} while ((i < 5) && (result < 0) && (errno == EAGAIN));
}
while ((i < 5) && (result < 0) && (errno == EAGAIN));
if (result == 0) exit(0);
switch (errno) {
if (result == 0)
exit(0);
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",
@@ -166,7 +196,7 @@ ipx_add_interface(int argc, char **argv)
id.ifr_name);
break;
case EAGAIN:
fprintf(stderr,
fprintf(stderr,
"%s: Insufficient memory to create interface.\n",
progname);
break;
@@ -181,61 +211,67 @@ ipx_add_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;
int result;
char errmsg[80];
char buffer[80];
char device[20];
char frame_type[20];
int fti;
FILE *fp;
struct sockaddr_ipx *sipx = (struct sockaddr_ipx *) &id.ifr_addr;
int s;
int result;
char errmsg[80];
char buffer[80];
char device[20];
char frame_type[20];
int fti;
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) {
fprintf(stderr,
if (fp == NULL)
{
fprintf(stderr,
"%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);
if (fti < 0) continue;
if (fti < 0)
continue;
sipx->sipx_type = frame_types[fti].ft_val;
}
sipx->sipx_action = IPX_DLTITF;
sipx->sipx_family = AF_IPX;
result = ioctl(s, SIOCSIFADDR, &id);
if (result == 0) continue;
switch (errno) {
if (result == 0)
continue;
switch (errno)
{
case EPROTONOSUPPORT:
fprintf(stderr, "%s: Invalid frame type (%s).\n",
progname, frame_type);
break;
case ENODEV:
fprintf(stderr, "%s: No such device (%s).\n",
fprintf(stderr, "%s: No such device (%s).\n",
progname, device);
break;
case EINVAL:
fprintf(stderr, "%s: No such IPX interface %s %s.\n",
fprintf(stderr, "%s: No such IPX interface %s %s.\n",
progname, device, frame_type);
break;
default:
@@ -251,16 +287,16 @@ ipx_delall_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;
int result;
char errmsg[80];
int fti;
if (argc != 3) {
struct sockaddr_ipx *sipx = (struct sockaddr_ipx *) &id.ifr_addr;
int s;
int result;
char errmsg[80];
int fti;
if (argc != 3)
{
usage();
}
sipx->sipx_network = 0L;
sipx->sipx_special = IPX_SPECIAL_NONE;
strcpy(id.ifr_name, argv[1]);
@@ -270,7 +306,8 @@ 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);
@@ -278,9 +315,11 @@ ipx_del_interface(int argc, char **argv)
sipx->sipx_action = IPX_DLTITF;
sipx->sipx_family = AF_IPX;
result = ioctl(s, SIOCSIFADDR, &id);
if (result == 0) exit(0);
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);
@@ -304,16 +343,16 @@ ipx_del_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;
int result;
char errmsg[80];
int fti;
if (argc != 3) {
struct sockaddr_ipx *sipx = (struct sockaddr_ipx *) &id.ifr_addr;
int s;
int result;
char errmsg[80];
int fti;
if (argc != 3)
{
usage();
}
sipx->sipx_network = 0L;
strcpy(id.ifr_name, argv[1]);
fti = lookup_frame_type(argv[2]);
@@ -322,25 +361,27 @@ 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",
argv[1], frame_types[fti].ft_name,
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]);
"IPX Address for (%s, %s) is %08X:%02X%02X%02X%02X%02X%02X.\n",
argv[1], frame_types[fti].ft_name,
(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);
@@ -364,31 +405,35 @@ ipx_check_interface(int argc, char **argv)
int
main(int argc, char **argv)
{
int i;
int i;
progname = argv[0];
if (argc < 2) {
if (argc < 2)
{
usage();
exit(-1);
}
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) {
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) {
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) {
for (i = 1; i < (argc-1); i++)
argv[i] = argv[i+1];
ipx_check_interface(argc-1, argv);
}
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)
{
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)
{
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)
{
for (i = 1; i < (argc - 1); i++)
argv[i] = argv[i + 1];
ipx_check_interface(argc - 1, argv);
}
usage();
return 0;
}

View File

@@ -1,5 +1,5 @@
/* Copyright (c) 1995-1996 Caldera, Inc. All Rights Reserved.
*
* See file COPYING for details.
*/
@@ -9,14 +9,14 @@
#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>
static struct ifreq id;
static char *progname;
static struct ifreq id;
static char *progname;
void
usage(void)
@@ -29,12 +29,15 @@ Usage: %s del\n", progname, progname);
int
map_char_to_val(char dig)
{
char digit = tolower(dig);
if ((digit >= '0') && (digit <= '9')) {
char digit = tolower(dig);
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;
}
}
@@ -42,90 +45,95 @@ map_char_to_val(char dig)
int
ipx_add_internal_net(int argc, char **argv)
{
struct sockaddr_ipx *sipx = (struct sockaddr_ipx *)&id.ifr_addr;
int s;
int result;
unsigned long netnum;
char errmsg[80];
int nodelen;
char *node;
char tmpnode[13];
unsigned char *tout;
char *tin;
int i;
if (argc != 3) {
struct sockaddr_ipx *sipx = (struct sockaddr_ipx *) &id.ifr_addr;
int s;
int result;
unsigned long netnum;
char errmsg[80];
int nodelen;
char *node;
char tmpnode[13];
unsigned char *tout;
char *tin;
int i;
if (argc != 3)
{
usage();
}
netnum = strtoul(argv[1], (char **)NULL, 16);
if ((netnum == 0L) || (netnum == 0xffffffffL)) {
fprintf(stderr, "%s: Inappropriate network number %08lX\n",
netnum = strtoul(argv[1], (char **) NULL, 16);
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++) {
memcpy(&(tmpnode[12 - nodelen]), node, nodelen);
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));
*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);
}
sipx->sipx_network = htonl(netnum);
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);
}
sipx->sipx_family = AF_IPX;
sipx->sipx_action = IPX_CRTITF;
i = 0;
do {
do
{
result = ioctl(s, SIOCSIFADDR, &id);
i++;
} while ((i < 5) && (result < 0) && (errno == EAGAIN));
}
while ((i < 5) && (result < 0) && (errno == EAGAIN));
if (result == 0) exit(0);
switch (errno) {
if (result == 0)
exit(0);
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,
fprintf(stderr,
"%s: Insufficient memory to create internal net.\n",
progname);
break;
@@ -140,19 +148,20 @@ ipx_add_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) {
struct sockaddr_ipx *sipx = (struct sockaddr_ipx *) &id.ifr_addr;
int s;
int result;
char errmsg[80];
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);
@@ -160,9 +169,11 @@ ipx_del_internal_net(int argc, char **argv)
sipx->sipx_family = AF_IPX;
sipx->sipx_action = IPX_DLTITF;
result = ioctl(s, SIOCSIFADDR, &id);
if (result == 0) exit(0);
if (result == 0)
exit(0);
switch (errno) {
switch (errno)
{
case ENOENT:
fprintf(stderr, "%s: No internal network configured.\n", progname);
break;
@@ -177,24 +188,25 @@ ipx_del_internal_net(int argc, char **argv)
int
main(int argc, char **argv)
{
int i;
int i;
progname = argv[0];
if (argc < 2) {
if (argc < 2)
{
usage();
exit(-1);
}
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) {
for (i = 1; i < (argc-1); i++)
argv[i] = argv[i+1];
ipx_del_internal_net(argc-1, argv);
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)
{
for (i = 1; i < (argc - 1); i++)
argv[i] = argv[i + 1];
ipx_del_internal_net(argc - 1, argv);
}
usage();
return 0;
}

View File

@@ -1,5 +1,6 @@
/* Copyright (c) 1995-1996 Caldera, Inc. All Rights Reserved.
*
* See file COPYING for details.
*/
@@ -10,24 +11,27 @@
#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;
static struct rtentry rd;
static char *progname;
int
map_char_to_val(char dig)
{
char digit = tolower(dig);
if ((digit >= '0') && (digit <= '9')) {
char digit = tolower(dig);
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;
}
}
@@ -35,8 +39,8 @@ map_char_to_val(char dig)
void
usage(void)
{
fprintf(stderr,
"Usage: %s add network(hex) router_network(hex) router_node(hex)\n\
fprintf(stderr,
"Usage: %s add network(hex) router_network(hex) router_node(hex)\n\
Usage: %s del network(hex)\n", progname, progname);
exit(-1);
}
@@ -45,27 +49,28 @@ int
ipx_add_route(int argc, char **argv)
{
/* Router */
struct sockaddr_ipx *sr = (struct sockaddr_ipx *)&rd.rt_gateway;
struct sockaddr_ipx *sr = (struct sockaddr_ipx *) &rd.rt_gateway;
/* Target */
struct sockaddr_ipx *st = (struct sockaddr_ipx *)&rd.rt_dst;
int s;
int result;
int nodelen;
int i;
unsigned long netnum;
char errmsg[80];
char *node;
char *tin;
char tmpnode[13];
unsigned char *tout;
struct sockaddr_ipx *st = (struct sockaddr_ipx *) &rd.rt_dst;
int s;
int result;
int nodelen;
int i;
unsigned long netnum;
char errmsg[80];
char *node;
char *tin;
char tmpnode[13];
unsigned char *tout;
if (argc != 4)
usage();
/* Network Number */
netnum = strtoul(argv[1], (char **)NULL, 16);
if ((netnum == 0xffffffffL) || (netnum == 0L)) {
fprintf(stderr, "%s: Inappropriate network number %08lX\n",
netnum = strtoul(argv[1], (char **) NULL, 16);
if ((netnum == 0xffffffffL) || (netnum == 0L))
{
fprintf(stderr, "%s: Inappropriate network number %08lX\n",
progname, netnum);
exit(-1);
}
@@ -73,66 +78,72 @@ ipx_add_route(int argc, char **argv)
st->sipx_network = htonl(netnum);
/* Router Network Number */
netnum = strtoul(argv[2], (char **)NULL, 16);
if ((netnum == 0xffffffffL) || (netnum == 0L)) {
fprintf(stderr, "%s: Inappropriate network number %08lX\n",
netnum = strtoul(argv[2], (char **) NULL, 16);
if ((netnum == 0xffffffffL) || (netnum == 0L))
{
fprintf(stderr, "%s: Inappropriate network number %08lX\n",
progname, netnum);
exit(-1);
}
sr->sipx_network = htonl(netnum);
/* Router Node */
node = argv[3];
nodelen = strlen(node);
if (nodelen > 12) {
fprintf(stderr, "%s: Node length is too long (> 12).\n",
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++) {
memcpy(&(tmpnode[12 - nodelen]), node, nodelen);
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));
*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++;
} while ((i < 5) && (result < 0) && (errno == EAGAIN));
}
while ((i < 5) && (result < 0) && (errno == EAGAIN));
if (result == 0) exit(0);
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);
@@ -146,23 +157,24 @@ int
ipx_del_route(int argc, char **argv)
{
/* Router */
struct sockaddr_ipx *sr = (struct sockaddr_ipx *)&rd.rt_gateway;
struct sockaddr_ipx *sr = (struct sockaddr_ipx *) &rd.rt_gateway;
/* Target */
struct sockaddr_ipx *st = (struct sockaddr_ipx *)&rd.rt_dst;
int s;
int result;
unsigned long netnum;
char errmsg[80];
if (argc != 2) {
struct sockaddr_ipx *st = (struct sockaddr_ipx *) &rd.rt_dst;
int s;
int result;
unsigned long netnum;
char errmsg[80];
if (argc != 2)
{
usage();
}
rd.rt_flags = RTF_GATEWAY;
/* Network Number */
netnum = strtoul(argv[1], (char **)NULL, 16);
if ((netnum == 0xffffffffL) || (netnum == 0L)) {
fprintf(stderr, "%s: Inappropriate network number %08lX.\n",
netnum = strtoul(argv[1], (char **) NULL, 16);
if ((netnum == 0xffffffffL) || (netnum == 0L))
{
fprintf(stderr, "%s: Inappropriate network number %08lX.\n",
progname, netnum);
exit(-1);
}
@@ -170,15 +182,18 @@ 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);
}
result = ioctl(s, SIOCDELRT, &rd);
if (result == 0) exit(0);
if (result == 0)
exit(0);
switch (errno) {
switch (errno)
{
case ENOENT:
fprintf(stderr, "%s: Route not found for network %08lX.\n",
progname, netnum);
@@ -198,22 +213,24 @@ ipx_del_route(int argc, char **argv)
int
main(int argc, char **argv)
{
int i;
int i;
progname = argv[0];
if (argc < 2) {
if (argc < 2)
{
usage();
exit(-1);
}
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) {
for (i = 1; i < (argc-1); i++)
argv[i] = argv[i+1];
ipx_del_route(argc-1, argv);
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)
{
for (i = 1; i < (argc - 1); i++)
argv[i] = argv[i + 1];
ipx_del_route(argc - 1, argv);
}
usage();
return 0;

View File

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

View File

@@ -1,7 +1,7 @@
/* ipxdump.c */
/* ipxdump.c */
/* Copyright 1996 Volker Lendecke, Goettingen, Germany
*
* 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
@@ -21,14 +21,13 @@
#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>
@@ -37,29 +36,29 @@
struct ipx_address
{
unsigned long net;
unsigned char node[IPX_NODE_LEN];
unsigned char node[IPX_NODE_LEN];
unsigned short sock;
};
struct ipx_packet
{
unsigned short ipx_checksum;
unsigned short ipx_checksum;
#define IPX_NO_CHECKSUM 0xFFFF
unsigned short ipx_pktsize;
unsigned char ipx_tctrl;
unsigned char ipx_type;
unsigned short ipx_pktsize;
unsigned char ipx_tctrl;
unsigned char ipx_type;
#define IPX_TYPE_UNKNOWN 0x00
#define IPX_TYPE_RIP 0x01 /* may also be 0 */
#define IPX_TYPE_SAP 0x04 /* may also be 0 */
#define IPX_TYPE_SPX 0x05 /* Not yet implemented */
#define IPX_TYPE_NCP 0x11 /* $lots for docs on this (SPIT) */
#define IPX_TYPE_PPROP 0x14 /* complicated flood fill brdcast [Not supported] */
struct ipx_address ipx_dest __attribute__ ((packed));
struct ipx_address ipx_source __attribute__ ((packed));
struct ipx_address ipx_dest __attribute__((packed));
struct ipx_address ipx_source __attribute__((packed));
};
void handle_frame (unsigned char *buf, int length, struct sockaddr *saddr);
void handle_frame(unsigned char *buf, int length, struct sockaddr *saddr);
void handle_ipx(char *frame, unsigned char *buf);
static int filter = 0;
@@ -73,7 +72,7 @@ int_handler()
}
void
main (int argc, char *argv[])
main(int argc, char *argv[])
{
int sd;
struct ifreq ifr, oldifr;
@@ -94,63 +93,59 @@ main (int argc, char *argv[])
}
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");
perror("Can't get socket");
fprintf(stderr, "You must run %s as root\n", argv[0]);
exit (1);
exit(1);
}
/* SET PROMISC */
strcpy (oldifr.ifr_name, device);
if (ioctl (sd, SIOCGIFFLAGS, &oldifr) < 0)
strcpy(oldifr.ifr_name, device);
if (ioctl(sd, SIOCGIFFLAGS, &oldifr) < 0)
{
close (sd);
perror ("Can't get flags");
exit (2);
close(sd);
perror("Can't get flags");
exit(2);
}
/* This should be rewritten to cooperate with other net tools */
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);
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);
length = recvfrom (sd, buf, sizeof(buf), 0,
&saddr, &sizeaddr);
if (length < 0 ) continue;
handle_frame (buf, length, &saddr);
length = recvfrom(sd, buf, sizeof(buf), 0,
&saddr, &sizeaddr);
if (length < 0)
continue;
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);
close(sd);
perror("Can't set flags");
exit(4);
}
close (sd);
exit (0);
close(sd);
exit(0);
}
void
handle_ipx (char *frame, unsigned char *buf)
handle_ipx(char *frame, unsigned char *buf)
{
int i;
struct ipx_packet *h = (struct ipx_packet *)buf;
struct ipx_packet *h = (struct ipx_packet *) buf;
struct sockaddr_ipx s_addr;
struct sockaddr_ipx d_addr;
int length = ntohs(h->ipx_pktsize);
@@ -161,16 +156,16 @@ handle_ipx (char *frame, unsigned char *buf)
memcpy(s_addr.sipx_node, h->ipx_source.node, sizeof(s_addr.sipx_node));
s_addr.sipx_port = h->ipx_source.sock;
s_addr.sipx_network = h->ipx_source.net;
s_addr.sipx_network = h->ipx_source.net;
memcpy(d_addr.sipx_node, h->ipx_dest.node, sizeof(d_addr.sipx_node));
d_addr.sipx_port = h->ipx_dest.sock;
d_addr.sipx_network = h->ipx_dest.net;
d_addr.sipx_network = h->ipx_dest.net;
if (filter != 0)
{
if ( (memcmp(filter_node, s_addr.sipx_node,
sizeof(filter_node)) != 0)
if ((memcmp(filter_node, s_addr.sipx_node,
sizeof(filter_node)) != 0)
&& (memcmp(filter_node, d_addr.sipx_node,
sizeof(filter_node)) != 0))
{
@@ -178,7 +173,6 @@ handle_ipx (char *frame, unsigned char *buf)
return;
}
}
printf("%s ", frame);
for (i = 0; i < length; i++)
@@ -193,9 +187,9 @@ handle_ipx (char *frame, unsigned char *buf)
}
void
handle_other (unsigned char *buf, int length, struct sockaddr *saddr)
handle_other(unsigned char *buf, int length, struct sockaddr *saddr)
{
struct ethhdr *eth = (struct ethhdr *)buf;
struct ethhdr *eth = (struct ethhdr *) buf;
unsigned char *p = &(buf[sizeof(struct ethhdr)]);
if (ntohs(eth->h_proto) < 1536)
@@ -206,36 +200,34 @@ handle_other (unsigned char *buf, int length, struct sockaddr *saddr)
* which isnt a used 802.2 SSAP/DSAP. This won't work
* 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))
if ((*(unsigned short *) p == htons(0xe0e0))
&& (p[2] == 0x03))
{
handle_ipx("802.2", p+3);
handle_ipx("802.2", p + 3);
return;
}
if (memcmp(p, "\252\252\003\000\000\000\201\067", 8) == 0)
{
handle_ipx("snap", p+8);
handle_ipx("snap", p + 8);
return;
}
}
}
void
handle_frame (unsigned char *buf, int length, struct sockaddr *saddr)
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 )
unsigned short packet_type = ((struct ethhdr *) buf)->h_proto;
switch (htons(packet_type))
{
case __constant_ntohs(ETH_P_IPX):
case ETH_P_IPX:
handle_ipx("EtherII", &(buf[sizeof(struct ethhdr)]));
break;
default:

File diff suppressed because it is too large Load Diff

View File

@@ -1,97 +1,101 @@
/*
IPX support library - general functions
IPX support library - general functions
Copyright (C) 1994, 1995 Ales Dryak <e-mail: A.Dryak@sh.cvut.cz>
Copyright (C) 1996, Volker Lendecke <lendecke@namu01.gwdg.de>
Copyright (C) 1994, 1995 Ales Dryak <e-mail: A.Dryak@sh.cvut.cz>
Copyright (C) 1996, Volker Lendecke <lendecke@namu01.gwdg.de>
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 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.
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.
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 <netinet/in.h>
#include "ipxutil.h"
void
ipx_fprint_node(FILE *file, IPXNode node)
ipx_fprint_node(FILE * file, IPXNode node)
{
fprintf(file,"%02X%02X%02X%02X%02X%02X",
(unsigned char)node[0],
(unsigned char)node[1],
(unsigned char)node[2],
(unsigned char)node[3],
(unsigned char)node[4],
(unsigned char)node[5]
);
fprintf(file, "%02X%02X%02X%02X%02X%02X",
(unsigned char) node[0],
(unsigned char) node[1],
(unsigned char) node[2],
(unsigned char) node[3],
(unsigned char) node[4],
(unsigned char) node[5]
);
}
void
ipx_fprint_network(FILE *file, IPXNet net)
ipx_fprint_network(FILE * file, IPXNet net)
{
fprintf(file,"%08lX",net);
fprintf(file, "%08lX", net);
}
void
ipx_fprint_port(FILE *file, IPXPort port)
ipx_fprint_port(FILE * file, IPXPort port)
{
fprintf(file,"%04X",port);
fprintf(file, "%04X", port);
}
void
ipx_fprint_saddr(FILE *file, struct sockaddr_ipx *sipx)
ipx_fprint_saddr(FILE * file, struct sockaddr_ipx *sipx)
{
ipx_fprint_network(file,ntohl(sipx->sipx_network));
fprintf(file,":");
ipx_fprint_node(file,sipx->sipx_node);
fprintf(file,":");
ipx_fprint_port(file,ntohs(sipx->sipx_port));
ipx_fprint_network(file, ntohl(sipx->sipx_network));
fprintf(file, ":");
ipx_fprint_node(file, sipx->sipx_node);
fprintf(file, ":");
ipx_fprint_port(file, ntohs(sipx->sipx_port));
}
void
ipx_print_node(IPXNode node)
{
ipx_fprint_node(stdout,node);
ipx_fprint_node(stdout, node);
}
void
ipx_print_network(IPXNet net)
{
ipx_fprint_network(stdout,net);
ipx_fprint_network(stdout, net);
}
void
ipx_print_port(IPXPort port)
{
ipx_fprint_port(stdout,port);
ipx_fprint_port(stdout, port);
}
void
ipx_print_saddr(struct sockaddr_ipx *sipx)
{
ipx_fprint_saddr(stdout,sipx);
ipx_fprint_saddr(stdout, sipx);
}
void
ipx_assign_node(IPXNode dest, IPXNode src)
{
memcpy(dest,src,sizeof(IPXNode));
memcpy(dest, src, sizeof(IPXNode));
}
int
ipx_node_equal(IPXNode n1, IPXNode n2)
{
return memcmp(n1,n2,sizeof(IPXNode))==0;
return memcmp(n1, n2, sizeof(IPXNode)) == 0;
}
int
@@ -106,8 +110,7 @@ ipx_sscanf_node(char *buf, IPXNode node)
{
return -1;
}
for (i=0; i<6; i++)
for (i = 0; i < 6; i++)
{
node[i] = n[i];
}
@@ -115,7 +118,7 @@ ipx_sscanf_node(char *buf, IPXNode node)
}
int
ipx_sscanf_net(char *buf, IPXNet *target)
ipx_sscanf_net(char *buf, IPXNet * target)
{
if (sscanf(buf, "%8lX", target) == 1)
{
@@ -124,6 +127,8 @@ ipx_sscanf_net(char *buf, IPXNet *target)
return -1;
}
IPXNode ipx_this_node={0,0,0,0,0,0};
IPXNode ipx_broadcast_node={0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
char ipx_err_string[IPX_MAX_ERROR+1]="no error detected";
IPXNode ipx_this_node =
{0, 0, 0, 0, 0, 0};
IPXNode ipx_broadcast_node =
{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
char ipx_err_string[IPX_MAX_ERROR + 1] = "no error detected";

View File

@@ -1,31 +1,31 @@
/*
IPX support library
IPX support library
Copyright (C) 1994, 1995 Ales Dryak <e-mail: A.Dryak@sh.cvut.cz>
Copyright (C) 1996, Volker Lendecke <lendecke@namu01.gwdg.de>
Copyright (C) 1994, 1995 Ales Dryak <e-mail: A.Dryak@sh.cvut.cz>
Copyright (C) 1996, Volker Lendecke <lendecke@namu01.gwdg.de>
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 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.
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.
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 __IPXUTIL_H__
#define __IPXUTIL_H__
#include <stdio.h>
#include <linux/ipx.h>
#include "kernel/ipx.h"
#define IPX_MAX_ERROR (255)
#define IPX_THIS_NET (0)
@@ -44,22 +44,22 @@ typedef unsigned short int tick_t;
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_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);
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, IPXNode node);
int ipx_sscanf_net(char *buf, IPXNet *target);
int ipx_sscanf_net(char *buf, IPXNet * target);
void ipx_assign_node(IPXNode dest,IPXNode src);
int ipx_node_equal(IPXNode n1,IPXNode n2);
void ipx_assign_node(IPXNode dest, IPXNode src);
int ipx_node_equal(IPXNode n1, IPXNode n2);
extern IPXNode ipx_this_node;
extern IPXNode ipx_broadcast_node;
extern char ipx_err_string[IPX_MAX_ERROR+1];
extern char ipx_err_string[IPX_MAX_ERROR + 1];
#endif

View File

@@ -1,304 +0,0 @@
/*
* ncp.h
*
* Copyright (C) 1995 by Volker Lendecke
*
*/
#ifndef _LINUX_NCP_H
#define _LINUX_NCP_H
#include <linux/types.h>
#include <linux/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 {
__u16 type __attribute__ ((packed));
__u8 sequence __attribute__ ((packed));
__u8 conn_low __attribute__ ((packed));
__u8 task __attribute__ ((packed));
__u8 conn_high __attribute__ ((packed));
__u8 function __attribute__ ((packed));
__u8 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_BINDERY_USER (0x0001)
#define NCP_BINDERY_UGROUP (0x0002)
#define NCP_BINDERY_PQUEUE (0x0003)
#define NCP_BINDERY_FSERVER (0x0004)
#define NCP_BINDERY_NAME_LEN (48)
struct ncp_bindery_object {
__u32 object_id;
__u16 object_type;
__u8 object_name[NCP_BINDERY_NAME_LEN];
__u8 object_flags;
__u8 object_security;
__u8 object_has_prop;
};
struct nw_property {
__u8 value[128];
__u8 more_flag;
__u8 property_flag;
};
struct prop_net_address {
__u32 network __attribute__ ((packed));
__u8 node[IPX_NODE_LEN] __attribute__ ((packed));
__u16 port __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];
};
struct ncp_filesearch_info {
__u8 volume_number;
__u16 directory_id;
__u16 sequence_no;
__u8 access_rights;
};
#define NCP_MAX_FILENAME 14
/* these define the attribute byte as seen by NCP */
#define aRONLY (1L<<0)
#define aHIDDEN (1L<<1)
#define aSYSTEM (1L<<2)
#define aEXECUTE (1L<<3)
#define aDIR (1L<<4)
#define aARCH (1L<<5)
#define AR_READ (0x01)
#define AR_WRITE (0x02)
#define AR_EXCLUSIVE (0x20)
#define NCP_FILE_ID_LEN 6
struct ncp_file_info {
__u8 file_id[NCP_FILE_ID_LEN];
char file_name[NCP_MAX_FILENAME+1];
__u8 file_attributes;
__u8 file_mode;
__u32 file_length;
__u16 creation_date;
__u16 access_date;
__u16 update_date;
__u16 update_time;
};
/* 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
/* Defines for ReturnInformationMask */
#define RIM_NAME (0x0001L)
#define RIM_SPACE_ALLOCATED (0x0002L)
#define RIM_ATTRIBUTES (0x0004L)
#define RIM_DATA_SIZE (0x0008L)
#define RIM_TOTAL_SIZE (0x0010L)
#define RIM_EXT_ATTR_INFO (0x0020L)
#define RIM_ARCHIVE (0x0040L)
#define RIM_MODIFY (0x0080L)
#define RIM_CREATION (0x0100L)
#define RIM_OWNING_NAMESPACE (0x0200L)
#define RIM_DIRECTORY (0x0400L)
#define RIM_RIGHTS (0x0800L)
#define RIM_ALL (0x0FFFL)
#define RIM_COMPRESSED_INFO (0x80000000L)
/* 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 (0x0002L)
#define DM_CREATE_DATE (0x0004L)
#define DM_CREATE_TIME (0x0008L)
#define DM_CREATOR_ID (0x0010L)
#define DM_ARCHIVE_DATE (0x0020L)
#define DM_ARCHIVE_TIME (0x0040L)
#define DM_ARCHIVER_ID (0x0080L)
#define DM_MODIFY_DATE (0x0100L)
#define DM_MODIFY_TIME (0x0200L)
#define DM_MODIFIER_ID (0x0400L)
#define DM_LAST_ACCESS_DATE (0x0800L)
#define DM_INHERITED_RIGHTS_MASK (0x1000L)
#define DM_MAXIMUM_SPACE (0x2000L)
struct nw_modify_dos_info
{
__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));
};
struct nw_queue_job_entry {
__u16 InUse __attribute__ ((packed));
__u32 prev __attribute__ ((packed));
__u32 next __attribute__ ((packed));
__u32 ClientStation __attribute__ ((packed));
__u32 ClientTask __attribute__ ((packed));
__u32 ClientObjectID __attribute__ ((packed));
__u32 TargetServerID __attribute__ ((packed));
__u8 TargetExecTime[6] __attribute__ ((packed));
__u8 JobEntryTime[6] __attribute__ ((packed));
__u32 JobNumber __attribute__ ((packed));
__u16 JobType __attribute__ ((packed));
__u16 JobPosition __attribute__ ((packed));
__u16 JobControlFlags __attribute__ ((packed));
__u8 FileNameLen __attribute__ ((packed));
char JobFileName[13] __attribute__ ((packed));
__u32 JobFileHandle __attribute__ ((packed));
__u32 ServerStation __attribute__ ((packed));
__u32 ServerTaskNumber __attribute__ ((packed));
__u32 ServerObjectID __attribute__ ((packed));
char JobTextDescription[50] __attribute__ ((packed));
char ClientRecordArea[152] __attribute__ ((packed));
};
struct queue_job {
struct nw_queue_job_entry j;
__u8 file_handle[6];
};
#define QJE_OPER_HOLD 0x80
#define QJE_USER_HOLD 0x40
#define QJE_ENTRYOPEN 0x20
#define QJE_SERV_RESTART 0x10
#define QJE_SERV_AUTO 0x08
/* ClientRecordArea for print jobs */
#define KEEP_ON 0x0400
#define NO_FORM_FEED 0x0800
#define NOTIFICATION 0x1000
#define DELETE_FILE 0x2000
#define EXPAND_TABS 0x4000
#define PRINT_BANNER 0x8000
struct print_job_record {
__u8 Version __attribute__ ((packed));
__u8 TabSize __attribute__ ((packed));
__u16 Copies __attribute__ ((packed));
__u16 CtrlFlags __attribute__ ((packed));
__u16 Lines __attribute__ ((packed));
__u16 Rows __attribute__ ((packed));
char FormName[16] __attribute__ ((packed));
__u8 Reserved[6] __attribute__ ((packed));
char BannerName[13] __attribute__ ((packed));
char FnameBanner[13] __attribute__ ((packed));
char FnameHeader[14] __attribute__ ((packed));
char Path[80] __attribute__ ((packed));
};
#endif /* _LINUX_NCP_H */

View File

@@ -1,164 +0,0 @@
/*
* ncp_fs.h
*
* Copyright (C) 1995 by Volker Lendecke
*
*/
#ifndef _LINUX_NCP_FS_H
#define _LINUX_NCP_FS_H
#include <linux/fs.h>
#include <linux/in.h>
#include <linux/types.h>
#include <linux/ncp_mount.h>
#include <linux/ncp_fs_sb.h>
#include <linux/ncp_fs_i.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;
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;
};
#define NCP_IOC_NCPREQUEST _IOR('n', 1, struct ncp_ioctl_request)
#define NCP_IOC_GETMOUNTUID _IOW('n', 2, 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)
/*
* The packet size to allocate. One page should be enough.
*/
#define NCP_PACKET_SIZE 4070
#define NCP_MAXPATHLEN 255
#define NCP_MAXNAMELEN 14
#ifdef __KERNEL__
/* The readdir cache size controls how many directory entries are
* cached.
*/
#define NCP_READDIR_CACHE_SIZE 64
#define NCP_MAX_RPC_TIMEOUT (6*HZ)
/* Guess, what 0x564c is :-) */
#define NCP_SUPER_MAGIC 0x564c
#define NCP_SBP(sb) ((struct ncp_server *)((sb)->u.generic_sbp))
#define NCP_INOP(inode) ((struct ncp_inode_info *)((inode)->u.generic_ip))
#define NCP_SERVER(inode) NCP_SBP((inode)->i_sb)
#define NCP_FINFO(inode) (&(NCP_INOP(inode)->finfo))
#define NCP_ISTRUCT(inode) (&(NCP_FINFO(inode)->i))
#ifdef DEBUG_NCP_MALLOC
#include <linux/malloc.h>
extern int ncp_malloced;
extern int ncp_current_malloced;
static inline void *
ncp_kmalloc(unsigned int size, int priority)
{
ncp_malloced += 1;
ncp_current_malloced += 1;
return kmalloc(size, priority);
}
static inline void
ncp_kfree_s(void *obj, int size)
{
ncp_current_malloced -= 1;
kfree_s(obj, size);
}
#else /* DEBUG_NCP_MALLOC */
#define ncp_kmalloc(s,p) kmalloc(s,p)
#define ncp_kfree_s(o,s) kfree_s(o,s)
#endif /* DEBUG_NCP_MALLOC */
#if DEBUG_NCP > 0
#define DPRINTK(format, args...) printk(format , ## args)
#else
#define DPRINTK(format, args...)
#endif
#if DEBUG_NCP > 1
#define DDPRINTK(format, args...) printk(format , ## args)
#else
#define DDPRINTK(format, args...)
#endif
/* linux/fs/ncpfs/file.c */
extern struct inode_operations ncp_file_inode_operations;
int ncp_make_open(struct inode *i, int right);
/* linux/fs/ncpfs/dir.c */
extern struct inode_operations ncp_dir_inode_operations;
void ncp_free_inode_info(struct ncp_inode_info *i);
void ncp_free_all_inodes(struct ncp_server *server);
void ncp_init_root(struct ncp_server *server);
int ncp_conn_logged_in(struct ncp_server *server);
int ncp_stat_root(struct ncp_server *server);
void ncp_init_dir_cache(void);
void ncp_invalid_dir_cache(struct inode *ino);
struct ncp_inode_info *ncp_find_inode(struct inode *inode);
ino_t ncp_info_ino(struct ncp_server *server, struct ncp_inode_info *info);
void ncp_invalidate_all_inodes(struct ncp_server *server);
void ncp_free_dir_cache(void);
int ncp_date_dos2unix(__u16 time, __u16 date);
void ncp_date_unix2dos(int unix_date, __u16 *time, __u16 *date);
/* linux/fs/ncpfs/ioctl.c */
int ncp_ioctl (struct inode * inode, struct file * filp,
unsigned int cmd, unsigned long arg);
/* linux/fs/ncpfs/inode.c */
struct super_block *ncp_read_super(struct super_block *sb,
void *raw_data, int silent);
void ncp_invalidate_connection(struct ncp_server *server);
int ncp_conn_is_valid(struct ncp_server *server);
/* linux/fs/ncpfs/sock.c */
int ncp_request(struct ncp_server *server, int function);
int ncp_connect(struct ncp_server *server);
int ncp_disconnect(struct ncp_server *server);
int ncp_catch_watchdog(struct ncp_server *server);
int ncp_dont_catch_watchdog(struct ncp_server *server);
void ncp_lock_server(struct ncp_server *server);
void ncp_unlock_server(struct ncp_server *server);
/* linux/fs/ncpfs/mmap.c */
int ncp_mmap(struct inode * inode, struct file * file, struct vm_area_struct * vma);
#endif /* __KERNEL__ */
#endif /* _LINUX_NCP_FS_H */

View File

@@ -1,36 +0,0 @@
/*
* ncp_fs_i.h
*
* Copyright (C) 1995 by Paal-Kr. Engstad and Volker Lendecke
*
*/
#ifndef _LINUX_NCP_FS_I
#define _LINUX_NCP_FS_I
#include <linux/ncp.h>
#ifdef __KERNEL__
enum ncp_inode_state {
NCP_INODE_VALID = 19, /* Inode currently in use */
NCP_INODE_LOOKED_UP, /* directly before iget */
NCP_INODE_CACHED, /* in a path to an inode which is in use */
NCP_INODE_INVALID
};
/*
* ncp fs inode data (in memory only)
*/
struct ncp_inode_info {
enum ncp_inode_state state;
int nused; /* for directories:
number of references in memory */
struct ncp_inode_info *dir;
struct ncp_inode_info *next, *prev;
struct inode *inode;
struct nw_file_info finfo;
};
#endif
#endif

View File

@@ -1,75 +0,0 @@
/*
* ncp_fs_sb.h
*
* Copyright (C) 1995 by Volker Lendecke
*
*/
#ifndef _NCP_FS_SB
#define _NCP_FS_SB
#include <linux/ncp_mount.h>
#include <linux/types.h>
#ifdef __KERNEL__
#define NCP_DEFAULT_BUFSIZE 1024
struct ncp_server {
struct ncp_mount_data m; /* Nearly all of the mount data is of
interest for us later, so we store
it completely. */
__u8 name_space[NCP_NUMBER_OF_VOLUMES];
struct file *ncp_filp; /* File pointer to ncp socket */
struct file *wdog_filp; /* File pointer to wdog socket */
void *data_ready; /* The wdog socket gets a new
data_ready callback. We store the
old one for checking purposes and
to reset it on unmounting. */
u8 sequence;
u8 task;
u16 connection; /* Remote connection number */
u8 completion; /* Status message from server */
u8 conn_status; /* Bit 4 = 1 ==> Server going down, no
requests allowed anymore.
Bit 0 = 1 ==> Server is down. */
int buffer_size; /* Negotiated bufsize */
int reply_size; /* Size of last reply */
int packet_size;
unsigned char *packet; /* Here we prepare requests and
receive replies */
int lock; /* To prevent mismatch in protocols. */
struct wait_queue *wait;
int current_size; /* for packet preparation */
int has_subfunction;
int ncp_reply_size;
struct ncp_inode_info root;
char root_path; /* '\0' */
};
static inline int
ncp_conn_valid(struct ncp_server *server)
{
return ((server->conn_status & 0x11) == 0);
}
static inline void
ncp_invalidate_conn(struct ncp_server *server)
{
server->conn_status |= 0x01;
}
#endif /* __KERNEL__ */
#endif

View File

@@ -1,49 +0,0 @@
/*
* ncp_mount.h
*
* Copyright (C) 1995 by Volker Lendecke
*
*/
#ifndef _LINUX_NCP_MOUNT_H
#define _LINUX_NCP_MOUNT_H
#include <linux/types.h>
#include <linux/ipx.h>
#include <linux/ncp.h>
#include <linux/ncp_fs_i.h>
#define NCP_MOUNT_VERSION 2
#define NCP_USERNAME_LEN (NCP_BINDERY_NAME_LEN)
#define NCP_PASSWORD_LEN 20
/* Values for flags */
#define NCP_MOUNT_SOFT 0x0001
#define NCP_MOUNT_INTR 0x0002
struct ncp_mount_data {
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 */
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+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;
uid_t uid;
gid_t gid;
mode_t file_mode;
mode_t dir_mode;
};
#endif

View File

@@ -1,65 +0,0 @@
#
# Makefile for the linux ncp-filesystem routines.
#
CFLAGS = -Wall -Wstrict-prototypes -O2 -DMODULE -fomit-frame-pointer \
$(INCLUDES) -DNCPFS_VERSION=\"$(VERSION)\"\
# -DDEBUG_NCP=1 -DDEBUG_NCP_MALLOC
# -DDEBUG_NCP_MALLOC
CC = gcc -D__KERNEL__ -I.
AS = as
ARCH = i386
.c.s:
$(CC) $(CFLAGS) -S $<
.c.o:
$(CC) $(CFLAGS) -c $<
.s.o:
$(AS) -o $*.o $<
OBJS= dir.o inode.o file.o sock.o ioctl.o ncplib_kernel.o mmap.o
all: $(INTERM_BINDIR)/ncpfs.o
$(INTERM_BINDIR)/ncpfs.o: $(OBJS)
$(LD) -r -o $@ $(OBJS)
ncplib_kernel.o: ncplib_kernel.c ncplib_kernel.h
$(CC) $(CFLAGS) -finline-functions -c $<
dep:
$(CPP) -M $(INCLUDES) *.c > .depend
clean:
rm -f *.o *~
realclean: clean
rm -f ncpmount ncptest .depend $(DISTFILE) *.out
modules: ncpfs.o
SRCPATH=$(shell pwd)
SRCDIR=$(shell basename $(SRCPATH))
DISTFILE=$(SRCDIR).tgz
BACKUPFILE=ncpfs01.tgz
HOME=/home/me
backup:
(rm -f $(DISTFILE); cd ..; tar cvf - $(SRCDIR) | gzip -1 \
> $(HOME)/tarz/backup/$(BACKUPFILE))
(cd $(HOME)/tarz/backup; ls -l $(BACKUPFILE); mcopy $(BACKUPFILE) a:)
dist: realclean
rm -fr mnt
(cd ..; \
tar cvf - $(SRCDIR) | \
gzip -9 > $(DISTFILE); \
mv $(DISTFILE) $(SRCDIR))
#
# include a dependency file if one exists
#
ifeq (.depend,$(wildcard .depend))
include .depend
endif

File diff suppressed because it is too large Load Diff

View File

@@ -1,287 +0,0 @@
/*
* file.c
*
* Copyright (C) 1995 by Paal-Kr. Engstad and Volker Lendecke
*
*/
#include <linux/config.h>
#ifdef MODULE
#include <linux/module.h>
#include <linux/version.h>
#endif
#include <asm/segment.h>
#include <asm/system.h>
#include <linux/sched.h>
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/fcntl.h>
#include <linux/stat.h>
#include <linux/mm.h>
#include <linux/ncp_fs.h>
#include <linux/locks.h>
#include "ncplib_kernel.h"
#include <linux/malloc.h>
static inline int min(int a, int b)
{
return a<b ? a : b;
}
static int
ncp_fsync(struct inode *inode, struct file *file)
{
return 0;
}
int
ncp_make_open(struct inode *i, int right)
{
struct nw_file_info *finfo;
if (i == NULL)
{
printk("ncp_make_open: got NULL inode\n");
return -EINVAL;
}
finfo = NCP_FINFO(i);
DPRINTK("ncp_make_open: dirent->opened = %d\n", finfo->opened);
lock_super(i->i_sb);
if (finfo->opened == 0)
{
finfo->access = -1;
/* tries max. rights */
if (ncp_open_create_file_or_subdir(NCP_SERVER(i),
NULL, NULL,
OC_MODE_OPEN, 0,
AR_READ | AR_WRITE,
finfo) == 0)
{
finfo->access = O_RDWR;
}
else if (ncp_open_create_file_or_subdir(NCP_SERVER(i),
NULL, NULL,
OC_MODE_OPEN, 0,
AR_READ,
finfo) == 0)
{
finfo->access = O_RDONLY;
}
}
unlock_super(i->i_sb);
if ( ((right == O_RDONLY) && ( (finfo->access == O_RDONLY)
|| (finfo->access == O_RDWR)))
|| ((right == O_WRONLY) && ( (finfo->access == O_WRONLY)
|| (finfo->access == O_RDWR)))
|| ((right == O_RDWR) && (finfo->access == O_RDWR)))
return 0;
return -EACCES;
}
static int
ncp_file_read(struct inode *inode, struct file *file, char *buf, int count)
{
int bufsize, already_read;
off_t pos;
int errno;
DPRINTK("ncp_file_read: enter %s\n", NCP_ISTRUCT(inode)->entryName);
if (inode == NULL)
{
DPRINTK("ncp_file_read: inode = NULL\n");
return -EINVAL;
}
if (!ncp_conn_valid(NCP_SERVER(inode)))
{
return -EIO;
}
if (!S_ISREG(inode->i_mode))
{
DPRINTK("ncp_file_read: read from non-file, mode %07o\n",
inode->i_mode);
return -EINVAL;
}
pos = file->f_pos;
if (pos + count > inode->i_size)
{
count = inode->i_size - pos;
}
if (count <= 0)
{
return 0;
}
if ((errno = ncp_make_open(inode, O_RDONLY)) != 0)
{
return errno;
}
bufsize = NCP_SERVER(inode)->buffer_size;
already_read = 0;
/* First read in as much as possible for each bufsize. */
while (already_read < count)
{
int read_this_time;
int to_read = min(bufsize - (pos % bufsize),
count - already_read);
if (ncp_read(NCP_SERVER(inode), NCP_FINFO(inode)->file_handle,
pos, to_read, buf, &read_this_time) != 0)
{
return -EIO; /* This is not exact, i know.. */
}
pos += read_this_time;
buf += read_this_time;
already_read += read_this_time;
if (read_this_time < to_read)
{
break;
}
}
file->f_pos = pos;
if (!IS_RDONLY(inode))
{
inode->i_atime = CURRENT_TIME;
}
inode->i_dirt = 1;
DPRINTK("ncp_file_read: exit %s\n", NCP_ISTRUCT(inode)->entryName);
return already_read;
}
static int
ncp_file_write(struct inode *inode, struct file *file, char *buf,
int count)
{
int bufsize, already_written;
off_t pos;
int errno;
if (inode == NULL)
{
DPRINTK("ncp_file_write: inode = NULL\n");
return -EINVAL;
}
if (!ncp_conn_valid(NCP_SERVER(inode)))
{
return -EIO;
}
if (!S_ISREG(inode->i_mode))
{
DPRINTK("ncp_file_write: write to non-file, mode %07o\n",
inode->i_mode);
return -EINVAL;
}
DPRINTK("ncp_file_write: enter %s\n", NCP_ISTRUCT(inode)->entryName);
if (count <= 0)
{
return 0;
}
if ((errno = ncp_make_open(inode, O_RDWR)) != 0)
{
return errno;
}
pos = file->f_pos;
if (file->f_flags & O_APPEND)
{
pos = inode->i_size;
}
bufsize = NCP_SERVER(inode)->buffer_size;
already_written = 0;
while (already_written < count)
{
int written_this_time;
int to_write = min(bufsize - (pos % bufsize),
count - already_written);
if (ncp_write(NCP_SERVER(inode), NCP_FINFO(inode)->file_handle,
pos, to_write, buf, &written_this_time) != 0)
{
return -EIO;
}
pos += written_this_time;
buf += written_this_time;
already_written += written_this_time;
if (written_this_time < to_write)
{
break;
}
}
inode->i_mtime = inode->i_ctime = CURRENT_TIME;
inode->i_dirt = 1;
file->f_pos = pos;
if (pos > inode->i_size)
{
inode->i_size = pos;
ncp_invalid_dir_cache(NCP_INOP(inode)->dir->inode);
}
DPRINTK("ncp_file_write: exit %s\n", NCP_ISTRUCT(inode)->entryName);
return already_written;
}
static struct file_operations ncp_file_operations = {
NULL, /* lseek - default */
ncp_file_read, /* read */
ncp_file_write, /* write */
NULL, /* readdir - bad */
NULL, /* select - default */
ncp_ioctl, /* ioctl */
ncp_mmap, /* mmap */
NULL, /* open */
NULL, /* release */
ncp_fsync, /* fsync */
};
struct inode_operations ncp_file_inode_operations = {
&ncp_file_operations, /* default file operations */
NULL, /* create */
NULL, /* lookup */
NULL, /* link */
NULL, /* unlink */
NULL, /* symlink */
NULL, /* mkdir */
NULL, /* rmdir */
NULL, /* mknod */
NULL, /* rename */
NULL, /* readlink */
NULL, /* follow_link */
NULL, /* bmap */
NULL /* truncate */
};

View File

@@ -1,515 +0,0 @@
/*
* inode.c
*
* Copyright (C) 1995 by Volker Lendecke
*
*/
#include <linux/config.h>
#ifdef MODULE
#include <linux/module.h>
#include <linux/version.h>
#else
#define MOD_INC_USE_COUNT
#define MOD_DEC_USE_COUNT
#endif
#include <asm/system.h>
#include <asm/segment.h>
#include <linux/sched.h>
#include <linux/ncp_fs.h>
#include <linux/kernel.h>
#include <linux/mm.h>
#include <linux/string.h>
#include <linux/stat.h>
#include <linux/errno.h>
#include <linux/locks.h>
#include <linux/fcntl.h>
#include <linux/malloc.h>
#include "ncplib_kernel.h"
extern int close_fp(struct file *filp);
static void ncp_put_inode(struct inode *);
static void ncp_read_inode(struct inode *);
static void ncp_put_super(struct super_block *);
static void ncp_statfs(struct super_block *sb, struct statfs *stat);
static int ncp_notify_change(struct inode *inode, struct iattr *attr);
static struct super_operations ncp_sops = {
ncp_read_inode, /* read inode */
ncp_notify_change, /* notify change */
NULL, /* write inode */
ncp_put_inode, /* put inode */
ncp_put_super, /* put superblock */
NULL, /* write superblock */
ncp_statfs, /* stat filesystem */
NULL
};
/* ncp_read_inode: Called from iget, it only traverses the allocated
ncp_inode_info's and initializes the inode from the data found
there. It does not allocate or deallocate anything. */
static void
ncp_read_inode(struct inode *inode)
{
/* Our task should be extremely simple here. We only have to
look up the infomation somebody else (ncp_iget) put into
the inode tree. The address of this information is the
inode->i_ino. Just to make sure everything went well, we
check it's there. */
struct ncp_inode_info *inode_info = ncp_find_inode(inode);
if (inode_info == NULL)
{
/* Ok, now we're in trouble. The inode info is not there. What
should we do now??? */
printk("ncp_read_inode: inode info not found\n");
return;
}
inode_info->state = NCP_INODE_VALID;
NCP_INOP(inode) = inode_info;
inode_info->inode = inode;
if (NCP_ISTRUCT(inode)->attributes & aDIR)
{
inode->i_mode = NCP_SERVER(inode)->m.dir_mode;
/* for directories dataStreamSize seems to be some
Object ID ??? */
inode->i_size = 512;
}
else
{
inode->i_mode = NCP_SERVER(inode)->m.file_mode;
inode->i_size = NCP_ISTRUCT(inode)->dataStreamSize;
}
DDPRINTK("ncp_read_inode: inode->i_mode = %u\n", inode->i_mode);
inode->i_nlink = 1;
inode->i_uid = NCP_SERVER(inode)->m.uid;
inode->i_gid = NCP_SERVER(inode)->m.gid;
inode->i_blksize = 512;
inode->i_rdev = 0;
if ((inode->i_blksize != 0) && (inode->i_size != 0))
{
inode->i_blocks =
(inode->i_size - 1) / inode->i_blksize + 1;
}
else
{
inode->i_blocks = 0;
}
inode->i_mtime = ncp_date_dos2unix(NCP_ISTRUCT(inode)->modifyTime,
NCP_ISTRUCT(inode)->modifyDate);
inode->i_ctime = ncp_date_dos2unix(NCP_ISTRUCT(inode)->creationTime,
NCP_ISTRUCT(inode)->creationDate);
inode->i_atime = ncp_date_dos2unix(0,
NCP_ISTRUCT(inode)->lastAccessDate);
if (S_ISREG(inode->i_mode))
{
inode->i_op = &ncp_file_inode_operations;
}
else if (S_ISDIR(inode->i_mode))
{
inode->i_op = &ncp_dir_inode_operations;
}
else
{
inode->i_op = NULL;
}
}
static void
ncp_put_inode(struct inode *inode)
{
struct nw_file_info *finfo = NCP_FINFO(inode);
struct super_block *sb = inode->i_sb;
lock_super(sb);
if (finfo->opened != 0)
{
if (ncp_close_file(NCP_SERVER(inode), finfo->file_handle)!=0)
{
/* We can't do anything but complain. */
printk("ncp_put_inode: could not close\n");
}
}
DDPRINTK("ncp_put_inode: put %s\n",
finfo->i.entryName);
ncp_free_inode_info(NCP_INOP(inode));
if (S_ISDIR(inode->i_mode))
{
DDPRINTK("ncp_put_inode: put directory %ld\n",
inode->i_ino);
ncp_invalid_dir_cache(inode);
}
clear_inode(inode);
unlock_super(sb);
}
struct super_block *
ncp_read_super(struct super_block *sb, void *raw_data, int silent)
{
struct ncp_mount_data *data = (struct ncp_mount_data *) raw_data;
struct ncp_server *server;
struct file *ncp_filp;
struct file *wdog_filp;
dev_t dev = sb->s_dev;
int error;
if (data == NULL)
{
printk("ncp_read_super: missing data argument\n");
sb->s_dev = 0;
return NULL;
}
if (data->version != NCP_MOUNT_VERSION)
{
printk("ncp warning: mount version %s than kernel\n",
(data->version < NCP_MOUNT_VERSION) ?
"older" : "newer");
sb->s_dev = 0;
return NULL;
}
if ( (data->ncp_fd >= NR_OPEN)
|| ((ncp_filp = current->files->fd[data->ncp_fd]) == NULL)
|| (!S_ISSOCK(ncp_filp->f_inode->i_mode)))
{
printk("ncp_read_super: invalid ncp socket\n");
sb->s_dev = 0;
return NULL;
}
if ( (data->wdog_fd >= NR_OPEN)
|| ((wdog_filp = current->files->fd[data->wdog_fd]) == NULL)
|| (!S_ISSOCK(wdog_filp->f_inode->i_mode)))
{
printk("ncp_read_super: invalid wdog socket\n");
sb->s_dev = 0;
return NULL;
}
/* We must malloc our own super-block info */
server = (struct ncp_server *)ncp_kmalloc(sizeof(struct ncp_server),
GFP_KERNEL);
if (server == NULL)
{
printk("ncp_read_super: could not alloc ncp_server\n");
return NULL;
}
ncp_filp->f_count += 1;
wdog_filp->f_count += 1;
lock_super(sb);
NCP_SBP(sb) = server;
sb->s_blocksize = 1024; /* Eh... Is this correct? */
sb->s_blocksize_bits = 10;
sb->s_magic = NCP_SUPER_MAGIC;
sb->s_dev = dev;
sb->s_op = &ncp_sops;
server->ncp_filp = ncp_filp;
server->wdog_filp = wdog_filp;
server->lock = 0;
server->wait = NULL;
server->packet = NULL;
server->buffer_size = 0;
server->conn_status = 0;
server->m = *data;
server->m.file_mode = (server->m.file_mode &
(S_IRWXU|S_IRWXG|S_IRWXO)) | S_IFREG;
server->m.dir_mode = (server->m.dir_mode &
(S_IRWXU|S_IRWXG|S_IRWXO)) | S_IFDIR;
server->packet_size = NCP_PACKET_SIZE;
server->packet = ncp_kmalloc(NCP_PACKET_SIZE, GFP_KERNEL);
if (server->packet == NULL)
{
printk("ncpfs: could not alloc packet\n");
error = -ENOMEM;
unlock_super(sb);
goto fail;
}
ncp_init_root(server);
/*
* Make the connection to the server
*/
if (ncp_catch_watchdog(server) != 0)
{
printk("ncp_read_super: Could not catch watchdog\n");
error = -EINVAL;
unlock_super(sb);
goto fail;
}
ncp_lock_server(server);
error = ncp_connect(server);
ncp_unlock_server(server);
unlock_super(sb);
if (error < 0)
{
sb->s_dev = 0;
printk("ncp_read_super: Failed connection, bailing out "
"(error = %d).\n", -error);
ncp_kfree_s(server->packet, server->packet_size);
ncp_dont_catch_watchdog(server);
goto fail;
}
DPRINTK("ncp_read_super: NCP_SBP(sb) = %x\n", (int)NCP_SBP(sb));
if (!(sb->s_mounted = iget(sb, ncp_info_ino(server, &(server->root)))))
{
sb->s_dev = 0;
printk("ncp_read_super: get root inode failed\n");
goto disconnect;
}
if (ncp_negotiate_buffersize(server, NCP_DEFAULT_BUFSIZE,
&(server->buffer_size)) != 0)
{
sb->s_dev = 0;
printk("ncp_read_super: could not get bufsize\n");
goto disconnect;
}
DPRINTK("ncpfs: bufsize = %d\n", server->buffer_size);
MOD_INC_USE_COUNT;
return sb;
disconnect:
ncp_lock_server(server);
ncp_disconnect(server);
ncp_unlock_server(server);
ncp_kfree_s(server->packet, server->packet_size);
ncp_dont_catch_watchdog(server);
fail:
ncp_filp->f_count -= 1;
wdog_filp->f_count -= 1;
ncp_kfree_s(NCP_SBP(sb), sizeof(struct ncp_server));
return NULL;
}
static void
ncp_put_super(struct super_block *sb)
{
struct ncp_server *server = NCP_SBP(sb);
lock_super(sb);
ncp_lock_server(server);
ncp_disconnect(server);
ncp_unlock_server(server);
close_fp(server->ncp_filp);
ncp_dont_catch_watchdog(server);
close_fp(server->wdog_filp);
ncp_free_all_inodes(server);
ncp_kfree_s(server->packet, server->packet_size);
sb->s_dev = 0;
ncp_kfree_s(NCP_SBP(sb), sizeof(struct ncp_server));
NCP_SBP(sb) = NULL;
unlock_super(sb);
MOD_DEC_USE_COUNT;
}
static void
ncp_statfs(struct super_block *sb, struct statfs *stat)
{
struct statfs tmp;
/* We cannot say how much disk space is left on a mounted
NetWare Server, because free space is distributed over
volumes, and the current user might have disk quotas. So
free space is not that simple to determine. Our decision
here is to err conservatively. */
tmp.f_type = NCP_SUPER_MAGIC;
tmp.f_bsize = 512;
tmp.f_blocks = 0;
tmp.f_bfree = 0;
tmp.f_bavail = 0;
tmp.f_files = -1;
tmp.f_ffree = -1;
tmp.f_namelen = 12;
memcpy_tofs(stat, &tmp, sizeof(tmp));
}
static int
ncp_notify_change(struct inode *inode, struct iattr *attr)
{
int result = 0;
int info_mask;
struct nw_modify_dos_info info;
if (!ncp_conn_valid(NCP_SERVER(inode)))
{
return -EIO;
}
if ((result = inode_change_ok(inode, attr)) < 0)
return result;
if (((attr->ia_valid & ATTR_UID) &&
(attr->ia_uid != NCP_SERVER(inode)->m.uid)))
return -EPERM;
if (((attr->ia_valid & ATTR_GID) &&
(attr->ia_uid != NCP_SERVER(inode)->m.gid)))
return -EPERM;
if (((attr->ia_valid & ATTR_MODE) &&
(attr->ia_mode &
~(S_IFREG | S_IFDIR | S_IRWXU | S_IRWXG | S_IRWXO))))
return -EPERM;
info_mask = 0;
memset(&info, 0, sizeof(info));
if ((attr->ia_valid & ATTR_CTIME) != 0)
{
info_mask |= (DM_CREATE_TIME|DM_CREATE_DATE);
ncp_date_unix2dos(attr->ia_ctime,
&(info.creationTime), &(info.creationDate));
}
if ((attr->ia_valid & ATTR_MTIME) != 0)
{
info_mask |= (DM_MODIFY_TIME|DM_MODIFY_DATE);
ncp_date_unix2dos(attr->ia_mtime,
&(info.modifyTime), &(info.modifyDate));
}
if ((attr->ia_valid & ATTR_ATIME) != 0)
{
__u16 dummy;
info_mask |= (DM_LAST_ACCESS_DATE);
ncp_date_unix2dos(attr->ia_ctime,
&(dummy), &(info.lastAccessDate));
}
if (info_mask != 0)
{
if ((result =
ncp_modify_file_or_subdir_dos_info(NCP_SERVER(inode),
NCP_ISTRUCT(inode),
info_mask,
&info)) != 0)
{
result = -EACCES;
if (info_mask == (DM_CREATE_TIME|DM_CREATE_DATE))
{
/* NetWare seems not to allow this. I
do not know why. So, just tell the
user everything went fine. This is
a terrible hack, but I do not know
how to do this correctly. */
result = 0;
}
}
}
if ((attr->ia_valid & ATTR_SIZE) != 0)
{
int written;
DPRINTK("ncpfs: trying to change size of %s to %ld\n",
NCP_ISTRUCT(inode)->entryName, attr->ia_size);
if ((result = ncp_make_open(inode, O_RDWR)) < 0)
{
return -EACCES;
}
ncp_write(NCP_SERVER(inode), NCP_FINFO(inode)->file_handle,
attr->ia_size, 0, "", &written);
/* According to ndir, the changes only take effect after
closing the file */
ncp_close_file(NCP_SERVER(inode),
NCP_FINFO(inode)->file_handle);
NCP_FINFO(inode)->opened = 0;
result = 0;
}
ncp_invalid_dir_cache(NCP_INOP(inode)->dir->inode);
return result;
}
#ifdef DEBUG_NCP_MALLOC
int ncp_malloced;
int ncp_current_malloced;
#endif
#ifdef MODULE
char kernel_version[] = UTS_RELEASE;
static struct file_system_type ncp_fs_type = {
ncp_read_super, "ncpfs", 0, NULL
};
int
init_module( void)
{
DPRINTK("ncpfs: init_module called\n");
#ifdef DEBUG_NCP_MALLOC
ncp_malloced = 0;
ncp_current_malloced = 0;
#endif
ncp_init_dir_cache();
register_filesystem(&ncp_fs_type);
printk("ncpfs version %s loaded\n", NCPFS_VERSION);
return 0;
}
void
cleanup_module(void)
{
DPRINTK("ncpfs: cleanup_module called\n");
ncp_free_dir_cache();
unregister_filesystem(&ncp_fs_type);
#ifdef DEBUG_NCP_MALLOC
printk("ncp_malloced: %d\n", ncp_malloced);
printk("ncp_current_malloced: %d\n", ncp_current_malloced);
#endif
}
#endif

View File

@@ -1,166 +0,0 @@
/*
* ioctl.c
*
* Copyright (C) 1995 by Volker Lendecke
*
*/
#include <linux/config.h>
#ifdef MODULE
#include <linux/module.h>
#include <linux/version.h>
#endif
#include <asm/segment.h>
#include <linux/errno.h>
#include <linux/fs.h>
#include <linux/ncp_fs.h>
#include <linux/ioctl.h>
#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/ncp.h>
int
ncp_ioctl (struct inode * inode, struct file * filp,
unsigned int cmd, unsigned long arg)
{
int result;
struct ncp_ioctl_request request;
struct ncp_fs_info info;
struct ncp_server *server = NCP_SERVER(inode);
/*
* Binary compatible with 1.3.XX releases.
* Take this out in 2.1.0 development series.
* <mec@duracef.shout.net> 12 Mar 1996
*/
switch(cmd) {
case _IOR('n', 1, unsigned char *):
cmd = NCP_IOC_NCPREQUEST;
break;
case _IOR('u', 1, uid_t):
cmd = NCP_IOC_GETMOUNTUID;
break;
case _IO('l', 1):
cmd = NCP_IOC_CONN_LOGGED_IN;
break;
case _IOWR('i', 1, unsigned char *):
cmd = NCP_IOC_GET_FS_INFO;
break;
}
switch(cmd) {
case NCP_IOC_NCPREQUEST:
if ( (permission(inode, MAY_WRITE) != 0)
&& (current->uid != server->m.mounted_uid))
{
return -EACCES;
}
if ((result = verify_area(VERIFY_READ, (char *)arg,
sizeof(request))) != 0)
{
return result;
}
memcpy_fromfs(&request, (struct ncp_ioctl_request *)arg,
sizeof(request));
if ( (request.function > 255)
|| (request.size >
NCP_PACKET_SIZE - sizeof(struct ncp_request_header)))
{
return -EINVAL;
}
if ((result = verify_area(VERIFY_WRITE, (char *)request.data,
NCP_PACKET_SIZE)) != 0)
{
return result;
}
ncp_lock_server(server);
/* FIXME: We hack around in the server's structures
here to be able to use ncp_request */
server->has_subfunction = 0;
server->current_size = request.size;
memcpy_fromfs(server->packet, request.data, request.size);
ncp_request(server, request.function);
DPRINTK("ncp_ioctl: copy %d bytes\n",
server->reply_size);
memcpy_tofs(request.data, server->packet, server->reply_size);
ncp_unlock_server(server);
return server->reply_size;
case NCP_IOC_CONN_LOGGED_IN:
if ( (permission(inode, MAY_WRITE) != 0)
&& (current->uid != server->m.mounted_uid))
{
return -EACCES;
}
return ncp_conn_logged_in(server);
case NCP_IOC_GET_FS_INFO:
if ( (permission(inode, MAY_WRITE) != 0)
&& (current->uid != server->m.mounted_uid))
{
return -EACCES;
}
if ((result = verify_area(VERIFY_WRITE, (char *)arg,
sizeof(info))) != 0)
{
return result;
}
memcpy_fromfs(&info, (struct ncp_fs_info *)arg,
sizeof(info));
if (info.version != NCP_GET_FS_INFO_VERSION)
{
DPRINTK("info.version invalid: %d\n", info.version);
return -EINVAL;
}
info.addr = server->m.serv_addr;
info.mounted_uid = server->m.mounted_uid;
info.connection = server->connection;
info.buffer_size = server->buffer_size;
info.volume_number = NCP_ISTRUCT(inode)->volNumber;
info.directory_id = NCP_ISTRUCT(inode)->DosDirNum;
memcpy_tofs((struct ncp_fs_info *)arg, &info, sizeof(info));
return 0;
case NCP_IOC_GETMOUNTUID:
if ( (permission(inode, MAY_READ) != 0)
&& (current->uid != server->m.mounted_uid))
{
return -EACCES;
}
if ((result = verify_area(VERIFY_WRITE, (uid_t*) arg,
sizeof(uid_t))) != 0)
{
return result;
}
put_fs_word(server->m.mounted_uid, (uid_t*) arg);
return 0;
default:
return -EINVAL;
}
return -EINVAL;
}

View File

@@ -1,157 +0,0 @@
/*
* mmap.c
*
* Copyright (C) 1995 by Volker Lendecke
*
*/
#include <linux/config.h>
#ifdef MODULE
#include <linux/module.h>
#include <linux/version.h>
#endif
#include <linux/stat.h>
#include <linux/sched.h>
#include <linux/kernel.h>
#include <linux/mm.h>
#include <linux/shm.h>
#include <linux/errno.h>
#include <linux/mman.h>
#include <linux/string.h>
#include <linux/malloc.h>
#include <linux/fcntl.h>
#include <linux/ncp_fs.h>
#include "ncplib_kernel.h"
#include <asm/segment.h>
#include <asm/system.h>
static inline int min(int a, int b)
{
return a<b ? a : b;
}
/*
* Fill in the supplied page for mmap
*/
static unsigned long
ncp_file_mmap_nopage(struct vm_area_struct * area,
unsigned long address, unsigned long page, int no_share)
{
struct inode * inode = area->vm_inode;
unsigned int clear;
unsigned long tmp;
int bufsize;
int pos;
unsigned short fs;
address &= PAGE_MASK;
pos = address - area->vm_start + area->vm_offset;
clear = 0;
if (address + PAGE_SIZE > area->vm_end)
{
clear = address + PAGE_SIZE - area->vm_end;
}
/* what we can read in one go */
bufsize = NCP_SERVER(inode)->buffer_size;
fs = get_fs();
set_fs(get_ds());
if (ncp_make_open(inode, O_RDONLY) < 0)
{
clear = PAGE_SIZE;
}
else
{
int already_read = 0;
int count = PAGE_SIZE - clear;
int to_read;
while (already_read < count)
{
int read_this_time;
if ((pos % bufsize) != 0)
{
to_read = bufsize - (pos % bufsize);
}
else
{
to_read = bufsize;
}
to_read = min(to_read, count - already_read);
if (ncp_read(NCP_SERVER(inode),
NCP_FINFO(inode)->file_handle,
pos, to_read,
(char *)(page + already_read),
&read_this_time) != 0)
{
read_this_time = 0;
}
pos += read_this_time;
already_read += read_this_time;
if (read_this_time < to_read)
{
break;
}
}
}
set_fs(fs);
tmp = page + PAGE_SIZE;
while (clear--) {
*(char *)--tmp = 0;
}
return page;
}
struct vm_operations_struct ncp_file_mmap = {
NULL, /* open */
NULL, /* close */
NULL, /* unmap */
NULL, /* protect */
NULL, /* sync */
NULL, /* advise */
ncp_file_mmap_nopage, /* nopage */
NULL, /* wppage */
NULL, /* swapout */
NULL, /* swapin */
};
/* This is used for a general mmap of a ncp file */
int
ncp_mmap(struct inode * inode, struct file * file, struct vm_area_struct * vma)
{
DPRINTK("ncp_mmap: called\n");
if (!ncp_conn_valid(NCP_SERVER(inode)))
{
return -EIO;
}
/* only PAGE_COW or read-only supported now */
if (vma->vm_flags & VM_SHARED)
return -EINVAL;
if (!inode->i_sb || !S_ISREG(inode->i_mode))
return -EACCES;
if (!IS_RDONLY(inode)) {
inode->i_atime = CURRENT_TIME;
inode->i_dirt = 1;
}
vma->vm_inode = inode;
inode->i_count++;
vma->vm_ops = &ncp_file_mmap;
return 0;
}

View File

@@ -1,641 +0,0 @@
#include <linux/config.h>
#ifdef MODULE
#include <linux/module.h>
#include <linux/version.h>
#endif
#include "ncplib_kernel.h"
typedef __u8 byte;
typedef __u16 word;
typedef __u32 dword;
static inline int min(int a, int b)
{
return a<b ? a : b;
}
static void
assert_server_locked(struct ncp_server *server)
{
if (server->lock == 0)
{
DPRINTK("ncpfs: server not locked!\n");
}
}
static void
ncp_add_byte(struct ncp_server *server, byte x)
{
assert_server_locked(server);
*(byte *)(&(server->packet[server->current_size])) = x;
server->current_size += 1;
return;
}
static void
ncp_add_word(struct ncp_server *server, word x)
{
assert_server_locked(server);
*(word *)(&(server->packet[server->current_size])) = x;
server->current_size += 2;
return;
}
static void
ncp_add_dword(struct ncp_server *server, dword x)
{
assert_server_locked(server);
*(dword *)(&(server->packet[server->current_size])) = x;
server->current_size += 4;
return;
}
static void
ncp_add_mem(struct ncp_server *server, const void *source, int size)
{
assert_server_locked(server);
memcpy(&(server->packet[server->current_size]), source, size);
server->current_size += size;
return;
}
static void
ncp_add_mem_fromfs(struct ncp_server *server, const char *source, int size)
{
assert_server_locked(server);
memcpy_fromfs(&(server->packet[server->current_size]), source, size);
server->current_size += size;
return;
}
static void
ncp_add_pstring(struct ncp_server *server, const char *s)
{
int len = strlen(s);
assert_server_locked(server);
if (len > 255)
{
DPRINTK("ncpfs: string too long: %s\n", s);
len = 255;
}
ncp_add_byte(server, len);
ncp_add_mem(server, s, len);
return;
}
static void
ncp_init_request(struct ncp_server *server)
{
ncp_lock_server(server);
server->current_size = sizeof(struct ncp_request_header);
server->has_subfunction = 0;
}
static void
ncp_init_request_s(struct ncp_server *server, int subfunction)
{
ncp_init_request(server);
ncp_add_word(server, 0); /* preliminary size */
ncp_add_byte(server, subfunction);
server->has_subfunction = 1;
}
static char *
ncp_reply_data(struct ncp_server *server, int offset)
{
return &(server->packet[sizeof(struct ncp_reply_header) + offset]);
}
static byte
ncp_reply_byte(struct ncp_server *server, int offset)
{
return *(byte *)(ncp_reply_data(server, offset));
}
static word
ncp_reply_word(struct ncp_server *server, int offset)
{
return *(word *)(ncp_reply_data(server, offset));
}
static dword
ncp_reply_dword(struct ncp_server *server, int offset)
{
return *(dword *)(ncp_reply_data(server, offset));
}
int
ncp_negotiate_buffersize(struct ncp_server *server,
int size, int *target)
{
int result;
ncp_init_request(server);
ncp_add_word(server, htons(size));
if ((result = ncp_request(server, 33)) != 0)
{
ncp_unlock_server(server);
return result;
}
*target =min(ntohs(ncp_reply_word(server, 0)), size);
ncp_unlock_server(server);
return 0;
}
int
ncp_get_volume_info_with_number(struct ncp_server *server, int n,
struct ncp_volume_info *target)
{
int result;
int len;
ncp_init_request_s(server, 44);
ncp_add_byte(server, n);
if ((result = ncp_request(server, 22)) != 0)
{
ncp_unlock_server(server);
return result;
}
target->total_blocks = ncp_reply_dword(server, 0);
target->free_blocks = ncp_reply_dword(server, 4);
target->purgeable_blocks = ncp_reply_dword(server, 8);
target->not_yet_purgeable_blocks = ncp_reply_dword(server, 12);
target->total_dir_entries = ncp_reply_dword(server, 16);
target->available_dir_entries = ncp_reply_dword(server, 20);
target->sectors_per_block = ncp_reply_byte(server, 28);
memset(&(target->volume_name), 0, sizeof(target->volume_name));
len = ncp_reply_byte(server, 29);
if (len > NCP_VOLNAME_LEN)
{
DPRINTK("ncpfs: volume name too long: %d\n", len);
ncp_unlock_server(server);
return -EIO;
}
memcpy(&(target->volume_name), ncp_reply_data(server, 30), len);
ncp_unlock_server(server);
return 0;
}
int
ncp_close_file(struct ncp_server *server, const char *file_id)
{
int result;
ncp_init_request(server);
ncp_add_byte(server, 0);
ncp_add_mem(server, file_id, 6);
if ((result = ncp_request(server, 66)) != 0)
{
ncp_unlock_server(server);
return result;
}
ncp_unlock_server(server);
return 0;
}
static void
ncp_add_handle_path(struct ncp_server *server,
__u8 vol_num,
__u32 dir_base, int have_dir_base,
char *path)
{
ncp_add_byte(server, vol_num);
ncp_add_dword(server, dir_base);
if (have_dir_base != 0)
{
ncp_add_byte(server, 1); /* dir_base */
}
else
{
ncp_add_byte(server, 0xff); /* no handle */
}
if (path != NULL)
{
ncp_add_byte(server, 1); /* 1 component */
ncp_add_pstring(server, path);
}
else
{
ncp_add_byte(server, 0);
}
}
static void
ncp_extract_file_info(void *structure, struct nw_info_struct *target)
{
__u8 *name_len;
const int info_struct_size = sizeof(struct nw_info_struct) - 257;
memcpy(target, structure, info_struct_size);
name_len = structure + info_struct_size;
target->nameLen = *name_len;
strncpy(target->entryName, name_len+1, *name_len);
target->entryName[*name_len] = '\0';
return;
}
int
ncp_obtain_info(struct ncp_server *server,
__u8 vol_num, __u32 dir_base,
char *path, /* At most 1 component */
struct nw_info_struct *target)
{
int result;
if (target == NULL)
{
return -EINVAL;
}
ncp_init_request(server);
ncp_add_byte(server, 6); /* subfunction */
ncp_add_byte(server, server->name_space[vol_num]);
ncp_add_byte(server, server->name_space[vol_num]);
ncp_add_word(server, 0xff); /* get all */
ncp_add_dword(server, RIM_ALL);
ncp_add_handle_path(server, vol_num, dir_base, 1, path);
if ((result = ncp_request(server, 87)) != 0)
{
ncp_unlock_server(server);
return result;
}
ncp_extract_file_info(ncp_reply_data(server, 0), target);
ncp_unlock_server(server);
return 0;
}
static inline int
ncp_has_os2_namespace(struct ncp_server *server, __u8 volume)
{
int result;
__u8 *namespace;
__u16 no_namespaces;
ncp_init_request(server);
ncp_add_byte(server, 24); /* Subfunction: Get Name Spaces Loaded */
ncp_add_word(server, 0);
ncp_add_byte(server, volume);
if ((result = ncp_request(server, 87)) != 0)
{
ncp_unlock_server(server);
return 0;
}
no_namespaces = ncp_reply_word(server, 0);
namespace = ncp_reply_data(server, 2);
while (no_namespaces > 0)
{
DPRINTK("get_namespaces: found %d on %d\n", *namespace,volume);
if (*namespace == 4)
{
DPRINTK("get_namespaces: found OS2\n");
ncp_unlock_server(server);
return 1;
}
namespace += 1;
no_namespaces -= 1;
}
ncp_unlock_server(server);
return 0;
}
int
ncp_lookup_volume(struct ncp_server *server,
char *volname,
struct nw_info_struct *target)
{
int result;
int volnum;
DPRINTK("ncp_lookup_volume: looking up vol %s\n", volname);
ncp_init_request(server);
ncp_add_byte(server, 22); /* Subfunction: Generate dir handle */
ncp_add_byte(server, 0); /* DOS namespace */
ncp_add_byte(server, 0); /* reserved */
ncp_add_byte(server, 0); /* reserved */
ncp_add_byte(server, 0); /* reserved */
ncp_add_byte(server, 0); /* faked volume number */
ncp_add_dword(server, 0); /* faked dir_base */
ncp_add_byte(server, 0xff); /* Don't have a dir_base */
ncp_add_byte(server, 1); /* 1 path component */
ncp_add_pstring(server, volname);
if ((result = ncp_request(server, 87)) != 0)
{
ncp_unlock_server(server);
return result;
}
memset(target, 0, sizeof(*target));
target->DosDirNum = target->dirEntNum = ncp_reply_dword(server, 4);
target->volNumber = volnum = ncp_reply_byte(server, 8);
ncp_unlock_server(server);
server->name_space[volnum] = ncp_has_os2_namespace(server,volnum)?4:0;
DPRINTK("lookup_vol: namespace[%d] = %d\n",
volnum, server->name_space[volnum]);
target->nameLen = strlen(volname);
strcpy(target->entryName, volname);
target->attributes = aDIR;
return 0;
}
int
ncp_modify_file_or_subdir_dos_info(struct ncp_server *server,
struct nw_info_struct *file,
__u32 info_mask,
struct nw_modify_dos_info *info)
{
int result;
ncp_init_request(server);
ncp_add_byte(server, 7); /* subfunction */
ncp_add_byte(server, server->name_space[file->volNumber]);
ncp_add_byte(server, 0); /* reserved */
ncp_add_word(server, 0x8006); /* search attribs: all */
ncp_add_dword(server, info_mask);
ncp_add_mem(server, info, sizeof(*info));
ncp_add_handle_path(server, file->volNumber,
file->dirEntNum, 1, NULL);
if ((result = ncp_request(server, 87)) != 0)
{
ncp_unlock_server(server);
return result;
}
ncp_unlock_server(server);
return 0;
}
int
ncp_del_file_or_subdir(struct ncp_server *server,
struct nw_info_struct *dir, char *name)
{
int result;
ncp_init_request(server);
ncp_add_byte(server, 8); /* subfunction */
ncp_add_byte(server, server->name_space[dir->volNumber]);
ncp_add_byte(server, 0); /* reserved */
ncp_add_word(server, 0x8006); /* search attribs: all */
ncp_add_handle_path(server, dir->volNumber,
dir->dirEntNum, 1, name);
if ((result = ncp_request(server, 87)) != 0)
{
ncp_unlock_server(server);
return result;
}
ncp_unlock_server(server);
return 0;
}
static inline void
ConvertToNWfromDWORD ( __u32 sfd , __u8 ret[6] )
{
__u16 *dest = (__u16 *) ret;
memcpy(&(dest[1]), &sfd, 4);
dest[0] = dest[1] + 1;
return;
}
/* If both dir and name are NULL, then in target there's already a
looked-up entry that wants to be opened. */
int
ncp_open_create_file_or_subdir(struct ncp_server *server,
struct nw_info_struct *dir, char *name,
int open_create_mode,
__u32 create_attributes,
int desired_acc_rights,
struct nw_file_info *target)
{
int result;
__u16 search_attribs = 0x0006;
__u8 volume = (dir != NULL) ? dir->volNumber : target->i.volNumber;
if ((create_attributes & aDIR) != 0)
{
search_attribs |= 0x8000;
}
ncp_init_request(server);
ncp_add_byte(server, 1); /* subfunction */
ncp_add_byte(server, server->name_space[volume]);
ncp_add_byte(server, open_create_mode);
ncp_add_word(server, search_attribs);
ncp_add_dword(server, RIM_ALL);
ncp_add_dword(server, create_attributes);
/* The desired acc rights seem to be the inherited rights mask
for directories */
ncp_add_word(server, desired_acc_rights);
if (dir != NULL)
{
ncp_add_handle_path(server, volume, dir->dirEntNum, 1, name);
}
else
{
ncp_add_handle_path(server, volume, target->i.dirEntNum,
1, NULL);
}
if ((result = ncp_request(server, 87)) != 0)
{
ncp_unlock_server(server);
return result;
}
target->opened = 1;
target->server_file_handle = ncp_reply_dword(server, 0);
target->open_create_action = ncp_reply_byte(server, 4);
if (dir != NULL)
{
/* in target there's a new finfo to fill */
ncp_extract_file_info(ncp_reply_data(server, 5), &(target->i));
}
ConvertToNWfromDWORD(target->server_file_handle, target->file_handle);
ncp_unlock_server(server);
return 0;
}
int
ncp_initialize_search(struct ncp_server *server,
struct nw_info_struct *dir,
struct nw_search_sequence *target)
{
int result;
ncp_init_request(server);
ncp_add_byte(server, 2); /* subfunction */
ncp_add_byte(server, server->name_space[dir->volNumber]);
ncp_add_byte(server, 0); /* reserved */
ncp_add_handle_path(server, dir->volNumber, dir->dirEntNum, 1, NULL);
if ((result = ncp_request(server, 87)) != 0)
{
ncp_unlock_server(server);
return result;
}
memcpy(target, ncp_reply_data(server, 0), sizeof(*target));
ncp_unlock_server(server);
return 0;
}
/* Search for everything */
int
ncp_search_for_file_or_subdir(struct ncp_server *server,
struct nw_search_sequence *seq,
struct nw_info_struct *target)
{
int result;
ncp_init_request(server);
ncp_add_byte(server, 3); /* subfunction */
ncp_add_byte(server, server->name_space[seq->volNumber]);
ncp_add_byte(server, 0); /* data stream (???) */
ncp_add_word(server, 0xffff); /* Search attribs */
ncp_add_dword(server, RIM_ALL); /* return info mask */
ncp_add_mem(server, seq, 9);
ncp_add_byte(server, 2); /* 2 byte pattern */
ncp_add_byte(server, 0xff); /* following is a wildcard */
ncp_add_byte(server, '*');
if ((result = ncp_request(server, 87)) != 0)
{
ncp_unlock_server(server);
return result;
}
memcpy(seq, ncp_reply_data(server, 0), sizeof(*seq));
ncp_extract_file_info(ncp_reply_data(server, 10), target);
ncp_unlock_server(server);
return 0;
}
int
ncp_ren_or_mov_file_or_subdir(struct ncp_server *server,
struct nw_info_struct *old_dir, char *old_name,
struct nw_info_struct *new_dir, char *new_name)
{
int result;
if ( (old_dir == NULL) || (old_name == NULL)
|| (new_dir == NULL) || (new_name == NULL))
return -EINVAL;
ncp_init_request(server);
ncp_add_byte(server, 4); /* subfunction */
ncp_add_byte(server, server->name_space[old_dir->volNumber]);
ncp_add_byte(server, 1); /* rename flag */
ncp_add_word(server, 0x8006); /* search attributes */
/* source Handle Path */
ncp_add_byte(server, old_dir->volNumber);
ncp_add_dword(server, old_dir->dirEntNum);
ncp_add_byte(server, 1);
ncp_add_byte(server, 1); /* 1 source component */
/* dest Handle Path */
ncp_add_byte(server, new_dir->volNumber);
ncp_add_dword(server, new_dir->dirEntNum);
ncp_add_byte(server, 1);
ncp_add_byte(server, 1); /* 1 destination component */
/* source path string */
ncp_add_pstring(server, old_name);
/* dest path string */
ncp_add_pstring(server, new_name);
result = ncp_request(server, 87);
ncp_unlock_server(server);
return result;
}
/* We have to transfer to/from user space */
int
ncp_read(struct ncp_server *server, const char *file_id,
__u32 offset, __u16 to_read,
char *target, int *bytes_read)
{
int result;
ncp_init_request(server);
ncp_add_byte(server, 0);
ncp_add_mem(server, file_id, 6);
ncp_add_dword(server, htonl(offset));
ncp_add_word(server, htons(to_read));
if ((result = ncp_request(server, 72)) != 0)
{
ncp_unlock_server(server);
return result;
}
*bytes_read = ntohs(ncp_reply_word(server, 0));
memcpy_tofs(target, ncp_reply_data(server, 2+(offset&1)), *bytes_read);
ncp_unlock_server(server);
return 0;
}
int
ncp_write(struct ncp_server *server, const char *file_id,
__u32 offset, __u16 to_write,
const char *source, int *bytes_written)
{
int result;
ncp_init_request(server);
ncp_add_byte(server, 0);
ncp_add_mem(server, file_id, 6);
ncp_add_dword(server, htonl(offset));
ncp_add_word(server, htons(to_write));
ncp_add_mem_fromfs(server, source, to_write);
if ((result = ncp_request(server, 73)) != 0)
{
ncp_unlock_server(server);
return result;
}
*bytes_written = to_write;
ncp_unlock_server(server);
return 0;
}

View File

@@ -1,162 +0,0 @@
#ifndef _NCPLIB_H
#define _NCPLIB_H
#include <linux/fs.h>
#include <linux/ncp.h>
#include <linux/ncp_fs.h>
#include <linux/ncp_fs_sb.h>
#include <linux/types.h>
#include <linux/errno.h>
#include <linux/malloc.h>
#include <linux/stat.h>
#include <linux/fcntl.h>
#include <asm/segment.h>
#include <asm/string.h>
#include <linux/ncp.h>
int
ncp_negotiate_buffersize(struct ncp_server *server, int size,
int *target);
int
ncp_get_encryption_key(struct ncp_server *server,
char *target);
int
ncp_get_bindery_object_id(struct ncp_server *server,
int object_type, char *object_name,
struct ncp_bindery_object *target);
int
ncp_login_encrypted(struct ncp_server *server,
struct ncp_bindery_object *object,
unsigned char *key,
unsigned char *passwd);
int
ncp_login_user(struct ncp_server *server,
unsigned char *username,
unsigned char *password);
int
ncp_get_volume_info_with_number(struct ncp_server *server, int n,
struct ncp_volume_info *target);
int
ncp_get_volume_number(struct ncp_server *server, const char *name,
int *target);
int
ncp_file_search_init(struct ncp_server *server,
int dir_handle, const char *path,
struct ncp_filesearch_info *target);
int
ncp_file_search_continue(struct ncp_server *server,
struct ncp_filesearch_info *fsinfo,
int attributes, const char *path,
struct ncp_file_info *target);
int
ncp_get_finfo(struct ncp_server *server,
int dir_handle, const char *path, const char *name,
struct ncp_file_info *target);
int
ncp_open_file(struct ncp_server *server,
int dir_handle, const char *path,
int attr, int access,
struct ncp_file_info *target);
int
ncp_close_file(struct ncp_server *server, const char *file_id);
int
ncp_create_newfile(struct ncp_server *server,
int dir_handle, const char *path,
int attr,
struct ncp_file_info *target);
int
ncp_create_file(struct ncp_server *server,
int dir_handle, const char *path,
int attr,
struct ncp_file_info *target);
int
ncp_erase_file(struct ncp_server *server,
int dir_handle, const char *path,
int attr);
int
ncp_rename_file(struct ncp_server *server,
int old_handle, const char *old_path,
int attr,
int new_handle, const char *new_path);
int
ncp_create_directory(struct ncp_server *server,
int dir_handle, const char *path,
int inherit_mask);
int
ncp_delete_directory(struct ncp_server *server,
int dir_handle, const char *path);
int
ncp_rename_directory(struct ncp_server *server,
int dir_handle,
const char *old_path, const char *new_path);
int
ncp_read(struct ncp_server *server, const char *file_id,
__u32 offset, __u16 to_read,
char *target, int *bytes_read);
int
ncp_write(struct ncp_server *server, const char *file_id,
__u32 offset, __u16 to_write,
const char *source, int *bytes_written);
int
ncp_obtain_info(struct ncp_server *server,
__u8 vol_num, __u32 dir_base,
char *path, /* At most 1 component */
struct nw_info_struct *target);
int
ncp_lookup_volume(struct ncp_server *server,
char *volname,
struct nw_info_struct *target);
int
ncp_modify_file_or_subdir_dos_info(struct ncp_server *server,
struct nw_info_struct *file,
__u32 info_mask,
struct nw_modify_dos_info *info);
int
ncp_del_file_or_subdir(struct ncp_server *server,
struct nw_info_struct *dir, char *name);
int
ncp_open_create_file_or_subdir(struct ncp_server *server,
struct nw_info_struct *dir, char *name,
int open_create_mode,
__u32 create_attributes,
int desired_acc_rights,
struct nw_file_info *target);
int
ncp_initialize_search(struct ncp_server *server,
struct nw_info_struct *dir,
struct nw_search_sequence *target);
int
ncp_search_for_file_or_subdir(struct ncp_server *server,
struct nw_search_sequence *seq,
struct nw_info_struct *target);
int
ncp_ren_or_mov_file_or_subdir(struct ncp_server *server,
struct nw_info_struct *old_dir, char *old_name,
struct nw_info_struct *new_dir, char *new_name);
#endif /* _NCPLIB_H */

View File

@@ -1,576 +0,0 @@
/*
* linux/fs/ncp/sock.c
*
* Copyright (C) 1992, 1993 Rick Sladkey
*
* Modified 1995 by Volker Lendecke to be usable for ncp
*
*/
#include <linux/config.h>
#ifdef MODULE
#include <linux/module.h>
#include <linux/version.h>
#endif
#include <linux/sched.h>
#include <linux/ncp_fs.h>
#include <linux/errno.h>
#include <linux/socket.h>
#include <linux/fcntl.h>
#include <linux/stat.h>
#include <asm/segment.h>
#include <linux/in.h>
#include <linux/net.h>
#include <linux/mm.h>
#include <linux/netdevice.h>
#include <linux/ipx.h>
#include <linux/ncp.h>
#include <linux/ncp_fs.h>
#include <linux/ncp_fs_sb.h>
#include "/usr/src/linux/net/inet/sock.h"
#define _S(nr) (1<<((nr)-1))
static void
ncp_wdog_data_ready(struct sock *sk, int len)
{
struct socket *sock = sk->socket;
if (!sk->dead)
{
unsigned char packet_buf[2];
struct sockaddr_ipx sender;
int addr_len = sizeof(struct sockaddr_ipx);
int result;
unsigned short fs;
fs = get_fs();
set_fs(get_ds());
result = sock->ops->recvfrom(sock, (void *)packet_buf, 2, 1, 0,
(struct sockaddr *)&sender,
&addr_len);
if ( (result != 2)
|| (packet_buf[1] != '?')
/* How to check connection number here? */
)
{
/* Error, throw away the complete packet */
sock->ops->recvfrom(sock, (void *)packet_buf, 2, 1, 0,
(struct sockaddr *)&sender,
&addr_len);
printk("ncpfs: got strange packet on watchdog "
"socket\n");
}
else
{
int result;
DDPRINTK("ncpfs: got watchdog from:\n");
DDPRINTK("ncpfs: %08lX:%02X%02X%02X%02X%02X%02X:%04X,"
" conn:%02X,type:%c\n",
htonl(sender.sipx_network),
sender.sipx_node[0], sender.sipx_node[1],
sender.sipx_node[2], sender.sipx_node[3],
sender.sipx_node[4], sender.sipx_node[5],
ntohs(sender.sipx_port),
packet_buf[0], packet_buf[1]);
packet_buf[1] = 'Y';
result = sock->ops->sendto(sock, (void *)packet_buf,
2, 1, 0,
(struct sockaddr *)&sender,
sizeof(sender));
DDPRINTK("send result: %d\n", result);
}
set_fs(fs);
}
}
int
ncp_catch_watchdog(struct ncp_server *server)
{
struct file *file;
struct inode *inode;
struct socket *sock;
struct sock *sk;
if ( (server == NULL)
|| ((file = server->wdog_filp) == NULL)
|| ((inode = file->f_inode) == NULL)
|| (!S_ISSOCK(inode->i_mode)))
{
printk("ncp_catch_watchdog: did not get valid server!\n");
server->data_ready = NULL;
return -EINVAL;
}
sock = &(inode->u.socket_i);
if (sock->type != SOCK_DGRAM)
{
printk("ncp_catch_watchdog: did not get SOCK_STREAM\n");
server->data_ready = NULL;
return -EINVAL;
}
sk = (struct sock *)(sock->data);
if (sk == NULL)
{
printk("ncp_catch_watchdog: sk == NULL");
server->data_ready = NULL;
return -EINVAL;
}
DDPRINTK("ncp_catch_watchdog.: sk->d_r = %x, server->d_r = %x\n",
(unsigned int)(sk->data_ready),
(unsigned int)(server->data_ready));
if (sk->data_ready == ncp_wdog_data_ready)
{
printk("ncp_catch_watchdog: already done\n");
return -EINVAL;
}
server->data_ready = sk->data_ready;
sk->data_ready = ncp_wdog_data_ready;
return 0;
}
int
ncp_dont_catch_watchdog(struct ncp_server *server)
{
struct file *file;
struct inode *inode;
struct socket *sock;
struct sock *sk;
if ( (server == NULL)
|| ((file = server->wdog_filp) == NULL)
|| ((inode = file->f_inode) == NULL)
|| (!S_ISSOCK(inode->i_mode)))
{
printk("ncp_dont_catch_watchdog: "
"did not get valid server!\n");
return -EINVAL;
}
sock = &(inode->u.socket_i);
if (sock->type != SOCK_DGRAM)
{
printk("ncp_dont_catch_watchdog: did not get SOCK_STREAM\n");
return -EINVAL;
}
sk = (struct sock *)(sock->data);
if (sk == NULL)
{
printk("ncp_dont_catch_watchdog: sk == NULL");
return -EINVAL;
}
if (server->data_ready == NULL)
{
printk("ncp_dont_catch_watchdog: "
"server->data_ready == NULL\n");
return -EINVAL;
}
if (sk->data_ready != ncp_wdog_data_ready)
{
printk("ncp_dont_catch_watchdog: "
"sk->data_callback != ncp_data_callback\n");
return -EINVAL;
}
DDPRINTK("ncp_dont_catch_watchdog: sk->d_r = %x, server->d_r = %x\n",
(unsigned int)(sk->data_ready),
(unsigned int)(server->data_ready));
sk->data_ready = server->data_ready;
server->data_ready = NULL;
return 0;
}
#define NCP_SLACK_SPACE 1024
#define _S(nr) (1<<((nr)-1))
static int
do_ncp_rpc_call(struct ncp_server *server, int size)
{
struct file *file;
struct inode *inode;
struct socket *sock;
unsigned short fs;
int result;
char *start = server->packet;
select_table wait_table;
struct select_table_entry entry;
int (*select) (struct inode *, struct file *, int, select_table *);
int init_timeout, max_timeout;
int timeout;
int retrans;
int major_timeout_seen;
int acknowledge_seen;
int n;
int addrlen;
unsigned long old_mask;
/* We have to check the result, so store the complete header */
struct ncp_request_header request =
*((struct ncp_request_header *)(server->packet));
struct ncp_reply_header reply;
file = server->ncp_filp;
inode = file->f_inode;
select = file->f_op->select;
sock = &inode->u.socket_i;
if (!sock)
{
printk("ncp_rpc_call: socki_lookup failed\n");
return -EBADF;
}
init_timeout = server->m.time_out;
max_timeout = NCP_MAX_RPC_TIMEOUT;
acknowledge_seen = 0;
retrans = server->m.retry_count;
major_timeout_seen = 0;
old_mask = current->blocked;
current->blocked |= ~(_S(SIGKILL)
#if 0
| _S(SIGSTOP)
#endif
| ((server->m.flags & NCP_MOUNT_INTR)
? ((current->sigaction[SIGINT - 1].sa_handler == SIG_DFL
? _S(SIGINT) : 0)
| (current->sigaction[SIGQUIT - 1].sa_handler == SIG_DFL
? _S(SIGQUIT) : 0))
: 0));
fs = get_fs();
set_fs(get_ds());
for (n = 0, timeout = init_timeout; ; n++, timeout <<= 1)
{
DDPRINTK("ncpfs: %08lX:%02X%02X%02X%02X%02X%02X:%04X\n",
htonl(server->m.serv_addr.sipx_network),
server->m.serv_addr.sipx_node[0],
server->m.serv_addr.sipx_node[1],
server->m.serv_addr.sipx_node[2],
server->m.serv_addr.sipx_node[3],
server->m.serv_addr.sipx_node[4],
server->m.serv_addr.sipx_node[5],
ntohs(server->m.serv_addr.sipx_port));
DDPRINTK("ncpfs: req.typ: %04X, con: %d, "
"seq: %d",
request.type,
(request.conn_high << 8) + request.conn_low,
request.sequence);
DDPRINTK(" func: %d\n",
request.function);
result = sock->ops->sendto(sock, (void *) start, size, 0, 0,
(struct sockaddr *)
&(server->m.serv_addr),
sizeof(server->m.serv_addr));
if (result < 0)
{
printk("ncp_rpc_call: send error = %d\n", result);
break;
}
re_select:
wait_table.nr = 0;
wait_table.entry = &entry;
current->state = TASK_INTERRUPTIBLE;
if ( !select(inode, file, SEL_IN, &wait_table)
&& !select(inode, file, SEL_IN, NULL))
{
if (timeout > max_timeout)
{
/* JEJB/JSP 2/7/94
* This is useful to see if the system is
* hanging */
if (acknowledge_seen == 0)
{
printk("NCP max timeout reached\n");
}
timeout = max_timeout;
}
current->timeout = jiffies + timeout;
schedule();
remove_wait_queue(entry.wait_address, &entry.wait);
current->state = TASK_RUNNING;
if (current->signal & ~current->blocked)
{
current->timeout = 0;
result = -ERESTARTSYS;
break;
}
if (!current->timeout)
{
if (n < retrans)
continue;
if (server->m.flags & NCP_MOUNT_SOFT)
{
printk("NCP server not responding\n");
result = -EIO;
break;
}
n = 0;
timeout = init_timeout;
init_timeout <<= 1;
if (!major_timeout_seen)
{
printk("NCP server not responding\n");
}
major_timeout_seen = 1;
continue;
}
else
current->timeout = 0;
}
else if (wait_table.nr)
remove_wait_queue(entry.wait_address, &entry.wait);
current->state = TASK_RUNNING;
addrlen = 0;
/* Get the header from the next packet using a peek, so keep it
* on the recv queue. If it is wrong, it will be some reply
* we don't now need, so discard it */
result = sock->ops->recvfrom(sock, (void *)&reply,
sizeof(reply), 1, MSG_PEEK,
NULL, &addrlen);
if (result < 0)
{
if (result == -EAGAIN)
{
DPRINTK("ncp_rpc_call: bad select ready\n");
goto re_select;
}
if (result == -ECONNREFUSED)
{
DPRINTK("ncp_rpc_call: server playing coy\n");
goto re_select;
}
if (result != -ERESTARTSYS)
{
printk("ncp_rpc_call: recv error = %d\n",
-result);
}
break;
}
if ( (result == sizeof(reply))
&& (reply.type == NCP_POSITIVE_ACK))
{
/* Throw away the packet */
DPRINTK("ncp_rpc_call: got positive acknowledge\n");
sock->ops->recvfrom(sock, (void *)&reply,
sizeof(reply), 1, 0,
NULL, &addrlen);
n = 0;
timeout = max_timeout;
acknowledge_seen = 1;
goto re_select;
}
DDPRINTK("ncpfs: rep.typ: %04X, con: %d, tsk: %d,"
"seq: %d\n",
reply.type,
(reply.conn_high << 8) + reply.conn_low,
reply.task,
reply.sequence);
if ( (result >= sizeof(reply))
&& (reply.type == NCP_REPLY)
&& ( (request.type == NCP_ALLOC_SLOT_REQUEST)
|| ( (reply.sequence == request.sequence)
&& (reply.conn_low == request.conn_low)
/* seem to get wrong task from NW311 && (reply.task == request.task)*/
&& (reply.conn_high == request.conn_high))))
{
if (major_timeout_seen)
printk("NCP server OK\n");
break;
}
/* JEJB/JSP 2/7/94
* we have xid mismatch, so discard the packet and start
* again. What a hack! but I can't call recvfrom with
* a null buffer yet. */
sock->ops->recvfrom(sock, (void *)&reply, sizeof(reply), 1, 0,
NULL, &addrlen);
DPRINTK("ncp_rpc_call: reply mismatch\n");
goto re_select;
}
/*
* we have the correct reply, so read into the correct place and
* return it
*/
result = sock->ops->recvfrom(sock, (void *)start, server->packet_size,
1, 0, NULL, &addrlen);
if (result < 0)
{
printk("NCP: notice message: result=%d\n", result);
}
else if (result < sizeof(struct ncp_reply_header))
{
printk("NCP: just caught a too small read memory size..., "
"email to NET channel\n");
printk("NCP: result=%d,addrlen=%d\n", result, addrlen);
result = -EIO;
}
current->blocked = old_mask;
set_fs(fs);
return result;
}
/*
* We need the server to be locked here, so check!
*/
static int
ncp_do_request(struct ncp_server *server, int size)
{
if (server->lock == 0)
{
printk("ncpfs: Server not locked!\n");
return -EIO;
}
return do_ncp_rpc_call(server, size);
}
/* ncp_do_request assures that at least a complete reply header is
* received. It assumes that server->current_size contains the ncp
* request size */
int
ncp_request(struct ncp_server *server, int function)
{
struct ncp_request_header *h
= (struct ncp_request_header *)(server->packet);
struct ncp_reply_header *reply
= (struct ncp_reply_header *)(server->packet);
int request_size = server->current_size
- sizeof(struct ncp_request_header);
int result;
if (server->has_subfunction != 0)
{
*(__u16 *)&(h->data[0]) = request_size - 2;
}
h->type = NCP_REQUEST;
server->sequence += 1;
h->sequence = server->sequence;
h->conn_low = (server->connection) & 0xff;
h->conn_high = ((server->connection) & 0xff00) >> 8;
h->task = (current->pid) & 0xff;
h->function = function;
if ((result = ncp_do_request(server, request_size + sizeof(*h))) < 0)
{
DPRINTK("ncp_request_error: %d\n", result);
return result;
}
server->completion = reply->completion_code;
server->conn_status = reply->connection_state;
server->reply_size = result;
server->ncp_reply_size = result - sizeof(struct ncp_reply_header);
result = reply->completion_code;
if (result != 0)
{
DPRINTK("ncp_completion_code: %x\n", result);
}
return result;
}
int
ncp_connect(struct ncp_server *server)
{
struct ncp_request_header *h
= (struct ncp_request_header *)(server->packet);
int result;
h->type = NCP_ALLOC_SLOT_REQUEST;
server->sequence = 0;
h->sequence = server->sequence;
h->conn_low = 0xff;
h->conn_high = 0xff;
h->task = (current->pid) & 0xff;
h->function = 0;
if ((result = ncp_do_request(server, sizeof(*h))) < 0)
{
return result;
}
server->sequence = 0;
server->connection = h->conn_low + (h->conn_high * 256);
return 0;
}
int
ncp_disconnect(struct ncp_server *server)
{
struct ncp_request_header *h
= (struct ncp_request_header *)(server->packet);
h->type = NCP_DEALLOC_SLOT_REQUEST;
server->sequence += 1;
h->sequence = server->sequence;
h->conn_low = (server->connection) & 0xff;
h->conn_high = ((server->connection) & 0xff00) >> 8;
h->task = (current->pid) & 0xff;
h->function = 0;
return ncp_do_request(server, sizeof(*h));
}
void
ncp_lock_server(struct ncp_server *server)
{
#if 0
/* For testing, only 1 process */
if (server->lock != 0)
{
DPRINTK("ncpfs: server locked!!!\n");
}
#endif
while (server->lock)
sleep_on(&server->wait);
server->lock = 1;
}
void
ncp_unlock_server(struct ncp_server *server)
{
if (server->lock != 1)
{
printk("ncp_unlock_server: was not locked!\n");
}
server->lock = 0;
wake_up(&server->wait);
}

View File

@@ -19,6 +19,15 @@ endif
CFLAGS += $(PIC_FLAG)
ifdef NDS_SUPPORT
CFLAGS += -DNDS_SUPPORT
NDS_OBJ = ndslib.o mpilib.o ndscrypt.o
endif
ifdef SIGNATURES
CFLAGS += -DSIGNATURES
SIGN_OBJ = ncpsign.o
endif
default:
make -C ..
@@ -27,8 +36,17 @@ all: libcom_err.a ncplib_err.o $(NCP_LIB)
install:
$(INSTALL_LIB)
mpilib.o: mpilib.c
$(CC) $(CFLAGS) -DPORTABLE -DSMITH -DUNIT32 -DMUNIT16 -c mpilib.c
ndscrypt.o: ndscrypt.c
$(CC) $(CFLAGS) -c ndscrypt.c
ndslib.o: ndslib.c
$(CC) $(CFLAGS) -DPORTABLE -DSMITH -DUNIT32 -DMUNIT16 -c ndslib.c
ncpsign.o: ncpsign.c
$(CC) $(CFLAGS) -c ncpsign.c
ncplib.o: ncplib.c ncplib_err.h
$(CC) $(CFLAGS) -finline-functions -c ncplib.c
$(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
@@ -38,8 +56,9 @@ COM_ERR_OFILES = com_err/com_err.o com_err/error_message.o com_err/et_name.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)
$(NCP_LIB): ncplib.o ncplib_err.o libcom_err.a $(SIGN_OBJ) $(NDS_OBJ)
$(LIB_LINK_COMMAND) ncplib.o ncplib_err.o $(SIGN_OBJ) \
$(COM_ERR_OFILES) $(NDS_OBJ)
ln -sf libncp.so.1.0 libncp.so.1
ln -sf libncp.so.1 libncp.so
export LD_LIBRARY_PATH=`pwd`:LD_LIBRARY_PATH

View File

@@ -17,31 +17,34 @@
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)
const char *whoami;
errcode_t code;
const char *fmt;
va_list args;
default_com_err_proc(whoami, code, fmt, args)
const char *whoami;
errcode_t code;
const char *fmt;
va_list args;
#endif
{
if (whoami) {
fputs(whoami, stderr);
fputs(": ", stderr);
}
if (code) {
fputs(error_message(code), stderr);
fputs(" ", stderr);
}
if (fmt) {
vfprintf (stderr, fmt, args);
}
/* should do this only on a tty in raw mode */
putc('\r', stderr);
putc('\n', stderr);
fflush(stderr);
if (whoami)
{
fputs(whoami, stderr);
fputs(": ", stderr);
}
if (code)
{
fputs(error_message(code), stderr);
fputs(" ", stderr);
}
if (fmt)
{
vfprintf(stderr, fmt, args);
}
/* should do this only on a tty in raw mode */
putc('\r', stderr);
putc('\n', stderr);
fflush(stderr);
}
#ifdef __STDC__
@@ -53,62 +56,69 @@ 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)
const char *whoami;
errcode_t code;
const char *fmt;
va_list args;
void
com_err_va(whoami, code, fmt, args)
const char *whoami;
errcode_t code;
const char *fmt;
va_list args;
#endif
{
(*com_err_hook) (whoami, code, fmt, args);
(*com_err_hook) (whoami, code, fmt, 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)
va_dcl
void
com_err(va_alist)
va_dcl
{
const char *whoami, *fmt;
errcode_t code;
const char *whoami, *fmt;
errcode_t code;
#endif
va_list pvar;
va_list pvar;
if (!com_err_hook)
com_err_hook = default_com_err_proc;
if (!com_err_hook)
com_err_hook = default_com_err_proc;
#ifdef VARARGS
va_start (pvar);
whoami = va_arg (pvar, const char *);
code = va_arg (pvar, errcode_t);
fmt = va_arg (pvar, const char *);
va_start(pvar);
whoami = va_arg(pvar, const char *);
code = va_arg(pvar, errcode_t);
fmt = va_arg(pvar, const char *);
#else
va_start(pvar, fmt);
va_start(pvar, fmt);
#endif
com_err_va (whoami, code, fmt, pvar);
va_end(pvar);
com_err_va(whoami, code, fmt, pvar);
va_end(pvar);
}
errf set_com_err_hook (new_proc)
errf new_proc;
errf
set_com_err_hook(new_proc)
errf new_proc;
{
errf x = com_err_hook;
errf x = com_err_hook;
if (new_proc)
com_err_hook = new_proc;
else
if (new_proc)
com_err_hook = new_proc;
else
com_err_hook = default_com_err_proc;
return x;
}
errf
reset_com_err_hook()
{
errf x = com_err_hook;
com_err_hook = default_com_err_proc;
return x;
}
errf reset_com_err_hook () {
errf x = com_err_hook;
com_err_hook = default_com_err_proc;
return x;
return x;
}

View File

@@ -16,25 +16,25 @@ typedef long errcode_t;
#include <stdarg.h>
/* ANSI C -- use prototypes etc */
void com_err (const char *, long, const char *, ...);
void com_err_va (const char *whoami, errcode_t code, const char *fmt,
va_list args);
char const *error_message (long);
void com_err(const char *, long, const char *,...);
void com_err_va(const char *whoami, errcode_t code, const char *fmt,
va_list args);
char const *error_message(long);
extern void (*com_err_hook) (const char *, long, const char *, va_list);
void (*set_com_err_hook (void (*) (const char *, long, const char *, va_list)))
(const char *, long, const char *, va_list);
void (*reset_com_err_hook (void)) (const char *, long, const char *, va_list);
int init_error_table(const char * const *msgs, int base, int count);
void (*set_com_err_hook(void (*)(const char *, long, const char *, va_list)))
(const char *, long, const char *, va_list);
void (*reset_com_err_hook(void)) (const char *, long, const char *, va_list);
int init_error_table(const char *const *msgs, int base, int count);
#else
/* no prototypes */
void com_err ();
void com_err_va ();
char *error_message ();
void com_err();
void com_err_va();
char *error_message();
extern void (*com_err_hook) ();
void (*set_com_err_hook ()) ();
void (*reset_com_err_hook ()) ();
void (*set_com_err_hook()) ();
void (*reset_com_err_hook()) ();
int init_error_table();
#endif
#define __COM_ERR_H
#endif /* ! defined(__COM_ERR_H) */
#endif /* ! defined(__COM_ERR_H) */

View File

@@ -19,64 +19,72 @@
static char buffer[25];
struct et_list * _et_list = (struct et_list *) NULL;
struct et_list *_et_list = (struct et_list *) NULL;
#ifdef __STDC__
const char * error_message (errcode_t code)
const char *
error_message(errcode_t code)
#else
const char * error_message (code)
errcode_t code;
const char *
error_message(code)
errcode_t code;
#endif
{
int offset;
struct et_list *et;
int table_num;
int started = 0;
char *cp;
int offset;
struct et_list *et;
int table_num;
int started = 0;
char *cp;
offset = code & ((1<<ERRCODE_RANGE)-1);
table_num = code - offset;
if (!table_num) {
offset = code & ((1 << ERRCODE_RANGE) - 1);
table_num = code - offset;
if (!table_num)
{
#ifdef HAS_SYS_ERRLIST
if (offset < sys_nerr)
return(sys_errlist[offset]);
else
goto oops;
if (offset < sys_nerr)
return (sys_errlist[offset]);
else
goto oops;
#else
cp = strerror(offset);
if (cp)
return(cp);
else
goto oops;
cp = strerror(offset);
if (cp)
return (cp);
else
goto oops;
#endif
}
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;
return(et->table->msgs[offset]);
}
}
oops:
strcpy (buffer, "Unknown code ");
if (table_num) {
strcat (buffer, error_table_name (table_num));
strcat (buffer, " ");
}
for (cp = buffer; *cp; cp++)
;
if (offset >= 100) {
*cp++ = '0' + offset / 100;
offset %= 100;
started++;
}
if (started || offset >= 10) {
*cp++ = '0' + offset / 10;
offset %= 10;
}
*cp++ = '0' + offset;
*cp = '\0';
return(buffer);
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;
return (et->table->msgs[offset]);
}
}
oops:
strcpy(buffer, "Unknown code ");
if (table_num)
{
strcat(buffer, error_table_name(table_num));
strcat(buffer, " ");
}
for (cp = buffer; *cp; cp++)
;
if (offset >= 100)
{
*cp++ = '0' + offset / 100;
offset %= 100;
started++;
}
if (started || offset >= 10)
{
*cp++ = '0' + offset / 10;
offset %= 10;
}
*cp++ = '0' + offset;
*cp = '\0';
return (buffer);
}

View File

@@ -11,16 +11,18 @@
#define const
#endif
struct error_table {
char const * const * msgs;
long base;
int n_msgs;
struct error_table
{
char const *const *msgs;
long base;
int n_msgs;
};
struct et_list {
struct et_list *next;
const struct error_table *table;
struct et_list
{
struct et_list *next;
const struct error_table *table;
};
extern struct et_list * _et_list;
extern struct et_list *_et_list;
#define ERRCODE_RANGE 8 /* # of bits to shift table number */
#define BITS_PER_CHAR 6 /* # bits to shift per character in name */

View File

@@ -9,28 +9,30 @@
#include "internal.h"
static const char char_set[] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_";
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_";
static char buf[6];
const char * error_table_name(num)
int num;
const char *
error_table_name(num)
int num;
{
int ch;
int i;
char *p;
int ch;
int i;
char *p;
/* num = aa aaa abb bbb bcc ccc cdd ddd d?? ??? ??? */
p = buf;
num >>= ERRCODE_RANGE;
/* 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--) {
ch = (num >> BITS_PER_CHAR * i) & ((1 << BITS_PER_CHAR) - 1);
if (ch != 0)
*p++ = char_set[ch-1];
}
*p = '\0';
return(buf);
/* num = aa aaa abb bbb bcc ccc cdd ddd d?? ??? ??? */
p = buf;
num >>= ERRCODE_RANGE;
/* 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--)
{
ch = (num >> BITS_PER_CHAR * i) & ((1 << BITS_PER_CHAR) - 1);
if (ch != 0)
*p++ = char_set[ch - 1];
}
*p = '\0';
return (buf);
}

View File

@@ -4,7 +4,7 @@
* $Locker: $
*
* Copyright 1986, 1987, 1988 by MIT Information Systems and
* the MIT Student Information Processing Board.
* the MIT Student Information Processing Board.
*
* For copyright info, see mit-sipb-copyright.h.
*/
@@ -23,36 +23,39 @@
#define const
#endif
struct foobar {
struct et_list etl;
struct error_table et;
struct foobar
{
struct et_list etl;
struct error_table et;
};
extern struct et_list * _et_list;
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)
const char * const * msgs;
int base;
int count;
int
init_error_table(msgs, base, count)
const char *const *msgs;
int base;
int count;
#endif
{
struct foobar * new_et;
struct foobar *new_et;
if (!base || !count || !msgs)
if (!base || !count || !msgs)
return 0;
new_et = (struct foobar *) malloc(sizeof(struct foobar));
if (!new_et)
return ENOMEM; /* oops */
new_et->etl.table = &new_et->et;
new_et->et.msgs = msgs;
new_et->et.base = base;
new_et->et.n_msgs = count;
new_et->etl.next = _et_list;
_et_list = &new_et->etl;
return 0;
new_et = (struct foobar *) malloc(sizeof(struct foobar));
if (!new_et)
return ENOMEM; /* oops */
new_et->etl.table = &new_et->et;
new_et->et.msgs = msgs;
new_et->et.base = base;
new_et->et.n_msgs= count;
new_et->etl.next = _et_list;
_et_list = &new_et->etl;
return 0;
}

View File

@@ -10,13 +10,13 @@
#include <errno.h>
#ifdef NEED_SYS_ERRLIST
extern char const * const sys_errlist[];
extern char const *const sys_errlist[];
extern const int sys_nerr;
#endif
/* AIX and Ultrix have standard conforming header files. */
#if !defined(ultrix) && !defined(_AIX)
#ifdef __STDC__
void perror (const char *);
void perror(const char *);
#endif
#endif

View File

@@ -1,19 +1,18 @@
/*
Copyright 1987, 1988 by the Student Information Processing Board
of the Massachusetts Institute of Technology
Copyright 1987, 1988 by the Student Information Processing Board
of the Massachusetts Institute of Technology
Permission to use, copy, modify, and distribute this software
and its documentation for any purpose and without fee is
hereby granted, provided that the above copyright notice
appear in all copies and that both that copyright notice and
this permission notice appear in supporting documentation,
and that the names of M.I.T. and the M.I.T. S.I.P.B. not be
used in advertising or publicity pertaining to distribution
of the software without specific, written prior permission.
M.I.T. and the M.I.T. S.I.P.B. make no representations about
the suitability of this software for any purpose. It is
provided "as is" without express or implied warranty.
*/
Permission to use, copy, modify, and distribute this software
and its documentation for any purpose and without fee is
hereby granted, provided that the above copyright notice
appear in all copies and that both that copyright notice and
this permission notice appear in supporting documentation,
and that the names of M.I.T. and the M.I.T. S.I.P.B. not be
used in advertising or publicity pertaining to distribution
of the software without specific, written prior permission.
M.I.T. and the M.I.T. S.I.P.B. make no representations about
the suitability of this software for any purpose. It is
provided "as is" without express or implied warranty.
*/

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) (*(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(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) {
char initlast[16]={0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef,
0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10};
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

295
lib/ndscrypt.c Normal file
View File

@@ -0,0 +1,295 @@
/*
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"
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);
}
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
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};
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
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;
unsigned short *p;
i1 = *((unsigned short *)in);
i2 = *((unsigned short *)in + 1);
i3 = *((unsigned short *)in + 2);
i4 = *((unsigned short *)in + 3);
p = (unsigned short *)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];
}
}
*((unsigned short *)out) = i1;
*((unsigned short *)out + 1) = i2;
*((unsigned short *)out + 2) = i3;
*((unsigned short *)out + 3) = i4;
}
void nwdecrypt(const unsigned short *cryptbuf, const char *in, char *out) {
int i, j;
unsigned short *p;
register unsigned int i1, i2, i3, i4;
i1 = *((unsigned short *)in);
i2 = *((unsigned short *)in + 1);
i3 = *((unsigned short *)in + 2);
i4 = *((unsigned short *)in + 3);
p = (unsigned short *)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];
}
}
*((unsigned short *)out) = i1;
*((unsigned short *)out + 1) = i2;
*((unsigned short *)out + 2) = i3;
*((unsigned short *)out + 3) = 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, *dp, *hend, c;
hp1 = (hp = (unsigned char *)hash) + 1;
hend = hp + hashlen;
dp = (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 */

1235
lib/ndslib.c Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -1,17 +1,17 @@
/*$*********************************************************
$*
$* 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.
$*
$**********************************************************/
$*
$* 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.
$*
$********************************************************* */
/****************************************************************************
@@ -91,28 +91,28 @@ 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};
{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 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
@@ -128,32 +128,35 @@ shuffle1(buf32 temp, unsigned char *target)
{
for (s = 0; s <= 31; ++s)
{
b3 = (temp[s]+b4) ^ (temp[(s+b4)&31] - encryptkeys[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);
for (i = 0; i <= 15; ++i)
{
target[i] = encrypttable[temp[2 * i]]
| (encrypttable[temp[2 * i + 1]] << 4);
}
}
static void
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)) {
while ((buflen > 0)
&& (buf[buflen - 1] == 0))
{
buflen = buflen - 1;
}
for (s = 0; s < 32; s++) {
for (s = 0; s < 32; s++)
{
temp[s] = 0;
}
@@ -176,17 +179,17 @@ shuffle(const unsigned char *lon, const unsigned char *buf, int buflen,
{
b2 = d;
temp[s] = temp[s] ^ encryptkeys[s];
} else {
} 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);
shuffle1(temp, target);
}
@@ -198,7 +201,7 @@ nw_encrypt(const unsigned char *fra,
buf32 k;
int s;
shuffle(&(fra[0]), buf, 16, &(k[ 0]));
shuffle(&(fra[0]), buf, 16, &(k[0]));
shuffle(&(fra[4]), buf, 16, &(k[16]));
for (s = 0; s <= 15; ++s)
@@ -219,16 +222,17 @@ nw_encrypt(const unsigned char *fra,
/* server side (mars etc.) should:
* store the *encrypted* password internally (output from shuffle)
* verify if nw_encrypt(cryptkey from GetCryptKey, old stored password)
== cryptkey in EncryptedChangePassword request buffer (this means
old password was correct)
== cryptkey in EncryptedChangePassword request buffer (this means
old password was correct)
* decrypt new password in request buffer using (yet to write) inverse of
newpassencrypt with old stored password as parameter
newpassencrypt with old stored password as parameter
* compute the length of the unencrypted new password as len ^ (first byte of
old internal password) ^ (second byte of old internal password)
old internal password) ^ (second byte of old internal password)
*/
static char
newshuffle[256+16] = {
static char
newshuffle[256 + 16] =
{
0x0f, 0x08, 0x05, 0x07, 0x0c, 0x02, 0x0e, 0x09,
0x00, 0x01, 0x06, 0x0d, 0x03, 0x04, 0x0b, 0x0a,
0x02, 0x0c, 0x0e, 0x06, 0x0f, 0x00, 0x01, 0x08,
@@ -279,17 +283,17 @@ newshuffle[256+16] = {
* - Shuffle (aus nwcrypt.c) altes passwort nach old (16 bytes)
* - shuffle neues passwort nach new (16 bytes)
* - nwpassencrypt (diese Funktion) zweimal aufrufen fuer je 8 bytes:
* nwpassencrypt(old+0, new+0, out+0)
* nwpassencrypt(old+8, new+8, out+8)
* nwpassencrypt(old+0, new+0, out+0)
* nwpassencrypt(old+8, new+8, out+8)
* - NCP-Buffer aufbauen:
* 2 byte Laenge im Hi-Lo-Format
* 1 byte Funktion (0x4b)
* 8 byte (nwcrypt Ergebnis analog login/verify password)
* 2 byte Objecttype
* 1 byte Objectname-Laenge
* n byte Objectname
* 1 byte (Laenge des eingegebenen neuen Passworts ^ old[0] ^ old[1])&0x7f|0x40
* 16 byte (Ergebnis dieser Funktion doppelt aufgerufen, s.o.)
* 2 byte Laenge im Hi-Lo-Format
* 1 byte Funktion (0x4b)
* 8 byte (nwcrypt Ergebnis analog login/verify password)
* 2 byte Objecttype
* 1 byte Objectname-Laenge
* n byte Objectname
* 1 byte (Laenge des eingegebenen neuen Passworts ^ old[0] ^ old[1])&0x7f|0x40
* 16 byte (Ergebnis dieser Funktion doppelt aufgerufen, s.o.)
*/
/*
@@ -308,31 +312,31 @@ newpassencrypt(char *old, char *new, char *out)
memcpy(copy, new, 8);
for (i=0; i<16; i++)
for (i = 0; i < 16; i++)
{
for (di=0, ax=0, p=old; di<8; di++, ax+=0x20, p++)
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;
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--)
ch = old[7];
for (bx = old + 7; bx > old; bx--)
{
*bx=((bx[-1]>>4)&0x0f)|((*bx)<<4);
*bx = ((bx[-1] >> 4) & 0x0f) | ((*bx) << 4);
}
*old=((ch>>4)&0x0f)|(*old)<<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);
if (newshuffle[di + 0x100] & 1)
ch = ((copy[newshuffle[di + 0x100] / 2] >> 4) & 0x0f);
else
ch=copy[newshuffle[di+0x100]/2]&0x0f;
out[di/2]|=((di&1) ? ch<<4 : ch);
ch = copy[newshuffle[di + 0x100] / 2] & 0x0f;
out[di / 2] |= ((di & 1) ? ch << 4 : ch);
}
memcpy(copy, out, 8);
}

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

41
lib/usuals.h Normal file
View File

@@ -0,0 +1,41 @@
/* usuals.h - The usual typedefs, etc.
*/
#ifndef USUALS /* Assures no redefinitions of usual types...*/
#define USUALS
typedef unsigned char boolean; /* values are TRUE or FALSE */
typedef unsigned char byte; /* values are 0-255 */
typedef byte *byteptr; /* pointer to byte */
typedef char *string; /* pointer to ASCII character string */
typedef unsigned short word16; /* values are 0-65535 */
#ifdef __alpha
typedef unsigned int word32; /* values are 0-4294967295 */
#else
typedef unsigned long word32; /* values are 0-4294967295 */
#endif
#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

@@ -14,7 +14,7 @@ nprint \- NetWare print client
] [
.B -P
.I password
|
|
.B -n
] [
.B -C

View File

@@ -14,7 +14,7 @@ nwbocreate \- Create a NetWare Bindery Object
] [
.B -P
.I password
|
|
.B -n
] [
.B -C

View File

@@ -14,7 +14,7 @@ nwbols \- List NetWare Bindery Objects
] [
.B -P
.I password
|
|
.B -n
] [
.B -C

View File

@@ -14,7 +14,7 @@ nwboprops \- List properies of a NetWare Bindery Object
] [
.B -P
.I password
|
|
.B -n
] [
.B -C

View File

@@ -14,7 +14,7 @@ nwborm \- Remove a NetWare Bindery Object
] [
.B -P
.I password
|
|
.B -n
] [
.B -C

View File

@@ -14,7 +14,7 @@ nwbpadd \- Set the value of a NetWare Bindery Property
] [
.B -P
.I password
|
|
.B -n
] [
.B -C

View File

@@ -14,7 +14,7 @@ nwbpset \- Create a bindery property or set its value
] [
.B -P
.I password
|
|
.B -n
] [
.B -C

85
man/nwfstime.1 Normal file
View File

@@ -0,0 +1,85 @@
.TH NWFSTIME 1 12/10/1996 nwfstime nwfstime
.SH NAME
nwfstime \- Display / Set a NetWare server's date and time
.SH SYNOPSIS
.B nwfstime
[
.B -h
] [
.B -S
.I server
] [
.B -U
.I user name
] [
.B -P
.I password
|
.B -n
] [
.B -C
] [
.B -s
]
.SH DESCRIPTION
.B nwfstime
displays a NetWare server's date and time. You can also set a NetWare
server's date and time from the local time.
.SH OPTIONS
.B -h
.RS 3
With -h nwfstime prints a little help text.
.RE
.B -S
.I server
.RS 3
is the name of the server you want to use.
.RE
.B -U
.I user
.RS 3
.B user
is the user name to use for login. To set the server's time, you need
supervisor privileges.
.RE
.B -P
.I password
.RS 3
.B password
is the password to use for login. If neither
.B -n
nor
.B -P
are given, and the user has no open connection to the server, nwfstime
prompts for a password.
.RE
.B -n
.RS 3
.B -n
should be given if no password is required for the login. As you need
supervisor privileges for setting the date and time, this option is
probably not used very often.
.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
.B -s
.RS 3
With
.B -s,
nwfstime sets the file server's date and time according to the local
date and time.
.RE

View File

@@ -14,7 +14,7 @@ nwgrant \- Add Trustee Rights to a directory
] [
.B -P
.I password
|
|
.B -n
] [
.B -C

View File

@@ -1,4 +1,4 @@
.TH NWPASSWD 1 06/22/1996 nwpasswd nwpasswd
.TH NWPASSWD 1 01/16/1997 nwpasswd nwpasswd
.SH NAME
nwpasswd \- Change a user's password
.SH SYNOPSIS
@@ -11,6 +11,9 @@ nwpasswd \- Change a user's password
] [
.B -U
.I user name
] [
.B -O
.I object name
]
.B -t
.I object type
@@ -43,6 +46,16 @@ is the name of the server you want to use.
is the name of the bindery object whose password is to be changed.
.RE
.B -O
.I object name
.RS 3
If you have supervisor privileges, you can change other users'
passwords. With
.B -O
you can tell nwpasswd the name of the user whose password should be
changed.
.RE
.B -t
.I object type
.RS 3

View File

@@ -14,7 +14,7 @@ nwrevoke \- Revoke a Trustee Right from a directory
] [
.B -P
.I password
|
|
.B -n
] [
.B -C

127
man/nwtrustee.1 Normal file
View File

@@ -0,0 +1,127 @@
.TH NWTRUSTEE 8 7/9/1996 nwtrustee nwtrustee
.SH NAME
nwtrustee \- List an object's trustee directory assignments
.SH SYNOPSIS
.B nwtrustee
[
.B -h
] [
.B -S
.I server
] [
.B -U
.I user name
] [
.B -P
.I password
|
.B -n
] [
.B -C
] [
.B -l
.I volume number
] [
.B -L
.I volume name
] [
.B -o
.I object id
] [
.B -O
.I object name
] [
.B -t
.I object type
] [
.B -v
]
.SH DESCRIPTION
.B nwtrustee
lists the trustee directory assignments a user has on a specific volume.
.B nwtrustee
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 $HOME/.nwclient MUST be 600 for security reasons.
.SH OPTIONS
.B -h
.RS 3
.B -h
is used to print out a short help text.
.RE
.B -S
.I server
.RS 3
.B server
is the name of the server you want to use.
.RE
.B -U
.I user
.RS 3
.B user
is the user name to use for login.
.RE
.B -P
.I password
.RS 3
.B password
is the password to use for login. If neither
.B -n
nor
.B -P
are given, and the user has no open connection to the server, nwtrustee
prompts for a password.
.RE
.B -n
.RS 3
.B -n
should be given if no password is required for the login.
.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
.B -o
.I object id
.RS 3
The bindery object id of the user whose assignments should be listed.
Alternatively, use -O object name.
.RE
.B -O
.I object name
.RS 3
The name of the user whose assignments should be listed.
.RE
.B -t
.I object type
.RS 3
The type of object whose assignments should be listed. This defaults to 1,
which means user. Another sensible value is 2, which means group.
.RE
.B -v
.RS 3
Verbose listing. Also list the specific rights that are assigned to the
user.
.RE
.SH AUTHORS
nwtrustee was written by Jacek Stepniewski <cunio@gazeta.pl>.
This manual page was written by Volker Lendecke.

View File

@@ -14,7 +14,7 @@ nwuserlist \- List Users logged in at a NetWare server
] [
.B -P
.I password
|
|
.B -n
] [
.B -C

100
man/nwvolinfo.1 Normal file
View File

@@ -0,0 +1,100 @@
.TH NWVOLINFO 8 7/9/1996 nwvolinfo nwvolinfo
.SH NAME
nwvolinfo \- Diplay info on NetWare Volumes
.SH SYNOPSIS
.B nwvolinfo
[
.B -h
] [
.B -S
.I server
] [
.B -U
.I user name
] [
.B -P
.I password
|
.B -n
] [
.B -C
] [
.B -v
.I volume
] [
.B -N
]
.SH DESCRIPTION
.B nwvolinfo
displays information on a NetWare Server Volume.
.B nwvolinfo
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 $HOME/.nwclient MUST be 600 for security reasons.
.SH OPTIONS
.B -h
.RS 3
.B -h
is used to print out a short help text.
.RE
.B -S
.I server
.RS 3
.B server
is the name of the server you want to use.
.RE
.B -U
.I user
.RS 3
.B user
is the user name to use for login.
.RE
.B -P
.I password
.RS 3
.B password
is the password to use for login. If neither
.B -n
nor
.B -P
are given, and the user has no open connection to the server, nwvolinfo
prompts for a password.
.RE
.B -n
.RS 3
.B -n
should be given if no password is required for the login.
.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
.B -v
.I volume
.RS 3
The volume name to be used. Defaults to 'SYS'.
.RE
.B -N
.RS 3
Display the information in numeric-only format for use in a pipe.
.RE
.SH AUTHORS
nwvolinfo was written by Jacek Stepniewski <cunio@gazeta.pl> based on
utilities by Volker Lendecke.

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

@@ -14,7 +14,7 @@ pserver \- NetWare print server
] [
.B -P
.I password
|
|
.B -n
] [
.B -C
@@ -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,18 @@
Begin3
Title: ncpfs
Version: 2.0.7
Entered-date: 27. October 1996
Version: 2.0.12
Entered-date: March 13, 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
~148k ncpfs-2.0.7.tgz
~ 1k ncpfs-2.0.7.lsm
~195k ncpfs-2.0.12.tgz
~ 1k ncpfs-2.0.12.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

14
patches/README Normal file
View File

@@ -0,0 +1,14 @@
To apply the patches, cd into the appropriate kernel source directory
and do:
patch -p1 < patch-file
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.
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.

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