diff --git a/.downloads/ncpfs-2.2.0.tgz b/.downloads/ncpfs-2.2.0.tgz new file mode 100644 index 0000000..5974da3 Binary files /dev/null and b/.downloads/ncpfs-2.2.0.tgz differ diff --git a/BUGS b/BUGS index c0d8116..662fc84 100644 --- a/BUGS +++ b/BUGS @@ -13,9 +13,8 @@ down the complete ipx subsystem by deleting all ipx interfaces, unmounting all ncpfs volumes (in this order!) and restarting all again. -For the kernel hackers who want to look at the problem: The routine -ipx_sendmsg in net/ipx/af_ipx.c sometimes locks forever if called with -nonblock=0. I DO NOT KNOW WHY!!! HELP ME, PLEASE! +This problem has been solved by Martin Stover (THANKS!!) +See patches/lockup-2.0.30.diff for the fix. ------------------------------------------------------------------------------- @@ -34,3 +33,17 @@ like Nov 25 16:09:08 lx01 kernel: alloc_skb called nonatomically from interrupt 0000002e These are a bit annoying, but completely harmless. + +------------------------------------------------------------------------------- + +Known bugs: + +- It returns error 255 during bindery login on one site... I do not know why. +- If GetNearsetServer returns invalid (nonexistant, downed) server, all + utilities gives up. VLM/Client32 in this situation tries randomly choosen + server after 30 secs timeout. You have to fix your routers at this time. + Sorry. +- NFS namespace does not work on Netware Storage Services volume... Sorry, + it is not my fault and I did not found any workaround (maybe that I have + workaround for NSS from NW5Beta3) + diff --git a/Changes b/Changes index 0fe1c47..8acb1fb 100644 --- a/Changes +++ b/Changes @@ -1,9 +1,130 @@ I only began this file with ncpfs-0.12. If you're interested in older versions, you can find them on ftp.gwdg.de:/pub/linux/misc/ncpfs/old. -ncpfs-2.0.10 -> ncpfs-2.1.1 -- Restructured the kernel part a bit, moved watchdog and message support - out of the kernel into ncpmount. +[Versions ncpfs-2.0.12.x are available at ftp://platan.vc.cvut.cz/pub/linux/ncpfs] + +ncpfs-2.0.12.10 -> ncpfs-2.2.0 +- VANA: minor cleanup + +ncpfs-2.0.12.9 -> ncpfs-2.0.12.10 +- VANA: you can now access NDS server without replica of its conteiner + (TODO: access to server if server has R/W replica of your account but + does not have replica of itself) +- VANA: Alpha still no go :-( + +ncpfs-2.0.12.8 -> ncpfs-2.0.12.9 +- Eloy A. Paris: Fixes in library code + +ncpfs-2.0.12.7 -> ncpfs-2.0.12.8 +- VANA: bugfix, now it works again without ipxripd +- VANA: still cleaning up, ncp_open() and NDS byte ordering + +ncpfs-2.0.12.6 -> ncpfs-2.0.12.7 +- VANA: bugfixes, nwpurge + +ncpfs-2.0.12.5 -> ncpfs-2.0.12.6 +- VANA: ncpmount supports NCP over IP (no incoming broadcast at this time) + +ncpfs-2.0.12.4 -> ncpfs-2.0.12.5 +- Eloy A. Paris: Makefile bugfix + +ncpfs-2.0.12.3 -> ncpfs-2.0.12.4 +- VANA: Bugfixes +- VANA: Alpha stage of native NCP over IP support (no kernel at this time) + +ncpfs-2.0.12.2 -> ncpfs-2.0.12.3 +- VANA: Major makefile changes, compile warning cleanup + +ncpfs-2.0.12.1 -> ncpfs-2.0.12.2 +- Eloy A. Paris : Makefile cleanup +- VANA: More merging sutil/ncplib.c and lib/ncplib.c, not fully functional yet + +ncpfs-2.0.12 -> ncpfs-2.0.12.1 +- Dave, VANA: Bindery logins for all utilities (-b) +- VANA: Specify signature level for ncpmount (-i number) +- VANA: Start of merging sutil/*lib* with lib/*lib* + +ncpfs-2.0.11.19 -> ncpfs-2.0.12 +- Polished for release 2.0.12 +- Dave: pserver fixes, including addition of %d flag. + +ncpfs-2.0.11.18 -> ncpfs-2.0.11.19 +- Dave, VANA: new userspace utilities - pqstat and pqrm + +ncpfs-2.0.11.17 -> ncpfs-2.0.11.18 (no userspace change) +- Dave: getwd() did not work on 2.1.x +- VANA: Volumes are now always listed lowercased on 2.1.x + +ncpfs-2.0.11.16 -> ncpfs-2.0.11.17 +- David Woodhouse : 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 de Bruijn + +ncpfs-2.0.11.8 -> ncpfs-2.0.11.9 +- VANA: Added call to lock connection (dropped in 2.0.11.7, sorry) + +ncpfs-2.0.11.7 -> ncpfs-2.0.11.8 +- VANA: Can be correctly compiled without signatures support in kernel (I hope) +- VANA: Fix in kernel in setting task number + +ncpfs-2.0.11.6 -> ncpfs-2.0.11.7 +- VANA: Codebase synchronized with Arne de Bruijn +- ARNE: Gracelogins on NDS +- VANA: Removed some (one) compilation warnings + +ncpfs-2.0.11.5 -> ncpfs-2.0.11.6 +- VANA: Support for NDS login accross servers + +ncpfs-2.0.11.4 -> ncpfs-2.0.11.5 +- VANA: Cleanup in ndscrypt +- VANA: Bugfix: empty password for NDS login is now allowed & works + +ncpfs-2.0.11.3 -> ncpfs-2.0.11.4 +- Enabled some buffer cleaning +- Added parameter "-b" to ncpmount for bindery login to NDS server + +ncpfs-2.0.11.2 -> ncpfs-2.0.11.3 +- Added NDS support by Arne de Bruijn ; small fixes in code; + moved sections to do same things as DOS login does. + +ncpfs-2.0.11.1 -> ncpfs-2.0.11.2 +- VANA: Fixed that some error conditions in LOGIN should start packet signatures + +ncpfs-2.0.11 -> ncpfs-2.0.11.1 +- VANA: Added packet signatures by Arne de Bruijn + +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 ;-) diff --git a/FAQ b/FAQ index 8a3d947..f08ec41 100644 --- a/FAQ +++ b/FAQ @@ -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. diff --git a/Makefile b/Makefile index 3aad401..38410a0 100644 --- a/Makefile +++ b/Makefile @@ -2,12 +2,6 @@ # Makefile for the linux ncp-filesystem routines. # -VERSION = 2.1.1 - -# If you are using kerneld to autoload ncp support, -# uncomment this (kerneld is in linux since about 1.3.57): -KERNELD = -DHAVE_KERNELD - # If your system is ELF, either also do a 'make install', or append the util/ # directory where the dynamic library resides to the environment # variable LD_LIBRARY_PATH @@ -15,22 +9,23 @@ HAVE_ELF=$(shell file `whereis gcc|cut -d ' ' -f 2`| \ grep ELF >/dev/null && echo -n yes ) TOPDIR = $(shell pwd) -BINDIR = /usr/bin -SBINDIR = /sbin -SUBDIRS = lib sutil util ipx-1.0 man +include ./Makeinit -KVERSION=$(shell uname -r | cut -b1-3) +EXECSUBDIRS = lib-static-su sutil util ipx-1.0 +SUBDIRS := $(EXECSUBDIRS) lib-shared lib-static man +INSTALL_SUBDIRS := util sutil man ipx-1.0 +ifeq ($(HAVE_ELF),yes) +EXECSUBDIRS := lib-shared $(EXECSUBDIRS) +INSTALL_SUBDIRS := lib-shared $(INSTALL_SUBDIRS) +else +EXECSUBDIRS := lib-static $(EXECSUBDIRS) +INSTALL_SUBDIRS := lib-static $(INSTALL_SUBDIRS) +endif -INCLUDES=-I$(TOPDIR)/include - -COPT = -O2 -COPT += -g -CFLAGS = $(COPT) -Wall $(INCLUDES) $(KERNELD) -DNCPFS_VERSION=\"$(VERSION)\" - -export INCLUDES BINDIR SBINDIR KERNELD VERSION HAVE_ELF CFLAGS +export INCLUDES VERSION HAVE_ELF CFLAGS all: - for i in $(SUBDIRS); do make -C $$i all; done + set -e; for i in $(EXECSUBDIRS); do make -C $$i all; done @if [ "$(HAVE_ELF)" = yes ] ;\ then \ echo ; echo ; echo ;\ @@ -47,7 +42,7 @@ dep: for i in $(SUBDIRS); do make -C $$i dep; done install: - for i in $(SUBDIRS); do make -C $$i install; done + for i in $(INSTALL_SUBDIRS); do make -C $$i install; done clean_me: rm -f `find -name '*.out'` diff --git a/Makeinit b/Makeinit new file mode 100644 index 0000000..3f80e10 --- /dev/null +++ b/Makeinit @@ -0,0 +1,79 @@ +VERSION = 2.2.0 + +# If you want to include NDS support for ncpmount uncomment this: +# WARNING! NDS support is very beta, uncomment only if you are testing +# because anything can happen (like crashing the linux box or nw server). +NDS_SUPPORT = 1 + +# If you want to include packet signature support uncomment this: +# WARNING! packet signature support is in beta stage, uncomment only when you +# know what you are doing, anything can happen (like crashing the linux box or +# netware server). +# When enabling, make sure you have applied the kernel patches too, +# otherwise the packet signatures won't work. +SIGNATURES = 1 + +# If you want to eat only one NDS connection. Does not work at this time. +# (waiting for Novell...) +NDS_PRIVATEKEY = 1 + +# If you want native IP support, uncomment CONFIG_NATIVEIP +# Do not forget that it is VERY ALPHA code, with almost no support +# Enable only if you are interested in NCP over IP and you want help +# me. -A ip.address is your friend. At this time you have to silently +# ignore Login to server XXXX as YYYY - think that XXXX is ip.address and +# not one taken from .nwclient. Also, if you have not .nwclient, you have +# to add -S DUMMY on commandline. +CONFIG_NATIVE_IP = 1 + +# Include code for Linux2.0.x +MOUNT2 = 1 +# Include code for Linux2.1.x +MOUNT3 = 1 + +# ######################################################## +BINDIR = /usr/bin +SBINDIR = /sbin +LIBSODIR = /lib +LIBADIR = /usr/lib +MANDIR = /usr/local/man + +CC = gcc + +COPT = -O2 +CWARN = -Wall +# CWARN = -Wall -Wstrict-prototypes -Wpointer-arith -Wcast-qual -Waggregate-return -Wnested-externs -Winline -Wbad-function-cast -W #-Werror #-Wwrite-strings -Wtraditional -Wshadow +# ######################################################## + +ifdef SIGNATURES +CFLAGS_DEFINES += -DSIGNATURES +endif +ifdef NDS_SUPPORT +CFLAGS_DEFINES += -DNDS_SUPPORT +endif +ifdef CONFIG_NATIVE_IP +CFLAGS_DEFINES += -DCONFIG_NATIVE_IP +endif +ifdef MOUNT2 +CFLAGS_DEFINES += -DMOUNT2 +endif +ifdef MOUNT3 +CFLAGS_DEFINES += -DMOUNT3 +endif +CFLAGS_DEFINES += -DNCPFS_VERSION=\"$(VERSION)\" +CFLAGS_OPTIONS += $(COPT) +CFLAGS_OPTIONS += $(CWARN) + +CCFLAGS = $(CFLAGS_DEFINES) $(CFLAGS_OPTIONS) -I../include + +# If your system is ELF, either also do a 'make install', or append the util/ +# directory where the dynamic library resides to the environment +# variable LD_LIBRARY_PATH +HAVE_ELF=$(shell file `whereis gcc|cut -d ' ' -f 2`| \ + grep ELF >/dev/null && echo -n yes ) +#HAVE_ELF=yes + +TOPDIR = $(shell pwd) + +INCLUDES=-I$(TOPDIR)/include + diff --git a/README b/README index 47f5ab0..54d0cbf 100644 --- a/README +++ b/README @@ -1,7 +1,7 @@ -This is ncpfs, the user utilities that are needed to use the NCP kernel support -present in Linux since version 1.3.71. This version of ncpfs is only usable -with Linux 2.1.29 and later. To use it, please apply the patch contained in the -patches/ directory. +This is ncpfs, a free NetWare client filesystem for Linux. Besides +some little utilities it also contains nprint, which enables you to +print on NetWare print queues. The opposite side, pserver, is also +provided. ncpfs works with NetWare versions 3.x and following. It does NOT work with NetWare version 2.x. Some of the NetWare look-alikes, such as @@ -24,11 +24,25 @@ information. INSTALLATION -Before you start the installation of the user utilities, please make sure that -your kernel is 2.1.29 or later. If you are using 2.1.29, please apply the patch -contained in patches/linux-2.1.29.diff. You have to compile your kernel with -IPX and NCP support compiled in. But as you are using a development kernel, you -probably know what you're doing :-). +Before you start the installation, make sure that your kernel has IPX +support compiled in. When 'make config' asks you for + +The IPX protocol (CONFIG_IPX) [N/y/m/?] + +simply answer 'y'. Probably you do not need the full internal net that +you are asked for next. + +If you are not using 2.0.x kernels, you can comment out MOUNT2=1 line +in the Makeinit. +If you are not using 2.1.x kernels, you can comment out MOUNT3=1 line +in the Makeinit. + +If you are not using NDS access, you can comment out NDS_SUPPORT=1 in +the Makeinit. +If you are not using packet signatures, you can comment out SIGNATURES=1 +in the Makeinit. + +After you adapted your Makeinit, type 'make' and, as root, 'make install'. HELP @@ -110,9 +124,6 @@ limitation is the lack of uid, gid and permission information per file. You have to assign those values once for a complete mounted directory. -You will not be able to access servers that require packet -signatures. This seems to be one of Novell's bigger secrets :-(. - Have fun with ncpfs! Volker diff --git a/README.NDS b/README.NDS new file mode 100644 index 0000000..6ba5590 --- /dev/null +++ b/README.NDS @@ -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 diff --git a/contrib/tknwmsg/nwmsg.c b/contrib/tknwmsg/nwmsg.c index 51c8df9..6f0c200 100644 --- a/contrib/tknwmsg/nwmsg.c +++ b/contrib/tknwmsg/nwmsg.c @@ -27,7 +27,8 @@ static int search_utmp(char *user, char *tty); static char *progname; -void main(int argc, char *argv[]) +void +main(int argc, char *argv[]) { struct ncp_conn *conn; char message[256]; @@ -50,23 +51,27 @@ void main(int argc, char *argv[]) openlog("nwmsg", LOG_PID, LOG_LPR); - if (argc != 2) { + if (argc != 2) + { fprintf(stderr, "usage: %s mount-point\n", progname); exit(1); } mount_point = argv[1]; - if ((conn = ncp_open_mount(mount_point, &err)) == NULL) { + if ((conn = ncp_open_mount(mount_point, &err)) == NULL) + { com_err(progname, err, "in ncp_open_mount"); exit(1); } - if (ncp_get_broadcast_message(conn, message) != 0) { + if (ncp_get_broadcast_message(conn, message) != 0) + { fprintf(stderr, "%s: could not get broadcast message\n", progname); ncp_close(conn); exit(1); } - if (strlen(message) == 0) { + if (strlen(message) == 0) + { syslog(LOG_DEBUG, "no message"); exit(0); } @@ -75,7 +80,8 @@ void main(int argc, char *argv[]) #endif info.version = NCP_GET_FS_INFO_VERSION; - if (ioctl(conn->mount_fid, NCP_IOC_GET_FS_INFO, &info) < 0) { + if (ioctl(conn->mount_fid, NCP_IOC_GET_FS_INFO, &info) < 0) + { fprintf(stderr, "%s: could not ioctl on connection: %s\n", progname, strerror(errno)); ncp_close(conn); @@ -83,30 +89,37 @@ void main(int argc, char *argv[]) } ncp_close(conn); - if ((pwd = getpwuid(info.mounted_uid)) == NULL) { + if ((pwd = getpwuid(info.mounted_uid)) == NULL) + { fprintf(stderr, "%s: user %d not known\n", progname, info.mounted_uid); exit(1); } - if ((mtab = fopen(MOUNTED, "r")) == NULL) { + if ((mtab = fopen(MOUNTED, "r")) == NULL) + { fprintf(stderr, "%s: can't open %s\n", progname, MOUNTED); exit(1); } - while ((mnt = getmntent(mtab)) != NULL) { - if (strcmp(mnt->mnt_dir, mount_point) == 0) { + while ((mnt = getmntent(mtab)) != NULL) + { + if (strcmp(mnt->mnt_dir, mount_point) == 0) + { break; } } - if (mnt == NULL) { + if (mnt == NULL) + { syslog(LOG_DEBUG, "cannot find mtab entry\n"); } - if (search_utmp(pwd->pw_name, tty) != 0) { + if (search_utmp(pwd->pw_name, tty) != 0) + { exit(1); } sprintf(tty_path, "/dev/%s", tty); - if ((tty_file = fopen(tty_path, "w")) == NULL) { + if ((tty_file = fopen(tty_path, "w")) == NULL) + { fprintf(stderr, "%s: cannot open %s: %s\n", progname, tty_path, strerror(errno)); exit(1); @@ -139,16 +152,18 @@ void main(int argc, char *argv[]) * term_chk - check that a terminal exists, and get the message bit * and the access time */ -static int term_chk(char *tty, int *msgsokP, time_t * atimeP, int *showerror) +static int +term_chk(char *tty, int *msgsokP, time_t * atimeP, int *showerror) { struct stat s; char path[MAXPATHLEN]; (void) sprintf(path, "/dev/%s", tty); - if (stat(path, &s) < 0) { + if (stat(path, &s) < 0) + { if (showerror) (void) fprintf(stderr, - "write: %s: %s\n", path, strerror(errno)); + "write: %s: %s\n", path, strerror(errno)); return (1); } *msgsokP = (s.st_mode & (S_IWRITE >> 3)) != 0; /* group write bit */ @@ -167,7 +182,8 @@ static int term_chk(char *tty, int *msgsokP, time_t * atimeP, int *showerror) * Special case for writing to yourself - ignore the terminal you're * writing from, unless that's the only terminal with messages enabled. */ -static int search_utmp(char *user, char *tty) +static int +search_utmp(char *user, char *tty) { struct utmp u; time_t bestatime, atime; @@ -175,7 +191,8 @@ static int search_utmp(char *user, char *tty) char atty[sizeof(u.ut_line) + 1]; - if ((ufd = open(_PATH_UTMP, O_RDONLY)) < 0) { + if ((ufd = open(_PATH_UTMP, O_RDONLY)) < 0) + { perror("utmp"); return -1; } @@ -183,7 +200,8 @@ static int search_utmp(char *user, char *tty) bestatime = 0; user_is_me = 0; while (read(ufd, (char *) &u, sizeof(u)) == sizeof(u)) - if (strncmp(user, u.ut_name, sizeof(u.ut_name)) == 0) { + if (strncmp(user, u.ut_name, sizeof(u.ut_name)) == 0) + { ++nloggedttys; (void) strncpy(atty, u.ut_line, sizeof(u.ut_line)); @@ -198,13 +216,15 @@ static int search_utmp(char *user, char *tty) continue; /* it's not a valid entry */ ++nttys; - if (atime > bestatime) { + if (atime > bestatime) + { bestatime = atime; (void) strcpy(tty, atty); } } (void) close(ufd); - if (nloggedttys == 0) { + if (nloggedttys == 0) + { (void) fprintf(stderr, "write: %s is not logged in\n", user); return -1; } diff --git a/include/glibstub.h b/include/glibstub.h new file mode 100644 index 0000000..89b0332 --- /dev/null +++ b/include/glibstub.h @@ -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__ */ + diff --git a/include/ipxlib.h b/include/ipxlib.h index 048d7dd..2bcb976 100644 --- a/include/ipxlib.h +++ b/include/ipxlib.h @@ -8,15 +8,14 @@ #ifndef _IPXLIB_H #define _IPXLIB_H - -#include +#include "kernel/types.h" #include "ncp.h" -#include -#include +#include "kernel/ipx.h" -typedef unsigned long IPXNet; -typedef unsigned short IPXPort; -typedef unsigned char IPXNode[IPX_NODE_LEN]; +typedef u_int32_t IPXNet; +typedef u_int16_t IPXPort; +typedef u_int8_t IPXNode[IPX_NODE_LEN]; +typedef const u_int8_t CIPXNode[IPX_NODE_LEN]; #define IPX_USER_PTYPE (0x00) #define IPX_RIP_PTYPE (0x01) @@ -32,30 +31,35 @@ typedef unsigned char IPXNode[IPX_NODE_LEN]; #define IPX_SAP_FILE_SERVER (0x0004) -struct sap_query { - unsigned short query_type; /* net order */ - unsigned short server_type; /* net order */ +struct sap_query +{ + u_int16_t query_type; /* net order */ + u_int16_t server_type; /* net order */ }; -struct sap_server_ident { - unsigned short server_type __attribute__((packed)); - char server_name[48] __attribute__((packed)); - IPXNet server_network __attribute__((packed)); - IPXNode server_node __attribute__((packed)); - IPXPort server_port __attribute__((packed)); - unsigned short intermediate_network __attribute__((packed)); +struct sap_server_ident +{ + u_int16_t server_type __attribute__((packed)); + char server_name[48] __attribute__((packed)); + IPXNet server_network __attribute__((packed)); + IPXNode server_node __attribute__((packed)); + IPXPort server_port __attribute__((packed)); + u_int16_t intermediate_network __attribute__((packed)); }; #define IPX_RIP_REQUEST (0x1) #define IPX_RIP_RESPONSE (0x2) -struct ipx_rip_packet { - __u16 operation __attribute__((packed)); - struct ipx_rt_def { - __u32 network __attribute__((packed)); - __u16 hops __attribute__((packed)); - __u16 ticks __attribute__((packed)); - } rt[1] __attribute__((packed)); +struct ipx_rip_packet +{ + u_int16_t operation __attribute__((packed)); + struct ipx_rt_def + { + u_int32_t network __attribute__((packed)); + u_int16_t hops __attribute__((packed)); + u_int16_t ticks __attribute__((packed)); + } + rt[1] __attribute__((packed)); }; #define IPX_BROADCAST_NODE ("\xff\xff\xff\xff\xff\xff") @@ -85,8 +89,10 @@ void int ipx_sscanf_node(char *buf, unsigned char node[IPX_NODE_LEN]); void - ipx_assign_node(IPXNode dest, IPXNode src); + ipx_assign_node(IPXNode dest, CIPXNode src); int - ipx_node_equal(IPXNode n1, IPXNode n2); + ipx_node_equal(CIPXNode n1, CIPXNode n2); +int +ipx_sscanf_saddr(char* buf, struct sockaddr_ipx* sipx); #endif /* _IPXLIB_H */ diff --git a/include/kernel/fs.h b/include/kernel/fs.h new file mode 100644 index 0000000..ae00f2f --- /dev/null +++ b/include/kernel/fs.h @@ -0,0 +1,11 @@ +#ifndef _KERNEL_FS_H +#define _KERNEL_FS_H + +#include "glibstub.h" +#ifdef HAVE_SYS_MOUNT_H +#include +#else +#include +#endif + +#endif diff --git a/include/kernel/if.h b/include/kernel/if.h new file mode 100644 index 0000000..14dee6d --- /dev/null +++ b/include/kernel/if.h @@ -0,0 +1,11 @@ +#ifndef _KERNEL_IF_H +#define _KERNEL_IF_H + +#include "glibstub.h" +#ifdef HAVE_NET_IF_H +#include +#else +#include +#endif + +#endif diff --git a/include/kernel/ipx.h b/include/kernel/ipx.h new file mode 100644 index 0000000..ff4f153 --- /dev/null +++ b/include/kernel/ipx.h @@ -0,0 +1,15 @@ +#ifndef _KERNEL_IPX_H +#define _KERNEL_IPX_H + +#include "glibstub.h" +#ifdef HAVE_NETIPX_IPX_H +#include +#else +#include +#endif + +#ifndef IPXPROTO_IPX +#define IPXPROTO_IPX (PF_IPX) +#endif + +#endif diff --git a/include/kernel/ncp.h b/include/kernel/ncp.h new file mode 100644 index 0000000..cd02499 --- /dev/null +++ b/include/kernel/ncp.h @@ -0,0 +1,213 @@ +/* + * ncp.h + * + * Copyright (C) 1995 by Volker Lendecke + * Modified for sparc by J.F. Chadima + * + */ + +#ifndef _LINUX_NCP_H +#define _LINUX_NCP_H + +#include "kernel/types.h" +#include "kernel/ipx.h" + +#define NCP_PTYPE (0x11) +#define NCP_PORT (0x0451) + +#define NCP_ALLOC_SLOT_REQUEST (0x1111) +#define NCP_REQUEST (0x2222) +#define NCP_DEALLOC_SLOT_REQUEST (0x5555) + +struct ncp_request_header { + u_int16_t type __attribute__((packed)); + u_int8_t sequence __attribute__((packed)); + u_int8_t conn_low __attribute__((packed)); + u_int8_t task __attribute__((packed)); + u_int8_t conn_high __attribute__((packed)); + u_int8_t function __attribute__((packed)); + u_int8_t data[0] __attribute__((packed)); +}; + +#define NCP_REPLY (0x3333) +#define NCP_POSITIVE_ACK (0x9999) + +struct ncp_reply_header { + __u16 type __attribute__((packed)); + __u8 sequence __attribute__((packed)); + __u8 conn_low __attribute__((packed)); + __u8 task __attribute__((packed)); + __u8 conn_high __attribute__((packed)); + __u8 completion_code __attribute__((packed)); + __u8 connection_state __attribute__((packed)); + __u8 data[0] __attribute__((packed)); +}; + +#define NCP_VOLNAME_LEN (16) +#define NCP_NUMBER_OF_VOLUMES (64) +struct ncp_volume_info { + __u32 total_blocks; + __u32 free_blocks; + __u32 purgeable_blocks; + __u32 not_yet_purgeable_blocks; + __u32 total_dir_entries; + __u32 available_dir_entries; + __u8 sectors_per_block; + char volume_name[NCP_VOLNAME_LEN + 1]; +}; + +/* these define the attribute byte as seen by NCP */ +#define aRONLY (ntohl(0x01000000)) +#define aHIDDEN (ntohl(0x02000000)) +#define aSYSTEM (ntohl(0x04000000)) +#define aEXECUTE (ntohl(0x08000000)) +#define aDIR (ntohl(0x10000000)) +#define aARCH (ntohl(0x20000000)) + +#define AR_READ (ntohs(0x0100)) +#define AR_WRITE (ntohs(0x0200)) +#define AR_EXCLUSIVE (ntohs(0x2000)) + +#define NCP_FILE_ID_LEN 6 + +/* Defines for Name Spaces */ +#define NW_NS_DOS 0 +#define NW_NS_MAC 1 +#define NW_NS_NFS 2 +#define NW_NS_FTAM 3 +#define NW_NS_OS2 4 + +#if 0 /* Sorry, I do not think so... VANA */ +/* Defines for ReturnInformationMask */ +#define RIM_NAME (ntohl(0x01000000L)) +#define RIM_SPACE_ALLOCATED (ntohl(0x02000000L)) +#define RIM_ATTRIBUTES (ntohl(0x04000000L)) +#define RIM_DATA_SIZE (ntohl(0x08000000L)) +#define RIM_TOTAL_SIZE (ntohl(0x10000000L)) +#define RIM_EXT_ATTR_INFO (ntohl(0x20000000L)) +#define RIM_ARCHIVE (ntohl(0x40000000L)) +#define RIM_MODIFY (ntohl(0x80000000L)) +#define RIM_CREATION (ntohl(0x00010000L)) +#define RIM_OWNING_NAMESPACE (ntohl(0x00020000L)) +#define RIM_DIRECTORY (ntohl(0x00040000L)) +#define RIM_RIGHTS (ntohl(0x00080000L)) +#define RIM_ALL (ntohl(0xFF0F0000L)) +#define RIM_COMPRESSED_INFO (ntohl(0x00000080L)) +#else +#define RIM_NAME 0x00000001 +#define RIM_SPACE_ALLOCATED 0x00000002 +#define RIM_ATTRIBUTES 0x00000004 +#define RIM_DATA_SIZE 0x00000008 +#define RIM_TOTAL_SIZE 0x00000010 +#define RIM_EXT_ATTR_INFO 0x00000020 +#define RIM_ARCHIVE 0x00000040 +#define RIM_MODIFY 0x00000080 +#define RIM_CREATION 0x00000100 +#define RIM_OWNING_NAMESPACE 0x00000200 +#define RIM_DIRECTORY 0x00000400 +#define RIM_RIGHTS 0x00000800 +#define RIM_ALL 0x00000FFF +#define RIM_COMPRESSED_INFO 0x80000000UL +#endif + +/* open/create modes */ +#define OC_MODE_OPEN 0x01 +#define OC_MODE_TRUNCATE 0x02 +#define OC_MODE_REPLACE 0x02 +#define OC_MODE_CREATE 0x08 + +/* open/create results */ +#define OC_ACTION_NONE 0x00 +#define OC_ACTION_OPEN 0x01 +#define OC_ACTION_CREATE 0x02 +#define OC_ACTION_TRUNCATE 0x04 +#define OC_ACTION_REPLACE 0x04 + +/* access rights attributes */ +#ifndef AR_READ_ONLY +#define AR_READ_ONLY 0x0001 +#define AR_WRITE_ONLY 0x0002 +#define AR_DENY_READ 0x0004 +#define AR_DENY_WRITE 0x0008 +#define AR_COMPATIBILITY 0x0010 +#define AR_WRITE_THROUGH 0x0040 +#define AR_OPEN_COMPRESSED 0x0100 +#endif + +struct nw_info_struct { + __u32 spaceAlloc __attribute__((packed)); + __u32 attributes __attribute__((packed)); + __u16 flags __attribute__((packed)); + __u32 dataStreamSize __attribute__((packed)); + __u32 totalStreamSize __attribute__((packed)); + __u16 numberOfStreams __attribute__((packed)); + __u16 creationTime __attribute__((packed)); + __u16 creationDate __attribute__((packed)); + __u32 creatorID __attribute__((packed)); + __u16 modifyTime __attribute__((packed)); + __u16 modifyDate __attribute__((packed)); + __u32 modifierID __attribute__((packed)); + __u16 lastAccessDate __attribute__((packed)); + __u16 archiveTime __attribute__((packed)); + __u16 archiveDate __attribute__((packed)); + __u32 archiverID __attribute__((packed)); + __u16 inheritedRightsMask __attribute__((packed)); + __u32 dirEntNum __attribute__((packed)); + __u32 DosDirNum __attribute__((packed)); + __u32 volNumber __attribute__((packed)); + __u32 EADataSize __attribute__((packed)); + __u32 EAKeyCount __attribute__((packed)); + __u32 EAKeySize __attribute__((packed)); + __u32 NSCreator __attribute__((packed)); + __u8 nameLen __attribute__((packed)); + __u8 entryName[256] __attribute__((packed)); +}; + +/* modify mask - use with MODIFY_DOS_INFO structure */ +#define DM_ATTRIBUTES (ntohl(0x02000000L)) +#define DM_CREATE_DATE (ntohl(0x04000000L)) +#define DM_CREATE_TIME (ntohl(0x08000000L)) +#define DM_CREATOR_ID (ntohl(0x10000000L)) +#define DM_ARCHIVE_DATE (ntohl(0x20000000L)) +#define DM_ARCHIVE_TIME (ntohl(0x40000000L)) +#define DM_ARCHIVER_ID (ntohl(0x80000000L)) +#define DM_MODIFY_DATE (ntohl(0x00010000L)) +#define DM_MODIFY_TIME (ntohl(0x00020000L)) +#define DM_MODIFIER_ID (ntohl(0x00040000L)) +#define DM_LAST_ACCESS_DATE (ntohl(0x00080000L)) +#define DM_INHERITED_RIGHTS_MASK (ntohl(0x00100000L)) +#define DM_MAXIMUM_SPACE (ntohl(0x00200000L)) + +struct nw_modify_dos_info { + __u32 attributes __attribute__((packed)); + __u16 creationDate __attribute__((packed)); + __u16 creationTime __attribute__((packed)); + __u32 creatorID __attribute__((packed)); + __u16 modifyDate __attribute__((packed)); + __u16 modifyTime __attribute__((packed)); + __u32 modifierID __attribute__((packed)); + __u16 archiveDate __attribute__((packed)); + __u16 archiveTime __attribute__((packed)); + __u32 archiverID __attribute__((packed)); + __u16 lastAccessDate __attribute__((packed)); + __u16 inheritanceGrantMask __attribute__((packed)); + __u16 inheritanceRevokeMask __attribute__((packed)); + __u32 maximumSpace __attribute__((packed)); +}; + +struct nw_file_info { + struct nw_info_struct i; + int opened; + int access; + __u32 server_file_handle __attribute__((packed)); + __u8 open_create_action __attribute__((packed)); + __u8 file_handle[6] __attribute__((packed)); +}; + +struct nw_search_sequence { + __u8 volNumber __attribute__((packed)); + __u32 dirBase __attribute__((packed)); + __u32 sequence __attribute__((packed)); +}; + +#endif /* _LINUX_NCP_H */ diff --git a/include/kernel/ncp_fs.h b/include/kernel/ncp_fs.h new file mode 100644 index 0000000..3abdff6 --- /dev/null +++ b/include/kernel/ncp_fs.h @@ -0,0 +1,110 @@ +/* + * ncp_fs.h + * + * Copyright (C) 1995, 1996 by Volker Lendecke + * + */ + +#ifndef _KERNEL_NCP_FS_H +#define _KERNEL_NCP_FS_H + +#include "kernel/fs.h" +#include +#include + +/* + * ioctl commands + */ + +struct ncp_ioctl_request { + unsigned int function; + unsigned int size; + char *data; +}; + +struct ncp_fs_info { + int version; + struct sockaddr_ipx addr; + __kerXX_uid_t mounted_uid; + int connection; /* Connection number the server assigned us */ + int buffer_size; /* The negotiated buffer size, to be + used for read/write requests! */ + + int volume_number; + __u32 directory_id; +}; + +struct ncp_sign_init +{ + char sign_root[8]; + char sign_last[16]; +}; + +struct ncp_lock_ioctl +{ +#define NCP_LOCK_LOG 0 +#define NCP_LOCK_SH 1 +#define NCP_LOCK_EX 2 +#define NCP_LOCK_CLEAR 256 + int cmd; + int origin; + unsigned int offset; + unsigned int length; +#define NCP_LOCK_DEFAULT_TIMEOUT 18 +#define NCP_LOCK_MAX_TIMEOUT 180 + int timeout; +}; + +struct ncp_setroot_ioctl +{ + int volNumber; + int namespace; + __u32 dirEntNum; +}; + +struct ncp_objectname_ioctl +{ +#define NCP_AUTH_NONE 0x00 +#define NCP_AUTH_BIND 0x31 +#define NCP_AUTH_NDS 0x32 + int auth_type; + size_t object_name_len; + void* object_name; +}; + +struct ncp_privatedata_ioctl +{ + size_t len; + void* data; /* ~1000 for NDS */ +}; + +#define NCP_IOC_NCPREQUEST _IOR('n', 1, struct ncp_ioctl_request) +#define NCP_IOC_GETMOUNTUID _IOW('n', 2, __kernel_uid_t) +#define NCP_IOC_CONN_LOGGED_IN _IO('n', 3) + +#define NCP_GET_FS_INFO_VERSION (1) +#define NCP_IOC_GET_FS_INFO _IOWR('n', 4, struct ncp_fs_info) + +#define NCP_IOC_SIGN_INIT _IOR('n', 5, struct ncp_sign_init) +#define NCP_IOC_SIGN_WANTED _IOR('n', 6, int) +#define NCP_IOC_SET_SIGN_WANTED _IOW('n', 6, int) + +#define NCP_IOC_LOCKUNLOCK _IOR('n', 7, struct ncp_lock_ioctl) + +#define NCP_IOC_GETROOT _IOW('n', 8, struct ncp_setroot_ioctl) +#define NCP_IOC_SETROOT _IOR('n', 8, struct ncp_setroot_ioctl) + +#define NCP_IOC_GETOBJECTNAME _IOWR('n', 9, struct ncp_objectname_ioctl) +#define NCP_IOC_SETOBJECTNAME _IOR('n', 9, struct ncp_objectname_ioctl) +#define NCP_IOC_GETPRIVATEDATA _IOWR('n', 10, struct ncp_privatedata_ioctl) +#define NCP_IOC_SETPRIVATEDATA _IOR('n', 10, struct ncp_privatedata_ioctl) + +/* + * The packet size to allocate. One page should be enough. + */ +#define NCP_PACKET_SIZE 4070 + +#define NCP_MAXPATHLEN 255 +#define NCP_MAXNAMELEN 14 + +#endif /* _LINUX_NCP_FS_H */ diff --git a/include/kernel/route.h b/include/kernel/route.h new file mode 100644 index 0000000..f5c0b83 --- /dev/null +++ b/include/kernel/route.h @@ -0,0 +1,12 @@ +#ifndef __KERNEL_ROUTE_H__ +#define __KERNEL_ROUTE_H__ + +#include "glibstub.h" +#ifdef HAVE_NET_ROUTE_H +#include +#else +#include +#endif + +#endif /* __KERNEL_ROUTE_H__ */ + diff --git a/include/kernel/types.h b/include/kernel/types.h new file mode 100644 index 0000000..c2286ca --- /dev/null +++ b/include/kernel/types.h @@ -0,0 +1,40 @@ +#ifndef __KERNEL_TYPES_H__ +#define __KERNEL_TYPES_H__ + +#include + +#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 + +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 +#endif +#endif + +#endif /* __KERNEL_TYPES_H__ */ + diff --git a/include/ncp.h b/include/ncp.h index dc117a9..29361ba 100644 --- a/include/ncp.h +++ b/include/ncp.h @@ -9,10 +9,10 @@ #ifndef _NCP_H #define _NCP_H -#include -#include -#include -#include +#include "kernel/types.h" +#include "kernel/ipx.h" +#include "kernel/ncp.h" +#include "kernel/ncp_fs.h" #define NCP_BINDERY_USER (0x0001) #define NCP_BINDERY_UGROUP (0x0002) @@ -119,5 +119,4 @@ struct print_job_record { char Path[80] __attribute__((packed)); }; - #endif /* _NCP_H */ diff --git a/include/ncplib.h b/include/ncplib.h index 141d16b..634d0c8 100644 --- a/include/ncplib.h +++ b/include/ncplib.h @@ -8,13 +8,17 @@ #ifndef _NCPLIB_H #define _NCPLIB_H -#include #include "ncp.h" -#include #include #include #include +#ifdef SIGNATURES +#ifndef NCP_IOC_SIGN_INIT +#undef SIGNATURES +#endif /* NCP_IOC_SIGN_INIT */ +#endif /* SIGNATURES */ + #include "ipxlib.h" #include "com_err.h" @@ -22,31 +26,36 @@ typedef __u8 byte; typedef __u16 word; typedef __u32 dword; +typedef int NWCCODE; + #ifndef memzero #include #define memzero(object) memset(&(object), 0, sizeof(object)) #endif -#define BVAL(buf,pos) (((__u8 *)(buf))[pos]) +#define BVAL(buf,pos) (((const __u8 *)(buf))[pos]) +#define BWVAL(buf,pos) (((__u8*)(buf))[pos]) #define PVAL(buf,pos) ((unsigned)BVAL(buf,pos)) -#define BSET(buf,pos,val) (BVAL(buf,pos) = (val)) +#define BSET(buf,pos,val) (BWVAL(buf,pos) = (val)) static inline word - WVAL_HL(__u8 * buf, int pos) +WVAL_HL(const __u8 * buf, int pos) { return PVAL(buf, pos) << 8 | PVAL(buf, pos + 1); } static inline dword - DVAL_HL(__u8 * buf, int pos) +DVAL_HL(const __u8 * buf, int pos) { return WVAL_HL(buf, pos) << 16 | WVAL_HL(buf, pos + 2); } -static inline void WSET_HL(__u8 * buf, int pos, word val) +static inline void +WSET_HL(__u8 * buf, int pos, word val) { BSET(buf, pos, val >> 8); BSET(buf, pos + 1, val & 0xff); } -static inline void DSET_HL(__u8 * buf, int pos, dword val) +static inline void +DSET_HL(__u8 * buf, int pos, dword val) { WSET_HL(buf, pos, val >> 16); WSET_HL(buf, pos + 2, val & 0xffff); @@ -58,20 +67,22 @@ static inline void DSET_HL(__u8 * buf, int pos, dword val) #if defined(__i386__) static inline word - WVAL_LH(__u8 * buf, int pos) +WVAL_LH(const __u8 * buf, int pos) { - return *((word *) (buf + pos)); + return *((const word *) (buf + pos)); } static inline dword - DVAL_LH(__u8 * buf, int pos) +DVAL_LH(const __u8 * buf, int pos) { - return *((dword *) (buf + pos)); + return *((const dword *) (buf + pos)); } -static inline void WSET_LH(__u8 * buf, int pos, word val) +static inline void +WSET_LH(__u8 * buf, int pos, word val) { *((word *) (buf + pos)) = val; } -static inline void DSET_LH(__u8 * buf, int pos, dword val) +static inline void +DSET_LH(__u8 * buf, int pos, dword val) { *((dword *) (buf + pos)) = val; } @@ -79,21 +90,23 @@ static inline void DSET_LH(__u8 * buf, int pos, dword val) #else static inline word - WVAL_LH(__u8 * buf, int pos) +WVAL_LH(const __u8 * buf, int pos) { return PVAL(buf, pos) | PVAL(buf, pos + 1) << 8; } static inline dword - DVAL_LH(__u8 * buf, int pos) +DVAL_LH(const __u8 * buf, int pos) { return WVAL_LH(buf, pos) | WVAL_LH(buf, pos + 2) << 16; } -static inline void WSET_LH(__u8 * buf, int pos, word val) +static inline void +WSET_LH(__u8 * buf, int pos, word val) { BSET(buf, pos, val & 0xff); BSET(buf, pos + 1, val >> 8); } -static inline void DSET_LH(__u8 * buf, int pos, dword val) +static inline void +DSET_LH(__u8 * buf, int pos, dword val) { WSET_LH(buf, pos, val & 0xffff); WSET_LH(buf, pos + 2, val >> 16); @@ -101,19 +114,18 @@ static inline void DSET_LH(__u8 * buf, int pos, dword val) #endif - - - void str_upper(char *name); -enum connect_state { +enum connect_state +{ NOT_CONNECTED = 0, CONN_PERMANENT, CONN_TEMPORARY }; -struct ncp_conn { +struct ncp_conn +{ enum connect_state is_connected; @@ -139,14 +151,22 @@ struct ncp_conn { int current_size; int has_subfunction; int verbose; - int ncp_reply_size; + size_t ncp_reply_size; int lock; char packet[NCP_PACKET_SIZE]; +#ifdef SIGNATURES + /* Field used to make packet signatures */ + int sign_wanted; + int sign_active; + char sign_root[8]; + char sign_last[16]; +#endif }; -struct ncp_conn_spec { +struct ncp_conn_spec +{ char server[NCP_BINDERY_NAME_LEN]; char user[NCP_BINDERY_NAME_LEN]; uid_t uid; @@ -154,12 +174,16 @@ struct ncp_conn_spec { char password[NCP_BINDERY_NAME_LEN]; }; -struct ncp_search_seq { +#ifndef __MAKE_SULIB__ +struct ncp_search_seq +{ struct nw_search_sequence s; int namespace; }; +#endif /* not __MAKE_SULIB__ */ -struct ncp_property_info { +struct ncp_property_info +{ __u8 property_name[16]; __u8 property_flags; __u8 property_security; @@ -186,34 +210,35 @@ struct ncp_conn * /* Open a connection */ struct ncp_conn * - ncp_open(const struct ncp_conn_spec *spec, long *err); +ncp_open(const struct ncp_conn_spec *spec, long *err); /* Open a connection on an existing mount point */ -struct ncp_conn * - ncp_open_mount(const char *mount_point, long *err); +int +ncp_open_mount(const char *mount_point, struct ncp_conn** conn); /* Find a permanent connection that fits the spec, return NULL if * there is none. */ char * - ncp_find_permanent(const struct ncp_conn_spec *spec); +ncp_find_permanent(const struct ncp_conn_spec *spec); /* Find the address of a file server */ -struct sockaddr_ipx * - ncp_find_fileserver(const char *server_name, long *err); +long +ncp_find_fileserver(const char *server_name, struct sockaddr* addr, size_t addrlen); /* Find the address of a server */ -struct sockaddr_ipx * - ncp_find_server(const char **server_name, int type, long *err); +long +ncp_find_server(const char **server_name, int type, struct sockaddr* addr, size_t addrlen); /* Detach from a permanent connection or destroy a temporary connection */ long - ncp_close(struct ncp_conn *conn); +ncp_close(struct ncp_conn *conn); /* like getmntent, get_ncp_conn_ent scans /etc/mtab for usable connections */ -struct ncp_conn_ent { +struct ncp_conn_ent +{ char server[NCP_BINDERY_NAME_LEN]; char user[NCP_BINDERY_NAME_LEN]; uid_t uid; @@ -221,7 +246,7 @@ struct ncp_conn_ent { }; struct ncp_conn_ent * - ncp_get_conn_ent(FILE * filep); +ncp_get_conn_ent(FILE * filep); #define NWCLIENT (".nwclient") #define NWC_NOPASSWORD ("-") @@ -232,6 +257,12 @@ struct ncp_conn_spec * ncp_find_conn_spec(const char *server, const char *user, const char *password, int login_necessary, uid_t uid, long *err); +#ifdef __MAKE_SULIB__ +struct ncp_conn_spec * + ncp_find_conn_spec2(const char *server, const char *user, const char *password, + int login_necessary, uid_t uid, int allow_multiple_conns, + long *err); +#else /* __MAKE_SULIB__ */ long ncp_get_file_server_description_strings(struct ncp_conn *conn, char target[512]); @@ -241,7 +272,8 @@ long long ncp_set_file_server_time(struct ncp_conn *conn, time_t * source); -struct ncp_file_server_info { +struct ncp_file_server_info +{ __u8 ServerName[48] __attribute__((packed)); __u8 FileServiceVersion __attribute__((packed)); __u8 FileServiceSubVersion __attribute__((packed)); @@ -288,9 +320,16 @@ long __u8 no_conn, const __u8 * connections, const char *message); +long + ncp_send_broadcast2(struct ncp_conn *conn, + unsigned int conns, const unsigned int* connlist, + const char* message); +#endif /* not __MAKE_SULIB__ */ + long ncp_get_encryption_key(struct ncp_conn *conn, char *target); +#ifndef __MAKE_SULIB__ long ncp_get_bindery_object_id(struct ncp_conn *conn, __u16 object_type, @@ -302,7 +341,7 @@ long struct ncp_bindery_object *target); long ncp_scan_bindery_object(struct ncp_conn *conn, - __u32 last_id, __u16 object_type, char *search_string, + __u32 last_id, __u16 object_type, char *search_string, struct ncp_bindery_object *target); long ncp_create_bindery_object(struct ncp_conn *conn, @@ -320,14 +359,17 @@ long __u16 object_type, const char *object_name, __u8 security); +#endif /* not __MAKE_SULIB__ */ -struct ncp_station_addr { +struct ncp_station_addr +{ __u32 NetWork __attribute__((packed)); __u8 Node[6] __attribute__((packed)); __u16 Socket __attribute__((packed)); }; -struct ncp_prop_login_control { +struct ncp_prop_login_control +{ __u8 AccountExpireDate[3] __attribute__((packed)); __u8 Disabled __attribute__((packed)); __u8 PasswordExpireDate[3] __attribute__((packed)); @@ -351,10 +393,11 @@ long int object_type, const char *object_name, int segment, const char *prop_name, struct nw_property *target); +#ifndef __MAKE_SULIB__ long ncp_scan_property(struct ncp_conn *conn, __u16 object_type, const char *object_name, - __u32 last_id, char *search_string, + __u32 last_id, const char *search_string, struct ncp_property_info *property_info); long ncp_add_object_to_set(struct ncp_conn *conn, @@ -387,7 +430,7 @@ long __u16 object_type, const char *object_name, const char *property_name, __u8 segment, - struct nw_property *property_value); + const struct nw_property *property_value); /* Bit masks for security flag */ #define NCP_SEC_CHECKSUMMING_REQUESTED (1) @@ -421,13 +464,24 @@ long const unsigned char *key, const unsigned char *oldpasswd, const unsigned char *newpasswd); +#endif /* not __MAKE_SULIB__ */ +#define NWE_SIGNATURE_LEVEL_CONFLICT (0x8861) #define NCP_GRACE_PERIOD (0xdf) +#ifndef __MAKE_SULIB__ +long + ncp_get_bindery_object_id(struct ncp_conn *conn, + __u16 object_type, + const char *object_name, + struct ncp_bindery_object *target); +#endif /* not __MAKE_SULIB__ */ + long ncp_login_user(struct ncp_conn *conn, const unsigned char *username, const unsigned char *password); +#ifndef __MAKE_SULIB__ long ncp_get_volume_info_with_number(struct ncp_conn *conn, int n, struct ncp_volume_info *target); @@ -528,6 +582,15 @@ long __u32 count, __u32 * copied_count); +#define SA_NORMAL (0x0000) +#define SA_HIDDEN (0x0002) +#define SA_SYSTEM (0x0004) +#define SA_SUBDIR_ONLY (0x0010) +#define SA_SUBDIR_FILES (0x8000) +#define SA_ALL (SA_SUBDIR_FILES | SA_SYSTEM | SA_HIDDEN) +#define SA_SUBDIR_ALL (SA_SUBDIR_ONLY | SA_SYSTEM | SA_HIDDEN) +#define SA_FILES_ALL (SA_NORMAL | SA_SYSTEM | SA_HIDDEN) + long ncp_obtain_file_or_subdir_info(struct ncp_conn *conn, __u8 source_ns, __u8 target_ns, @@ -555,7 +618,7 @@ long long ncp_do_lookup(struct ncp_conn *conn, struct nw_info_struct *dir, - char *path, /* may only be one component */ + const char *path, /* may only be one component */ struct nw_info_struct *target); long @@ -583,6 +646,13 @@ long int namespace, struct ncp_search_seq *target); +long +ncp_search_for_file_or_subdir2(struct ncp_conn *conn, + int search_attributes, + u_int32_t RIM, + struct ncp_search_seq *seq, + struct nw_info_struct *target); + long ncp_search_for_file_or_subdir(struct ncp_conn *conn, struct ncp_search_seq *seq, @@ -590,14 +660,35 @@ long long ncp_ren_or_mov_file_or_subdir(struct ncp_conn *conn, - struct nw_info_struct *old_dir, char *old_name, - struct nw_info_struct *new_dir, char *new_name); + struct nw_info_struct *old_dir, char *old_name, + struct nw_info_struct *new_dir, char *new_name); long ncp_create_queue_job_and_file(struct ncp_conn *conn, __u32 queue_id, struct queue_job *job); +long + ncp_get_queue_length(struct ncp_conn *conn, + __u32 queue_id, + __u32 *queue_length); + +long + ncp_get_queue_job_ids(struct ncp_conn *conn, + __u32 queue_id, + __u32 queue_section, + __u32 *length1, + __u32 *length2, + __u32 ids[]); +long + ncp_get_queue_job_info(struct ncp_conn *conn, + __u32 queue_id, + __u32 job_id, + struct nw_queue_job_entry *jobdata); + +long +NWRemoveJobFromQueue2(struct ncp_conn* conn, __u32 queue_id, __u32 job_id); + long ncp_close_file_and_start_job(struct ncp_conn *conn, __u32 queue_id, @@ -622,10 +713,12 @@ long long ncp_abort_servicing_job(struct ncp_conn *conn, __u32 queue_id, __u32 job_number); +#endif /* not __MAKE_SULIB__ */ long ncp_get_broadcast_message(struct ncp_conn *conn, char message[256]); +#ifndef __MAKE_SULIB__ long ncp_dealloc_dir_handle(struct ncp_conn *conn, __u8 dir_handle); @@ -644,7 +737,8 @@ long struct nw_info_struct *file, __u16 * target); -struct ncp_trustee_struct { +struct ncp_trustee_struct +{ __u32 object_id; __u16 rights; }; @@ -655,5 +749,75 @@ long __u16 rights_mask, int object_count, struct ncp_trustee_struct *rights); +struct ncp_deleted_file +{ + int32_t seq; + __u32 vol; + __u32 base; +}; -#endif /* _NCPLIB_H */ +long +ncp_ns_scan_salvageable_file(struct ncp_conn* conn, __u8 src_ns, + int dirstyle, __u8 vol_num, + __u32 dir_base, + const unsigned char* encpath, int pathlen, + struct ncp_deleted_file* finfo, + char* name, int maxnamelen); + +long +ncp_ns_purge_file(struct ncp_conn* conn, const struct ncp_deleted_file* finfo); + +long +ncp_ns_get_full_name(struct ncp_conn* conn, __u8 src_ns, __u8 dst_ns, + int dirstyle, __u8 vol_num, __u32 dir_base, + const unsigned char* encpath, size_t pathlen, + char* name, size_t maxnamelen); + +#endif /* not __MAKE_SULIB__ */ + +#ifdef SIGNATURES +long +ncp_sign_start(struct ncp_conn *conn, const char *sign_root); +#endif /* SIGNATURES */ + +#ifdef NDS_SUPPORT +long +ncp_send_nds_frag(struct ncp_conn *conn, + int ndsverb, + const char *inbuf, size_t inbuflen, + char *outbuf, size_t outbufsize, size_t *outbuflen); + +long +ncp_send_nds(struct ncp_conn *conn, int fn, + const char *data_in, size_t data_in_len, + char *data_out, size_t data_out_max, size_t *data_out_len); + +long +ncp_change_conn_state(struct ncp_conn *conn, int new_state); +#endif + +struct ncp_conn * +ncp_open_addr(struct sockaddr *target, long *err); + +#ifdef __MAKE_SULIB__ +int +ncp_path_to_NW_format(const char* path, unsigned char* buff, int buffsize); + +long +ncp_obtain_file_or_subdir_info2(struct ncp_conn* conn, __u8 source_ns, + __u8 target_ns, __u16 search_attribs, __u32 rim, + int dir_style, __u8 vol, __u32 dirent, + const unsigned char* path, int pathlen, + struct nw_info_struct* target); + +#endif /* __MAKE_SULIB__ */ + +int +ncp_get_mount_uid(int fid, uid_t* uid); + +#ifdef __MAKE_SULIB__ +long +ncp_renegotiate_connparam(struct ncp_conn* conn, int buffsize, int options); +#endif /* __MAKE_SULIB__ */ + +#endif /* _NCPLIB_H */ diff --git a/include/ncpsign.h b/include/ncpsign.h new file mode 100644 index 0000000..72d8f8e --- /dev/null +++ b/include/ncpsign.h @@ -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 diff --git a/include/ndslib.h b/include/ndslib.h new file mode 100644 index 0000000..89a4813 --- /dev/null +++ b/include/ndslib.h @@ -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_ */ diff --git a/ipx-1.0/Makefile b/ipx-1.0/Makefile index c12bf8d..5a29d7d 100644 --- a/ipx-1.0/Makefile +++ b/ipx-1.0/Makefile @@ -1,5 +1,8 @@ -CFLAGS = -O2 -Wall +include ../Makeinit +# CFLAGS = -O2 -Wall -I../include UTILS = ipx_configure ipx_interface ipx_internal_net ipx_route +MAN8 := $(UTILS) +CFLAGS := $(CCFLAGS) all: $(UTILS) @@ -17,3 +20,4 @@ install: $(UTILS) do \ install $$i $(BINDIR); \ done + for i in $(MAN8); do install $$i.8 -m 644 $(MANDIR)/man8; done diff --git a/ipx-1.0/Samples/ipxrcv.c b/ipx-1.0/Samples/ipxrcv.c index c01a0f8..d076506 100644 --- a/ipx-1.0/Samples/ipxrcv.c +++ b/ipx-1.0/Samples/ipxrcv.c @@ -5,7 +5,8 @@ #include #include -int main(int argc, char **argv) +int +main(int argc, char **argv) { struct sockaddr_ipx sipx; int s; @@ -14,7 +15,8 @@ int main(int argc, char **argv) int len; s = socket(AF_IPX, SOCK_DGRAM, AF_IPX); - if (s < 0) { + if (s < 0) + { perror("IPX: socket: "); exit(-1); } @@ -24,14 +26,16 @@ int main(int argc, char **argv) sipx.sipx_type = 17; len = sizeof(sipx); result = bind(s, (struct sockaddr *) &sipx, sizeof(sipx)); - if (result < 0) { + if (result < 0) + { perror("IPX: bind: "); exit(-1); } msg[0] = '\0'; result = recvfrom(s, msg, sizeof(msg), 0, (struct sockaddr *) &sipx, &len); - if (result < 0) { + if (result < 0) + { perror("IPX: recvfrom: "); } printf("From %08lX:%02X%02X%02X%02X%02X%02X:%04X\n", diff --git a/ipx-1.0/Samples/ipxsend.c b/ipx-1.0/Samples/ipxsend.c index ad92629..e8b519d 100644 --- a/ipx-1.0/Samples/ipxsend.c +++ b/ipx-1.0/Samples/ipxsend.c @@ -9,7 +9,8 @@ #include #include -int main(int argc, char **argv) +int +main(int argc, char **argv) { struct sockaddr_ipx sipx; int s; @@ -18,7 +19,8 @@ int main(int argc, char **argv) int len = sizeof(sipx); s = socket(AF_IPX, SOCK_DGRAM, AF_IPX); - if (s < 0) { + if (s < 0) + { perror("IPX: socket: "); exit(-1); } @@ -28,7 +30,8 @@ int main(int argc, char **argv) sipx.sipx_type = 17; result = bind(s, (struct sockaddr *) &sipx, sizeof(sipx)); - if (result < 0) { + if (result < 0) + { perror("IPX: bind: "); exit(-1); } @@ -36,7 +39,8 @@ int main(int argc, char **argv) sipx.sipx_port = htons(0x5000); result = sendto(s, msg, sizeof(msg), 0, (struct sockaddr *) &sipx, sizeof(sipx)); - if (result < 0) { + if (result < 0) + { perror("IPX: send: "); exit(-1); } diff --git a/ipx-1.0/Samples/rip.c b/ipx-1.0/Samples/rip.c index 38f4419..67f660e 100644 --- a/ipx-1.0/Samples/rip.c +++ b/ipx-1.0/Samples/rip.c @@ -9,13 +9,15 @@ #include #include -struct rip_data { +struct rip_data +{ unsigned long rip_net; unsigned short rip_hops __attribute__((packed)); unsigned short rip_ticks __attribute__((packed)); }; -int main(int argc, char **argv) +int +main(int argc, char **argv) { struct sockaddr_ipx sipx; int result; @@ -26,7 +28,8 @@ int main(int argc, char **argv) struct rip_data *rp; s = socket(AF_IPX, SOCK_DGRAM, AF_IPX); - if (s < 0) { + if (s < 0) + { perror("IPX: socket: "); exit(-1); } @@ -35,15 +38,18 @@ int main(int argc, char **argv) sipx.sipx_port = htons(0x453); sipx.sipx_type = 17; result = bind(s, (struct sockaddr *) &sipx, sizeof(sipx)); - if (result < 0) { + if (result < 0) + { perror("IPX: bind: "); exit(-1); } - while (1) { + while (1) + { len = sizeof(sipx); result = recvfrom(s, msg, sizeof(msg), 0, (struct sockaddr *) &sipx, &len); - if (result < 0) { + if (result < 0) + { perror("IPX: recvfrom"); exit(-1); } @@ -56,7 +62,8 @@ int main(int argc, char **argv) sipx.sipx_node[6], sipx.sipx_node[5]); bptr += 2; rp = (struct rip_data *) bptr; - while (result >= sizeof(struct rip_data)) { + while (result >= sizeof(struct rip_data)) + { printf("\tNET: %08lX HOPS: %d\n", ntohl(rp->rip_net), ntohs(rp->rip_hops)); result -= sizeof(struct rip_data); diff --git a/ipx-1.0/Samples/sap.c b/ipx-1.0/Samples/sap.c index 5bf696b..cfb3a6b 100644 --- a/ipx-1.0/Samples/sap.c +++ b/ipx-1.0/Samples/sap.c @@ -10,7 +10,8 @@ #include -struct sap_data { +struct sap_data +{ unsigned short sap_type __attribute__((packed)); char sap_name[48] __attribute__((packed)); unsigned long sap_net __attribute__((packed)); @@ -19,7 +20,8 @@ struct sap_data { unsigned short sap_hops __attribute__((packed)); }; -int main(int argc, char **argv) +int +main(int argc, char **argv) { int s; int result; @@ -31,12 +33,14 @@ int main(int argc, char **argv) struct sap_data *sp; s = socket(AF_IPX, SOCK_DGRAM, AF_IPX); - if (s < 0) { + if (s < 0) + { perror("IPX: socket: "); exit(-1); } result = setsockopt(s, SOL_SOCKET, SO_DEBUG, &val, 4); - if (result < 0) { + if (result < 0) + { perror("IPX: setsockopt: "); exit(-1); } @@ -46,15 +50,18 @@ int main(int argc, char **argv) sipx.sipx_type = 17; result = bind(s, (struct sockaddr *) &sipx, sizeof(sipx)); - if (result < 0) { + if (result < 0) + { perror("IPX: bind: "); exit(-1); } - while (1) { + while (1) + { len = 1024; result = recvfrom(s, msg, sizeof(msg), 0, (struct sockaddr *) &sipx, &len); - if (result < 0) { + if (result < 0) + { perror("IPX: recvfrom: "); exit(-1); } @@ -67,7 +74,8 @@ int main(int argc, char **argv) bptr += 2; sp = (struct sap_data *) bptr; - while (result >= sizeof(struct sap_data)) { + while (result >= sizeof(struct sap_data)) + { int i; sp->sap_name[32] = '\0'; diff --git a/man/ipx_configure.8 b/ipx-1.0/ipx_configure.8 similarity index 100% rename from man/ipx_configure.8 rename to ipx-1.0/ipx_configure.8 diff --git a/ipx-1.0/ipx_configure.c b/ipx-1.0/ipx_configure.c index 92e98bb..37ce88e 100644 --- a/ipx-1.0/ipx_configure.c +++ b/ipx-1.0/ipx_configure.c @@ -8,7 +8,7 @@ #include #include #include -#include +#include "kernel/ipx.h" #include #include #include @@ -24,7 +24,8 @@ struct option options[] = char *progname; -void usage(void) +void +usage(void) { fprintf(stderr, "Usage: %s --auto_primary=[on|off]\n\ @@ -33,23 +34,27 @@ Usage: %s --help\n\ Usage: %s\n", progname, progname, progname, progname); } -int map_string_to_bool(char *optarg) +int +map_string_to_bool(char *optarg) { if ((strcasecmp(optarg, "ON") == 0) || (strcasecmp(optarg, "TRUE") == 0) || (strcasecmp(optarg, "SET") == 0) || - (strcasecmp(optarg, "YES") == 0)) { + (strcasecmp(optarg, "YES") == 0)) + { return 1; } else if ((strcasecmp(optarg, "OFF") == 0) || (strcasecmp(optarg, "FALSE") == 0) || (strcasecmp(optarg, "CLEAR") == 0) || - (strcasecmp(optarg, "NO") == 0)) { + (strcasecmp(optarg, "NO") == 0)) + { return 0; } return -1; } -int main(int argc, char **argv) +int +main(int argc, char **argv) { int s; int result; @@ -63,11 +68,13 @@ int main(int argc, char **argv) progname = argv[0]; s = socket(AF_IPX, SOCK_DGRAM, AF_IPX); - if (s < 0) { + if (s < 0) + { int old_errno = errno; sprintf(errmsg, "%s: socket", progname); perror(errmsg); - if (old_errno == -EINVAL) { + if (old_errno == -EINVAL) + { fprintf(stderr, "Probably you have no IPX support in " "your kernel\n"); } @@ -75,20 +82,24 @@ int main(int argc, char **argv) } sprintf(errmsg, "%s: ioctl", progname); while ((result = getopt_long(argc, argv, "", options, - &option_index)) != -1) { - switch (result) { + &option_index)) != -1) + { + switch (result) + { case 1: if (got_auto_pri) break; got_auto_pri++; val = map_string_to_bool(optarg); - if (val < 0) { + if (val < 0) + { usage(); exit(-1); } result = ioctl(s, SIOCAIPXPRISLT, &val); - if (result < 0) { + if (result < 0) + { perror(errmsg); exit(-1); } @@ -99,12 +110,14 @@ int main(int argc, char **argv) got_auto_itf++; val = map_string_to_bool(optarg); - if (val < 0) { + if (val < 0) + { usage(); exit(-1); } result = ioctl(s, SIOCAIPXITFCRT, &val); - if (result < 0) { + if (result < 0) + { perror(errmsg); exit(-1); } @@ -115,15 +128,17 @@ int main(int argc, char **argv) } } result = ioctl(s, SIOCIPXCFGDATA, &data); - if (result < 0) { + if (result < 0) + { perror(errmsg); exit(-1); } - if (argc == 1) { + if (argc == 1) + { fprintf(stdout, "Auto Primary Select is %s\n\ Auto Interface Create is %s\n", (data.ipxcfg_auto_select_primary) ? "ON" : "OFF", - (data.ipxcfg_auto_create_interfaces) ? "ON" : "OFF"); + (data.ipxcfg_auto_create_interfaces) ? "ON" : "OFF"); } exit(0); } diff --git a/man/ipx_interface.8 b/ipx-1.0/ipx_interface.8 similarity index 100% rename from man/ipx_interface.8 rename to ipx-1.0/ipx_interface.8 diff --git a/ipx-1.0/ipx_interface.c b/ipx-1.0/ipx_interface.c index 0ba3da5..7a73a84 100644 --- a/ipx-1.0/ipx_interface.c +++ b/ipx-1.0/ipx_interface.c @@ -11,8 +11,8 @@ #include #include #include -#include -#include +#include "kernel/ipx.h" +#include "kernel/if.h" #include #include #include @@ -21,7 +21,8 @@ static struct ifreq id; static char *progname; -void usage(void) +void +usage(void) { fprintf(stderr, "Usage: %s add [-p] device frame_type [net_number]\n\ Usage: %s del device frame_type\n\ @@ -30,11 +31,12 @@ Usage: %s check device frame_type\n", progname, progname, progname, progname); exit(-1); } -struct frame_type { +struct frame_type +{ char *ft_name; unsigned char ft_val; -} frame_types[] = - +} +frame_types[] = { { "802.2", IPX_FRAME_8022 @@ -61,19 +63,22 @@ struct frame_type { #define NFTYPES (sizeof(frame_types)/sizeof(struct frame_type)) -int lookup_frame_type(char *frame) +int +lookup_frame_type(char *frame) { - int j; + size_t j; for (j = 0; (j < NFTYPES) && (strcasecmp(frame_types[j].ft_name, frame)); - j++); + j++) + ; if (j != NFTYPES) return j; fprintf(stderr, "%s: Frame type must be", progname); - for (j = 0; j < NFTYPES; j++) { + for (j = 0; j < NFTYPES; j++) + { fprintf(stderr, "%s%s", (j == NFTYPES - 1) ? " or " : " ", frame_types[j].ft_name); @@ -82,7 +87,8 @@ int lookup_frame_type(char *frame) return -1; } -int ipx_add_interface(int argc, char **argv) +int +ipx_add_interface(int argc, char **argv) { struct sockaddr_ipx *sipx = (struct sockaddr_ipx *) &id.ifr_addr; int s; @@ -95,19 +101,24 @@ int ipx_add_interface(int argc, char **argv) sipx->sipx_special = IPX_SPECIAL_NONE; sipx->sipx_network = 0L; sipx->sipx_type = IPX_FRAME_NONE; - while ((c = getopt(argc, argv, "p")) > 0) { - switch (c) { + while ((c = getopt(argc, argv, "p")) > 0) + { + switch (c) + { case 'p': sipx->sipx_special = IPX_PRIMARY; break; } } - if (((i = (argc - optind)) < 2) || (i > 3)) { + if (((i = (argc - optind)) < 2) || (i > 3)) + { usage(); } - for (i = optind; i < argc; i++) { - switch (i - optind) { + for (i = optind; i < argc; i++) + { + switch (i - optind) + { case 0: /* Physical Device - Required */ strcpy(id.ifr_name, argv[i]); break; @@ -120,9 +131,10 @@ int ipx_add_interface(int argc, char **argv) case 2: /* Network Number - Optional */ netnum = strtoul(argv[i], (char **) NULL, 16); - if (netnum == 0xffffffffL) { + if (netnum == 0xffffffffL) + { fprintf(stderr, - "%s: Inappropriate network number %08lX\n", + "%s: Inappropriate network number %08lX\n", progname, netnum); exit(-1); } @@ -132,11 +144,13 @@ int ipx_add_interface(int argc, char **argv) } s = socket(AF_IPX, SOCK_DGRAM, AF_IPX); - if (s < 0) { + if (s < 0) + { int old_errno = errno; sprintf(errmsg, "%s: socket", progname); perror(errmsg); - if (old_errno == -EINVAL) { + if (old_errno == -EINVAL) + { fprintf(stderr, "Probably you have no IPX support in " "your kernel\n"); } @@ -145,7 +159,8 @@ int ipx_add_interface(int argc, char **argv) i = 0; sipx->sipx_family = AF_IPX; sipx->sipx_action = IPX_CRTITF; - do { + do + { result = ioctl(s, SIOCSIFADDR, &id); i++; } @@ -154,14 +169,15 @@ int ipx_add_interface(int argc, char **argv) if (result == 0) exit(0); - switch (errno) { + switch (errno) + { case EEXIST: fprintf(stderr, "%s: Primary network already selected.\n", progname); break; case EADDRINUSE: - fprintf(stderr, "%s: Network number (%08lX) already in use.\n", - progname, htonl(sipx->sipx_network)); + fprintf(stderr, "%s: Network number (%08X) already in use.\n", + progname, (u_int32_t)htonl(sipx->sipx_network)); break; case EPROTONOSUPPORT: fprintf(stderr, "%s: Invalid frame type (%s).\n", @@ -192,7 +208,8 @@ int ipx_add_interface(int argc, char **argv) exit(-1); } -int ipx_delall_interface(int argc, char **argv) +int +ipx_delall_interface(int argc, char **argv) { struct sockaddr_ipx *sipx = (struct sockaddr_ipx *) &id.ifr_addr; int s; @@ -205,26 +222,31 @@ int ipx_delall_interface(int argc, char **argv) FILE *fp; s = socket(AF_IPX, SOCK_DGRAM, AF_IPX); - if (s < 0) { + if (s < 0) + { sprintf(errmsg, "%s: socket", progname); perror(errmsg); exit(-1); } fp = fopen("/proc/net/ipx_interface", "r"); - if (fp == NULL) { + if (fp == NULL) + { fprintf(stderr, - "%s: Unable to open \"/proc/net/ipx_interface.\"\n", + "%s: Unable to open \"/proc/net/ipx_interface.\"\n", progname); exit(-1); } fgets(buffer, 80, fp); while (fscanf(fp, "%s %s %s %s %s", buffer, buffer, buffer, - device, frame_type) == 5) { + device, frame_type) == 5) + { sipx->sipx_network = 0L; - if (strcasecmp(device, "Internal") == 0) { + if (strcasecmp(device, "Internal") == 0) + { sipx->sipx_special = IPX_INTERNAL; - } else { + } else + { sipx->sipx_special = IPX_SPECIAL_NONE; strcpy(id.ifr_name, device); fti = lookup_frame_type(frame_type); @@ -238,7 +260,8 @@ int ipx_delall_interface(int argc, char **argv) result = ioctl(s, SIOCSIFADDR, &id); if (result == 0) continue; - switch (errno) { + switch (errno) + { case EPROTONOSUPPORT: fprintf(stderr, "%s: Invalid frame type (%s).\n", progname, frame_type); @@ -261,7 +284,8 @@ int ipx_delall_interface(int argc, char **argv) exit(0); } -int ipx_del_interface(int argc, char **argv) +int +ipx_del_interface(int argc, char **argv) { struct sockaddr_ipx *sipx = (struct sockaddr_ipx *) &id.ifr_addr; int s; @@ -269,7 +293,8 @@ int ipx_del_interface(int argc, char **argv) char errmsg[80]; int fti; - if (argc != 3) { + if (argc != 3) + { usage(); } sipx->sipx_network = 0L; @@ -281,7 +306,8 @@ int ipx_del_interface(int argc, char **argv) sipx->sipx_type = frame_types[fti].ft_val; s = socket(AF_IPX, SOCK_DGRAM, AF_IPX); - if (s < 0) { + if (s < 0) + { sprintf(errmsg, "%s: socket", progname); perror(errmsg); exit(-1); @@ -292,7 +318,8 @@ int ipx_del_interface(int argc, char **argv) if (result == 0) exit(0); - switch (errno) { + switch (errno) + { case EPROTONOSUPPORT: fprintf(stderr, "%s: Invalid frame type (%s).\n", progname, frame_types[fti].ft_name); @@ -313,7 +340,8 @@ int ipx_del_interface(int argc, char **argv) exit(-1); } -int ipx_check_interface(int argc, char **argv) +int +ipx_check_interface(int argc, char **argv) { struct sockaddr_ipx *sipx = (struct sockaddr_ipx *) &id.ifr_addr; int s; @@ -321,7 +349,8 @@ int ipx_check_interface(int argc, char **argv) char errmsg[80]; int fti; - if (argc != 3) { + if (argc != 3) + { usage(); } sipx->sipx_network = 0L; @@ -332,24 +361,27 @@ int ipx_check_interface(int argc, char **argv) sipx->sipx_type = frame_types[fti].ft_val; s = socket(AF_IPX, SOCK_DGRAM, AF_IPX); - if (s < 0) { + if (s < 0) + { sprintf(errmsg, "%s: socket", progname); perror(errmsg); exit(-1); } sipx->sipx_family = AF_IPX; result = ioctl(s, SIOCGIFADDR, &id); - if (result == 0) { + if (result == 0) + { printf( - "IPX Address for (%s, %s) is %08lX:%02X%02X%02X%02X%02X%02X.\n", + "IPX Address for (%s, %s) is %08X:%02X%02X%02X%02X%02X%02X.\n", argv[1], frame_types[fti].ft_name, - htonl(sipx->sipx_network), sipx->sipx_node[0], + (u_int32_t)htonl(sipx->sipx_network), sipx->sipx_node[0], sipx->sipx_node[1], sipx->sipx_node[2], sipx->sipx_node[3], sipx->sipx_node[4], sipx->sipx_node[5]); exit(0); } - switch (errno) { + switch (errno) + { case EPROTONOSUPPORT: fprintf(stderr, "%s: Invalid frame type (%s).\n", progname, frame_types[fti].ft_name); @@ -370,28 +402,34 @@ int ipx_check_interface(int argc, char **argv) exit(-1); } -int main(int argc, char **argv) +int +main(int argc, char **argv) { int i; progname = argv[0]; - if (argc < 2) { + if (argc < 2) + { usage(); exit(-1); } - if (strncasecmp(argv[1], "add", 3) == 0) { + if (strncasecmp(argv[1], "add", 3) == 0) + { for (i = 1; i < (argc - 1); i++) argv[i] = argv[i + 1]; ipx_add_interface(argc - 1, argv); - } else if (strncasecmp(argv[1], "delall", 6) == 0) { + } else if (strncasecmp(argv[1], "delall", 6) == 0) + { for (i = 1; i < (argc - 1); i++) argv[i] = argv[i + 1]; ipx_delall_interface(argc - 1, argv); - } else if (strncasecmp(argv[1], "del", 3) == 0) { + } else if (strncasecmp(argv[1], "del", 3) == 0) + { for (i = 1; i < (argc - 1); i++) argv[i] = argv[i + 1]; ipx_del_interface(argc - 1, argv); - } else if (strncasecmp(argv[1], "check", 5) == 0) { + } else if (strncasecmp(argv[1], "check", 5) == 0) + { for (i = 1; i < (argc - 1); i++) argv[i] = argv[i + 1]; ipx_check_interface(argc - 1, argv); diff --git a/man/ipx_internal_net.8 b/ipx-1.0/ipx_internal_net.8 similarity index 100% rename from man/ipx_internal_net.8 rename to ipx-1.0/ipx_internal_net.8 diff --git a/ipx-1.0/ipx_internal_net.c b/ipx-1.0/ipx_internal_net.c index 121007e..004a8c7 100644 --- a/ipx-1.0/ipx_internal_net.c +++ b/ipx-1.0/ipx_internal_net.c @@ -9,8 +9,8 @@ #include #include #include -#include -#include +#include "kernel/ipx.h" +#include "kernel/if.h" #include #include #include @@ -18,26 +18,32 @@ static struct ifreq id; static char *progname; -void usage(void) +void +usage(void) { fprintf(stderr, "Usage: %s add net_number(hex) node(hex)\n\ Usage: %s del\n", progname, progname); exit(-1); } -int map_char_to_val(char dig) +int +map_char_to_val(char dig) { char digit = tolower(dig); - if ((digit >= '0') && (digit <= '9')) { + if ((digit >= '0') && (digit <= '9')) + { return digit - '0'; - } else if ((digit >= 'a') && (digit <= 'f')) { + } else if ((digit >= 'a') && (digit <= 'f')) + { return (10 + (digit - 'a')); - } else { + } else + { return 0; } } -int ipx_add_internal_net(int argc, char **argv) +int +ipx_add_internal_net(int argc, char **argv) { struct sockaddr_ipx *sipx = (struct sockaddr_ipx *) &id.ifr_addr; int s; @@ -51,38 +57,45 @@ int ipx_add_internal_net(int argc, char **argv) char *tin; int i; - if (argc != 3) { + if (argc != 3) + { usage(); } netnum = strtoul(argv[1], (char **) NULL, 16); - if ((netnum == 0L) || (netnum == 0xffffffffL)) { + if ((netnum == 0L) || (netnum == 0xffffffffL)) + { fprintf(stderr, "%s: Inappropriate network number %08lX\n", progname, netnum); exit(-1); } node = argv[2]; nodelen = strlen(node); - if (nodelen > 12) { + if (nodelen > 12) + { fprintf(stderr, "%s: Node length is too long (> 12).\n", progname); exit(-1); } - for (i = 0; (i < nodelen) && isxdigit(node[i]); i++); + for (i = 0; (i < nodelen) && isxdigit(node[i]); i++) + ; - if (i < nodelen) { + if (i < nodelen) + { fprintf(stderr, "%s: Invalid value in node, must be hex digits.\n", progname); exit(-1); } strcpy(tmpnode, "000000000000"); memcpy(&(tmpnode[12 - nodelen]), node, nodelen); - for (tin = tmpnode, tout = sipx->sipx_node; *tin != '\0'; tin += 2, tout++) { + for (tin = tmpnode, tout = sipx->sipx_node; *tin != '\0'; tin += 2, tout++) + { *tout = (unsigned char) map_char_to_val(*tin); *tout <<= 4; *tout |= (unsigned char) map_char_to_val(*(tin + 1)); } if ((memcmp(sipx->sipx_node, "\0\0\0\0\0\0\0\0", IPX_NODE_LEN) == 0) || - (memcmp(sipx->sipx_node, "\377\377\377\377\377\377", IPX_NODE_LEN) == 0)) { + (memcmp(sipx->sipx_node, "\377\377\377\377\377\377", IPX_NODE_LEN) == 0)) + { fprintf(stderr, "%s: Node is invalid.\n", progname); exit(-1); } @@ -90,7 +103,8 @@ int ipx_add_internal_net(int argc, char **argv) sipx->sipx_type = IPX_FRAME_NONE; sipx->sipx_special = IPX_INTERNAL; s = socket(AF_IPX, SOCK_DGRAM, AF_IPX); - if (s < 0) { + if (s < 0) + { sprintf(errmsg, "%s: socket", progname); perror(errmsg); exit(-1); @@ -98,7 +112,8 @@ int ipx_add_internal_net(int argc, char **argv) sipx->sipx_family = AF_IPX; sipx->sipx_action = IPX_CRTITF; i = 0; - do { + do + { result = ioctl(s, SIOCSIFADDR, &id); i++; } @@ -107,18 +122,19 @@ int ipx_add_internal_net(int argc, char **argv) if (result == 0) exit(0); - switch (errno) { + switch (errno) + { case EEXIST: fprintf(stderr, "%s: Primary network already selected.\n", progname); break; case EADDRINUSE: - fprintf(stderr, "%s: Network number (%08lX) already in use.\n", - progname, htonl(sipx->sipx_network)); + fprintf(stderr, "%s: Network number (%08X) already in use.\n", + progname, (u_int32_t)htonl(sipx->sipx_network)); break; case EAGAIN: fprintf(stderr, - "%s: Insufficient memory to create internal net.\n", + "%s: Insufficient memory to create internal net.\n", progname); break; default: @@ -129,20 +145,23 @@ int ipx_add_internal_net(int argc, char **argv) exit(-1); } -int ipx_del_internal_net(int argc, char **argv) +int +ipx_del_internal_net(int argc, char **argv) { struct sockaddr_ipx *sipx = (struct sockaddr_ipx *) &id.ifr_addr; int s; int result; char errmsg[80]; - if (argc != 1) { + if (argc != 1) + { usage(); } sipx->sipx_network = 0L; sipx->sipx_special = IPX_INTERNAL; s = socket(AF_IPX, SOCK_DGRAM, AF_IPX); - if (s < 0) { + if (s < 0) + { sprintf(errmsg, "%s: socket", progname); perror(errmsg); exit(-1); @@ -153,7 +172,8 @@ int ipx_del_internal_net(int argc, char **argv) if (result == 0) exit(0); - switch (errno) { + switch (errno) + { case ENOENT: fprintf(stderr, "%s: No internal network configured.\n", progname); break; @@ -165,20 +185,24 @@ int ipx_del_internal_net(int argc, char **argv) exit(-1); } -int main(int argc, char **argv) +int +main(int argc, char **argv) { int i; progname = argv[0]; - if (argc < 2) { + if (argc < 2) + { usage(); exit(-1); } - if (strncasecmp(argv[1], "add", 3) == 0) { + if (strncasecmp(argv[1], "add", 3) == 0) + { for (i = 1; i < (argc - 1); i++) argv[i] = argv[i + 1]; ipx_add_internal_net(argc - 1, argv); - } else if (strncasecmp(argv[1], "del", 3) == 0) { + } else if (strncasecmp(argv[1], "del", 3) == 0) + { for (i = 1; i < (argc - 1); i++) argv[i] = argv[i + 1]; ipx_del_internal_net(argc - 1, argv); diff --git a/man/ipx_route.8 b/ipx-1.0/ipx_route.8 similarity index 100% rename from man/ipx_route.8 rename to ipx-1.0/ipx_route.8 diff --git a/ipx-1.0/ipx_route.c b/ipx-1.0/ipx_route.c index bdb4381..47df63b 100644 --- a/ipx-1.0/ipx_route.c +++ b/ipx-1.0/ipx_route.c @@ -11,28 +11,33 @@ #include #include #include -#include +#include "kernel/ipx.h" #include #include #include -#include +#include "kernel/route.h" static struct rtentry rd; static char *progname; -int map_char_to_val(char dig) +int +map_char_to_val(char dig) { char digit = tolower(dig); - if ((digit >= '0') && (digit <= '9')) { + if ((digit >= '0') && (digit <= '9')) + { return digit - '0'; - } else if ((digit >= 'a') && (digit <= 'f')) { + } else if ((digit >= 'a') && (digit <= 'f')) + { return (10 + (digit - 'a')); - } else { + } else + { return 0; } } -void usage(void) +void +usage(void) { fprintf(stderr, "Usage: %s add network(hex) router_network(hex) router_node(hex)\n\ @@ -40,7 +45,8 @@ Usage: %s del network(hex)\n", progname, progname); exit(-1); } -int ipx_add_route(int argc, char **argv) +int +ipx_add_route(int argc, char **argv) { /* Router */ struct sockaddr_ipx *sr = (struct sockaddr_ipx *) &rd.rt_gateway; @@ -62,7 +68,8 @@ int ipx_add_route(int argc, char **argv) /* Network Number */ netnum = strtoul(argv[1], (char **) NULL, 16); - if ((netnum == 0xffffffffL) || (netnum == 0L)) { + if ((netnum == 0xffffffffL) || (netnum == 0L)) + { fprintf(stderr, "%s: Inappropriate network number %08lX\n", progname, netnum); exit(-1); @@ -72,7 +79,8 @@ int ipx_add_route(int argc, char **argv) /* Router Network Number */ netnum = strtoul(argv[2], (char **) NULL, 16); - if ((netnum == 0xffffffffL) || (netnum == 0L)) { + if ((netnum == 0xffffffffL) || (netnum == 0L)) + { fprintf(stderr, "%s: Inappropriate network number %08lX\n", progname, netnum); exit(-1); @@ -82,40 +90,47 @@ int ipx_add_route(int argc, char **argv) /* Router Node */ node = argv[3]; nodelen = strlen(node); - if (nodelen > 12) { + if (nodelen > 12) + { fprintf(stderr, "%s: Node length is too long (> 12).\n", progname); exit(-1); } - for (i = 0; (i < nodelen) && isxdigit(node[i]); i++); + for (i = 0; (i < nodelen) && isxdigit(node[i]); i++) + ; - if (i < nodelen) { + if (i < nodelen) + { fprintf(stderr, "%s: Invalid value in node, must be hex digits.\n", progname); exit(-1); } strcpy(tmpnode, "000000000000"); memcpy(&(tmpnode[12 - nodelen]), node, nodelen); - for (tin = tmpnode, tout = sr->sipx_node; *tin != '\0'; tin += 2, tout++) { + for (tin = tmpnode, tout = sr->sipx_node; *tin != '\0'; tin += 2, tout++) + { *tout = (unsigned char) map_char_to_val(*tin); *tout <<= 4; *tout |= (unsigned char) map_char_to_val(*(tin + 1)); } if ((memcmp(sr->sipx_node, "\0\0\0\0\0\0\0\0", IPX_NODE_LEN) == 0) || - (memcmp(sr->sipx_node, "\377\377\377\377\377\377", IPX_NODE_LEN) == 0)) { + (memcmp(sr->sipx_node, "\377\377\377\377\377\377", IPX_NODE_LEN) == 0)) + { fprintf(stderr, "%s: Node (%s) is invalid.\n", progname, tmpnode); exit(-1); } s = socket(AF_IPX, SOCK_DGRAM, AF_IPX); - if (s < 0) { + if (s < 0) + { sprintf(errmsg, "%s: socket", progname); perror(errmsg); exit(-1); } sr->sipx_family = st->sipx_family = AF_IPX; i = 0; - do { + do + { result = ioctl(s, SIOCADDRT, &rd); i++; } @@ -124,10 +139,11 @@ int ipx_add_route(int argc, char **argv) if (result == 0) exit(0); - switch (errno) { + switch (errno) + { case ENETUNREACH: - fprintf(stderr, "%s: Router network (%08lX) not reachable.\n", - progname, htonl(sr->sipx_network)); + fprintf(stderr, "%s: Router network (%08X) not reachable.\n", + progname, (u_int32_t)htonl(sr->sipx_network)); break; default: sprintf(errmsg, "%s: ioctl", progname); @@ -137,7 +153,8 @@ int ipx_add_route(int argc, char **argv) exit(-1); } -int ipx_del_route(int argc, char **argv) +int +ipx_del_route(int argc, char **argv) { /* Router */ struct sockaddr_ipx *sr = (struct sockaddr_ipx *) &rd.rt_gateway; @@ -148,13 +165,15 @@ int ipx_del_route(int argc, char **argv) unsigned long netnum; char errmsg[80]; - if (argc != 2) { + if (argc != 2) + { usage(); } rd.rt_flags = RTF_GATEWAY; /* Network Number */ netnum = strtoul(argv[1], (char **) NULL, 16); - if ((netnum == 0xffffffffL) || (netnum == 0L)) { + if ((netnum == 0xffffffffL) || (netnum == 0L)) + { fprintf(stderr, "%s: Inappropriate network number %08lX.\n", progname, netnum); exit(-1); @@ -163,7 +182,8 @@ int ipx_del_route(int argc, char **argv) st->sipx_family = sr->sipx_family = AF_IPX; s = socket(AF_IPX, SOCK_DGRAM, AF_IPX); - if (s < 0) { + if (s < 0) + { sprintf(errmsg, "%s: socket", progname); perror(errmsg); exit(-1); @@ -172,7 +192,8 @@ int ipx_del_route(int argc, char **argv) if (result == 0) exit(0); - switch (errno) { + switch (errno) + { case ENOENT: fprintf(stderr, "%s: Route not found for network %08lX.\n", progname, netnum); @@ -189,20 +210,24 @@ int ipx_del_route(int argc, char **argv) exit(-1); } -int main(int argc, char **argv) +int +main(int argc, char **argv) { int i; progname = argv[0]; - if (argc < 2) { + if (argc < 2) + { usage(); exit(-1); } - if (strncasecmp(argv[1], "add", 3) == 0) { + if (strncasecmp(argv[1], "add", 3) == 0) + { for (i = 1; i < (argc - 1); i++) argv[i] = argv[i + 1]; ipx_add_route(argc - 1, argv); - } else if (strncasecmp(argv[1], "del", 3) == 0) { + } else if (strncasecmp(argv[1], "del", 3) == 0) + { for (i = 1; i < (argc - 1); i++) argv[i] = argv[i + 1]; ipx_del_route(argc - 1, argv); diff --git a/ipxdump/Makefile b/ipxdump/Makefile index b67fab8..08372dd 100644 --- a/ipxdump/Makefile +++ b/ipxdump/Makefile @@ -1,6 +1,6 @@ EXEC= ipxdump ipxparse -CFLAGS= -Wall -O2 +CFLAGS= -Wall -O2 -I../include OBJECTS= ipxutil.o all: $(EXEC) diff --git a/ipxdump/ipxdump.c b/ipxdump/ipxdump.c index 4844865..69744fe 100644 --- a/ipxdump/ipxdump.c +++ b/ipxdump/ipxdump.c @@ -21,26 +21,27 @@ #include #include #include -#include +#include #include #include -#include +#include #include -#include -#include -#include +#include +#include #include #include #include #include "ipxutil.h" -struct ipx_address { +struct ipx_address +{ unsigned long net; unsigned char node[IPX_NODE_LEN]; unsigned short sock; }; -struct ipx_packet { +struct ipx_packet +{ unsigned short ipx_checksum; #define IPX_NO_CHECKSUM 0xFFFF unsigned short ipx_pktsize; @@ -61,15 +62,18 @@ void handle_frame(unsigned char *buf, int length, struct sockaddr *saddr); void handle_ipx(char *frame, unsigned char *buf); static int filter = 0; +static int allframes = 0; static IPXNode filter_node; static int exit_request = 0; -static void int_handler() +static void +int_handler() { exit_request = 1; } -void main(int argc, char *argv[]) +void +main(int argc, char *argv[]) { int sd; struct ifreq ifr, oldifr; @@ -81,14 +85,30 @@ void main(int argc, char *argv[]) signal(SIGINT, int_handler); - if (argc > 1) { - if (ipx_sscanf_node(argv[1], filter_node) != 0) { - fprintf(stderr, "usage: %s [node]\n", argv[0]); + while (1) { + int opt; + + opt = getopt(argc, argv, "r"); + if (opt == -1) break; + switch (opt) { + case 'r':allframes = 1; break; + case ':':; + case '?':break; + default: printf("?? unknown option returned by getopt\n"); + break; + } + } + if (optind < argc) + { + if (ipx_sscanf_node(argv[optind], filter_node) != 0) + { + fprintf(stderr, "usage: %s [-a] [node]\n", argv[0]); exit(1); } filter = 1; } - if ((sd = socket(AF_INET, SOCK_PACKET, htons(ETH_P_ALL))) < 0) { + if ((sd = socket(AF_INET, SOCK_PACKET, htons(ETH_P_ALL))) < 0) + { perror("Can't get socket"); fprintf(stderr, "You must run %s as root\n", argv[0]); exit(1); @@ -96,7 +116,8 @@ void main(int argc, char *argv[]) /* SET PROMISC */ strcpy(oldifr.ifr_name, device); - if (ioctl(sd, SIOCGIFFLAGS, &oldifr) < 0) { + if (ioctl(sd, SIOCGIFFLAGS, &oldifr) < 0) + { close(sd); perror("Can't get flags"); exit(2); @@ -105,12 +126,14 @@ void main(int argc, char *argv[]) ifr = oldifr; ifr.ifr_flags |= IFF_PROMISC; - if (ioctl(sd, SIOCSIFFLAGS, &ifr) < 0) { + if (ioctl(sd, SIOCSIFFLAGS, &ifr) < 0) + { close(sd); perror("Can't set flags"); exit(3); } - while (exit_request == 0) { + while (exit_request == 0) + { /* This is the main data-gathering loop; keep it small and fast */ sizeaddr = sizeof(saddr); @@ -118,11 +141,23 @@ void main(int argc, char *argv[]) &saddr, &sizeaddr); if (length < 0) continue; - handle_frame(buf, length, &saddr); + if (allframes) { + unsigned char* ptr = buf; + if (filter) { + if (memcmp(filter_node, buf, 6)&&memcmp(filter_node, buf+6, 6)) + continue; + } + printf("raweth "); + while (length--) printf("%02X", *ptr++); + printf("\n"); + } else { + handle_frame(buf, length, &saddr); + } } /* This should be rewritten to cooperate with other net tools */ - if (ioctl(sd, SIOCSIFFLAGS, &oldifr) < 0) { + if (ioctl(sd, SIOCSIFFLAGS, &oldifr) < 0) + { close(sd); perror("Can't set flags"); exit(4); @@ -131,7 +166,8 @@ void main(int argc, char *argv[]) exit(0); } -void handle_ipx(char *frame, unsigned char *buf) +void +handle_ipx(char *frame, unsigned char *buf) { int i; struct ipx_packet *h = (struct ipx_packet *) buf; @@ -151,32 +187,38 @@ void handle_ipx(char *frame, unsigned char *buf) d_addr.sipx_port = h->ipx_dest.sock; d_addr.sipx_network = h->ipx_dest.net; - if (filter != 0) { + if (filter != 0) + { if ((memcmp(filter_node, s_addr.sipx_node, sizeof(filter_node)) != 0) && (memcmp(filter_node, d_addr.sipx_node, - sizeof(filter_node)) != 0)) { + sizeof(filter_node)) != 0)) + { /* Not for us */ return; } } printf("%s ", frame); - for (i = 0; i < length; i++) { + for (i = 0; i < length; i++) + { printf("%2.2X", buf[i]); } printf("\n"); - if (!isatty(STDOUT_FILENO)) { + if (!isatty(STDOUT_FILENO)) + { fflush(stdout); } } -void handle_other(unsigned char *buf, int length, struct sockaddr *saddr) +void +handle_other(unsigned char *buf, int length, struct sockaddr *saddr) { struct ethhdr *eth = (struct ethhdr *) buf; unsigned char *p = &(buf[sizeof(struct ethhdr)]); - if (ntohs(eth->h_proto) < 1536) { + if (ntohs(eth->h_proto) < 1536) + { /* This is a magic hack to spot IPX packets. Older * Novell breaks the protocol design and runs IPX over * 802.3 without an 802.2 LLC layer. We look for FFFF @@ -184,28 +226,33 @@ void handle_other(unsigned char *buf, int length, struct sockaddr *saddr) * for fault tolerant netware but does for the rest. */ - if (*(unsigned short *) p == 0xffff) { + if (*(unsigned short *) p == 0xffff) + { handle_ipx("802.3", p); return; } if ((*(unsigned short *) p == htons(0xe0e0)) - && (p[2] == 0x03)) { + && (p[2] == 0x03)) + { handle_ipx("802.2", p + 3); return; } - if (memcmp(p, "\252\252\003\000\000\000\201\067", 8) == 0) { + if (memcmp(p, "\252\252\003\000\000\000\201\067", 8) == 0) + { handle_ipx("snap", p + 8); return; } } } -void handle_frame(unsigned char *buf, int length, struct sockaddr *saddr) +void +handle_frame(unsigned char *buf, int length, struct sockaddr *saddr) { /* Ethernet packet type ID field */ unsigned short packet_type = ((struct ethhdr *) buf)->h_proto; - switch (packet_type) { - case __constant_ntohs(ETH_P_IPX): + switch (htons(packet_type)) + { + case ETH_P_IPX: handle_ipx("EtherII", &(buf[sizeof(struct ethhdr)])); break; default: diff --git a/ipxdump/ipxparse.c b/ipxdump/ipxparse.c index 6f3562f..04a828a 100644 --- a/ipxdump/ipxparse.c +++ b/ipxdump/ipxparse.c @@ -21,29 +21,34 @@ #include #include #include -#include +#include #include #include -#include +#include #include -#include -#include -#include +#include +#include #include #include #include #include #include "ipxutil.h" +#define __u8 u_int8_t +#define __u16 u_int16_t +#define __u32 u_int32_t + #define DUMPALLSAPS /* #define if you want to dump all SAP's */ -struct ipx_address { +struct ipx_address +{ unsigned long net; unsigned char node[IPX_NODE_LEN]; unsigned short sock; }; -struct ipx_packet { +struct ipx_packet +{ unsigned short ipx_checksum; #define IPX_NO_CHECKSUM 0xFFFF unsigned short ipx_pktsize; @@ -63,7 +68,8 @@ struct ipx_packet { #define NCP_REQUEST (0x2222) #define NCP_DEALLOC_SLOT_REQUEST (0x5555) -struct ncp_request_header { +struct ncp_request_header +{ __u16 type __attribute__((packed)); __u8 sequence __attribute__((packed)); __u8 conn_low __attribute__((packed)); @@ -76,7 +82,8 @@ struct ncp_request_header { #define NCP_REPLY (0x3333) #define NCP_POSITIVE_ACK (0x9999) -struct ncp_reply_header { +struct ncp_reply_header +{ __u16 type __attribute__((packed)); __u8 sequence __attribute__((packed)); __u8 conn_low __attribute__((packed)); @@ -89,7 +96,8 @@ struct ncp_reply_header { #define NCP_BURST_PACKET (0x7777) -struct ncp_burst_header { +struct ncp_burst_header +{ __u16 type __attribute__((packed)); __u8 system_flags __attribute__((packed)); __u8 stream_type __attribute__((packed)); @@ -120,29 +128,37 @@ int handle_burst(struct sockaddr_ipx *source, /* SAP Query structure (returned in sap_packet as an array) * NBO == Network Byte Order) */ -typedef struct saps { +typedef struct saps +{ __u16 serverType __attribute__((packed)); /* NBO */ __u8 serverName[SAP_MAX_SERVER_NAME_LENGTH] __attribute__((packed)); struct ipx_address serverAddress __attribute__((packed)); __u16 serverHops __attribute__((packed)); /* NBO */ -} SAPS; +} +SAPS; /* General Service/Nearest Server Response SAP packet */ -union sap_packet { +union sap_packet +{ unsigned short sapOperation; - struct sap_query { + struct sap_query + { __u16 sapOperation __attribute__((packed)); __u16 serverType __attribute__((packed)); - } query; - struct sap_response { + } + query; + struct sap_response + { __u16 sapOperation __attribute__((packed)); /* each SAP can has a max of SAP_MAX_SAPS_PER_PACKET packets */ SAPS sap[SAP_MAX_SAPS_PER_PACKET] __attribute__((packed)); - } response; + } + response; }; /* print out one SAP record */ -static void print_sap(FILE * file, SAPS * sapp) +static void +print_sap(FILE * file, SAPS * sapp) { fprintf(file, " Name:%s, serverType 0x%x, ", sapp->serverName, @@ -155,7 +171,8 @@ static void print_sap(FILE * file, SAPS * sapp) fprintf(file, " (Hops %d)\n", ntohs(sapp->serverHops)); } -void handle_ipx(unsigned char *buf, int length, char *frame, int no) +void +handle_ipx(unsigned char *buf, int length, char *frame, int no) { struct ipx_packet *h = (struct ipx_packet *) buf; struct sockaddr_ipx s_addr; @@ -183,11 +200,13 @@ void handle_ipx(unsigned char *buf, int length, char *frame, int no) printf("\n"); if (handle_burst(&s_addr, &d_addr, buf + sizeof(struct ipx_packet), - length - sizeof(struct ipx_packet), no) != 0) { + length - sizeof(struct ipx_packet), no) != 0) + { return; } if ((ntohs(s_addr.sipx_port) == 0x451) - || (ntohs(d_addr.sipx_port) == 0x451)) { + || (ntohs(d_addr.sipx_port) == 0x451)) + { handle_ncp(&s_addr, &d_addr, buf + sizeof(struct ipx_packet), length - sizeof(struct ipx_packet), no); } else @@ -198,21 +217,25 @@ void handle_ipx(unsigned char *buf, int length, char *frame, int no) printf(" type 0x05 (SPX sequenced packet)\n"); else if (h->ipx_type == 0x14) printf(" type 0x14 (propogated Client-NetBios)\n"); - else { + else + { hbo_dsock = ntohs(d_addr.sipx_port); - if (hbo_dsock == 0x452) { /* SAP */ + if (hbo_dsock == 0x452) /* SAP */ + { sappacket = (union sap_packet *) (buf + sizeof(struct ipx_packet)); hbo_sapop = ntohs(sappacket->sapOperation); - if ((hbo_sapop == 0x01) || (hbo_sapop == 0x03)) { + if ((hbo_sapop == 0x01) || (hbo_sapop == 0x03)) + { printf(" type 0x%x, SAP op:0x%x %s Query, " "serverType 0x%x wanted\n", h->ipx_type, hbo_sapop, - (hbo_sapop == 0x01) ? "General Service" : - (hbo_sapop == 0x03) ? "Nearest Server" : + (hbo_sapop == 0x01) ? "General Service" : + (hbo_sapop == 0x03) ? "Nearest Server" : "Error", - ntohs(sappacket->query.serverType)); - } else { + ntohs(sappacket->query.serverType)); + } else + { int hops; hops = ntohs(sappacket-> @@ -228,18 +251,20 @@ void handle_ipx(unsigned char *buf, int length, char *frame, int no) ? "[Shutdown]" : ""); /* Service ending */ - if (hops >= SAP_SHUTDOWN) { + if (hops >= SAP_SHUTDOWN) + { print_sap(stdout, - sappacket->response.sap); + sappacket->response.sap); } #ifdef DUMPALLSAPS /* If you want to dump all SAP's */ - else { + else + { int num_saps; SAPS *sapp; num_saps = (length - - sizeof(struct ipx_packet) + - sizeof(struct ipx_packet) - 2) / sizeof(SAPS); sapp = sappacket->response.sap; @@ -263,13 +288,15 @@ void handle_ipx(unsigned char *buf, int length, char *frame, int no) } -int handle_burst(struct sockaddr_ipx *source, - struct sockaddr_ipx *target, - unsigned char *buf, int length, int no) +int +handle_burst(struct sockaddr_ipx *source, + struct sockaddr_ipx *target, + unsigned char *buf, int length, int no) { struct ncp_burst_header *rq = (struct ncp_burst_header *) buf; - if (rq->type != NCP_BURST_PACKET) { + if (rq->type != NCP_BURST_PACKET) + { return 0; } printf("Burst Packet\n"); @@ -279,22 +306,25 @@ int handle_burst(struct sockaddr_ipx *source, rq->source_conn, rq->dest_conn, (unsigned int) ntohl(rq->packet_sequence)); printf("Send Delay: %08X, Burst Seq: %04X, Ack Seq: %04X\n", - (unsigned int) ntohl(rq->send_delay), ntohs(rq->burst_sequence), + (unsigned int) ntohl(rq->send_delay), ntohs(rq->burst_sequence), ntohs(rq->ack_sequence)); printf("Burst Length: %08X\n", (unsigned int) ntohl(rq->burst_length)); printf("Data Offset: %08X, Data Bytes: %04X, Missing Frags: %04X\n", - (unsigned int) ntohl(rq->data_offset), ntohs(rq->data_bytes), + (unsigned int) ntohl(rq->data_offset), ntohs(rq->data_bytes), ntohs(rq->missing_frags)); - if (ntohs(rq->data_bytes) == 24) { - struct ncp_burst_request { + if (ntohs(rq->data_bytes) == 24) + { + struct ncp_burst_request + { struct ncp_burst_header h __attribute__((packed)); __u32 function __attribute__((packed)); __u32 file_handle __attribute__((packed)); __u8 reserved[8] __attribute__((packed)); __u32 file_offset __attribute__((packed)); __u32 number_of_bytes __attribute__((packed)); - } *brq = (struct ncp_burst_request *) rq; + } + *brq = (struct ncp_burst_request *) rq; printf("Assuming Burst Request:\n"); printf("%s: Handle %08X, Offset %08X, Bytes %08X\n", @@ -307,9 +337,10 @@ int handle_burst(struct sockaddr_ipx *source, return 1; } -void handle_ncp(struct sockaddr_ipx *source, - struct sockaddr_ipx *target, - unsigned char *buf, int length, int no) +void +handle_ncp(struct sockaddr_ipx *source, + struct sockaddr_ipx *target, + unsigned char *buf, int length, int no) { struct ncp_request_header *rq = (struct ncp_request_header *) buf; struct ncp_reply_header *rs = (struct ncp_reply_header *) buf; @@ -321,7 +352,8 @@ void handle_ncp(struct sockaddr_ipx *source, static struct ncp_request_header request_header; static char request_data[5]; - if (ntohs(rq->type) == NCP_REQUEST) { + if (ntohs(rq->type) == NCP_REQUEST) + { /* Request */ printf("NCP request: conn: %-5d, seq: %-3d, task: %-3d, ", rq->conn_low + 256 * rq->conn_high, @@ -334,7 +366,8 @@ void handle_ncp(struct sockaddr_ipx *source, data = buf + sizeof(struct ncp_request_header); data_length = length - sizeof(struct ncp_request_header); - switch (rq->function) { + switch (rq->function) + { case 18: printf("fn: %-3d\n", rq->function); printf("Get Volume Info with Number\n"); @@ -346,7 +379,8 @@ void handle_ncp(struct sockaddr_ipx *source, case 21: printf("fn: %-3d, subfn: %-3d\n", rq->function, data[2]); - switch (data[2]) { + switch (data[2]) + { case 0: printf("Send Broadcast Message\n"); break; @@ -360,7 +394,8 @@ void handle_ncp(struct sockaddr_ipx *source, case 22: printf("fn: %-3d, subfn: %-3d\n", rq->function, data[2]); - switch (data[2]) { + switch (data[2]) + { case 00: printf("Set Directory Handle\n"); break; @@ -404,7 +439,8 @@ void handle_ncp(struct sockaddr_ipx *source, case 23: printf("fn: %-3d, subfn: %-3d\n", rq->function, data[2]); - switch (data[2]) { + switch (data[2]) + { case 17: printf("Get Fileserver Information\n"); break; @@ -527,7 +563,8 @@ void handle_ncp(struct sockaddr_ipx *source, case 87: printf("fn: %-3d, subfn: %-3d\n", rq->function, data[0]); - switch (data[0]) { + switch (data[0]) + { case 1: { unsigned char *p = &(data[0]); @@ -537,7 +574,7 @@ void handle_ncp(struct sockaddr_ipx *source, printf("Search Attributes: %x\n", *(__u16 *) & (p[3])); printf("Return Information Mask: %x\n", - (unsigned int) (*(__u32 *) & (p[5]))); + (unsigned int) (*(__u32 *) & (p[5]))); printf("Desired Access Rights: %x\n", *(__u16 *) & (p[9])); break; @@ -564,10 +601,12 @@ void handle_ncp(struct sockaddr_ipx *source, break; case 97: { - struct INPUT { + struct INPUT + { __u16 proposed_max_size; __u8 security_flag; - } *i = (struct INPUT *) data; + } + *i = (struct INPUT *) data; printf("fn: %-3d\n", rq->function); printf("Get Big Packet NCP Max Packet Size\n"); @@ -579,26 +618,28 @@ void handle_ncp(struct sockaddr_ipx *source, } case 101: { - struct INPUT { + struct INPUT + { __u32 local_conn_id; __u32 local_max_packet_size; __u16 local_target_socket; __u32 local_max_send_size; __u32 local_max_recv_size; - } *i = (struct INPUT *) data; + } + *i = (struct INPUT *) data; printf("fn: %-3d\n", rq->function); printf("Packet Burst Connection Request\n"); - printf("local_conn_id: %lx\n", - ntohl(i->local_conn_id)); - printf("local_max_packet_size: %lx\n", - ntohl(i->local_max_packet_size)); - printf("local_target_socket: %lx\n", - ntohl(i->local_target_socket)); - printf("local_max_send_size: %lx\n", - ntohl(i->local_max_send_size)); - printf("local_max_recv_size: %lx\n", - ntohl(i->local_max_recv_size)); + printf("local_conn_id: %x\n", + (u_int32_t)ntohl(i->local_conn_id)); + printf("local_max_packet_size: %x\n", + (u_int32_t)ntohl(i->local_max_packet_size)); + printf("local_target_socket: %x\n", + (u_int32_t)ntohl(i->local_target_socket)); + printf("local_max_send_size: %x\n", + (u_int32_t)ntohl(i->local_max_send_size)); + printf("local_max_recv_size: %x\n", + (u_int32_t)ntohl(i->local_max_recv_size)); } break; case 104: @@ -617,20 +658,23 @@ void handle_ncp(struct sockaddr_ipx *source, workstation, and tell me whether anything of this makes sense at all. */ - switch (data[0]) { + switch (data[0]) + { case 1: printf("Ping for NDS\n"); break; case 2: { - struct INPUT { + struct INPUT + { __u8 subfunction_code; __u32 fragger_handle; __u32 max_fragment_size; __u32 message_size; __u32 fragment_flag; __u32 verb; - } *i = (struct INPUT *) data; + } + *i = (struct INPUT *) data; printf("Send NDS Fragment Request/Reply\n"); printf("fragger_handle: %lx\n", (unsigned long) i->fragger_handle); @@ -642,7 +686,8 @@ void handle_ncp(struct sockaddr_ipx *source, (unsigned long) i->fragment_flag); printf("verb: %d\n", i->verb); - switch (i->verb) { + switch (i->verb) + { case 1: printf("Resolve Name\n"); break; @@ -899,7 +944,8 @@ void handle_ncp(struct sockaddr_ipx *source, printf("fn: %-3d\n", rq->function); } } - if (ntohs(rs->type) == NCP_REPLY) { + if (ntohs(rs->type) == NCP_REPLY) + { printf("NCP respons: conn: %-5d, seq: %-3d, task: %-3d, ", rs->conn_low + 256 * rs->conn_high, rs->sequence, rs->task); @@ -911,20 +957,25 @@ void handle_ncp(struct sockaddr_ipx *source, if ((memcmp(&request_source, target, sizeof(request_source)) == 0) - && (request_header.sequence == rs->sequence)) { - switch (request_header.function) { + && (request_header.sequence == rs->sequence)) + { + switch (request_header.function) + { case 22: - switch (request_data[2]) { + switch (request_data[2]) + { case 18: { - struct XDATA { + struct XDATA + { __u8 new_directory_handle; __u8 access_rights_mask; - } *x = (struct XDATA *) data; + } + *x = (struct XDATA *) data; printf("new_directory_handle: %x\n", - x->new_directory_handle); + x->new_directory_handle); printf("access_rights_mask: %x\n", - x->access_rights_mask); + x->access_rights_mask); } break; } @@ -935,13 +986,15 @@ void handle_ncp(struct sockaddr_ipx *source, break; case 97: { - struct XDATA { + struct XDATA + { __u16 accepted_max_size; __u16 echo_socket; __u8 security_flag; - } *x = (struct XDATA *) data; + } + *x = (struct XDATA *) data; printf("accepted_max_size: %x\n", - ntohs(x->accepted_max_size)); + ntohs(x->accepted_max_size)); printf("echo_socket: %x\n", ntohs(x->echo_socket)); printf("security_flag: %x\n", @@ -950,44 +1003,55 @@ void handle_ncp(struct sockaddr_ipx *source, break; case 101: { - struct XDATA { + struct XDATA + { __u8 completion_code; __u32 remote_target_id; __u32 remote_max_packet_size; - } *x = (struct XDATA *) data; + } + *x = (struct XDATA *) data; printf("completion_code: %x\n", x->completion_code); - printf("remote_target_id: %lx\n", - ntohl(x->remote_target_id)); - printf("remote_max_packet_size: %lx\n", - ntohl(x->remote_max_packet_size)); + printf("remote_target_id: %x\n", + (u_int32_t)ntohl(x->remote_target_id)); + printf("remote_max_packet_size: %x\n", + (u_int32_t)ntohl(x->remote_max_packet_size)); } break; } } } - if (data == NULL) { + if (data == NULL) + { data = buf; data_length = length; } i = 0; - while (i < data_length) { + while (i < data_length) + { int j; - for (j = i; j < i + 16; j++) { - if (j >= data_length) { + for (j = i; j < i + 16; j++) + { + if (j >= data_length) + { printf(" "); - } else { + } else + { printf("%-2.2X", data[j]); } } printf(" "); - for (j = i; j < i + 16; j++) { - if (j >= data_length) { + for (j = i; j < i + 16; j++) + { + if (j >= data_length) + { break; } - if (isprint(data[j])) { + if (isprint(data[j])) + { printf("%c", data[j]); - } else { + } else + { printf("."); } } @@ -998,7 +1062,8 @@ void handle_ncp(struct sockaddr_ipx *source, } -void main(int argc, char *argv[]) +void +main(int argc, char *argv[]) { unsigned char buf[16384]; unsigned char packet[8192]; @@ -1006,13 +1071,16 @@ void main(int argc, char *argv[]) int len; int i = 1; - while (fgets(buf, sizeof(buf), stdin) != NULL) { - if (strlen(buf) == sizeof(buf) - 1) { + while (fgets(buf, sizeof(buf), stdin) != NULL) + { + if (strlen(buf) == sizeof(buf) - 1) + { fprintf(stderr, "line too long\n"); exit(1); } b = strchr(buf, ' '); - if (b == NULL) { + if (b == NULL) + { fprintf(stderr, "illegal line format\n"); exit(1); } @@ -1020,9 +1088,11 @@ void main(int argc, char *argv[]) b += 1; len = 0; - while ((b[0] != '\0') && (b[1] != '\0')) { + while ((b[0] != '\0') && (b[1] != '\0')) + { unsigned int value; - if (sscanf(b, "%2x", &value) != 1) { + if (sscanf(b, "%2x", &value) != 1) + { fprintf(stderr, "illegal packet\n"); exit(1); } diff --git a/ipxdump/ipxutil.c b/ipxdump/ipxutil.c index d3fba8b..7fe5c4c 100644 --- a/ipxdump/ipxutil.c +++ b/ipxdump/ipxutil.c @@ -27,7 +27,8 @@ #include #include "ipxutil.h" -void ipx_fprint_node(FILE * file, IPXNode node) +void +ipx_fprint_node(FILE * file, IPXNode node) { fprintf(file, "%02X%02X%02X%02X%02X%02X", (unsigned char) node[0], @@ -39,17 +40,20 @@ void ipx_fprint_node(FILE * file, IPXNode node) ); } -void ipx_fprint_network(FILE * file, IPXNet net) +void +ipx_fprint_network(FILE * file, IPXNet net) { fprintf(file, "%08lX", net); } -void ipx_fprint_port(FILE * file, IPXPort port) +void +ipx_fprint_port(FILE * file, IPXPort port) { fprintf(file, "%04X", port); } -void ipx_fprint_saddr(FILE * file, struct sockaddr_ipx *sipx) +void +ipx_fprint_saddr(FILE * file, struct sockaddr_ipx *sipx) { ipx_fprint_network(file, ntohl(sipx->sipx_network)); fprintf(file, ":"); @@ -58,55 +62,66 @@ void ipx_fprint_saddr(FILE * file, struct sockaddr_ipx *sipx) ipx_fprint_port(file, ntohs(sipx->sipx_port)); } -void ipx_print_node(IPXNode node) +void +ipx_print_node(IPXNode node) { ipx_fprint_node(stdout, node); } -void ipx_print_network(IPXNet net) +void +ipx_print_network(IPXNet net) { ipx_fprint_network(stdout, net); } -void ipx_print_port(IPXPort port) +void +ipx_print_port(IPXPort port) { ipx_fprint_port(stdout, port); } -void ipx_print_saddr(struct sockaddr_ipx *sipx) +void +ipx_print_saddr(struct sockaddr_ipx *sipx) { ipx_fprint_saddr(stdout, sipx); } -void ipx_assign_node(IPXNode dest, IPXNode src) +void +ipx_assign_node(IPXNode dest, IPXNode src) { memcpy(dest, src, sizeof(IPXNode)); } -int ipx_node_equal(IPXNode n1, IPXNode n2) +int +ipx_node_equal(IPXNode n1, IPXNode n2) { return memcmp(n1, n2, sizeof(IPXNode)) == 0; } -int ipx_sscanf_node(char *buf, IPXNode node) +int +ipx_sscanf_node(char *buf, IPXNode node) { int i; int n[6]; if ((i = sscanf(buf, "%2x%2x%2x%2x%2x%2x", &(n[0]), &(n[1]), &(n[2]), - &(n[3]), &(n[4]), &(n[5]))) != 6) { + &(n[3]), &(n[4]), &(n[5]))) != 6) + { return -1; } - for (i = 0; i < 6; i++) { + for (i = 0; i < 6; i++) + { node[i] = n[i]; } return 0; } -int ipx_sscanf_net(char *buf, IPXNet * target) +int +ipx_sscanf_net(char *buf, IPXNet * target) { - if (sscanf(buf, "%8lX", target) == 1) { + if (sscanf(buf, "%8lX", target) == 1) + { return 0; } return -1; diff --git a/ipxdump/ipxutil.h b/ipxdump/ipxutil.h index e259a58..3c7a78d 100644 --- a/ipxdump/ipxutil.h +++ b/ipxdump/ipxutil.h @@ -25,7 +25,7 @@ #define __IPXUTIL_H__ #include -#include +#include "kernel/ipx.h" #define IPX_MAX_ERROR (255) #define IPX_THIS_NET (0) diff --git a/lib-shared/Makefile b/lib-shared/Makefile new file mode 100644 index 0000000..f964e20 --- /dev/null +++ b/lib-shared/Makefile @@ -0,0 +1,28 @@ +include ../Makeinit +NCPLIB = libncp.so +NCPLIB_BIN = $(NCPLIB).1.0 +NCPLIB_SONAME = $(NCPLIB).1 +CCFLAGS += -I../include -I. +PIC_FLAG = -fPIC +export PIC_FLAG +CCFLAGS += $(PIC_FLAG) + +vpath %.c ../lib +vpath %.et ../lib + +include ../lib/Makelib + +install: all + rm -f $(LIBSODIR)/$(NCPLIB) + install $(NCPLIB_BIN) $(LIBSODIR) + ldconfig + ln -sf $(NCPLIB_SONAME) $(LIBSODIR)/$(NCPLIB) + +$(NCPLIB): $(NCPLIB_BIN) + rm -f $@ + ln -sf $< $@ + +$(NCPLIB_BIN): $(O_OBJ) $(O_LIB) + $(CC) -shared -o $@ -Wl,-soname=$(NCPLIB_SONAME) $(O_OBJ) -lc + + diff --git a/lib-static-su/Makefile b/lib-static-su/Makefile new file mode 100644 index 0000000..e4cc037 --- /dev/null +++ b/lib-static-su/Makefile @@ -0,0 +1,17 @@ +include ../Makeinit +NCPLIB = libncp.a +NCPLIB_BIN := $(NCPLIB) +CCFLAGS += -I../include -I. +CCFLAGS += -D__MAKE_SULIB__ + +vpath %.c ../lib +vpath %.et ../lib + +include ../lib/Makelib + +install: + +$(NCPLIB_BIN): $(O_OBJ) + ar r $@ $(O_OBJ) + + diff --git a/lib-static/Makefile b/lib-static/Makefile new file mode 100644 index 0000000..fb3b38f --- /dev/null +++ b/lib-static/Makefile @@ -0,0 +1,17 @@ +include ../Makeinit +NCPLIB = libncp.a +NCPLIB_BIN = $(NCPLIB) +CCFLAGS += -I../include -I. + +vpath %.c ../lib +vpath %.et ../lib + +include ../lib/Makelib + +install: all + install $(NCPLIB_BIN) $(LIBADIR) + +$(NCPLIB_BIN): $(O_OBJ) + ar r $@ $(O_OBJ) + + diff --git a/lib/Makefile b/lib/Makefile index 5e73e9f..151fedd 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -2,70 +2,19 @@ # Makefile for the linux ncp-filesystem routines. # -CC = gcc - -ifeq ($(HAVE_ELF),yes) -PIC_FLAG = -fPIC -NCP_LIB = libncp.so.1.0 -LIB_LINK_COMMAND = gcc -shared -Wl,-soname,libncp.so.1 -o $(NCP_LIB) -INSTALL_LIB = install $(NCP_LIB) -m 755 /lib; \ - ln -sf $(NCP_LIB) /lib/libncp.so.1; \ - ldconfig -export PIC_FLAG -else -NCP_LIB = libncp.a -LIB_LINK_COMMAND = ar r libncp.a -endif - -CFLAGS += $(PIC_FLAG) - default: make -C .. -all: libcom_err.a ncplib_err.o $(NCP_LIB) +all: install: - $(INSTALL_LIB) - -ncplib.o: ncplib.c ncplib_err.h - $(CC) $(CFLAGS) -c ncplib.c - -COM_ERR_CFILES = com_err/com_err.c com_err/error_message.c com_err/et_name.c \ - com_err/init_et.c -COM_ERR_OFILES = com_err/com_err.o com_err/error_message.o com_err/et_name.o \ - com_err/init_et.o - -libcom_err.a: $(COM_ERR_CFILES) - make -C com_err - -$(NCP_LIB): ncplib.o ncplib_err.o libcom_err.a - $(LIB_LINK_COMMAND) ncplib.o ncplib_err.o $(COM_ERR_OFILES) - ln -sf libncp.so.1.0 libncp.so.1 - ln -sf libncp.so.1 libncp.so - export LD_LIBRARY_PATH=`pwd`:LD_LIBRARY_PATH - -ncplib_err.o: ncplib_err.h ncplib_err.c - $(CC) $(CFLAGS) -c ncplib_err.c - -ncplib_err.h: ncplib_err.et - com_err/compile_et ncplib_err - ln -sf ../lib/ncplib_err.h ../include/ncplib_err.h - -ncplib_err.c: ncplib_err.et - com_err/compile_et ncplib_err - -dep: ncplib_err.h - make -C com_err dep - $(CPP) -M $(INCLUDES) *.c > .depend + make -C com_err install clean: make -C com_err clean - rm -f *.o *~ ncplib_err.[ch] ../include/ncplib_err.h - rm -f libncp.* -mrproper: clean +mrproper: make -C com_err mrproper - rm -f $(UTILS) .depend $(DISTFILE) # # include a dependency file if one exists diff --git a/lib/Makelib b/lib/Makelib new file mode 100644 index 0000000..2d545c0 --- /dev/null +++ b/lib/Makelib @@ -0,0 +1,61 @@ +# +# Makefile for the linux ncp-filesystem routines. +# + +BASE_OBJ = ncplib.o +ifdef NDS_SUPPORT +NDS_OBJ = ndslib.o mpilib.o +BASE_OBJ += ndscrypt.o +endif +ifdef SIGNATURES +BASE_OBJ += ncpsign.o +endif + +O_OBJ := $(BASE_OBJ) $(NDS_OBJ) ncplib_err.o + +all: $(NCPLIB) + +$(NDS_OBJ): %.o: %.c ncplib_err.h + $(CC) $(CFLAGS) $(CCFLAGS) -DPORTABLE -DSMITH -DUNIT32 -DMUNIT16 -o $@ -c $< + +$(BASE_OBJ): %.o: %.c ncplib_err.h + $(CC) $(CFLAGS) $(CCFLAGS) -o $@ -c $< + +COM_ERR = ../lib/com_err + +COM_ERR_CFILES = $(COM_ERR)/com_err.c $(COM_ERR)/error_message.c \ + $(COM_ERR)/et_name.c $(COM_ERR)/init_et.c +COM_ERR_OFILES = $(COM_ERR)/com_err.o $(COM_ERR)/error_message.o \ + $(COM_ERR)/et_name.o $(COM_ERR)/init_et.o + +O_OBJ += $(COM_ERR_OFILES) + +$(COM_ERR_OFILES): %.o: %.c + make -C $(COM_ERR) + +ncplib_err.o: ncplib_err.h ncplib_err.c + $(CC) $(CFLAGS) $(CCFLAGS) -c ncplib_err.c + +ncplib_err.h ncplib_err.c: ncplib_err.et + $(COM_ERR)/compile_et ../lib/ncplib_err + +dep: ncplib_err.h + make -C $(COM_ERR) dep + $(CPP) -M $(INCLUDES) *.c > .depend + +clean: + make -C $(COM_ERR) clean + rm -f *.o *~ ncplib_err.[ch] ../include/ncplib_err.h + rm -f libncp.* libcom_err.a + +mrproper: clean + make -C $(COM_ERR) mrproper + rm -f $(UTILS) .depend $(DISTFILE) + +# +# include a dependency file if one exists +# +ifeq (.depend,$(wildcard .depend)) +include .depend +endif + diff --git a/lib/com_err/Makefile b/lib/com_err/Makefile index eeafb15..9a415bd 100644 --- a/lib/com_err/Makefile +++ b/lib/com_err/Makefile @@ -5,14 +5,13 @@ OBJECTS = com_err.o error_message.o et_name.o init_et.o CFLAGS = -Wall -O2 $(PIC_FLAG) -all: ../libcom_err.a - -../libcom_err.a: $(OBJECTS) - ar r ../libcom_err.a $(OBJECTS) +all: $(OBJECTS) dep: $(CPP) -M $(INCLUDES) *.c > .depend +install: + clean: rm -f *.o ../libcom_err.a diff --git a/lib/com_err/com_err.c b/lib/com_err/com_err.c index f5ab310..e1a0158 100644 --- a/lib/com_err/com_err.c +++ b/lib/com_err/com_err.c @@ -17,25 +17,28 @@ static void #ifdef __STDC__ - default_com_err_proc(const char *whoami, errcode_t code, const - char *fmt, va_list args) +default_com_err_proc(const char *whoami, errcode_t code, const + char *fmt, va_list args) #else - default_com_err_proc(whoami, code, fmt, args) +default_com_err_proc(whoami, code, fmt, args) const char *whoami; errcode_t code; const char *fmt; va_list args; #endif { - if (whoami) { + if (whoami) + { fputs(whoami, stderr); fputs(": ", stderr); } - if (code) { + if (code) + { fputs(error_message(code), stderr); fputs(" ", stderr); } - if (fmt) { + if (fmt) + { vfprintf(stderr, fmt, args); } /* should do this only on a tty in raw mode */ @@ -53,10 +56,12 @@ typedef void (*errf) (); errf com_err_hook = default_com_err_proc; #ifdef __STDC__ -void com_err_va(const char *whoami, errcode_t code, const char *fmt, - va_list args) +void +com_err_va(const char *whoami, errcode_t code, const char *fmt, + va_list args) #else -void com_err_va(whoami, code, fmt, args) +void +com_err_va(whoami, code, fmt, args) const char *whoami; errcode_t code; const char *fmt; @@ -67,12 +72,14 @@ va_list args; } #ifndef VARARGS -void com_err(const char *whoami, - errcode_t code, - const char *fmt,...) +void +com_err(const char *whoami, + errcode_t code, + const char *fmt,...) { #else -void com_err(va_alist) +void +com_err(va_alist) va_dcl { const char *whoami, *fmt; diff --git a/lib/com_err/compile_et b/lib/com_err/compile_et index 872e147..b361717 100755 --- a/lib/com_err/compile_et +++ b/lib/com_err/compile_et @@ -2,7 +2,7 @@ # # AWK=/usr/bin/awk -DIR=com_err/ +DIR=../lib/com_err ROOT=`echo $1 | sed -e s/.et$//` BASE=`basename $ROOT` diff --git a/lib/com_err/error_message.c b/lib/com_err/error_message.c index d3e0c55..ee2f049 100644 --- a/lib/com_err/error_message.c +++ b/lib/com_err/error_message.c @@ -24,10 +24,10 @@ struct et_list *_et_list = (struct et_list *) NULL; #ifdef __STDC__ const char * - error_message(errcode_t code) +error_message(errcode_t code) #else const char * - error_message(code) +error_message(code) errcode_t code; #endif { @@ -39,7 +39,8 @@ errcode_t code; offset = code & ((1 << ERRCODE_RANGE) - 1); table_num = code - offset; - if (!table_num) { + if (!table_num) + { #ifdef HAS_SYS_ERRLIST if (offset < sys_nerr) return (sys_errlist[offset]); @@ -53,8 +54,10 @@ errcode_t code; goto oops; #endif } - for (et = _et_list; et; et = et->next) { - if (et->table->base == table_num) { + for (et = _et_list; et; et = et->next) + { + if (et->table->base == table_num) + { /* This is the right table */ if (et->table->n_msgs <= offset) goto oops; @@ -63,17 +66,21 @@ errcode_t code; } oops: strcpy(buffer, "Unknown code "); - if (table_num) { + if (table_num) + { strcat(buffer, error_table_name(table_num)); strcat(buffer, " "); } - for (cp = buffer; *cp; cp++); - if (offset >= 100) { + for (cp = buffer; *cp; cp++) + ; + if (offset >= 100) + { *cp++ = '0' + offset / 100; offset %= 100; started++; } - if (started || offset >= 10) { + if (started || offset >= 10) + { *cp++ = '0' + offset / 10; offset %= 10; } diff --git a/lib/com_err/error_table.h b/lib/com_err/error_table.h index 06c410a..ab498fa 100644 --- a/lib/com_err/error_table.h +++ b/lib/com_err/error_table.h @@ -11,12 +11,14 @@ #define const #endif -struct error_table { +struct error_table +{ char const *const *msgs; long base; int n_msgs; }; -struct et_list { +struct et_list +{ struct et_list *next; const struct error_table *table; }; diff --git a/lib/com_err/et_name.c b/lib/com_err/et_name.c index c1f225b..75617d7 100644 --- a/lib/com_err/et_name.c +++ b/lib/com_err/et_name.c @@ -14,7 +14,7 @@ static const char char_set[] = static char buf[6]; const char * - error_table_name(num) +error_table_name(num) int num; { int ch; @@ -27,7 +27,8 @@ int num; /* num = ?? ??? ??? aaa aaa bbb bbb ccc ccc ddd ddd */ num &= 077777777; /* num = 00 000 000 aaa aaa bbb bbb ccc ccc ddd ddd */ - for (i = 4; i >= 0; i--) { + for (i = 4; i >= 0; i--) + { ch = (num >> BITS_PER_CHAR * i) & ((1 << BITS_PER_CHAR) - 1); if (ch != 0) *p++ = char_set[ch - 1]; diff --git a/lib/com_err/init_et.c b/lib/com_err/init_et.c index 1ac3675..8978434 100644 --- a/lib/com_err/init_et.c +++ b/lib/com_err/init_et.c @@ -23,7 +23,8 @@ #define const #endif -struct foobar { +struct foobar +{ struct et_list etl; struct error_table et; }; @@ -31,9 +32,11 @@ struct foobar { extern struct et_list *_et_list; #ifdef __STDC__ -int init_error_table(const char *const *msgs, int base, int count) +int +init_error_table(const char *const *msgs, int base, int count) #else -int init_error_table(msgs, base, count) +int +init_error_table(msgs, base, count) const char *const *msgs; int base; int count; diff --git a/lib/mpilib.c b/lib/mpilib.c new file mode 100644 index 0000000..0ac29ce --- /dev/null +++ b/lib/mpilib.c @@ -0,0 +1,1881 @@ +/* C source code for multiprecision arithmetic library routines. + Implemented Nov 86 by Philip Zimmermann + Last revised 27 Nov 91 by PRZ + + 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. The use of this + cryptographic software for developing weapon systems is expressly + forbidden. + + These routines implement all of the multiprecision arithmetic + necessary for number-theoretic cryptographic algorithms such as + ElGamal, Diffie-Hellman, Rabin, or factoring studies for large + composite numbers, as well as Rivest-Shamir-Adleman (RSA) public + key cryptography. + + 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. + + + The internal representation for these extended precision integer + "registers" is an array of "units". A unit is a machine word, which + is either an 8-bit byte, a 16-bit unsigned integer, or a 32-bit + unsigned integer, depending on the machine's word size. For example, + an IBM PC or AT uses a unit size of 16 bits. To perform arithmetic + on these huge precision integers, we pass pointers to these unit + arrays to various subroutines. A pointer to an array of units is of + type unitptr. This is a pointer to a huge integer "register". + + When calling a subroutine, we always pass a pointer to the BEGINNING + of the array of units, regardless of the byte order of the machine. + On a lowbyte-first machine, such as the Intel 80x86, this unitptr + points to the LEAST significant unit, and the array of units increases + significance to the right. On a highbyte-first machine, such as the + Motorola 680x0, this unitptr points to the MOST significant unit, and + the array of units decreases significance to the right. + + Modified 8 Apr 92 - HAJK + Implement new VAX/VMS primitive support. + + Modified 30 Sep 92 -Castor Fu + Upgraded PORTABLE support to allow sizeof(unit) == sizeof(long) + + Modified 28 Nov 92 - Thad Smith + Added Smith modmult, generalized non-portable support. +*/ + +/* #define COUNTMULTS */ /* count modmults for performance studies */ + +#ifdef DEBUG +#ifdef MSDOS +#ifdef __GO32__ /* DJGPP */ +#include +#else +#include +#endif /* __GO32__ */ +#define poll_for_break() {while (kbhit()) getch();} +#endif /* MSDOS */ +#endif /* DEBUG */ + +#ifndef poll_for_break +#define poll_for_break() /* stub */ +#endif + +#include "mpilib.h" + +#ifdef mp_smula +#ifdef mp_smul + Error: Both mp_smula and mp_smul cannot be defined. +#else +#define mp_smul mp_smula +#endif +#endif + +/* set macros for MULTUNIT */ +#ifdef MUNIT8 +#define MULTUNITSIZE 8 +typedef unsigned char MULTUNIT; +#ifdef UNIT8 +#define MULTUNIT_SIZE_SAME +#endif +#else /* not MUNIT8 */ +#ifdef MUNIT32 +#define MULTUNITSIZE 32 +typedef unsigned long MULTUNIT; +#ifdef UNIT32 +#define MULTUNIT_SIZE_SAME +#else +/* #error is not portable, this has the same effect */ +#include "UNITSIZE cannot be smaller than MULTUNITSIZE" +#endif +#else /* assume MUNIT16 */ +#define MULTUNITSIZE 16 +typedef unsigned short MULTUNIT; +#ifdef UNIT16 +#define MULTUNIT_SIZE_SAME +#endif /* UNIT16 */ +#ifdef UNIT8 +#include "UNITSIZE cannot be smaller than MULTUNITSIZE" +#endif /* UNIT8 */ +#endif /* MUNIT32 */ +#endif /* MUNIT8 */ + +#define MULTUNIT_msb ((MULTUNIT)1 << (MULTUNITSIZE-1)) /* msb of MULTUNIT */ +#define DMULTUNIT_msb (1L << (2*MULTUNITSIZE-1)) +#define MULTUNIT_mask ((MULTUNIT)((1L << MULTUNITSIZE)-1)) +#define MULTUNITs_perunit (UNITSIZE/MULTUNITSIZE) + + +void mp_smul (MULTUNIT *prod, MULTUNIT *multiplicand, MULTUNIT multiplier); +void mp_dmul (unitptr prod, unitptr multiplicand, unitptr multiplier); + +short global_precision = 0; /* units of precision for all routines */ +/* global_precision is the unit precision last set by set_precision. + Initially, set_precision() should be called to define global_precision + before using any of these other multiprecision library routines. + i.e.: set_precision(MAX_UNIT_PRECISION); +*/ + +/*************** multiprecision library primitives ****************/ +/* The following portable C primitives should be recoded in assembly. + The entry point name should be defined, in "mpilib.h" to the external + entry point name. If undefined, the C version will be used. +*/ + +typedef unsigned long int ulint; + +#ifndef mp_addc +boolean mp_addc + (register unitptr r1,register unitptr r2,register boolean carry) + /* multiprecision add with carry r2 to r1, result in r1 */ + /* carry is incoming carry flag-- value should be 0 or 1 */ +{ register unit x; + short precision; /* number of units to add */ + precision = global_precision; + make_lsbptr(r1,precision); + make_lsbptr(r2,precision); + while (precision--) + { + if (carry) + { x = *r1 + *r2 + 1; + carry = (*r2 >= (unit)(~ *r1)); + } else + { x = *r1 + *r2; + carry = (x < *r1) ; + } + post_higherunit(r2); + *post_higherunit(r1) = x; + } + return(carry); /* return the final carry flag bit */ +} /* mp_addc */ +#endif /* mp_addc */ + +#ifndef mp_subb +boolean mp_subb + (register unitptr r1,register unitptr r2,register boolean borrow) + /* multiprecision subtract with borrow, r2 from r1, result in r1 */ + /* borrow is incoming borrow flag-- value should be 0 or 1 */ +{ register unit x; + short precision; /* number of units to subtract */ + precision = global_precision; + make_lsbptr(r1,precision); + make_lsbptr(r2,precision); + while (precision--) + { if (borrow) + { x = *r1 - *r2 - 1; + borrow = (*r1 <= *r2); + } else + { x = *r1 - *r2; + borrow = (*r1 < *r2); + } + post_higherunit(r2); + *post_higherunit(r1) = x; + } + return(borrow); /* return the final carry/borrow flag bit */ +} /* mp_subb */ +#endif /* mp_subb */ + +#ifndef mp_rotate_left +boolean mp_rotate_left(register unitptr r1,register boolean carry) + /* multiprecision rotate left 1 bit with carry, result in r1. */ + /* carry is incoming carry flag-- value should be 0 or 1 */ +{ register int precision; /* number of units to rotate */ + unsigned int mcarry = carry, nextcarry=0; /* int is supposed to be + * the efficient size for ops*/ + precision = global_precision; + make_lsbptr(r1,precision); + while (precision--) + { + nextcarry = (((signedunit) *r1) < 0); + *r1 = (*r1 << 1) | mcarry; + mcarry = nextcarry; + pre_higherunit(r1); + } + return(nextcarry); /* return the final carry flag bit */ +} /* mp_rotate_left */ +#endif /* mp_rotate_left */ + +/************** end of primitives that should be in assembly *************/ + + +/* The mp_shift_right_bits function is not called in any time-critical + situations in public-key cryptographic functions, so it doesn't + need to be coded in assembly language. +*/ +void mp_shift_right_bits(register unitptr r1,register short bits) + /* multiprecision shift right bits, result in r1. + bits is how many bits to shift, must be <= UNITSIZE. + */ +{ register short precision; /* number of units to shift */ + register unit carry,nextcarry,bitmask; + register short unbits; + if (bits==0) return; /* shift zero bits is a no-op */ + carry = 0; + bitmask = power_of_2(bits)-1; + unbits = UNITSIZE-bits; /* shift bits must be <= UNITSIZE */ + precision = global_precision; + make_msbptr(r1,precision); + if (bits == UNITSIZE) { + while (precision--) { + nextcarry = *r1; + *r1 = carry; + carry = nextcarry; + pre_lowerunit(r1); + } + } else { + while (precision--) + { nextcarry = *r1 & bitmask; + *r1 >>= bits; + *r1 |= carry << unbits; + carry = nextcarry; + pre_lowerunit(r1); + } + } +} /* mp_shift_right_bits */ + + +#ifndef mp_compare +short mp_compare(register unitptr r1,register unitptr r2) +/* Compares multiprecision integers *r1, *r2, and returns: + -1 iff *r1 < *r2 + 0 iff *r1 == *r2 + +1 iff *r1 > *r2 +*/ +{ register short precision; /* number of units to compare */ + + precision = global_precision; + make_msbptr(r1,precision); + make_msbptr(r2,precision); + do + { if (*r1 < *r2) + return(-1); + if (*post_lowerunit(r1) > *post_lowerunit(r2)) + return(1); + } while (--precision); + return(0); /* *r1 == *r2 */ +} /* mp_compare */ +#endif /* mp_compare */ + + +boolean mp_inc(register unitptr r) + /* Increment multiprecision integer r. */ +{ register short precision; + precision = global_precision; + make_lsbptr(r,precision); + do + { if ( ++(*r) ) return(0); /* no carry */ + post_higherunit(r); + } while (--precision); + return(1); /* return carry set */ +} /* mp_inc */ + + +boolean mp_dec(register unitptr r) + /* Decrement multiprecision integer r. */ +{ register short precision; + precision = global_precision; + make_lsbptr(r,precision); + do + { if ( (signedunit) (--(*r)) != (signedunit) -1 ) + return(0); /* no borrow */ + post_higherunit(r); + } while (--precision); + return(1); /* return borrow set */ +} /* mp_dec */ + + +void mp_neg(register unitptr r) + /* Compute 2's complement, the arithmetic negative, of r */ +{ register short precision; /* number of units to negate */ + precision = global_precision; + mp_dec(r); /* 2's complement is 1's complement plus 1 */ + do /* now do 1's complement */ + { *r = ~(*r); + r++; + } while (--precision); +} /* mp_neg */ + +#ifndef mp_move +void mp_move(register unitptr dst,register unitptr src) +{ register short precision; /* number of units to move */ + precision = global_precision; + do { *dst++ = *src++; } while (--precision); +} /* mp_move */ +#endif /* mp_move */ + +void mp_init(register unitptr r, word16 value) + /* Init multiprecision register r with short value. */ +{ /* Note that mp_init doesn't extend sign bit for >32767 */ + + unitfill0( r, global_precision); + make_lsbptr(r,global_precision); + *post_higherunit(r) = value; +#ifdef UNIT8 + *post_higherunit(r) = value >> UNITSIZE; +#endif +} /* mp_init */ + + +short significance(register unitptr r) + /* Returns number of significant units in r */ +{ register short precision; + precision = global_precision; + make_msbptr(r,precision); + do + { if (*post_lowerunit(r)) + return(precision); + } while (--precision); + return(precision); +} /* significance */ + + +#ifndef unitfill0 +void unitfill0(unitptr r,word16 unitcount) + /* Zero-fill the unit buffer r. */ +{ while (unitcount--) *r++ = 0; +} /* unitfill0 */ +#endif /* unitfill0 */ + + +int mp_udiv(register unitptr remainder,register unitptr quotient, + register unitptr dividend,register unitptr divisor) + /* Unsigned divide, treats both operands as positive. */ +{ int bits; + short dprec; + register unit bitmask; + if (testeq(divisor,0)) + return(-1); /* zero divisor means divide error */ + mp_init0(remainder); + mp_init0(quotient); + /* normalize and compute number of bits in dividend first */ + init_bitsniffer(dividend,bitmask,dprec,bits); + /* rescale quotient to same precision (dprec) as dividend */ + rescale(quotient,global_precision,dprec); + make_msbptr(quotient,dprec); + + while (bits--) + { mp_rotate_left(remainder,(boolean)(sniff_bit(dividend,bitmask)!=0)); + if (mp_compare(remainder,divisor) >= 0) + { mp_sub(remainder,divisor); + stuff_bit(quotient,bitmask); + } + bump_2bitsniffers(dividend,quotient,bitmask); + } + return(0); +} /* mp_udiv */ + + +#ifdef UPTON_OR_SMITH +#define RECIPMARGIN 0 /* extra margin bits used by mp_recip() */ + +int mp_recip(register unitptr quotient,register unitptr divisor) + /* Compute reciprocal (quotient) as 1/divisor. Used by faster modmult. */ +{ int bits; + short qprec; + register unit bitmask; + unit remainder[MAX_UNIT_PRECISION]; + if (testeq(divisor,0)) + return(-1); /* zero divisor means divide error */ + mp_init0(remainder); + mp_init0(quotient); + + /* normalize and compute number of bits in quotient first */ + bits = countbits(divisor) + RECIPMARGIN; + bitmask = bitmsk(bits); /* bitmask within a single unit */ + qprec = bits2units(bits+1); + mp_setbit(remainder,(bits-RECIPMARGIN)-1); + /* rescale quotient to precision of divisor + RECIPMARGIN bits */ + rescale(quotient,global_precision,qprec); + make_msbptr(quotient,qprec); + + while (bits--) + { mp_shift_left(remainder); + if (mp_compare(remainder,divisor) >= 0) + { mp_sub(remainder,divisor); + stuff_bit(quotient,bitmask); + } + bump_bitsniffer(quotient,bitmask); + } + mp_init0(remainder); /* burn sensitive data left on stack */ + return(0); +} /* mp_recip */ +#endif /* UPTON_OR_SMITH */ + + +int mp_div(register unitptr remainder,register unitptr quotient, + register unitptr dividend,register unitptr divisor) + /* Signed divide, either or both operands may be negative. */ +{ boolean dvdsign,dsign; + int status; + dvdsign = (boolean)(mp_tstminus(dividend)!=0); + dsign = (boolean)(mp_tstminus(divisor)!=0); + if (dvdsign) mp_neg(dividend); + if (dsign) mp_neg(divisor); + status = mp_udiv(remainder,quotient,dividend,divisor); + if (dvdsign) mp_neg(dividend); /* repair caller's dividend */ + if (dsign) mp_neg(divisor); /* repair caller's divisor */ + if (status<0) return(status); /* divide error? */ + if (dvdsign) mp_neg(remainder); + if (dvdsign ^ dsign) mp_neg(quotient); + return(status); +} /* mp_div */ + + +word16 mp_shortdiv(register unitptr quotient, + register unitptr dividend,register word16 divisor) +/* This function does a fast divide and mod on a multiprecision dividend + using a short integer divisor returning a short integer remainder. + This is an unsigned divide. It treats both operands as positive. + It is used mainly for faster printing of large numbers in base 10. +*/ +{ int bits; + short dprec; + register unit bitmask; + register word16 remainder; + if (!divisor) /* if divisor == 0 */ + return(-1); /* zero divisor means divide error */ + remainder=0; + mp_init0(quotient); + /* normalize and compute number of bits in dividend first */ + init_bitsniffer(dividend,bitmask,dprec,bits); + /* rescale quotient to same precision (dprec) as dividend */ + rescale(quotient,global_precision,dprec); + make_msbptr(quotient,dprec); + + while (bits--) + { remainder <<= 1; + if (sniff_bit(dividend,bitmask)) + remainder++; + if (remainder >= divisor) + { remainder -= divisor; + stuff_bit(quotient,bitmask); + } + bump_2bitsniffers(dividend,quotient,bitmask); + } + return(remainder); +} /* mp_shortdiv */ + + +int mp_mod(register unitptr remainder, + register unitptr dividend,register unitptr divisor) + /* Unsigned divide, treats both operands as positive. */ +{ int bits; + short dprec; + register unit bitmask; + if (testeq(divisor,0)) + return(-1); /* zero divisor means divide error */ + mp_init0(remainder); + /* normalize and compute number of bits in dividend first */ + init_bitsniffer(dividend,bitmask,dprec,bits); + + while (bits--) + { mp_rotate_left(remainder,(boolean)(sniff_bit(dividend,bitmask)!=0)); + msub(remainder,divisor); + bump_bitsniffer(dividend,bitmask); + } + return(0); +} /* mp_mod */ + + +word16 mp_shortmod(register unitptr dividend,register word16 divisor) +/* This function does a fast mod operation on a multiprecision dividend + using a short integer modulus returning a short integer remainder. + This is an unsigned divide. It treats both operands as positive. + It is used mainly for fast sieve searches for large primes. +*/ +{ int bits; + short dprec; + register unit bitmask; + register word16 remainder; + if (!divisor) /* if divisor == 0 */ + return(-1); /* zero divisor means divide error */ + remainder=0; + /* normalize and compute number of bits in dividend first */ + init_bitsniffer(dividend,bitmask,dprec,bits); + + while (bits--) + { remainder <<= 1; + if (sniff_bit(dividend,bitmask)) + remainder++; + if (remainder >= divisor) remainder -= divisor; + bump_bitsniffer(dividend,bitmask); + } + return(remainder); +} /* mp_shortmod */ + + + +#ifdef COMB_MULT /* use faster "comb" multiply algorithm */ + /* We are skipping this code because it has a bug... */ + +int mp_mult(register unitptr prod, + register unitptr multiplicand, register unitptr multiplier) + /* Computes multiprecision prod = multiplicand * multiplier */ +{ /* Uses interleaved comb multiply algorithm. + This improved multiply more than twice as fast as a Russian + peasant multiply, because it does a lot fewer shifts. + Must have global_precision set to the size of the multiplicand + plus UNITSIZE-1 SLOP_BITS. Produces a product that is the sum + of the lengths of the multiplier and multiplicand. + + BUG ALERT: Unfortunately, this code has a bug. It fails for + some numbers. One such example: + x= 59DE 60CE 2345 8091 A02B 2A1C DBC3 8BE5 + x*x= 59DE 60CE 2345 26B3 993B 67A5 2499 0B7D + 52C8 CDC7 AFB3 61C8 243C 741B + --which is obviously wrong. The answer should be: + x*x= 1F8C 607B 5EA6 C061 2714 04A9 A0C6 A17A + C9AB 6095 C62F 3756 3843 E4D0 3950 7AD9 + We'll have to fix this some day. In the meantime, we'll + just have the compiler skip over this code. + + BUG NOTE: Possibly fixed. Needs testing. + */ + int bits; + register unit bitmask; + unitptr product, mplier, temp; + short mprec,mprec2; + unit mplicand[MAX_UNIT_PRECISION]; + + /* better clear full width--double precision */ + mp_init(prod+tohigher(global_precision),0); + + if (testeq(multiplicand,0)) + return(0); /* zero multiplicand means zero product */ + + mp_move(mplicand,multiplicand); /* save it from damage */ + + normalize(multiplier,mprec); + if (!mprec) + return(0); + + make_lsbptr(multiplier,mprec); + bitmask = 1; /* start scan at LSB of multiplier */ + + do /* UNITSIZE times */ + { /* do for bits 0-15 */ + product = prod; + mplier = multiplier; + mprec2 = mprec; + while (mprec2--) /* do for each word in multiplier */ + { + if (sniff_bit(mplier,bitmask)) + { if (mp_addc(product,multiplicand,0)) /* ripple carry */ + { /* After 1st time thru, this is rarely encountered. */ + temp = msbptr(product,global_precision); + pre_higherunit(temp); + /* temp now points to LSU of carry region. */ + unmake_lsbptr(temp,global_precision); + mp_inc(temp); + } /* ripple carry */ + } + pre_higherunit(mplier); + pre_higherunit(product); + } + if (!(bitmask <<= 1)) + break; + mp_shift_left(multiplicand); + + } while (TRUE); + + mp_move(multiplicand,mplicand); /* recover */ + + return(0); /* normal return */ +} /* mp_mult */ + +#endif /* COMB_MULT */ + + +/* Because the "comb" multiply has a bug, we will use the slower + Russian peasant multiply instead. Fortunately, the mp_mult + function is not called from any time-critical code. +*/ + +int mp_mult(register unitptr prod, + register unitptr multiplicand,register unitptr multiplier) + /* Computes multiprecision prod = multiplicand * multiplier */ +{ /* Uses "Russian peasant" multiply algorithm. */ + int bits; + register unit bitmask; + short mprec; + mp_init(prod,0); + if (testeq(multiplicand,0)) + return(0); /* zero multiplicand means zero product */ + /* normalize and compute number of bits in multiplier first */ + init_bitsniffer(multiplier,bitmask,mprec,bits); + + while (bits--) + { mp_shift_left(prod); + if (sniff_bit(multiplier,bitmask)) + mp_add(prod,multiplicand); + bump_bitsniffer(multiplier,bitmask); + } + return(0); +} /* mp_mult */ + + + +/* mp_modmult computes a multiprecision multiply combined with a + modulo operation. This is the most time-critical function in + this multiprecision arithmetic library for performing modulo + exponentiation. We experimented with different versions of modmult, + depending on the machine architecture and performance requirements. + We will either use a Russian Peasant modmult (peasant_modmult), + Charlie Merritt's modmult (merritt_modmult), Jimmy Upton's + modmult (upton_modmult), or Thad Smith's modmult (smith_modmult). + On machines with a hardware atomic multiply instruction, + Smith's modmult is fastest. It can utilize assembly subroutines to + speed up the hardware multiply logic and trial quotient calculation. + If the machine lacks a fast hardware multiply, Merritt's modmult + is preferred, which doesn't call any assembly multiply routine. + We use the alias names mp_modmult, stage_modulus, and modmult_burn + for the corresponding true names, which depend on what flavor of + modmult we are using. + + Before making the first call to mp_modmult, you must set up the + modulus-dependant precomputated tables by calling stage_modulus. + After making all the calls to mp_modmult, you call modmult_burn to + erase the tables created by stage_modulus that were left in memory. +*/ + +#ifdef COUNTMULTS +/* "number of modmults" counters, used for performance studies. */ +static unsigned int tally_modmults = 0; +static unsigned int tally_modsquares = 0; +#endif /* COUNTMULTS */ + + +#ifdef PEASANT +/* Conventional Russian peasant multiply with modulo algorithm. */ + +static unitptr pmodulus = 0; /* used only by mp_modmult */ + +int stage_peasant_modulus(unitptr n) +/* Must pass modulus to stage_modulus before calling modmult. + Assumes that global_precision has already been adjusted to the + size of the modulus, plus SLOP_BITS. +*/ +{ /* For this simple version of modmult, just copy unit pointer. */ + pmodulus = n; + return(0); /* normal return */ +} /* stage_peasant_modulus */ + + +int peasant_modmult(register unitptr prod, + unitptr multiplicand,register unitptr multiplier) +{ /* "Russian peasant" multiply algorithm, combined with a modulo + operation. This is a simple naive replacement for Merritt's + faster modmult algorithm. References global unitptr "modulus". + Computes: prod = (multiplicand*multiplier) mod modulus + WARNING: All the arguments must be less than the modulus! + */ + int bits; + register unit bitmask; + short mprec; + mp_init(prod,0); +/* if (testeq(multiplicand,0)) + return(0); */ /* zero multiplicand means zero product */ + /* normalize and compute number of bits in multiplier first */ + init_bitsniffer(multiplier,bitmask,mprec,bits); + + while (bits--) + { mp_shift_left(prod); + msub(prod,pmodulus); /* turns mult into modmult */ + if (sniff_bit(multiplier,bitmask)) + { mp_add(prod,multiplicand); + msub(prod,pmodulus); /* turns mult into modmult */ + } + bump_bitsniffer(multiplier,bitmask); + } + return(0); +} /* peasant_modmult */ + + +/* If we are using a version of mp_modmult that uses internal tables + in memory, we have to call modmult_burn() at the end of mp_modexp. + This is so that no sensitive data is left in memory after the program + exits. The Russian peasant method doesn't use any such tables. +*/ +void peasant_burn(void) +/* Alias for modmult_burn, called only from mp_modexp(). Destroys + internal modmult tables. This version does nothing because no + tables are used by the Russian peasant modmult. */ +{ } /* peasant_burn */ + +#endif /* PEASANT */ + + +#ifdef MERRITT +/*=========================================================================*/ +/* + This is Charlie Merritt's MODMULT algorithm, implemented in C by PRZ. + Also refined by Zhahai Stewart to reduce the number of subtracts. + Modified by Raymond Brand to reduce the number of SLOP_BITS by 1. + It performs a multiply combined with a modulo operation, without + going into "double precision". It is faster than the Russian peasant + method, and still works well on machines that lack a fast hardware + multiply instruction. +*/ + +/* The following support functions, macros, and data structures + are used only by Merritt's modmult algorithm... */ + +static void mp_lshift_unit(register unitptr r1) +/* Shift r1 1 whole unit to the left. Used only by modmult function. */ +{ register short precision; + register unitptr r2; + precision = global_precision; + make_msbptr(r1,precision); + r2 = r1; + while (--precision) + *post_lowerunit(r1) = *pre_lowerunit(r2); + *r1 = 0; +} /* mp_lshift_unit */ + + +/* moduli_buf contains shifted images of the modulus, set by stage_modulus */ +static unit moduli_buf[UNITSIZE-1][MAX_UNIT_PRECISION] = {0}; +static unitptr moduli[UNITSIZE] = /* contains pointers into moduli_buf */ +{ 0 + ,&moduli_buf[ 0][0], &moduli_buf[ 1][0], &moduli_buf[ 2][0], &moduli_buf[ 3][0], + &moduli_buf[ 4][0], &moduli_buf[ 5][0], &moduli_buf[ 6][0] +#ifndef UNIT8 + ,&moduli_buf[ 7][0] + ,&moduli_buf[ 8][0], &moduli_buf[ 9][0], &moduli_buf[10][0], &moduli_buf[11][0], + &moduli_buf[12][0], &moduli_buf[13][0], &moduli_buf[14][0] +#ifndef UNIT16 /* and not UNIT8 */ + ,&moduli_buf[15][0] + ,&moduli_buf[16][0], &moduli_buf[17][0], &moduli_buf[18][0], &moduli_buf[19][0], + &moduli_buf[20][0], &moduli_buf[21][0], &moduli_buf[22][0], &moduli_buf[23][0], + &moduli_buf[24][0], &moduli_buf[25][0], &moduli_buf[26][0], &moduli_buf[27][0], + &moduli_buf[28][0], &moduli_buf[29][0], &moduli_buf[30][0] +#endif /* UNIT16 and UNIT8 not defined */ +#endif /* UNIT8 not defined */ +}; + +/* To optimize msubs, need following 2 unit arrays, each filled + with the most significant unit and next-to-most significant unit + of the preshifted images of the modulus. */ +static unit msu_moduli[UNITSIZE] = {0}; /* most signif. unit */ +static unit nmsu_moduli[UNITSIZE] = {0}; /* next-most signif. unit */ + +/* mpdbuf contains preshifted images of the multiplicand, mod n. + It is used only by mp_modmult. It could be staticly declared + inside of mp_modmult, but we put it outside mp_modmult so that + it can be wiped clean by modmult_burn(), which is called at the + end of mp_modexp. This is so that no sensitive data is left in + memory after the program exits. +*/ +static unit mpdbuf[UNITSIZE-1][MAX_UNIT_PRECISION] = {0}; + + +static void stage_mp_images(unitptr images[UNITSIZE],unitptr r) +/* Computes UNITSIZE images of r, each shifted left 1 more bit. + Used only by modmult function. +*/ +{ short int i; + images[0] = r; /* no need to move the first image, just copy ptr */ + for (i=1; i= 0) && \ + (p_m || (mp_compare(prod,moduli[i]) >= 0) ) \ + ) mp_sub(prod,moduli[i]) +*/ + +/* Fully-optimized msubs macro (msubs2) follows... */ +#define msubs(i) if (((p_m = *msu_prod-msu_moduli[i])>0) || ( \ + (p_m==0) && ( (*nmsu_prod>nmsu_moduli[i]) || ( \ + (*nmsu_prod==nmsu_moduli[i]) && ((mp_compare(prod,moduli[i]) >= 0)) ))) ) \ + mp_sub(prod,moduli[i]) + + +int merritt_modmult(register unitptr prod, + unitptr multiplicand,register unitptr multiplier) + /* Performs combined multiply/modulo operation. + Computes: prod = (multiplicand*multiplier) mod modulus + WARNING: All the arguments must be less than the modulus! + Assumes the modulus has been predefined by first calling + stage_modulus. + */ +{ + /* p_m, msu_prod, and nmsu_prod are used by the optimized msubs macro...*/ + register signedunit p_m; + register unitptr msu_prod; /* ptr to most significant unit of product */ + register unitptr nmsu_prod; /* next-most signif. unit of product */ + short mprec; /* precision of multiplier, in units */ + /* Array mpd contains a list of pointers to preshifted images of + the multiplicand: */ + static unitptr mpd[UNITSIZE] = + { 0, &mpdbuf[ 0][0], &mpdbuf[ 1][0], &mpdbuf[ 2][0], + &mpdbuf[ 3][0], &mpdbuf[ 4][0], &mpdbuf[ 5][0], &mpdbuf[ 6][0] +#ifndef UNIT8 + ,&mpdbuf[ 7][0], &mpdbuf[ 8][0], &mpdbuf[ 9][0], &mpdbuf[10][0], + &mpdbuf[11][0], &mpdbuf[12][0], &mpdbuf[13][0], &mpdbuf[14][0] +#ifndef UNIT16 /* and not UNIT8 */ + ,&mpdbuf[15][0], &mpdbuf[16][0], &mpdbuf[17][0], &mpdbuf[18][0], + &mpdbuf[19][0], &mpdbuf[20][0], &mpdbuf[21][0], &mpdbuf[22][0], + &mpdbuf[23][0], &mpdbuf[24][0], &mpdbuf[25][0], &mpdbuf[26][0], + &mpdbuf[27][0], &mpdbuf[28][0], &mpdbuf[29][0], &mpdbuf[30][0] +#endif /* UNIT16 and UNIT8 not defined */ +#endif /* UNIT8 not defined */ + }; + + /* Compute preshifted images of multiplicand, mod n: */ + stage_mp_images(mpd,multiplicand); + + /* To optimize msubs, set up msu_prod and nmsu_prod: */ + msu_prod = msbptr(prod,global_precision); /* Get ptr to MSU of prod */ + nmsu_prod = msu_prod; + post_lowerunit(nmsu_prod); /* Get next-MSU of prod */ + + /* To understand this algorithm, it would be helpful to first + study the conventional Russian peasant modmult algorithm. + This one does about the same thing as Russian peasant, but + is organized differently to save some steps. It loops + through the multiplier a word (unit) at a time, instead of + a bit at a time. It word-shifts the product instead of + bit-shifting it, so it should be faster. It also does about + half as many subtracts as Russian peasant. + */ + + mp_init(prod,0); /* Initialize product to 0. */ + + /* The way mp_modmult is actually used in cryptographic + applications, there will NEVER be a zero multiplier or + multiplicand. So there is no need to optimize for that + condition. + */ +/* if (testeq(multiplicand,0)) + return(0); */ /* zero multiplicand means zero product */ + /* Normalize and compute number of units in multiplier first: */ + normalize(multiplier,mprec); + if (mprec==0) /* if precision of multiplier is 0 */ + return(0); /* zero multiplier means zero product */ + make_msbptr(multiplier,mprec); /* start at MSU of multiplier */ + + while (mprec--) /* Loop for the number of units in the multiplier */ + { + /* Shift the product one whole unit to the left. + This is part of the multiply phase of modmult. + */ + + mp_lshift_unit(prod); + + /* The product may have grown by as many as UNITSIZE + bits. That's why we have global_precision set to the + size of the modulus plus UNITSIZE slop bits. + Now reduce the product back down by conditionally + subtracting the preshifted images of the modulus. + This is part of the modulo reduction phase of modmult. + The following loop is unrolled for speed, using macros... + + for (i=UNITSIZE-1; i>=LOG_UNITSIZE; i--) + if (mp_compare(prod,moduli[i]) >= 0) + mp_sub(prod,moduli[i]); + */ + +#ifndef UNIT8 +#ifndef UNIT16 /* and not UNIT8 */ + msubs(31); + msubs(30); + msubs(29); + msubs(28); + msubs(27); + msubs(26); + msubs(25); + msubs(24); + msubs(23); + msubs(22); + msubs(21); + msubs(20); + msubs(19); + msubs(18); + msubs(17); + msubs(16); +#endif /* not UNIT16 and not UNIT8 */ + msubs(15); + msubs(14); + msubs(13); + msubs(12); + msubs(11); + msubs(10); + msubs(9); + msubs(8); +#endif /* not UNIT8 */ + msubs(7); + msubs(6); + msubs(5); +#ifndef UNIT32 + msubs(4); +#ifndef UNIT16 + msubs(3); +#endif +#endif + + /* Sniff each bit in the current unit of the multiplier, + and conditionally add the corresponding preshifted + image of the multiplicand to the product. + This is also part of the multiply phase of modmult. + + The following loop is unrolled for speed, using macros... + + for (i=UNITSIZE-1; i>=0; i--) + if (*multiplier & power_of_2(i)) + mp_add(prod,mpd[i]); + */ +#ifndef UNIT8 +#ifndef UNIT16 /* and not UNIT8 */ + sniffadd(31); + sniffadd(30); + sniffadd(29); + sniffadd(28); + sniffadd(27); + sniffadd(26); + sniffadd(25); + sniffadd(24); + sniffadd(23); + sniffadd(22); + sniffadd(21); + sniffadd(20); + sniffadd(19); + sniffadd(18); + sniffadd(17); + sniffadd(16); +#endif /* not UNIT16 and not UNIT8 */ + sniffadd(15); + sniffadd(14); + sniffadd(13); + sniffadd(12); + sniffadd(11); + sniffadd(10); + sniffadd(9); + sniffadd(8); +#endif /* not UNIT8 */ + sniffadd(7); + sniffadd(6); + sniffadd(5); + sniffadd(4); + sniffadd(3); + sniffadd(2); + sniffadd(1); + sniffadd(0); + + /* The product may have grown by as many as LOG_UNITSIZE+1 + bits. + Now reduce the product back down by conditionally + subtracting LOG_UNITSIZE+1 preshifted images of the + modulus. This is the modulo reduction phase of modmult. + + The following loop is unrolled for speed, using macros... + + for (i=LOG_UNITSIZE; i>=0; i--) + if (mp_compare(prod,moduli[i]) >= 0) + mp_sub(prod,moduli[i]); + */ + +#ifndef UNIT8 +#ifndef UNIT16 + msubs(5); +#endif + msubs(4); +#endif + msubs(3); + msubs(2); + msubs(1); + msubs(0); + + /* Bump pointer to next lower unit of multiplier: */ + post_lowerunit(multiplier); + + } /* Loop for the number of units in the multiplier */ + + return(0); /* normal return */ + +} /* merritt_modmult */ + + +#undef msubs +#undef sniffadd + + +/* Merritt's mp_modmult function leaves some internal tables in memory, + so we have to call modmult_burn() at the end of mp_modexp. + This is so that no cryptographically sensitive data is left in memory + after the program exits. +*/ +void merritt_burn(void) +/* Alias for modmult_burn, merritt_burn() is called only by mp_modexp. */ +{ unitfill0(&(mpdbuf[0][0]),(UNITSIZE-1)*MAX_UNIT_PRECISION); + unitfill0(&(moduli_buf[0][0]),(UNITSIZE-1)*MAX_UNIT_PRECISION); + unitfill0(msu_moduli,UNITSIZE); + unitfill0(nmsu_moduli,UNITSIZE); +} /* merritt_burn() */ + +/******* end of Merritt's MODMULT stuff. *******/ +/*=========================================================================*/ +#endif /* MERRITT */ + + +#ifdef UPTON_OR_SMITH /* Used by Upton's and Smith's modmult algorithms */ + +/* Jimmy Upton's multiprecision modmult algorithm in C. + Performs a multiply combined with a modulo operation. + + The following support functions and data structures + are used only by Upton's modmult algorithm... +*/ + +short munit_prec; /* global_precision expressed in MULTUNITs */ + +/* Note that since the SPARC CPU has no hardware integer multiply + instruction, there is not that much advantage in having an + assembly version of mp_smul on that machine. It might be faster + to use Merritt's modmult instead of Upton's modmult on the SPARC. +*/ + +/* + Multiply the single-word multiplier times the multiprecision integer + in multiplicand, accumulating result in prod. The resulting + multiprecision prod will be 1 word longer than the multiplicand. + multiplicand is munit_prec words long. We add into prod, so caller + should zero it out first. For best results, this time-critical + function should be implemented in assembly. + NOTE: Unlike other functions in the multiprecision arithmetic + library, both multiplicand and prod are pointing at the LSB, + regardless of byte order of the machine. On an 80x86, this makes + no difference. But if this assembly function is implemented + on a 680x0, it becomes important. +*/ +/* Note that this has been modified from the previous version to allow + better support for Smith's modmult: + The final carry bit is added to the existing product + array, rather than simply stored. +*/ + +#ifndef mp_smul +void mp_smul (MULTUNIT *prod, MULTUNIT *multiplicand, MULTUNIT multiplier) +{ + short i; + unsigned long p, carry; + + carry = 0; + for (i=0; i> MULTUNITSIZE; + } + /* Add carry to the next higher word of product / dividend */ + *prod += (MULTUNIT)carry; +} /* mp_smul */ +#endif + +/* mp_dmul is a double-precision multiply multiplicand times multiplier, + result into prod. prod must be pointing at a "double precision" + buffer. E.g. If global_precision is 10 words, prod must be + pointing at a 20-word buffer. +*/ +#ifndef mp_dmul +void mp_dmul (unitptr prod, unitptr multiplicand, unitptr multiplier) +{ + register int i; + register MULTUNIT *p_multiplicand, *p_multiplier; + register MULTUNIT *prodp; + + + unitfill0(prod,global_precision*2); /* Pre-zero prod */ + /* Calculate precision in units of MULTUNIT */ + munit_prec = global_precision * UNITSIZE / MULTUNITSIZE; + p_multiplicand = (MULTUNIT *)multiplicand; + p_multiplier = (MULTUNIT *)multiplier; + prodp = (MULTUNIT *)prod; + make_lsbptr(p_multiplicand,munit_prec); + make_lsbptr(p_multiplier,munit_prec); + make_lsbptr(prodp,munit_prec*2); + /* Multiply multiplicand by each word in multiplier, accumulating prod: */ + for (i=0; i 0) + mp_sub (d,modulus); + + mp_move(prod,d); + return(0); /* normal return */ +} /* upton_modmult */ + + +/* Upton's mp_modmult function leaves some internal arrays in memory, + so we have to call modmult_burn() at the end of mp_modexp. + This is so that no cryptographically sensitive data is left in memory + after the program exits. + upton_burn() is aliased to modmult_burn(). +*/ +void upton_burn(void) +{ + unitfill0(modulus,MAX_UNIT_PRECISION); + unitfill0(reciprocal,MAX_UNIT_PRECISION); + unitfill0(dhi,MAX_UNIT_PRECISION); + unitfill0(d_data,MAX_UNIT_PRECISION*2); + unitfill0(e_data,MAX_UNIT_PRECISION*2); + unitfill0(f_data,MAX_UNIT_PRECISION*2); + nbits = nbitsDivUNITSIZE = nbitsModUNITSIZE = 0; +} /* upton_burn */ + +/******* end of Upton's MODMULT stuff. *******/ +/*=========================================================================*/ +#endif /* UPTON */ + +#ifdef SMITH /* using Thad Smith's modmult algorithm */ + +/* Thad Smith's implementation of multiprecision modmult algorithm in C. + Performs a multiply combined with a modulo operation. + The multiplication is done with mp_dmul, the same as for Upton's + modmult. The modulus reduction is done by long division, in + which a trial quotient "digit" is determined, then the product of + that digit and the divisor are subtracted from the dividend. + + In this case, the digit is MULTUNIT in size and the subtraction + is done by adding the product to the one's complement of the + dividend, which allows use of the existing mp_smul routine. + + The following support functions and data structures + are used only by Smith's modmult algorithm... +*/ + +/* These scratchpad arrays are used only by smith_modmult (mp_modmult). + Some of them could be statically declared inside of mp_modmult, but we + put them outside mp_modmult so that they can be wiped clean by + modmult_burn(), which is called at the end of mp_modexp. This is + so that no sensitive data is left in memory after the program exits. +*/ + +static unit ALIGN ds_data[MAX_UNIT_PRECISION*2+2]; + +static unit mod_quotient [4]; +static unit mod_divisor [4]; /* 2 most signif. MULTUNITs of modulus */ + +static MULTUNIT *modmpl; /* ptr to modulus least significant + ** MULTUNIT */ +static int mshift; /* number of bits for + ** recip scaling */ +static MULTUNIT reciph; /* MSunit of scaled recip */ +static MULTUNIT recipl; /* LSunit of scaled recip */ + +static short modlenMULTUNITS; /* length of modulus in MULTUNITs */ +static MULTUNIT mutemp; /* temporary */ + +/* The routines mp_smul and mp_dmul are the same as for UPTON and + should be coded in assembly. Note, however, that the previous + Upton's mp_smul version has been modified to compatible with + Smith's modmult. The new version also still works for Upton's + modmult. +*/ + +#ifndef mp_set_recip +#define mp_set_recip(rh,rl,m) /* null */ +#else +/* setup routine for external mp_quo_digit */ +void mp_set_recip(MULTUNIT rh, MULTUNIT rl, int m); +#endif +MULTUNIT mp_quo_digit (MULTUNIT *dividend); + +#ifdef MULTUNIT_SIZE_SAME +#define mp_musubb mp_subb /* use existing routine */ +#else /* ! MULTUNIT_SIZE_SAME */ + +/* This performs the same function as mp_subb, but with MULTUNITs. + Note: Processors without alignment requirements may be able to use + mp_subb, even though MULTUNITs are smaller than units. In that case, + use mp_subb, since it would be faster if coded in assembly. Note that + this implementation won't work for MULTUNITs which are long -- use + mp_subb in that case. +*/ +#ifndef mp_musubb +boolean mp_musubb + (register MULTUNIT* r1,register MULTUNIT* r2,register boolean borrow) + /* multiprecision subtract of MULTUNITs with borrow, r2 from r1, + ** result in r1 */ + /* borrow is incoming borrow flag-- value should be 0 or 1 */ +{ register ulint x; /* won't work if sizeof(MULTUNIT)== + sizeof(long) */ + short precision; /* number of MULTUNITs to subtract */ + precision = global_precision * MULTUNITs_perunit; + make_lsbptr(r1,precision); + make_lsbptr(r2,precision); + while (precision--) + { x = (ulint) *r1 - (ulint) *post_higherunit(r2) - (ulint) borrow; + *post_higherunit(r1) = x; + borrow = (((1L << MULTUNITSIZE) & x) != 0L); + } + return (borrow); +} /* mp_musubb */ +#endif /* mp_musubb */ +#endif /* MULTUNIT_SIZE_SAME */ + +/* The function mp_quo_digit is the heart of Smith's modulo reduction, + which uses a form of long division. It computes a trial quotient + "digit" (MULTUNIT-sized digit) by multiplying the three most + significant MULTUNITs of the dividend by the two most significant + MULTUNITs of the reciprocal of the modulus. Note that this function + requires that MULTUNITSIZE * 2 <= sizeof(unsigned long). + + An important part of this technique is that the quotient never be + too small, although it may occasionally be too large. This was + done to eliminate the need to check and correct for a remainder + exceeding the divisor. It is easier to check for a negative + remainder. The following technique rarely needs correction for + MULTUNITs of at least 16 bits. + + The following routine has two implementations: + + ASM_PROTOTYPE defined: written to be an executable prototype for + an efficient assembly language implementation. Note that several + of the following masks and shifts can be done by directly + manipulating single precision registers on some architectures. + + ASM_PROTOTYPE undefined: a slightly more efficient implementation + in C. Although this version returns a result larger than the + optimum (which is corrected in smith_modmult) more often than the + prototype version, the faster execution in C more than makes up + for the difference. + + Parameter: dividend - points to the most significant MULTUNIT + of the dividend. Note that dividend actually contains the + one's complement of the actual dividend value (see comments for + smith_modmult). + + Return: the trial quotient digit resulting from dividing the first + three MULTUNITs at dividend by the upper two MULTUNITs of the + modulus. +*/ + +/* #define ASM_PROTOTYPE */ /* undefined: use C-optimized version */ + +#ifndef mp_quo_digit +MULTUNIT mp_quo_digit (MULTUNIT *dividend) { + unsigned long q, q0, q1, q2; + unsigned short lsb_factor; + +/* Compute the least significant product group. + The last terms of q1 and q2 perform upward rounding, which is + needed to guarantee that the result not be too small. +*/ + q1 = (dividend[tohigher(-2)] ^ MULTUNIT_mask) * (unsigned long)reciph + + reciph; + q2 = (dividend[tohigher(-1)] ^ MULTUNIT_mask) * (unsigned long)recipl + + (1L << MULTUNITSIZE) ; +#ifdef ASM_PROTOTYPE + lsb_factor = 1 & (q1>>MULTUNITSIZE) & (q2>>MULTUNITSIZE); + q = q1 + q2; + + /* The following statement is equivalent to shifting the sum right + one bit while shifting in the carry bit. + */ + q0 = (q1 > ~q2 ? DMULTUNIT_msb : 0) | (q >> 1); +#else /* optimized C version */ + q0 = (q1>>1) + (q2>>1) + 1; +#endif + +/* Compute the middle significant product group. */ + + q1 = (dividend[tohigher(-1)] ^ MULTUNIT_mask) * (unsigned long)reciph; + q2 = (dividend[ 0] ^ MULTUNIT_mask) * (unsigned long)recipl; +#ifdef ASM_PROTOTYPE + q = q1 + q2; + q = (q1 > ~q2 ? DMULTUNIT_msb : 0) | (q >> 1); + +/* Add in the most significant word of the first group. + The last term takes care of the carry from adding the lsb's + that were shifted out prior to addition. +*/ + q = (q0 >> MULTUNITSIZE)+ q + (lsb_factor & (q1 ^ q2)); +#else /* optimized C version */ + q = (q0 >> MULTUNITSIZE)+ (q1>>1) + (q2>>1) + 1; +#endif + +/* Compute the most significant term and add in the others */ + + q = (q >> (MULTUNITSIZE-2)) + + (((dividend[0] ^ MULTUNIT_mask) * (unsigned long)reciph) << 1); + q >>= mshift; + +/* Prevent overflow and then wipe out the intermediate results. */ + + mutemp = (MULTUNIT)min(q, (1L << MULTUNITSIZE) -1); + q= q0 = q1 = q2 = 0; lsb_factor = 0; (void)lsb_factor; + return mutemp; +} +#endif /* mp_quo_digit */ + +/* stage_smith_modulus() - Prepare for a Smith modmult. + + Calculate the reciprocal of modulus with a precision of two MULTUNITs. + Assumes that global_precision has already been adjusted to the + size of the modulus, plus SLOP_BITS. + + Note: This routine was designed to work with large values and + doesn't have the necessary testing or handling to work with a + modulus having less than three significant units. For such cases, + the separate multiply and modulus routines can be used. + + stage_smith_modulus() is aliased to stage_modulus(). +*/ + +int stage_smith_modulus(unitptr n_modulus) +{ + int original_precision; + int sigmod; /* significant units in modulus */ + unitptr mp; /* modulus most significant pointer */ + MULTUNIT *mpm; /* reciprocal pointer */ + int prec; /* precision of reciprocal calc in units */ + + mp_move(modulus, n_modulus); + modmpl = (MULTUNIT*) modulus; + modmpl = lsbptr (modmpl, global_precision * MULTUNITs_perunit); + nbits = countbits(modulus); + modlenMULTUNITS = (nbits+ MULTUNITSIZE-1) / MULTUNITSIZE; + + original_precision = global_precision; + + /* The following code copies the three most significant units of + * modulus to mod_divisor. + */ + mp = modulus; + sigmod = significance (modulus); + rescale (mp, original_precision, sigmod); +/* prec is the unit precision required for 3 MULTUNITs */ + prec = (3 +(MULTUNITs_perunit-1)) / MULTUNITs_perunit; + set_precision (prec); + + /* set mp = ptr to most significant units of modulus, then move + * the most significant units to mp_divisor + */ + mp = msbptr(mp,sigmod) -tohigher(prec-1); + unmake_lsbptr (mp, prec); + mp_move (mod_divisor, mp); + + /* Keep 2*MULTUNITSIZE bits in mod_divisor. + * This will (normally) result in a reciprocal of 2*MULTUNITSIZE+1 bits. + */ + mshift = countbits (mod_divisor) - 2*MULTUNITSIZE; + mp_shift_right_bits (mod_divisor, mshift); + mp_recip(mod_quotient,mod_divisor); + mp_shift_right_bits (mod_quotient,1); + + /* Reduce to: 0 < mshift <= MULTUNITSIZE */ + mshift = ((mshift + (MULTUNITSIZE-1)) % MULTUNITSIZE) +1; + /* round up, rescaling if necessary */ + mp_inc (mod_quotient); + if (countbits (mod_quotient) > 2*MULTUNITSIZE) { + mp_shift_right_bits (mod_quotient,1); + mshift--; /* now 0 <= mshift <= MULTUNITSIZE */ + } + mpm = lsbptr ((MULTUNIT*)mod_quotient, prec*MULTUNITs_perunit); + recipl = *post_higherunit (mpm); + reciph = *mpm; + mp_set_recip (reciph, recipl, mshift); + set_precision (original_precision); + return(0); /* normal return */ +} /* stage_smith_modulus */ + +/* Smith's algorithm performs a multiply combined with a modulo operation. + Computes: prod = (multiplicand*multiplier) mod modulus + The modulus must first be set by stage_smith_modulus(). + smith_modmult() is aliased to mp_modmult(). +*/ + +int +smith_modmult(unitptr prod, unitptr multiplicand, unitptr multiplier) +{ + unitptr d; /* ptr to product */ + MULTUNIT *dmph, *dmpl, *dmp; /* ptrs to dividend (high, low, first) + * aligned for subtraction */ +/* Note that dmph points one MULTUNIT higher than indicated by + global precision. This allows us to zero out a word one higher than + the normal precision. +*/ + short orig_precision; + short nqd; /* number of quotient digits remaining to + * be generated */ + short dmi; /* number of significant MULTUNITs in product */ + + d = ds_data + 1; /* room for leading MSB if HIGHFIRST */ + orig_precision = global_precision; + mp_dmul(d, multiplicand, multiplier); + + rescale(d, orig_precision * 2, orig_precision * 2 + 1); + set_precision(orig_precision * 2 + 1); + *msbptr(d, global_precision) = 0; /* leading 0 unit */ + +/* We now start working with MULTUNITs. + Determine the most significant MULTUNIT of the product so we don't + have to process leading zeros in our divide loop. +*/ + dmi = significance(d) * MULTUNITs_perunit; + if (dmi >= modlenMULTUNITS) + { /* Make dividend negative. This allows the use of mp_smul to + * "subtract" the product of the modulus and the trial divisor + * by actually adding to a negative dividend. + * The one's complement of the dividend is used, since it causes + * a zero value to be represented as all ones. This facilitates + * testing the result for possible overflow, since a sign bit + * indicates that no adjustment is necessary, and we should not + * attempt to adjust if the result of the addition is zero. + */ + mp_inc(d); + mp_neg(d); + set_precision(orig_precision); + munit_prec = global_precision * UNITSIZE / MULTUNITSIZE; + + /* Set msb, lsb, and normal ptrs of dividend */ + dmph = lsbptr((MULTUNIT *) d, (orig_precision * 2 + 1) * + MULTUNITs_perunit) + tohigher(dmi); + nqd = dmi + 1 - modlenMULTUNITS; + dmpl = dmph - tohigher(modlenMULTUNITS); + +/* Divide loop. + Each iteration computes the next quotient MULTUNIT digit, then + multiplies the divisor (modulus) by the quotient digit and adds + it to the one's complement of the dividend (equivalent to + subtracting). If the product was greater than the remaining dividend, + we get a non-negative result, in which case we subtract off the + modulus to get the proper negative remainder. +*/ + for (; nqd; nqd--) + { MULTUNIT q; /* quotient trial digit */ + + q = mp_quo_digit(dmph); + if (q > 0) + { mp_smul(dmpl, modmpl, q); + + /* Perform correction if q too large. + * This rarely occurs. + */ + if (!(*dmph & MULTUNIT_msb)) + { dmp = dmpl; + unmake_lsbptr(dmp, orig_precision * + MULTUNITs_perunit); + if (mp_musubb(dmp, + (MULTUNIT *) modulus, 0)) + (*dmph) --; + } + } + pre_lowerunit(dmph); + pre_lowerunit(dmpl); + } + /* d contains the one's complement of the remainder. */ + rescale(d, orig_precision * 2 + 1, orig_precision); + set_precision(orig_precision); + mp_neg(d); + mp_dec(d); + } else + { /* Product was less than modulus. Return it. */ + rescale(d, orig_precision * 2 + 1, orig_precision); + set_precision(orig_precision); + } + mp_move(prod, d); + return (0); /* normal return */ +} /* smith_modmult */ + + +/* Smith's mp_modmult function leaves some internal arrays in memory, + so we have to call modmult_burn() at the end of mp_modexp. + This is so that no cryptographically sensitive data is left in memory + after the program exits. + smith_burn() is aliased to modmult_burn(). +*/ +void smith_burn(void) +{ + empty_array (modulus); + empty_array (ds_data); + empty_array (mod_quotient); + empty_array (mod_divisor); + modmpl = 0; + mshift =nbits = 0; + reciph = recipl = 0; + modlenMULTUNITS = mutemp = 0; + mp_set_recip (0,0,0); +} /* smith_burn */ + +/* End of Thad Smith's implementation of modmult. */ + +#endif /* SMITH */ + + +int countbits(unitptr r) + /* Returns number of significant bits in r */ +{ int bits; + short prec; + register unit bitmask; + init_bitsniffer(r,bitmask,prec,bits); + return(bits); +} /* countbits */ + + +const char *copyright_notice(void) +/* force linker to include copyright notice in the executable object image. */ +{ return ("(c)1986 Philip Zimmermann"); } /* copyright_notice */ + + +int mp_modexp(register unitptr expout,register unitptr expin, + register unitptr exponent,register unitptr modulus) +{ /* Russian peasant combined exponentiation/modulo algorithm. + Calls modmult instead of mult. + Computes: expout = (expin**exponent) mod modulus + WARNING: All the arguments must be less than the modulus! + */ + int bits; + short oldprecision; + register unit bitmask; + unit product[MAX_UNIT_PRECISION]; + short eprec; + +#ifdef COUNTMULTS + tally_modmults = 0; /* clear "number of modmults" counter */ + tally_modsquares = 0; /* clear "number of modsquares" counter */ +#endif /* COUNTMULTS */ + mp_init(expout,1); + if (testeq(exponent,0)) + { if (testeq(expin,0)) + return(-1); /* 0 to the 0th power means return error */ + return(0); /* otherwise, zero exponent means expout is 1 */ + } + if (testeq(modulus,0)) + return(-2); /* zero modulus means error */ +#if SLOP_BITS > 0 /* if there's room for sign bits */ + if (mp_tstminus(modulus)) + return(-2); /* negative modulus means error */ +#endif /* SLOP_BITS > 0 */ + if (mp_compare(expin,modulus) >= 0) + return(-3); /* if expin >= modulus, return error */ + if (mp_compare(exponent,modulus) >= 0) + return(-4); /* if exponent >= modulus, return error */ + + oldprecision = global_precision; /* save global_precision */ + /* set smallest optimum precision for this modulus */ + set_precision(bits2units(countbits(modulus)+SLOP_BITS)); + /* rescale all these registers to global_precision we just defined */ + rescale(modulus,oldprecision,global_precision); + rescale(expin,oldprecision,global_precision); + rescale(exponent,oldprecision,global_precision); + rescale(expout,oldprecision,global_precision); + + if (stage_modulus(modulus)) + { set_precision(oldprecision); /* restore original precision */ + return(-5); /* unstageable modulus (STEWART algorithm) */ + } + + /* normalize and compute number of bits in exponent first */ + init_bitsniffer(exponent,bitmask,eprec,bits); + + /* We can "optimize out" the first modsquare and modmult: */ + bits--; /* We know for sure at this point that bits>0 */ + mp_move(expout,expin); /* expout = (1*1)*expin; */ + bump_bitsniffer(exponent,bitmask); + + while (bits--) + { + poll_for_break(); /* polls keyboard, allows ctrl-C to abort program */ +#ifdef COUNTMULTS + tally_modsquares++; /* bump "number of modsquares" counter */ +#endif /* COUNTMULTS */ + mp_modsquare(product,expout); + if (sniff_bit(exponent,bitmask)) + { mp_modmult(expout,product,expin); +#ifdef COUNTMULTS + tally_modmults++; /* bump "number of modmults" counter */ +#endif /* COUNTMULTS */ + } else + { + mp_move(expout,product); + } + bump_bitsniffer(exponent,bitmask); + } /* while bits-- */ + mp_burn(product); /* burn the evidence on the stack */ + modmult_burn(); /* ask mp_modmult to also burn its own evidence */ + +#ifdef COUNTMULTS /* diagnostic analysis */ + { long atomic_mults; + unsigned int unitcount,totalmults; + unitcount = bits2units(countbits(modulus)); + /* calculation assumes modsquare takes as long as a modmult: */ + atomic_mults = (long) tally_modmults * (unitcount * unitcount); + atomic_mults += (long) tally_modsquares * (unitcount * unitcount); + printf("%ld atomic mults for ",atomic_mults); + printf("%d+%d = %d modsqr+modmlt, at %d bits, %d words.\n", + tally_modsquares,tally_modmults, + tally_modsquares+tally_modmults, + countbits(modulus), unitcount); + } +#endif /* COUNTMULTS */ + + set_precision(oldprecision); /* restore original precision */ + + /* Do an explicit reference to the copyright notice so that the linker + will be forced to include it in the executable object image... */ + copyright_notice(); /* has no real effect at run time */ + + return(0); /* normal return */ +} /* mp_modexp */ + +int mp_modexp_crt(unitptr expout, unitptr expin, + unitptr p, unitptr q, unitptr ep, unitptr eq, unitptr u) + /* This is a faster modexp for moduli with a known + factorisation into two relatively prime factors p and q, + and an input relatively prime to the modulus, + the Chinese Remainder Theorem to do the computation + mod p and mod q, and then combine the results. This + relies on a number of precomputed values, but does not + actually require the modulus n or the exponent e. + + expout = expin ^ e mod (p*q). + We form this by evaluating + p2 = (expin ^ e) mod p and + q2 = (expin ^ e) mod q + and then combining the two by the CRT. + + Two optimisations of this are possible. First, we can + reduce expin modulo p and q before starting. + + Second, since we know the factorisation of p and q + (trivially derived from the factorisation of n = p*q), + and expin is relatively prime to both p and q, + we can use Euler's theorem, expin^phi(m) = 1 (mod m), + to throw away multiples of phi(p) or phi(q) in e. + Letting ep = e mod phi(p) and + eq = e mod phi(q) + then combining these two speedups, we only need to evaluate + p2 = ((expin mod p) ^ ep) mod p and + q2 = ((expin mod q) ^ eq) mod q. + + Now we need to apply the CRT. Starting with + expout = p2 (mod p) and + expout = q2 (mod q) + we can say that expout = p2 + p * k, and if we assume that + 0 <= p2 < p, then 0 <= expout < p*q for some 0 <= k < q. + Since we want expout = q2 (mod q), then + p*k = q2-p2 (mod q). Since p and q are relatively + prime, p has a multiplicative inverse u mod q. In other + words, + u = 1/p (mod q). + Multiplying by u on both sides gives k = u*(q2-p2) (mod q). + Since we want 0 <= k < q, we can thus find k as + k = (u * (q2-p2)) mod q. + + Once we have k, evaluating p2 + p * k is easy, and + that gives us the result. + + In the detailed implementation, there is a temporary, temp, + used to hold intermediate results, p2 is held in expout, + and q2 is used as a temporary in the final step when it is + no longer needed. With that, you should be able to + understand the code below. + */ +{ + unit q2[MAX_UNIT_PRECISION]; + unit temp[MAX_UNIT_PRECISION]; + int status; + +/* First, compiute p2 (physically held in M) */ + +/* p2 = [ (expin mod p) ^ ep ] mod p */ + mp_mod(temp,expin,p); /* temp = expin mod p */ + status = mp_modexp(expout,temp,ep,p); + if (status < 0) /* mp_modexp returned an error. */ + { mp_init(expout,1); + return(status); /* error return */ + } + +/* And the same thing for q2 */ + +/* q2 = [ (expin mod q) ^ eq ] mod q */ + mp_mod(temp,expin,q); /* temp = expin mod q */ + status = mp_modexp(q2,temp,eq,q); + if (status < 0) /* mp_modexp returned an error. */ + { mp_init(expout,1); + return(status); /* error return */ + } + +/* Now use the multiplicative inverse u to glue together the + two halves. +*/ +#if 0 +/* This optimisation is useful if you commonly get small results, + but for random results and large q, the odds of (1/q) of it + being useful do not warrant the test. +*/ + if (mp_compare(expout,q2) != 0) + { +#endif + /* Find q2-p2 mod q */ + if (mp_sub(q2,expout)) /* if the result went negative */ + mp_add(q2,q); /* add q to q2 */ + + /* expout = p2 + ( p * [(q2*u) mod q] ) */ + mp_mult(temp,q2,u); /* q2*u */ + mp_mod(q2,temp,q); /* (q2*u) mod q */ + mp_mult(temp,p,q2); /* p * [(q2*u) mod q] */ + mp_add(expout,temp); /* expout = p2 + p * [...] */ +#if 0 + } +#endif + + mp_burn(q2); /* burn the evidence on the stack...*/ + mp_burn(temp); + return(0); /* normal return */ +} /* mp_modexp_crt */ + + +/****************** end of MPI library ****************************/ diff --git a/lib/mpilib.h b/lib/mpilib.h new file mode 100644 index 0000000..0227105 --- /dev/null +++ b/lib/mpilib.h @@ -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 +#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 ****************************/ diff --git a/lib/ncplib.c b/lib/ncplib.c index 8fc7af2..4fceafb 100644 --- a/lib/ncplib.c +++ b/lib/ncplib.c @@ -5,8 +5,20 @@ * */ +#if 0 +#define ncp_dprintf(X...) printf(X) +#else +#define ncp_dprintf(X...) +#endif #include "ncplib.h" #include "ncplib_err.h" +#ifdef SIGNATURES +#include "ncpsign.h" +#endif +#ifdef NDS_SUPPORT +extern int bindery_only; +#include "ndslib.h" +#endif #include extern pid_t wait(int *); @@ -20,17 +32,35 @@ extern pid_t wait(int *); #include #include #include -#include +#include "kernel/route.h" #include #include #include #include #include #include +#ifdef CONFIG_NATIVE_IP +#include +#endif + +#define NCP_DEFAULT_BUFSIZE 1024 +#define NCP_MAX_BUFSIZE 1024 +#ifdef SIGNATURES +#define NCP_DEFAULT_OPTIONS 2 +int in_options = NCP_DEFAULT_OPTIONS; +#endif static long ncp_negotiate_buffersize(struct ncp_conn *conn, int size, int *target); + +#ifdef SIGNATURES +static long + ncp_negotiate_size_and_options(struct ncp_conn *conn, + int size, int options, + int *ret_size, int *ret_options); +#endif + static long ncp_login_object(struct ncp_conn *conn, const unsigned char *username, @@ -38,11 +68,16 @@ static long const unsigned char *password); static long - ncp_do_close(struct ncp_conn *conn); +ncp_do_close(struct ncp_conn *conn); -void str_upper(char *name) +static long +ncp_find_server_ipx(const char **server_name, int type, struct sockaddr_ipx* addr); + +void +str_upper(char *name) { - while (*name) { + while (*name) + { *name = toupper(*name); name = name + 1; } @@ -53,11 +88,13 @@ void str_upper(char *name) static int debug_level = 5; static FILE *logfile = stderr; -static void dprintf(int level, char *p,...) +static void +dprintf(int level, char *p,...) { va_list ap; - if (level > debug_level) { + if (level > debug_level) + { return; } va_start(ap, p); @@ -73,7 +110,8 @@ static void dprintf(int level, char *p,...) the file nwcrypt.c intact and separate for copyright reasons */ #include "nwcrypt.c" -void ipx_fprint_node(FILE * file, IPXNode node) +void +ipx_fprint_node(FILE * file, IPXNode node) { fprintf(file, "%02X%02X%02X%02X%02X%02X", (unsigned char) node[0], @@ -85,17 +123,20 @@ void ipx_fprint_node(FILE * file, IPXNode node) ); } -void ipx_fprint_network(FILE * file, IPXNet net) +void +ipx_fprint_network(FILE * file, IPXNet net) { - fprintf(file, "%08lX", ntohl(net)); + fprintf(file, "%08X", (u_int32_t)ntohl(net)); } -void ipx_fprint_port(FILE * file, IPXPort port) +void +ipx_fprint_port(FILE * file, IPXPort port) { fprintf(file, "%04X", ntohs(port)); } -void ipx_fprint_saddr(FILE * file, struct sockaddr_ipx *sipx) +void +ipx_fprint_saddr(FILE * file, struct sockaddr_ipx *sipx) { ipx_fprint_network(file, sipx->sipx_network); fprintf(file, ":"); @@ -104,66 +145,80 @@ void ipx_fprint_saddr(FILE * file, struct sockaddr_ipx *sipx) ipx_fprint_port(file, sipx->sipx_port); } -void ipx_print_node(IPXNode node) +void +ipx_print_node(IPXNode node) { ipx_fprint_node(stdout, node); } -void ipx_print_network(IPXNet net) +void +ipx_print_network(IPXNet net) { ipx_fprint_network(stdout, net); } -void ipx_print_port(IPXPort port) +void +ipx_print_port(IPXPort port) { ipx_fprint_port(stdout, port); } -void ipx_print_saddr(struct sockaddr_ipx *sipx) +void +ipx_print_saddr(struct sockaddr_ipx *sipx) { ipx_fprint_saddr(stdout, sipx); } -int ipx_sscanf_node(char *buf, unsigned char node[6]) +int +ipx_sscanf_node(char *buf, unsigned char node[6]) { int i; int n[6]; if ((i = sscanf(buf, "%2x%2x%2x%2x%2x%2x", &(n[0]), &(n[1]), &(n[2]), - &(n[3]), &(n[4]), &(n[5]))) != 6) { + &(n[3]), &(n[4]), &(n[5]))) != 6) + { return i; } - for (i = 0; i < 6; i++) { + for (i = 0; i < 6; i++) + { node[i] = n[i]; } return 6; } -static int ipx_sscanf_saddr(char *buf, struct sockaddr_ipx *target) +int +ipx_sscanf_saddr(char *buf, struct sockaddr_ipx *target) { char *p; struct sockaddr_ipx addr; + unsigned long sipx_network; addr.sipx_family = AF_IPX; addr.sipx_type = NCP_PTYPE; - if (sscanf(buf, "%lx", (unsigned long int *) &addr.sipx_network) != 1) { + if (sscanf(buf, "%lx", &sipx_network) != 1) + { return 1; } - addr.sipx_network = htonl(addr.sipx_network); - if ((p = strchr(buf, ':')) == NULL) { + addr.sipx_network = htonl(sipx_network); + if ((p = strchr(buf, ':')) == NULL) + { return 1; } p += 1; - if (ipx_sscanf_node(p, addr.sipx_node) != 6) { + if (ipx_sscanf_node(p, addr.sipx_node) != 6) + { return 1; } - if ((p = strchr(p, ':')) == NULL) { + if ((p = strchr(p, ':')) == NULL) + { return 1; } p += 1; - if (sscanf(p, "%hx", &addr.sipx_port) != 1) { + if (sscanf(p, "%hx", &addr.sipx_port) != 1) + { return 1; } addr.sipx_port = htons(addr.sipx_port); @@ -171,19 +226,16 @@ static int ipx_sscanf_saddr(char *buf, struct sockaddr_ipx *target) return 0; } -void ipx_assign_node(IPXNode dest, IPXNode src) -{ - memcpy(dest, src, IPX_NODE_LEN); -} - -int ipx_node_equal(IPXNode n1, IPXNode n2) +int +ipx_node_equal(CIPXNode n1, CIPXNode n2) { return memcmp(n1, n2, IPX_NODE_LEN) == 0; } -static int ipx_recvfrom(int sock, void *buf, int len, unsigned int flags, - struct sockaddr_ipx *sender, int *addrlen, int timeout, - long *err) +static int +x_recvfrom(int sock, void *buf, int len, unsigned int flags, + struct sockaddr *sender, int *addrlen, int timeout, + long *err) { fd_set rd, wr, ex; struct timeval tv; @@ -197,34 +249,277 @@ static int ipx_recvfrom(int sock, void *buf, int len, unsigned int flags, tv.tv_sec = timeout; tv.tv_usec = 0; - if ((result = select(sock + 1, &rd, &wr, &ex, &tv)) == -1) { + if ((result = select(sock + 1, &rd, &wr, &ex, &tv)) == -1) + { *err = errno; return -1; } - if (FD_ISSET(sock, &rd)) { - result = recvfrom(sock, buf, len, flags, - (struct sockaddr *) sender, addrlen); - } else { + if (FD_ISSET(sock, &rd)) + { + result = sender?recvfrom(sock, buf, len, flags, + sender, addrlen): + recv(sock, buf, len, flags); + } else + { result = -1; errno = ETIMEDOUT; } - if (result < 0) { + if (result < 0) + { *err = errno; } return result; } -static int ipx_recv(int sock, void *buf, int len, unsigned int flags, int timeout, - long *err) +static int +x_recv(int sock, void *buf, int len, unsigned int flags, int timeout, + long *err) { - struct sockaddr_ipx sender; - int addrlen = sizeof(sender); - - return ipx_recvfrom(sock, buf, len, flags, &sender, &addrlen, + return x_recvfrom(sock, buf, len, flags, NULL, 0, timeout, err); } -static int install_wdog(struct ncp_conn *conn) +#ifdef __MAKE_SULIB__ +static long +ipx_sap_find_nearest(int server_type, struct sockaddr_ipx *result, + char server_name[NCP_BINDERY_NAME_LEN]) +{ + struct sockaddr_ipx addr; + char data[1024]; + int sock; + int opt; + int packets; + int len; + + struct sap_server_ident *ident; + + if ((sock = socket(PF_IPX, SOCK_DGRAM, IPXPROTO_IPX)) < 0) + { + if (errno == EINVAL) + { + return NCPL_ET_NO_IPX; + } + return errno; + } + opt = 1; + /* Permit broadcast output */ + if (setsockopt(sock, SOL_SOCKET, SO_BROADCAST, &opt, sizeof(opt)) == -1) + { + goto finished; + } + memzero(addr); + addr.sipx_family = AF_IPX; + addr.sipx_network = htonl(0x0); + addr.sipx_port = htons(0x0); + addr.sipx_type = IPX_SAP_PTYPE; + + if (bind(sock, (struct sockaddr *) &addr, sizeof(addr)) == -1) + { + if (errno == EADDRNOTAVAIL) + { + errno = NCPL_ET_NO_INTERFACE; + } + goto finished; + } + WSET_HL(data, 0, IPX_SAP_NEAREST_QUERY); + WSET_HL(data, 2, server_type); + + memzero(addr); + addr.sipx_family = AF_IPX; + addr.sipx_port = htons(IPX_SAP_PORT); + addr.sipx_type = IPX_SAP_PTYPE; + addr.sipx_network = htonl(0x0); + ipx_assign_node(addr.sipx_node, IPX_BROADCAST_NODE); + + if (sendto(sock, data, 4, 0, + (struct sockaddr *) &addr, sizeof(addr)) < 0) + { + goto finished; + } + packets = 5; + do + { + long err; + len = x_recv(sock, data, 1024, 0, 1, &err); + if (len < 66) + { + packets = packets - 1; + continue; + } + } + while ((ntohs(*((__u16 *) data)) != IPX_SAP_NEAREST_RESPONSE) + && (packets > 0)); + + if (packets == 0) + { + close(sock); + return NCPL_ET_NO_SERVER; + } + ident = (struct sap_server_ident *) (data + 2); + + result->sipx_family = AF_IPX; + result->sipx_network = ident->server_network; + result->sipx_port = ident->server_port; + ipx_assign_node(result->sipx_node, ident->server_node); + + memcpy(server_name, ident->server_name, sizeof(ident->server_name)); + + errno = 0; + + finished: + close(sock); + return errno; +} +#endif /* __MAKE_SULIB__ */ + +static int +ipx_make_reachable(const struct sockaddr_ipx* target) +{ +#ifdef __MAKE_SULIB__ + IPXNet network = target->sipx_network; + struct rtentry rt_def; + /* Router */ + struct sockaddr_ipx *sr = (struct sockaddr_ipx *) &rt_def.rt_gateway; + /* Target */ + struct sockaddr_ipx *st = (struct sockaddr_ipx *) &rt_def.rt_dst; + + struct ipx_rip_packet rip; + struct sockaddr_ipx addr; + int addrlen; + int sock; + int opt; + int res = -1; + int i; + int packets; + + if (geteuid() != 0) + { + errno = EPERM; + return -1; + } + memzero(rip); + + sock = socket(PF_IPX, SOCK_DGRAM, IPXPROTO_IPX); + + if (sock == -1) + { + if (errno == EINVAL) + { + return NCPL_ET_NO_IPX; + } + return errno; + } + opt = 1; + /* Permit broadcast output */ + if (setsockopt(sock, SOL_SOCKET, SO_BROADCAST, &opt, sizeof(opt)) != 0) + { + goto finished; + } + memzero(addr); + addr.sipx_family = AF_IPX; + addr.sipx_network = htonl(0x0); + addr.sipx_port = htons(0x0); + addr.sipx_type = IPX_RIP_PTYPE; + + if (bind(sock, (struct sockaddr *) &addr, sizeof(addr)) != 0) + { + goto finished; + } + addr.sipx_family = AF_IPX; + addr.sipx_port = htons(IPX_RIP_PORT); + addr.sipx_type = IPX_RIP_PTYPE; + addr.sipx_network = htonl(0x0); + ipx_assign_node(addr.sipx_node, IPX_BROADCAST_NODE); + + rip.operation = htons(IPX_RIP_REQUEST); + rip.rt[0].network = network; + + if (sendto(sock, &rip, sizeof(rip), 0, + (struct sockaddr *) &addr, sizeof(addr)) < 0) + { + goto finished; + } + packets = 3; + do + { + long err; + int len; + + if (packets == 0) + { + goto finished; + } + addrlen = sizeof(struct sockaddr_ipx); + + len = x_recvfrom(sock, &rip, sizeof(rip), 0, (struct sockaddr*)sr, &addrlen, 1, + &err); + + if (len < sizeof(rip)) + { + packets = packets - 1; + continue; + } + } + while (ntohs(rip.operation) != IPX_RIP_RESPONSE); + + if (rip.rt[0].network != network) + { + goto finished; + } + rt_def.rt_flags = RTF_GATEWAY; + st->sipx_network = network; + st->sipx_family = AF_IPX; + sr->sipx_family = AF_IPX; + + i = 0; + do + { + res = ioctl(sock, SIOCADDRT, &rt_def); + i++; + } + while ((i < 5) && (res < 0) && (errno == EAGAIN)); + + finished: + close(sock); + + if (res != 0) + { + errno = ENETUNREACH; + } + return res; +#else + FILE *p; + char buf[40]; + + sprintf(buf, "nwsfind -a %08x:%02x%02x%02x%02x%02x%02x:%04x", + (u_int32_t)ntohl(target->sipx_network), + ((const unsigned char*)target->sipx_node)[0], + ((const unsigned char*)target->sipx_node)[1], + ((const unsigned char*)target->sipx_node)[2], + ((const unsigned char*)target->sipx_node)[3], + ((const unsigned char*)target->sipx_node)[4], + ((const unsigned char*)target->sipx_node)[5], + ntohs(target->sipx_port)); + + if (!(p = popen(buf, "r"))) { + return errno; + } + fgets(buf, sizeof(buf), p); + if (pclose(p)) { + return ENETUNREACH; + } + return 0; +#endif +} + +void +ipx_assign_node(IPXNode dest, CIPXNode src) +{ + memcpy(dest, src, IPX_NODE_LEN); +} + +static int +install_wdog(struct ncp_conn *conn) { int parent_pid = getpid(); int pid; @@ -236,28 +531,33 @@ static int install_wdog(struct ncp_conn *conn) int pktsize; - if ((pid = fork()) < 0) { + if ((pid = fork()) < 0) + { return -1; } - if (pid != 0) { + if (pid != 0) + { /* Parent, should go on as usual */ conn->wdog_pid = pid; return 0; } - while (1) { + while (1) + { long err; /* every 120 seconds we look if our parent is still alive */ - pktsize = ipx_recvfrom(sock, buf, sizeof(buf), 0, - &sender, &sizeofaddr, 120, &err); + pktsize = x_recvfrom(sock, buf, sizeof(buf), 0, + (struct sockaddr*)&sender, &sizeofaddr, 120, &err); - if (getppid() != parent_pid) { + if (getppid() != parent_pid) + { /* our parent has died, so nothing to do anymore */ exit(0); } if ((pktsize != 2) - || (buf[1] != '?')) { + || (buf[1] != '?')) + { continue; } buf[1] = 'Y'; @@ -272,26 +572,31 @@ static int install_wdog(struct ncp_conn *conn) static void assert_conn_locked(struct ncp_conn *conn); -static void assert_conn_not_locked(struct ncp_conn *conn) +static void +assert_conn_not_locked(struct ncp_conn *conn) { - if (conn->lock != 0) { + if (conn->lock != 0) + { ncp_printf("ncpfs: conn already locked!\n"); } } -static void ncp_lock_conn(struct ncp_conn *conn) +static void +ncp_lock_conn(struct ncp_conn *conn) { assert_conn_not_locked(conn); conn->lock = 1; } -static void ncp_unlock_conn(struct ncp_conn *conn) +static void +ncp_unlock_conn(struct ncp_conn *conn) { assert_conn_locked(conn); conn->lock = 0; } -static long do_ncp_call(struct ncp_conn *conn, int request_size) +static long +do_ncp_call(struct ncp_conn *conn, int request_size) { struct ncp_request_header request; @@ -301,53 +606,58 @@ static long do_ncp_call(struct ncp_conn *conn, int request_size) long err; memcpy(&request, conn->packet, sizeof(request)); +#ifdef SIGNATURES + if (conn->sign_active) + { + sign_packet(conn, &request_size); + } +#endif - while (retries > 0) { + while (retries > 0) + { struct ncp_reply_header reply; - struct sockaddr_ipx sender; - int sizeofaddr = sizeof(sender); retries -= 1; - result = sendto(conn->ncp_sock, conn->packet, - request_size, - 0, (struct sockaddr *) &(conn->i.addr), - sizeof(conn->i.addr)); + result = send(conn->ncp_sock, conn->packet, + request_size, 0); - if (result < 0) { + if (result < 0) + { return errno; } re_select: - len = ipx_recvfrom(conn->ncp_sock, - (char *) &reply, sizeof(reply), - MSG_PEEK, &sender, &sizeofaddr, 3, &err); + len = x_recv(conn->ncp_sock, + (char *) &reply, sizeof(reply), + MSG_PEEK, 3, &err); - if ((len < 0) && (err == ETIMEDOUT)) { + if ((len < 0) && (err == ETIMEDOUT)) + { continue; } - if (len < 0) { + if (len < 0) + { return err; } - if ( /* Is the sender wrong? */ - (memcmp(&sender.sipx_node, - &(conn->i.addr.sipx_node), 6) != 0) - || (sender.sipx_port != conn->i.addr.sipx_port) + if ( /* Did the sender send a positive acknowledge? */ - || ((len == sizeof(reply)) + ((len == sizeof(reply)) && (reply.type == NCP_POSITIVE_ACK)) + /* Did we get a bogus answer? */ || ((len < sizeof(reply)) || (reply.type != NCP_REPLY) - || ((request.type != NCP_ALLOC_SLOT_REQUEST) - && ((reply.sequence != request.sequence) - || (reply.conn_low != request.conn_low) - || (reply.conn_high != request.conn_high))))) { + || ((request.type != NCP_ALLOC_SLOT_REQUEST) + && ((reply.sequence != request.sequence) + || (reply.conn_low != request.conn_low) + || (reply.conn_high != request.conn_high))))) + { /* Then throw away the packet */ - ipx_recv(conn->ncp_sock, (char *) &reply, sizeof(reply), + x_recv(conn->ncp_sock, (char *) &reply, sizeof(reply), 0, 1, &err); goto re_select; } - ipx_recv(conn->ncp_sock, conn->packet, NCP_PACKET_SIZE, + len = x_recv(conn->ncp_sock, conn->packet, NCP_PACKET_SIZE, 0, 1, &err); conn->reply_size = len; return 0; @@ -355,14 +665,16 @@ static long do_ncp_call(struct ncp_conn *conn, int request_size) return ETIMEDOUT; } -static int ncp_mount_request(struct ncp_conn *conn, int function) +static int +ncp_mount_request(struct ncp_conn *conn, int function) { struct ncp_ioctl_request request; int result; assert_conn_locked(conn); - if (conn->has_subfunction != 0) { + if (conn->has_subfunction != 0) + { WSET_HL(conn->packet, 7, conn->current_size - sizeof(struct ncp_request_header) - 2); } @@ -370,20 +682,23 @@ static int ncp_mount_request(struct ncp_conn *conn, int function) request.size = conn->current_size; request.data = conn->packet; - if ((result = ioctl(conn->mount_fid, NCP_IOC_NCPREQUEST, &request)) < 0) { + if ((result = ioctl(conn->mount_fid, NCP_IOC_NCPREQUEST, &request)) < 0) + { return result; } conn->completion = BVAL(conn->packet, 6); conn->conn_status = BVAL(conn->packet, 7); conn->ncp_reply_size = result - sizeof(struct ncp_reply_header); - if ((conn->completion != 0) && (conn->verbose != 0)) { + if ((conn->completion != 0) && (conn->verbose != 0)) + { ncp_printf("ncp_request_error: %d\n", conn->completion); } return conn->completion == 0 ? 0 : NCPL_ET_REQUEST_ERROR; } -static long ncp_temp_request(struct ncp_conn *conn, int function) +static long +ncp_temp_request(struct ncp_conn *conn, int function) { long err; @@ -398,11 +713,13 @@ static long ncp_temp_request(struct ncp_conn *conn, int function) BSET(conn->packet, 4, 1); BSET(conn->packet, 6, function); - if (conn->has_subfunction != 0) { + if (conn->has_subfunction != 0) + { WSET_HL(conn->packet, 7, conn->current_size - sizeof(struct ncp_request_header) - 2); } - if ((err = do_ncp_call(conn, conn->current_size)) != 0) { + if ((err = do_ncp_call(conn, conn->current_size)) != 0) + { return err; } conn->completion = BVAL(conn->packet, 6); @@ -410,42 +727,71 @@ static long ncp_temp_request(struct ncp_conn *conn, int function) conn->ncp_reply_size = conn->reply_size - sizeof(struct ncp_reply_header); - if ((conn->completion != 0) && (conn->verbose != 0)) { + if ((conn->completion != 0) && (conn->verbose != 0)) + { ncp_printf("ncp_completion_code: %d\n", conn->completion); } return conn->completion == 0 ? 0 : NCPL_ET_REQUEST_ERROR; } -#ifdef PACKET_SIGNATURES -static long ncp_setup_security(struct ncp_conn *conn) +long +ncp_renegotiate_connparam(struct ncp_conn *conn, int buffsize, int in_options) { - __u8 security; - __u8 accepted_security; - __u16 socket, size; + int neg_buffsize; + int err; +#ifdef SIGNATURES + int options; + + /* TODO: Signatures active? I am not sure whether we can unnegotiate them */ + if (conn->sign_active) in_options |= 2; - conn->want_signatures = 0; - if (ncp_get_big_ncp_max_packet_size(conn, 576, 0, &size, &socket, - &accepted_security) != 0) { - return 0; + if ((err = ncp_negotiate_size_and_options(conn, buffsize, in_options, + &neg_buffsize, &options)) == 0) + { + if ((options & 2) != (in_options & 2)) + { + err = ncp_negotiate_size_and_options(conn, + buffsize, options & 2, &neg_buffsize, &options); + } } - if ((accepted_security & NCP_SEC_SIGNATURE_REQUESTED) == 0) { - return 0; + else +#endif + { +#ifdef SIGNATURES + options = 0; +#endif + err = ncp_negotiate_buffersize(conn, NCP_DEFAULT_BUFSIZE, + &neg_buffsize); + } + if (err) { + return err; } - security = NCP_SEC_SIGNATURE_REQUESTED; - if (ncp_get_big_ncp_max_packet_size(conn, 576, security, - &size, &socket, - &accepted_security) != 0) { - return 0; - } - if ((accepted_security & NCP_SEC_SIGNATURE_REQUESTED) != 0) { - conn->want_signatures = 1; + if ((neg_buffsize < 512) || (neg_buffsize > NCP_MAX_BUFSIZE)) + return -1; + conn->i.buffer_size = neg_buffsize; +#ifdef SIGNATURES + conn->sign_wanted = (options & 2) ? 1:0; + if (conn->is_connected == CONN_PERMANENT) { + int cursign; + + if (ioctl(conn->mount_fid, NCP_IOC_SIGN_WANTED, &cursign)) { + /* ncpfs does not support SIGN_WANTED -> current sign level = 0 */ + cursign = 0; + } + if (cursign) cursign = 1; + if (cursign != conn->sign_wanted) { + int newsign = conn->sign_wanted; + + err = ioctl(conn->mount_fid, NCP_IOC_SET_SIGN_WANTED, &newsign); + } } +#endif return 0; } -#endif -static long ncp_connect_addr(struct ncp_conn *conn, const struct sockaddr_ipx *target, - int wdog_needed) +static long +ncp_connect_ipx_addr(struct ncp_conn *conn, const struct sockaddr_ipx *target, + int wdog_needed) { struct sockaddr_ipx addr; int addrlen; @@ -456,10 +802,13 @@ static long ncp_connect_addr(struct ncp_conn *conn, const struct sockaddr_ipx *t conn->is_connected = NOT_CONNECTED; conn->verbose = 0; - if ((ncp_sock = socket(AF_IPX, SOCK_DGRAM, PF_IPX)) == -1) { + if ((ncp_sock = socket(PF_IPX, SOCK_DGRAM, IPXPROTO_IPX)) == -1) + { return errno; } - if ((wdog_sock = socket(AF_IPX, SOCK_DGRAM, PF_IPX)) == -1) { + if ((wdog_sock = socket(PF_IPX, SOCK_DGRAM, IPXPROTO_IPX)) == -1) + { + close(ncp_sock); return errno; } addr.sipx_family = AF_IPX; @@ -471,7 +820,8 @@ static long ncp_connect_addr(struct ncp_conn *conn, const struct sockaddr_ipx *t addrlen = sizeof(addr); if ((bind(ncp_sock, (struct sockaddr *) &addr, sizeof(addr)) == -1) - || (getsockname(ncp_sock, (struct sockaddr *) &addr, &addrlen) == -1)) { + || (getsockname(ncp_sock, (struct sockaddr *) &addr, &addrlen) == -1)) + { int saved_errno = errno; close(ncp_sock); close(wdog_sock); @@ -479,7 +829,8 @@ static long ncp_connect_addr(struct ncp_conn *conn, const struct sockaddr_ipx *t } addr.sipx_port = htons(ntohs(addr.sipx_port) + 1); - if (bind(wdog_sock, (struct sockaddr *) &addr, sizeof(addr)) == -1) { + if (bind(wdog_sock, (struct sockaddr *) &addr, sizeof(addr)) == -1) + { int saved_errno = errno; close(ncp_sock); close(wdog_sock); @@ -491,6 +842,18 @@ static long ncp_connect_addr(struct ncp_conn *conn, const struct sockaddr_ipx *t conn->sequence = 0; conn->i.addr = *target; + if (connect(ncp_sock, (const struct sockaddr*)target, sizeof(*target)) == -1) + { + int saved_errno = errno; + + if ((saved_errno != ENETUNREACH) || ipx_make_reachable(target) + || connect(ncp_sock, (const struct sockaddr*)target, sizeof(*target))) {; + close(ncp_sock); + close(wdog_sock); + return saved_errno; + } + } + WSET_LH(conn->packet, 0, NCP_ALLOC_SLOT_REQUEST); BSET(conn->packet, 2, conn->sequence); BSET(conn->packet, 3, 0xff); @@ -498,14 +861,24 @@ static long ncp_connect_addr(struct ncp_conn *conn, const struct sockaddr_ipx *t BSET(conn->packet, 5, 0xff); BSET(conn->packet, 6, 0); - if ((err = do_ncp_call(conn, sizeof(struct ncp_request_header))) != 0) { - close(ncp_sock); - close(wdog_sock); - return err; + if ((err = do_ncp_call(conn, sizeof(struct ncp_request_header))) != 0) + { + if ((err != ENETUNREACH) + || (ipx_make_reachable(target) != 0) + || ((err = + do_ncp_call(conn, + sizeof(struct ncp_request_header))) != 0)) + { + close(ncp_sock); + close(wdog_sock); + return err; + } } - if (wdog_needed != 0) { + if (wdog_needed != 0) + { install_wdog(conn); - } else { + } else + { conn->wdog_pid = 0; } @@ -514,115 +887,370 @@ static long ncp_connect_addr(struct ncp_conn *conn, const struct sockaddr_ipx *t BVAL(conn->packet, 3) + (BVAL(conn->packet, 5) << 8); conn->is_connected = CONN_TEMPORARY; - if ((ncp_negotiate_buffersize(conn, 1024, - &(conn->i.buffer_size)) != 0) - || (conn->i.buffer_size < 512) - || (conn->i.buffer_size > 1024)) { +#ifdef SIGNATURES + conn->sign_active = 0; + conn->sign_wanted = 0; + err = ncp_renegotiate_connparam(conn, NCP_DEFAULT_BUFSIZE, in_options); +#else + err = ncp_renegotiate_connparam(conn, NCP_DEFAULT_BUFSIZE, 0); +#endif + + if (err != 0) + { ncp_do_close(conn); return -1; } return 0; } -static long ncp_connect_any(struct ncp_conn *conn, int wdog_needed) +#ifdef CONFIG_NATIVE_IP +static long +ncp_connect_in_addr(struct ncp_conn *conn, const struct sockaddr_in *target, + int wdog_needed) { - struct sockaddr_ipx *addr; - long result; - const char *server = NULL; + struct sockaddr_in addr; + int addrlen; + + int ncp_sock; long err; - if ((addr = ncp_find_server(&server, NCP_BINDERY_FSERVER, &err)) == NULL) { + conn->is_connected = NOT_CONNECTED; + conn->verbose = 0; + + if ((ncp_sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1) + { + return errno; + } + addr.sin_family = AF_INET; + addr.sin_port = htons(0x0); + addr.sin_addr.s_addr = INADDR_ANY; + + addrlen = sizeof(addr); + + if (bind(ncp_sock, (struct sockaddr *) &addr, sizeof(addr)) == -1) + { + int saved_errno = errno; + close(ncp_sock); + return saved_errno; + } + + conn->ncp_sock = ncp_sock; + conn->wdog_sock = -1; + + conn->sequence = 0; + conn->i.addr = *(const struct sockaddr_ipx*)target; + + if (connect(ncp_sock, (const struct sockaddr*)target, sizeof(*target)) == -1) + { + int saved_errno = errno; + close(ncp_sock); + return saved_errno; + } + + WSET_LH(conn->packet, 0, NCP_ALLOC_SLOT_REQUEST); + BSET(conn->packet, 2, conn->sequence); + BSET(conn->packet, 3, 0xff); + BSET(conn->packet, 4, 1); + BSET(conn->packet, 5, 0xff); + BSET(conn->packet, 6, 0); + + if ((err = do_ncp_call(conn, sizeof(struct ncp_request_header))) != 0) + { + /* ? request route ? */ + close(ncp_sock); return err; } - if ((result = ncp_connect_addr(conn, addr, wdog_needed)) != 0) { + + conn->wdog_pid = 0; + + conn->sequence = 0; + conn->i.connection = + BVAL(conn->packet, 3) + (BVAL(conn->packet, 5) << 8); + conn->is_connected = CONN_TEMPORARY; + +#ifdef SIGNATURES + conn->sign_active = 0; + conn->sign_wanted = 0; + err = ncp_renegotiate_connparam(conn, NCP_DEFAULT_BUFSIZE, in_options); +#else + err = ncp_renegotiate_connparam(conn, NCP_DEFAULT_BUFSIZE, 0); +#endif + + if (err != 0) + { + ncp_do_close(conn); + return -1; + } + return 0; +} +#endif /* CONFIG_NATIVE_IP */ + +static long +ncp_connect_addr(struct ncp_conn *conn, const struct sockaddr *target, + int wdog_needed) { + if (target->sa_family == AF_IPX) { + return ncp_connect_ipx_addr(conn, (const struct sockaddr_ipx*)target, wdog_needed); + } +#ifdef CONFIG_NATIVE_IP + if (target->sa_family == AF_INET) { + return ncp_connect_in_addr(conn, (const struct sockaddr_in*)target, wdog_needed); + } +#endif /* CONFIG_NATIVE_IP */ + return EAFNOSUPPORT; +} + +static long +ncp_connect_any(struct ncp_conn *conn, int wdog_needed) +{ +#ifndef __MAKE_SULIB__ + const char* server = NULL; +#else /* __MAKE_SULIB__ */ + char server[NCP_BINDERY_NAME_LEN]; +#endif /* __MAKE_SULIB__ */ + struct sockaddr_ipx addr; + long result; + +#ifndef __MAKE_SULIB__ + if ((result = ncp_find_server_ipx(&server, NCP_BINDERY_FSERVER, &addr)) != 0) +#else /* __MAKE_SULIB__ */ + if ((result = ipx_sap_find_nearest(IPX_SAP_FILE_SERVER, + &addr, server)) != 0) +#endif /* __MAKE_SULIB__ */ + { + return result; + } + if ((result = ncp_connect_ipx_addr(conn, &addr, wdog_needed)) != 0) + { return result; } strcpy(conn->server, server); return 0; } -struct sockaddr_ipx * - ncp_find_fileserver(const char *server_name, long *err) +static long +ncp_find_server_ipx(const char **server_name, int type, struct sockaddr_ipx* server_addr) { - return ncp_find_server(&server_name, NCP_BINDERY_FSERVER, err); -} - -struct sockaddr_ipx * - ncp_find_server(const char **server_name, int type, long *err) -{ - char command[256]; - char buf[128]; char server[NCP_BINDERY_NAME_LEN + 1]; - static struct sockaddr_ipx result; +#ifndef __MAKE_SULIB__ + char command[256]; + static char buf[128]; FILE *p; int res; char *n; +#else + long err; + static char nearest[NCP_BINDERY_NAME_LEN + 1]; + struct nw_property prop; + struct prop_net_address *n_addr = (struct prop_net_address *) ∝ + struct ncp_conn conn; + + initialize_NCPL_error_table(); +#endif /* __MAKE_SULIB__ */ memset(server, 0, sizeof(server)); - if (*server_name != NULL) { +#ifndef __MAKE_SULIB__ + if (*server_name != NULL) + { strncpy(server, *server_name, sizeof(server) - 1); str_upper(server); } sprintf(command, "nwsfind -t %d %s", type, server); p = popen(command, "r"); - if (p == NULL) { - *err = errno; - return NULL; + if (p == NULL) + { + return errno; } fgets(buf, sizeof(buf), p); - - if (buf[strlen(buf)] - 1 == '\n'); + res = strlen(buf); + if (res && (buf[res - 1] == '\n')) { - buf[strlen(buf)] = '\0'; + buf[res - 1] = '\0'; } - - if (((res = pclose(p)) != 0) || (ipx_sscanf_saddr(buf, &result) != 0)) { - *err = (*server_name != NULL) + if (((res = pclose(p)) != 0) || (ipx_sscanf_saddr(buf, server_addr) != 0)) + { + return (*server_name != NULL) ? NCPL_ET_HOST_UNKNOWN : NCPL_ET_NO_SERVER; - return NULL; } - if (*server_name == NULL) { - if ((n = strchr(buf, ' ')) == NULL) { - *err = NCPL_ET_HOST_UNKNOWN; - return NULL; + if (*server_name == NULL) + { + if ((n = strchr(buf, ' ')) == NULL) + { + return NCPL_ET_HOST_UNKNOWN; } *server_name = n; } - return &result; + return 0; +#else /* __MAKE_SULIB__ */ + memset(nearest, 0, sizeof(nearest)); + + if (*server_name != NULL) + { + if (strlen(*server_name) >= sizeof(server)) + { + return NCPL_ET_NAMETOOLONG; + } + strcpy(server, *server_name); + str_upper(server); + } + if ((err = ipx_sap_find_nearest(type, server_addr, nearest)) != 0) + { + return err; + } + /* We have to ask the nearest server for our wanted server */ + memzero(conn); + if ((err = ncp_connect_ipx_addr(&conn, server_addr, 0)) != 0) + { + return err; + } + if (*server_name == NULL) + { + *server_name = nearest; + ncp_do_close(&conn); + return 0; + } + /* The following optimization should have been done before + ncp_connect_addr. This would be convenient if there was a + simple way to find out whether there is a route to the + server. Parsing /proc/net/ipx_route is not too nice, so we + just connect to the server and immediately disconnect + again. This way we also find out if the server still has + free connection slots. */ + if (strcmp(server, nearest) == 0) + { + /* Our wanted server answered the SAP GNS request, so + use it */ + ncp_do_close(&conn); + return 0; + } + if (ncp_read_property_value(&conn, type, server, 1, + "NET_ADDRESS", &prop) != 0) + { + ncp_do_close(&conn); + return NCPL_ET_HOST_UNKNOWN; + } + if ((err = ncp_do_close(&conn)) != 0) + { + return err; + } + server_addr->sipx_family = AF_IPX; + server_addr->sipx_network = n_addr->network; + server_addr->sipx_port = n_addr->port; + ipx_assign_node(server_addr->sipx_node, n_addr->node); + + /* To make the final server reachable, we connect again. See + above. (When can we rely on all users running ipxd??? :-)) */ + memzero(conn); + if (((err = ncp_connect_ipx_addr(&conn, server_addr, 0)) != 0) + || ((err = ncp_do_close(&conn)) != 0)) + { + return err; + } + return 0; +#endif /* __MAKE_SULIB__ */ } -static long ncp_open_temporary(struct ncp_conn *conn, - const struct ncp_conn_spec *spec) +long +ncp_find_server(const char **server_name, int type, struct sockaddr* addr, size_t len) { + long err = NCPL_ET_HOST_UNKNOWN; + if (len >= sizeof(struct sockaddr_ipx)) { + err = ncp_find_server_ipx(server_name, type, (struct sockaddr_ipx*)addr); + if (!err) return 0; + } + return err; +} + +long +ncp_find_fileserver(const char *server_name, struct sockaddr* addr, size_t len) { - struct sockaddr_ipx *addr; - long err; + return ncp_find_server(&server_name, NCP_BINDERY_FSERVER, addr, len); +} - if (spec == NULL) { - return ncp_connect_any(conn, 1); - } - if ((addr = ncp_find_fileserver(spec->server, &err)) == NULL) { - return err; - } - if ((err = ncp_connect_addr(conn, addr, 1)) != 0) { - return err; - } - strcpy(conn->server, spec->server); +static int +ncp_login_conn(struct ncp_conn* conn, const char* object_name, int object_type, const char* password) { + int err; - if (strlen(spec->user) != 0) { - if (ncp_login_object(conn, spec->user, spec->login_type, - spec->password) != 0) { - ncp_do_close(conn); - return EACCES; +#ifdef NDS_SUPPORT + if (!nds_get_tree_name(conn, NULL, 0)) + { + err = nds_login_auth(conn, object_name, password); + if (!err) return 0; + if ((err == NCPL_ET_REQUEST_ERROR) && (conn->completion == NDS_GRACE_PERIOD)) { + fprintf(stderr, "Your password has expired\n"); + return 0; } - strcpy(conn->user, spec->user); + fprintf(stderr, "Unable to NDS log-in (error %d), trying bindery...\n", conn->completion); + } +#endif + if (ncp_login_object(conn, object_name, object_type, password) != 0) + { + return EACCES; } return 0; } +static long +ncp_open_temporary(struct ncp_conn *conn, + const char* server) +{ + struct sockaddr addr; + long err; + + if (server == NULL) + { + return ncp_connect_any(conn, 1); + } + if ((err = ncp_find_fileserver(server, &addr, sizeof(addr))) != 0) + { + return err; + } + if ((err = ncp_connect_addr(conn, &addr, 1)) != 0) + { + return err; + } + strcpy(conn->server, server); + + return 0; +} + +static long +ncp_open_temporary2(struct ncp_conn *conn, + const char* address, + const char* server) +{ +#ifdef CONFIG_NATIVE_IP + struct sockaddr_in addr; + long err; + struct hostent* h; + + if (!address) return EFAULT; + + h = gethostbyname(address); + if (!h) return NCPL_ET_HOST_UNKNOWN; + if (h->h_addrtype != AF_INET) return EAFNOSUPPORT; + if (h->h_length != 4) return EAFNOSUPPORT; + addr.sin_family = AF_INET; + addr.sin_port = htons(0x020C); + memcpy(&addr.sin_addr.s_addr, h->h_addr, 4); + + if ((err = ncp_connect_addr(conn, (struct sockaddr*)&addr, 1)) != 0) + { + return err; + } + strcpy(conn->server, server); + + return 0; +#else /* CONFIG_NATIVE_IP */ + (void)conn; + (void)address; + (void)server; + return EAFNOSUPPORT; +#endif /* CONFIG_NATIVE_IP */ +} + char * - ncp_find_permanent(const struct ncp_conn_spec *spec) +ncp_find_permanent(const struct ncp_conn_spec *spec) { FILE *mtab; struct ncp_conn_ent *conn_ent; @@ -632,28 +1260,34 @@ char * initialize_NCPL_error_table(); - if ((mtab = fopen(MOUNTED, "r")) == NULL) { + if ((mtab = fopen(MOUNTED, "r")) == NULL) + { return NULL; } - while ((conn_ent = ncp_get_conn_ent(mtab)) != NULL) { - if (spec != NULL) { + while ((conn_ent = ncp_get_conn_ent(mtab)) != NULL) + { + if (spec != NULL) + { if ((conn_ent->uid != spec->uid) || ((strlen(spec->server) != 0) && (strcasecmp(conn_ent->server, spec->server) != 0)) || ((strlen(spec->user) != 0) && (strcasecmp(conn_ent->user, - spec->user) != 0))) { + spec->user) != 0))) + { continue; } } mount_fid = open(conn_ent->mount_point, O_RDONLY, 0); - if (mount_fid < 0) { + if (mount_fid < 0) + { continue; } i.version = NCP_GET_FS_INFO_VERSION; - if (ioctl(mount_fid, NCP_IOC_GET_FS_INFO, &i) < 0) { + if (ioctl(mount_fid, NCP_IOC_GET_FS_INFO, &i) < 0) + { close(mount_fid); continue; } @@ -667,106 +1301,132 @@ char * return result; } -static int ncp_open_permanent(struct ncp_conn *conn, - const struct ncp_conn_spec *spec) +#ifdef SIGNATURES +static void +ncp_sign_init_perm(struct ncp_conn *conn) +{ + if (ioctl(conn->mount_fid, NCP_IOC_SIGN_WANTED, + &conn->sign_wanted) != 0) + conn->sign_wanted = 0; + conn->sign_active = 0; +} +#endif + +static int +ncp_open_permanent(const struct ncp_conn_spec *spec, struct ncp_conn** conn) { char *mount_point; + int err; - if (conn->is_connected != NOT_CONNECTED) { - errno = EBUSY; + if ((mount_point = ncp_find_permanent(spec)) == NULL) + { return -1; } - if ((mount_point = ncp_find_permanent(spec)) == NULL) { - return -1; + err = ncp_open_mount(mount_point, conn); + if (!err) { + if (spec != NULL) { + strncpy((*conn)->server, spec->server, sizeof((*conn)->server)); + strncpy((*conn)->user, spec->user, sizeof((*conn)->user)); + } else { + memset((*conn)->server, '\0', sizeof((*conn)->server)); + memset((*conn)->user, '\0', sizeof((*conn)->user)); + } } - if (strlen(mount_point) >= sizeof(conn->mount_point)) { - errno = ENAMETOOLONG; - return -1; - } - /* The rest has already been done in ncp_find_permanent, so we - * do not check errors anymore */ - conn->mount_fid = open(mount_point, O_RDONLY, 0); - conn->i.version = NCP_GET_FS_INFO_VERSION; - ioctl(conn->mount_fid, NCP_IOC_GET_FS_INFO, &(conn->i)); - if (spec != NULL) { - strncpy(conn->server, spec->server, sizeof(conn->server)); - strncpy(conn->user, spec->user, sizeof(conn->user)); - } else { - memset(conn->server, '\0', sizeof(conn->server)); - memset(conn->user, '\0', sizeof(conn->user)); - } - strcpy(conn->mount_point, mount_point); - conn->is_connected = CONN_PERMANENT; - return 0; + return err; } -struct ncp_conn * - ncp_open(const struct ncp_conn_spec *spec, long *err) +static struct ncp_conn * +ncp_open_2(const struct ncp_conn_spec *spec, long *err, const char* address) { struct ncp_conn *result; initialize_NCPL_error_table(); + if (ncp_open_permanent(spec, &result) == 0) { + return result; + } + result = malloc(sizeof(struct ncp_conn)); - if (result == NULL) { + if (result == NULL) + { *err = ENOMEM; return NULL; } memzero(*result); - if (ncp_open_permanent(result, spec) == 0) { - return result; + if (spec) { + *err = ncp_open_temporary2(result, address, spec->server); + if (*err) *err = ncp_open_temporary(result, spec->server); + } else { + *err = ncp_connect_any(result, 1); } - if ((*err = ncp_open_temporary(result, spec)) != 0) { + if (*err) { free(result); return NULL; } + if (spec && (strlen(spec->user) != 0)) { + *err = ncp_login_conn(result, spec->user, spec->login_type, spec->password); + if (*err) { + ncp_close(result); + return NULL; + } + strcpy(result->user, spec->user); + } return result; } - struct ncp_conn * - ncp_open_mount(const char *mount_point, long *err) +ncp_open(const struct ncp_conn_spec *spec, long *err) { + return ncp_open_2(spec, err, NULL); +} + +int +ncp_open_mount(const char *mount_point, struct ncp_conn** conn) { struct ncp_conn *result; initialize_NCPL_error_table(); + *conn = NULL; + if (strlen(mount_point) >= sizeof(result->mount_point)) { - *err = ENAMETOOLONG; - return NULL; + return ENAMETOOLONG; } result = malloc(sizeof(struct ncp_conn)); if (result == NULL) { - *err = ENOMEM; - return NULL; + return ENOMEM; } memzero(*result); result->is_connected = NOT_CONNECTED; result->mount_fid = open(mount_point, O_RDONLY, 0); - if (result->mount_fid < 0) { + if (result->mount_fid < 0) + { free(result); - *err = ENODEV; - return NULL; + return ENODEV; } strcpy(result->mount_point, mount_point); result->is_connected = CONN_PERMANENT; result->i.version = NCP_GET_FS_INFO_VERSION; - if (ioctl(result->mount_fid, NCP_IOC_GET_FS_INFO, &(result->i)) != 0) { + if (ioctl(result->mount_fid, NCP_IOC_GET_FS_INFO, &(result->i)) != 0) + { free(result); - *err = NCPL_ET_NO_NCPFS_FILE; - return NULL; + return NCPL_ET_NO_NCPFS_FILE; } - return result; +#ifdef SIGNATURES + ncp_sign_init_perm(result); +#endif + *conn = result; + return 0; } -static long ncp_user_disconnect(struct ncp_conn *conn) +static long +ncp_user_disconnect(struct ncp_conn *conn) { long result; @@ -779,24 +1439,30 @@ static long ncp_user_disconnect(struct ncp_conn *conn) BSET(conn->packet, 5, (conn->i.connection) >> 8); BSET(conn->packet, 6, 0); - if ((result = do_ncp_call(conn, sizeof(struct ncp_request_header))) != 0) { + if ((result = do_ncp_call(conn, sizeof(struct ncp_request_header))) != 0) + { return result; } close(conn->ncp_sock); - close(conn->wdog_sock); + if (conn->wdog_sock != -1) { + close(conn->wdog_sock); + } - if (conn->wdog_pid != 0) { + if (conn->wdog_pid != 0) + { kill(conn->wdog_pid, SIGTERM); wait(NULL); } return 0; } -static long ncp_do_close(struct ncp_conn *conn) +static long +ncp_do_close(struct ncp_conn *conn) { long result = -1; - switch (conn->is_connected) { + switch (conn->is_connected) + { case CONN_PERMANENT: result = close(conn->mount_fid); break; @@ -814,21 +1480,36 @@ static long ncp_do_close(struct ncp_conn *conn) return result; } -long ncp_close(struct ncp_conn *conn) +long +ncp_close(struct ncp_conn *conn) { long result; - if (conn == NULL) { + if (conn == NULL) + { return 0; } - if ((result = ncp_do_close(conn)) != 0) { + if ((result = ncp_do_close(conn)) != 0) + { return result; } free(conn); return 0; } +int +ncp_get_mount_uid(int fid, uid_t* uid) +{ + __kernel_uid_t k_uid; + int err; + + err = ioctl(fid, NCP_IOC_GETMOUNTUID, &k_uid); + if (err) return err; + *uid = k_uid; + return 0; +} + struct ncp_conn_ent * - ncp_get_conn_ent(FILE * filep) +ncp_get_conn_ent(FILE * filep) { static struct ncp_conn_ent entry; char server[2 * NCP_BINDERY_NAME_LEN]; @@ -839,25 +1520,31 @@ struct ncp_conn_ent * memzero(server); memzero(entry); - while ((mnt_ent = getmntent(filep)) != NULL) { - if (strcmp(mnt_ent->mnt_type, "ncpfs") != 0) { + while ((mnt_ent = getmntent(filep)) != NULL) + { + if (strcmp(mnt_ent->mnt_type, "ncpfs") != 0) + { continue; } - if (strlen(mnt_ent->mnt_fsname) >= sizeof(server)) { + if (strlen(mnt_ent->mnt_fsname) >= sizeof(server)) + { continue; } strcpy(server, mnt_ent->mnt_fsname); user = strchr(server, '/'); - if (user != NULL) { + if (user != NULL) + { *user = '\0'; user += 1; - if (strlen(user) >= sizeof(entry.user)) { + if (strlen(user) >= sizeof(entry.user)) + { continue; } strcpy(entry.user, user); } if ((strlen(server) >= sizeof(entry.server)) - || (strlen(mnt_ent->mnt_dir) >= sizeof(entry.mount_point))) { + || (strlen(mnt_ent->mnt_dir) >= sizeof(entry.mount_point))) + { continue; } strcpy(entry.server, server); @@ -865,10 +1552,12 @@ struct ncp_conn_ent * fid = open(entry.mount_point, O_RDONLY, 0); - if (fid == -1) { + if (fid == -1) + { continue; } - if (ioctl(fid, NCP_IOC_GETMOUNTUID, &entry.uid) != 0) { + if (ncp_get_mount_uid(fid, &entry.uid) != 0) + { close(fid); continue; } @@ -880,7 +1569,7 @@ struct ncp_conn_ent * } static struct ncp_conn_spec * - ncp_get_nwc_ent(FILE * nwc) +ncp_get_nwc_ent(FILE * nwc) { static struct ncp_conn_spec spec; char line[512]; @@ -891,41 +1580,51 @@ static struct ncp_conn_spec * memzero(spec); spec.uid = getuid(); - while (fgets(line, sizeof(line), nwc) != NULL) { + while (fgets(line, sizeof(line), nwc) != NULL) + { if ((line[0] == '\n') - || (line[0] == '#')) { + || (line[0] == '#')) + { continue; } line_len = strlen(line); - if (line[line_len - 1] == '\n') { + if (line[line_len - 1] == '\n') + { line[line_len - 1] = '\0'; } user = strchr(line, '/'); password = strchr(user != NULL ? user : line, ' '); - if (password != NULL) { + if (password != NULL) + { *password = '\0'; password += 1; } - if (user != NULL) { + if (user != NULL) + { *user = '\0'; user += 1; - if (strlen(user) >= sizeof(spec.user)) { + if (strlen(user) >= sizeof(spec.user)) + { continue; } strcpy(spec.user, user); } - if (strlen(line) >= sizeof(spec.server)) { + if (strlen(line) >= sizeof(spec.server)) + { continue; } strcpy(spec.server, line); - if (password != NULL) { - while (*password == ' ') { + if (password != NULL) + { + while (*password == ' ') + { password += 1; } - if (strlen(password) >= sizeof(spec.password)) { + if (strlen(password) >= sizeof(spec.password)) + { continue; } strcpy(spec.password, password); @@ -936,27 +1635,32 @@ static struct ncp_conn_spec * } FILE * - ncp_fopen_nwc(const char *user, const char *mode, long *err) +ncp_fopen_nwc(const char *user, const char *mode, long *err) { char path[MAXPATHLEN]; char *home = NULL; struct stat st; - if (mode == NULL) { + if (mode == NULL) + { mode = "r"; } - if (user == NULL) { + if (user == NULL) + { home = getenv("HOME"); - } else { + } else + { struct passwd *pwd; - if ((pwd = getpwnam(user)) != NULL) { + if ((pwd = getpwnam(user)) != NULL) + { home = pwd->pw_dir; } } if ((home == NULL) - || (strlen(home) + sizeof(NWCLIENT) + 2 > sizeof(path))) { + || (strlen(home) + sizeof(NWCLIENT) + 2 > sizeof(path))) + { *err = ENAMETOOLONG; return NULL; } @@ -964,26 +1668,25 @@ FILE * strcat(path, "/"); strcat(path, NWCLIENT); - if (stat(path, &st) != 0) { + if (stat(path, &st) != 0) + { *err = errno; return NULL; } - if ((st.st_mode & (S_IRWXO | S_IRWXG)) != 0) { + if ((st.st_mode & (S_IRWXO | S_IRWXG)) != 0) + { *err = NCPL_ET_INVALID_MODE; return NULL; } return fopen(path, mode); } - 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_spec2(const char *server, const char *user, const char *password, + int login_necessary, uid_t uid, int allow_multiple_conns, long *err) { static struct ncp_conn_spec spec; - struct ncp_conn conn; - FILE *nwc; struct ncp_conn_spec *nwc_ent; @@ -993,21 +1696,26 @@ struct ncp_conn_spec * memzero(spec); spec.uid = getuid(); - if (server != NULL) { - if (strlen(server) >= sizeof(spec.server)) { + if (server != NULL) + { + if (strlen(server) >= sizeof(spec.server)) + { *err = NCPL_ET_NAMETOOLONG; return NULL; } strcpy(spec.server, server); - } else { - if ((nwc = ncp_fopen_nwc(NULL, NULL, err)) == NULL) { + } else + { + if ((nwc = ncp_fopen_nwc(NULL, NULL, err)) == NULL) + { *err = NCPL_ET_NO_SERVER; return NULL; } nwc_ent = ncp_get_nwc_ent(nwc); fclose(nwc); - if (nwc_ent == NULL) { + if (nwc_ent == NULL) + { *err = NCPL_ET_NO_SPEC; return NULL; } @@ -1017,13 +1725,16 @@ struct ncp_conn_spec * str_upper(spec.server); - if (login_necessary == 0) { + if (login_necessary == 0) + { memset(spec.user, 0, sizeof(spec.user)); memset(spec.password, 0, sizeof(spec.password)); return &spec; } - if (user != NULL) { - if (strlen(user) >= sizeof(spec.user)) { + if (user != NULL) + { + if (strlen(user) >= sizeof(spec.user)) + { *err = NCPL_ET_NAMETOOLONG; return NULL; } @@ -1032,24 +1743,35 @@ struct ncp_conn_spec * str_upper(spec.user); spec.login_type = NCP_BINDERY_USER; - if (ncp_open_permanent(&conn, &spec) == 0) { - ncp_do_close(&conn); - return &spec; + if (!allow_multiple_conns) { + struct ncp_conn* conn; + + if (ncp_open_permanent(&spec, &conn) == 0) + { + ncp_close(conn); + return &spec; + } } - if (password != NULL) { - if (strlen(password) >= sizeof(spec.password)) { + if (password != NULL) + { + if (strlen(password) >= sizeof(spec.password)) + { *err = NCPL_ET_NAMETOOLONG; return NULL; } strcpy(spec.password, password); - } else { - if ((nwc = ncp_fopen_nwc(NULL, NULL, err)) != NULL) { - while ((nwc_ent = ncp_get_nwc_ent(nwc)) != NULL) { + } else + { + if ((nwc = ncp_fopen_nwc(NULL, NULL, err)) != NULL) + { + while ((nwc_ent = ncp_get_nwc_ent(nwc)) != NULL) + { if ((strcasecmp(spec.server, nwc_ent->server) != 0) || ((*spec.user != '\0') && (strcasecmp(spec.user, - nwc_ent->user) != 0))) { + nwc_ent->user) != 0))) + { continue; } strcpy(spec.user, nwc_ent->user); @@ -1060,25 +1782,31 @@ struct ncp_conn_spec * } } - if (strlen(spec.user) == 0) { + if (strlen(spec.user) == 0) + { *err = NCPL_ET_NO_USER; return NULL; } - if ((strlen(spec.password) == 0) && (password == NULL)) { + if ((strlen(spec.password) == 0) && (password == NULL)) + { char *password; - if (!(isatty(0) && isatty(1))) { + if (!(isatty(0) && isatty(1))) + { return NULL; } printf("Logging into %s as %s\n", spec.server, spec.user); password = getpass("Password: "); - if (strlen(password) > sizeof(spec.password)) { + if (strlen(password) > sizeof(spec.password)) + { return NULL; } strcpy(spec.password, password); - } else { - if (strcmp(spec.password, NWC_NOPASSWORD) == 0) { + } else + { + if (strcmp(spec.password, NWC_NOPASSWORD) == 0) + { *spec.password = '\0'; } } @@ -1089,21 +1817,32 @@ struct ncp_conn_spec * return &spec; } +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) { + return ncp_find_conn_spec2(server, user, password, login_necessary, + uid, 0, err); +} + 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) { - char *server = NULL; - char *user = NULL; - char *password = NULL; + const char *server = NULL; + const char *user = NULL; + const char *password = NULL; + const char *address = NULL; struct ncp_conn_spec *spec; int i = 1; - int get_argument(int arg_no, char **target) { + int get_argument(int arg_no, const char **target) + { int count = 1; - if (target != NULL) { - if (arg_no + 1 >= *argc) { + if (target != NULL) + { + if (arg_no + 1 >= *argc) + { /* No argument to switch */ errno = EINVAL; return -1; @@ -1113,7 +1852,8 @@ struct ncp_conn * } /* Delete the consumed switch from the argument list and decrement the argument count */ - while (count + arg_no < *argc) { + while (count + arg_no < *argc) + { argv[arg_no] = argv[arg_no + count]; arg_no += 1; } @@ -1125,34 +1865,58 @@ struct ncp_conn * *err = EINVAL; - while (i < *argc) { + while (i < *argc) + { if ((argv[i][0] != '-') - || (strlen(argv[i]) != 2)) { + || (strlen(argv[i]) != 2)) + { i += 1; continue; } - switch (argv[i][1]) { + switch (argv[i][1]) + { case 'S': - if (get_argument(i, &server) != 0) { + if (get_argument(i, &server) != 0) + { return NULL; } continue; case 'U': - if (get_argument(i, &user) != 0) { + if (get_argument(i, &user) != 0) + { return NULL; } continue; case 'P': - if (get_argument(i, &password) != 0) { + if (get_argument(i, &password) != 0) + { return NULL; } continue; case 'n': - if (get_argument(i, 0) != 0) { + if (get_argument(i, NULL) != 0) + { return NULL; } password = NWC_NOPASSWORD; continue; +#ifdef NDS_SUPPORT + case 'b': + if (get_argument(i, NULL) != 0) + { + return NULL; + } + bindery_only = 1; + continue; +#endif +#ifdef CONFIG_NATIVE_IP + case 'A': + if (get_argument(i, &address) != 0) + { + return NULL; + } + continue; +#endif /* CONFIG_NATIVE_IP */ } i += 1; } @@ -1160,32 +1924,38 @@ struct ncp_conn * spec = ncp_find_conn_spec(server, user, password, login_necessary, getuid(), err); - if (spec == NULL) { - if (login_necessary != 0) { + if (spec == NULL) + { + if (login_necessary != 0) + { return NULL; - } else { + } else + { return ncp_open(NULL, err); } } spec->login_type = login_type; - if (login_necessary == 0) { + if (login_necessary == 0) + { spec->user[0] = '\0'; } - return ncp_open(spec, err); + return ncp_open_2(spec, err, address); } 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) { return ncp_initialize_as(argc, argv, login_necessary, NCP_BINDERY_USER, err); } -static long ncp_request(struct ncp_conn *conn, int function) +static long +ncp_request(struct ncp_conn *conn, int function) { - switch (conn->is_connected) { + switch (conn->is_connected) + { case CONN_PERMANENT: return ncp_mount_request(conn, function); case CONN_TEMPORARY: @@ -1201,12 +1971,15 @@ static long ncp_request(struct ncp_conn *conn, int function) /* */ /****************************************************************************/ -static inline int min(int a, int b) +static inline int +min(int a, int b) { return (a < b) ? a : b; } -struct nw_time_buffer { +#ifndef __MAKE_SULIB__ +struct nw_time_buffer +{ __u8 year __attribute__((packed)); __u8 month __attribute__((packed)); __u8 day __attribute__((packed)); @@ -1217,7 +1990,7 @@ struct nw_time_buffer { }; static time_t - nw_to_ctime(struct nw_time_buffer *source) +nw_to_ctime(struct nw_time_buffer *source) { struct tm u_time; @@ -1229,20 +2002,25 @@ static time_t u_time.tm_mon = source->month - 1; u_time.tm_year = source->year; - if (u_time.tm_year < 80) { + if (u_time.tm_year < 80) + { u_time.tm_year += 100; } return mktime(&u_time); } +#endif /* not __MAKE_SULIB__ */ -static void assert_conn_locked(struct ncp_conn *conn) +static void +assert_conn_locked(struct ncp_conn *conn) { - if (conn->lock == 0) { + if (conn->lock == 0) + { ncp_printf("ncpfs: conn not locked!\n"); } } -static void ncp_add_byte(struct ncp_conn *conn, byte x) +static void +ncp_add_byte(struct ncp_conn *conn, byte x) { assert_conn_locked(conn); BSET(conn->packet, conn->current_size, x); @@ -1250,7 +2028,8 @@ static void ncp_add_byte(struct ncp_conn *conn, byte x) return; } -static void ncp_add_word_lh(struct ncp_conn *conn, word x) +static void +ncp_add_word_lh(struct ncp_conn *conn, word x) { assert_conn_locked(conn); WSET_LH(conn->packet, conn->current_size, x); @@ -1258,7 +2037,8 @@ static void ncp_add_word_lh(struct ncp_conn *conn, word x) return; } -static void ncp_add_dword_lh(struct ncp_conn *conn, dword x) +static void +ncp_add_dword_lh(struct ncp_conn *conn, dword x) { assert_conn_locked(conn); DSET_LH(conn->packet, conn->current_size, x); @@ -1266,7 +2046,8 @@ static void ncp_add_dword_lh(struct ncp_conn *conn, dword x) return; } -static void ncp_add_word_hl(struct ncp_conn *conn, word x) +static void +ncp_add_word_hl(struct ncp_conn *conn, word x) { assert_conn_locked(conn); WSET_HL(conn->packet, conn->current_size, x); @@ -1274,15 +2055,19 @@ static void ncp_add_word_hl(struct ncp_conn *conn, word x) return; } -static void ncp_add_dword_hl(struct ncp_conn *conn, dword x) +#ifndef __MAKE_SULIB__ +static void +ncp_add_dword_hl(struct ncp_conn *conn, dword x) { assert_conn_locked(conn); DSET_HL(conn->packet, conn->current_size, x); conn->current_size += 4; return; } +#endif /* __MAKE_SULIB__ */ -static void ncp_add_mem(struct ncp_conn *conn, const void *source, int size) +static void +ncp_add_mem(struct ncp_conn *conn, const void *source, int size) { assert_conn_locked(conn); memcpy(&(conn->packet[conn->current_size]), source, size); @@ -1290,11 +2075,13 @@ static void ncp_add_mem(struct ncp_conn *conn, const void *source, int size) return; } -static void ncp_add_pstring(struct ncp_conn *conn, const char *s) +static void +ncp_add_pstring(struct ncp_conn *conn, const char *s) { int len = strlen(s); assert_conn_locked(conn); - if (len > 255) { + if (len > 255) + { ncp_printf("ncpfs: string too long: %s\n", s); len = 255; } @@ -1303,7 +2090,8 @@ static void ncp_add_pstring(struct ncp_conn *conn, const char *s) return; } -static void ncp_init_request(struct ncp_conn *conn) +static void +ncp_init_request(struct ncp_conn *conn) { ncp_lock_conn(conn); @@ -1311,7 +2099,8 @@ static void ncp_init_request(struct ncp_conn *conn) conn->has_subfunction = 0; } -static void ncp_init_request_s(struct ncp_conn *conn, int subfunction) +static void +ncp_init_request_s(struct ncp_conn *conn, int subfunction) { ncp_init_request(conn); ncp_add_word_lh(conn, 0); /* preliminary size */ @@ -1322,37 +2111,39 @@ static void ncp_init_request_s(struct ncp_conn *conn, int subfunction) } static char * - ncp_reply_data(struct ncp_conn *conn, int offset) +ncp_reply_data(struct ncp_conn *conn, int offset) { return &(conn->packet[sizeof(struct ncp_reply_header) + offset]); } static byte - ncp_reply_byte(struct ncp_conn *conn, int offset) +ncp_reply_byte(struct ncp_conn *conn, int offset) { return *(byte *) (ncp_reply_data(conn, offset)); } static word - ncp_reply_word_hl(struct ncp_conn *conn, int offset) +ncp_reply_word_hl(struct ncp_conn *conn, int offset) { return WVAL_HL(ncp_reply_data(conn, offset), 0); } +#ifndef __MAKE_SULIB__ static word - ncp_reply_word_lh(struct ncp_conn *conn, int offset) +ncp_reply_word_lh(struct ncp_conn *conn, int offset) { return WVAL_LH(ncp_reply_data(conn, offset), 0); } +#endif /* __MAKE_SULIB__ */ static dword - ncp_reply_dword_hl(struct ncp_conn *conn, int offset) +ncp_reply_dword_hl(struct ncp_conn *conn, int offset) { return DVAL_HL(ncp_reply_data(conn, offset), 0); } static dword - ncp_reply_dword_lh(struct ncp_conn *conn, int offset) +ncp_reply_dword_lh(struct ncp_conn *conn, int offset) { return DVAL_LH(ncp_reply_data(conn, offset), 0); } @@ -1360,15 +2151,17 @@ static dword /* Here the ncp calls begin */ -static long ncp_negotiate_buffersize(struct ncp_conn *conn, - int size, int *target) +static long +ncp_negotiate_buffersize(struct ncp_conn *conn, + int size, int *target) { long result; ncp_init_request(conn); ncp_add_word_hl(conn, size); - if ((result = ncp_request(conn, 33)) != 0) { + if ((result = ncp_request(conn, 33)) != 0) + { ncp_unlock_conn(conn); return result; } @@ -1378,15 +2171,45 @@ static long ncp_negotiate_buffersize(struct ncp_conn *conn, return 0; } +#ifdef SIGNATURES +static long + ncp_negotiate_size_and_options(struct ncp_conn *conn, + int size, int options, + int *ret_size, int *ret_options) +{ + long result; -long ncp_get_file_server_description_strings(struct ncp_conn *conn, - char target[512]) + ncp_init_request(conn); + ncp_add_word_hl(conn, size); + ncp_add_byte(conn, options); + + if ((result = ncp_request(conn, 0x61)) != 0) + { + ncp_unlock_conn(conn); + return result; + } + if (ncp_reply_word_hl(conn, 0) == 0) + *ret_size = size; + else + *ret_size = min(ncp_reply_word_hl(conn, 0), size); + *ret_options = ncp_reply_byte(conn, 4); + + ncp_unlock_conn(conn); + return 0; +} +#endif + +#ifndef __MAKE_SULIB__ +long +ncp_get_file_server_description_strings(struct ncp_conn *conn, + char target[512]) { long result; ncp_init_request_s(conn, 201); - if ((result = ncp_request(conn, 23)) != 0) { + if ((result = ncp_request(conn, 23)) != 0) + { ncp_unlock_conn(conn); return result; } @@ -1395,13 +2218,15 @@ long ncp_get_file_server_description_strings(struct ncp_conn *conn, return 0; } -long ncp_get_file_server_time(struct ncp_conn *conn, time_t * target) +long +ncp_get_file_server_time(struct ncp_conn *conn, time_t * target) { long result; ncp_init_request(conn); - if ((result = ncp_request(conn, 20)) != 0) { + if ((result = ncp_request(conn, 20)) != 0) + { ncp_unlock_conn(conn); return result; } @@ -1410,14 +2235,16 @@ long ncp_get_file_server_time(struct ncp_conn *conn, time_t * target) return 0; } -long ncp_set_file_server_time(struct ncp_conn *conn, time_t * source) +long +ncp_set_file_server_time(struct ncp_conn *conn, time_t * source) { long result; int year; struct tm *utime = localtime(source); year = utime->tm_year; - if (year > 99) { + if (year > 99) + { year -= 100; } ncp_init_request_s(conn, 202); @@ -1433,12 +2260,14 @@ long ncp_set_file_server_time(struct ncp_conn *conn, time_t * source) return result; } -long ncp_get_file_server_information(struct ncp_conn *conn, - struct ncp_file_server_info *target) +long +ncp_get_file_server_information(struct ncp_conn *conn, + struct ncp_file_server_info *target) { long result; ncp_init_request_s(conn, 17); - if ((result = ncp_request(conn, 23)) != 0) { + if ((result = ncp_request(conn, 23)) != 0) + { ncp_unlock_conn(conn); return result; } @@ -1455,9 +2284,10 @@ long ncp_get_file_server_information(struct ncp_conn *conn, return 0; } -long ncp_get_connlist(struct ncp_conn *conn, - __u16 object_type, const char *object_name, - int *returned_no, __u8 conn_numbers[256]) +long +ncp_get_connlist(struct ncp_conn *conn, + __u16 object_type, const char *object_name, + int *returned_no, __u8 conn_numbers[256]) { long result; @@ -1465,7 +2295,8 @@ long ncp_get_connlist(struct ncp_conn *conn, ncp_add_word_hl(conn, object_type); ncp_add_pstring(conn, object_name); - if ((result = ncp_request(conn, 23)) != 0) { + if ((result = ncp_request(conn, 23)) != 0) + { ncp_unlock_conn(conn); return result; } @@ -1475,16 +2306,18 @@ long ncp_get_connlist(struct ncp_conn *conn, return 0; } -long ncp_get_stations_logged_info(struct ncp_conn *conn, - __u32 connection, - struct ncp_bindery_object *target, - time_t * login_time) +long +ncp_get_stations_logged_info(struct ncp_conn *conn, + __u32 connection, + struct ncp_bindery_object *target, + time_t * login_time) { long result; ncp_init_request_s(conn, 28); ncp_add_dword_lh(conn, connection); - if ((result = ncp_request(conn, 23)) != 0) { + if ((result = ncp_request(conn, 23)) != 0) + { ncp_unlock_conn(conn); return result; } @@ -1499,16 +2332,18 @@ long ncp_get_stations_logged_info(struct ncp_conn *conn, return 0; } -long ncp_get_internet_address(struct ncp_conn *conn, - __u32 connection, - struct sockaddr_ipx *target, - __u8 * conn_type) +long +ncp_get_internet_address(struct ncp_conn *conn, + __u32 connection, + struct sockaddr_ipx *target, + __u8 * conn_type) { long result; ncp_init_request_s(conn, 26); ncp_add_dword_lh(conn, connection); - if ((result = ncp_request(conn, 23)) != 0) { + if ((result = ncp_request(conn, 23)) != 0) + { ncp_unlock_conn(conn); return result; } @@ -1521,18 +2356,20 @@ long ncp_get_internet_address(struct ncp_conn *conn, return 0; } -long ncp_send_broadcast(struct ncp_conn *conn, - __u8 no_conn, const __u8 * connections, - const char *message) +long +ncp_send_broadcast(struct ncp_conn *conn, + __u8 no_conn, const __u8 * connections, + const char *message) { long result; - if (strlen(message) > 58) { + if (strlen(message) > 58) + { return NCPL_ET_MSG_TOO_LONG; } ncp_init_request_s(conn, 0); ncp_add_byte(conn, no_conn); - ncp_add_mem(conn, (char *) (connections), no_conn); + ncp_add_mem(conn, connections, no_conn); ncp_add_pstring(conn, message); result = ncp_request(conn, 21); @@ -1540,21 +2377,53 @@ long ncp_send_broadcast(struct ncp_conn *conn, return result; } +long +ncp_send_broadcast2(struct ncp_conn *conn, + unsigned int conns, const unsigned int* connlist, + const char* message) +{ + int i; + long result; + + i = strlen(message); + if (i > 255) + { + return NCPL_ET_MSG_TOO_LONG; + } + if (conns > 350) /* max pkt len ~ 1KB */ + /* maybe do it by handshaked length ? */ + return NCPL_ET_MSG_TOO_LONG; + + ncp_init_request_s(conn, 0x0A); + ncp_add_word_lh(conn, conns); + for (;conns; --conns) + ncp_add_dword_lh(conn, *connlist++); + ncp_add_byte(conn, i); + ncp_add_mem(conn, message, i); + result = ncp_request(conn, 0x15); + ncp_unlock_conn(conn); + return result; +} +#endif /* not __MAKE_SULIB__ */ + /* * target is a 8-byte buffer */ -long ncp_get_encryption_key(struct ncp_conn *conn, - char *target) +long +ncp_get_encryption_key(struct ncp_conn *conn, + char *target) { long result; ncp_init_request_s(conn, 23); - if ((result = ncp_request(conn, 23)) != 0) { + if ((result = ncp_request(conn, 23)) != 0) + { ncp_unlock_conn(conn); return result; } - if (conn->ncp_reply_size < 8) { + if (conn->ncp_reply_size < 8) + { ncp_printf("ncp_reply_size %d < 8\n", conn->ncp_reply_size); ncp_unlock_conn(conn); @@ -1565,21 +2434,24 @@ long ncp_get_encryption_key(struct ncp_conn *conn, return 0; } -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_id(struct ncp_conn *conn, + __u16 object_type, + const char *object_name, + struct ncp_bindery_object *target) { long result; ncp_init_request_s(conn, 53); ncp_add_word_hl(conn, object_type); ncp_add_pstring(conn, object_name); - if ((result = ncp_request(conn, 23)) != 0) { + if ((result = ncp_request(conn, 23)) != 0) + { ncp_unlock_conn(conn); return result; } - if (conn->ncp_reply_size < 54) { + if (conn->ncp_reply_size < 54) + { ncp_printf("ncp_reply_size %d < 54\n", conn->ncp_reply_size); ncp_unlock_conn(conn); @@ -1592,15 +2464,18 @@ long ncp_get_bindery_object_id(struct ncp_conn *conn, return 0; } -long ncp_get_bindery_object_name(struct ncp_conn *conn, - __u32 object_id, - struct ncp_bindery_object *target) +#ifndef __MAKE_SULIB__ +long +ncp_get_bindery_object_name(struct ncp_conn *conn, + __u32 object_id, + struct ncp_bindery_object *target) { long result; ncp_init_request_s(conn, 54); ncp_add_dword_hl(conn, object_id); - if ((result = ncp_request(conn, 23)) != 0) { + if ((result = ncp_request(conn, 23)) != 0) + { ncp_unlock_conn(conn); return result; } @@ -1611,9 +2486,10 @@ long ncp_get_bindery_object_name(struct ncp_conn *conn, return 0; } -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_scan_bindery_object(struct ncp_conn *conn, + __u32 last_id, __u16 object_type, char *search_string, + struct ncp_bindery_object *target) { long result; ncp_init_request_s(conn, 55); @@ -1621,7 +2497,8 @@ long ncp_scan_bindery_object(struct ncp_conn *conn, ncp_add_word_hl(conn, object_type); ncp_add_pstring(conn, search_string); - if ((result = ncp_request(conn, 23)) != 0) { + if ((result = ncp_request(conn, 23)) != 0) + { ncp_unlock_conn(conn); return result; } @@ -1637,11 +2514,12 @@ long ncp_scan_bindery_object(struct ncp_conn *conn, return 0; } -long ncp_create_bindery_object(struct ncp_conn *conn, - __u16 object_type, - const char *object_name, - __u8 object_security, - __u8 object_status) +long +ncp_create_bindery_object(struct ncp_conn *conn, + __u16 object_type, + const char *object_name, + __u8 object_security, + __u8 object_status) { long result; ncp_init_request_s(conn, 50); @@ -1656,9 +2534,10 @@ long ncp_create_bindery_object(struct ncp_conn *conn, } -long ncp_delete_bindery_object(struct ncp_conn *conn, - __u16 object_type, - const char *object_name) +long +ncp_delete_bindery_object(struct ncp_conn *conn, + __u16 object_type, + const char *object_name) { long result; ncp_init_request_s(conn, 51); @@ -1669,11 +2548,13 @@ long ncp_delete_bindery_object(struct ncp_conn *conn, ncp_unlock_conn(conn); return result; } +#endif /* not __MAKE_SULIB__ */ -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) +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) { long result; ncp_init_request_s(conn, 61); @@ -1682,7 +2563,8 @@ long ncp_read_property_value(struct ncp_conn *conn, ncp_add_byte(conn, segment); ncp_add_pstring(conn, prop_name); - if ((result = ncp_request(conn, 23)) != 0) { + if ((result = ncp_request(conn, 23)) != 0) + { ncp_unlock_conn(conn); return result; } @@ -1693,11 +2575,12 @@ long ncp_read_property_value(struct ncp_conn *conn, return 0; } - -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) +#ifndef __MAKE_SULIB__ +long +ncp_scan_property(struct ncp_conn *conn, + __u16 object_type, const char *object_name, + __u32 last_id, const char *search_string, + struct ncp_property_info *property_info) { long result; ncp_init_request_s(conn, 60); @@ -1706,7 +2589,8 @@ long ncp_scan_property(struct ncp_conn *conn, ncp_add_dword_hl(conn, last_id); ncp_add_pstring(conn, search_string); - if ((result = ncp_request(conn, 23)) != 0) { + if ((result = ncp_request(conn, 23)) != 0) + { ncp_unlock_conn(conn); return result; } @@ -1720,11 +2604,12 @@ long ncp_scan_property(struct ncp_conn *conn, return 0; } -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) +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) { long result; ncp_init_request_s(conn, 65); @@ -1739,10 +2624,11 @@ long ncp_add_object_to_set(struct ncp_conn *conn, return result; } -long ncp_change_property_security(struct ncp_conn *conn, - __u16 object_type, const char *object_name, - const char *property_name, - __u8 property_security) +long +ncp_change_property_security(struct ncp_conn *conn, + __u16 object_type, const char *object_name, + const char *property_name, + __u8 property_security) { long result; ncp_init_request_s(conn, 59); @@ -1756,10 +2642,11 @@ long ncp_change_property_security(struct ncp_conn *conn, return result; } -long ncp_create_property(struct ncp_conn *conn, - __u16 object_type, const char *object_name, - const char *property_name, - __u8 property_flags, __u8 property_security) +long +ncp_create_property(struct ncp_conn *conn, + __u16 object_type, const char *object_name, + const char *property_name, + __u8 property_flags, __u8 property_security) { long result; ncp_init_request_s(conn, 57); @@ -1774,11 +2661,12 @@ long ncp_create_property(struct ncp_conn *conn, return result; } -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_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 result; ncp_init_request_s(conn, 66); @@ -1793,9 +2681,10 @@ long ncp_delete_object_from_set(struct ncp_conn *conn, return result; } -long ncp_delete_property(struct ncp_conn *conn, - __u16 object_type, const char *object_name, - const char *property_name) +long +ncp_delete_property(struct ncp_conn *conn, + __u16 object_type, const char *object_name, + const char *property_name) { long result; ncp_init_request_s(conn, 58); @@ -1808,11 +2697,12 @@ long ncp_delete_property(struct ncp_conn *conn, return result; } -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) +long +ncp_write_property_value(struct ncp_conn *conn, + __u16 object_type, const char *object_name, + const char *property_name, + __u8 segment, + const struct nw_property *property_value) { long result; ncp_init_request_s(conn, 62); @@ -1828,19 +2718,21 @@ long ncp_write_property_value(struct ncp_conn *conn, return result; } -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) +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) { long result; ncp_init_request(conn); ncp_add_word_hl(conn, proposed_max_size); ncp_add_byte(conn, proposed_security_flag); - if ((result = ncp_request(conn, 97)) != 0) { + if ((result = ncp_request(conn, 97)) != 0) + { ncp_unlock_conn(conn); return result; } @@ -1850,11 +2742,13 @@ long ncp_get_big_ncp_max_packet_size(struct ncp_conn *conn, ncp_unlock_conn(conn); return 0; } +#endif /* not __MAKE_SULIB__ */ -long ncp_login_encrypted(struct ncp_conn *conn, - const struct ncp_bindery_object *object, - const unsigned char *key, - const unsigned char *passwd) +long +ncp_login_encrypted(struct ncp_conn *conn, + const struct ncp_bindery_object *object, + const unsigned char *key, + const unsigned char *passwd) { dword tmpID = htonl(object->object_id); unsigned char buf[128]; @@ -1871,12 +2765,22 @@ long ncp_login_encrypted(struct ncp_conn *conn, result = ncp_request(conn, 23); ncp_unlock_conn(conn); +#ifdef SIGNATURES + if ((result == 0) || ((result == NCPL_ET_REQUEST_ERROR) && + (conn->completion == NCP_GRACE_PERIOD))) + { + memcpy(buf + 16, key, 8); + sign_init(buf, buf); + result = ncp_sign_start(conn, buf); + } +#endif return result; } -long ncp_login_unencrypted(struct ncp_conn *conn, - __u16 object_type, const char *object_name, - const unsigned char *passwd) +long +ncp_login_unencrypted(struct ncp_conn *conn, + __u16 object_type, const char *object_name, + const unsigned char *passwd) { long result; ncp_init_request_s(conn, 20); @@ -1888,11 +2792,13 @@ long ncp_login_unencrypted(struct ncp_conn *conn, return result; } -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) +#ifndef __MAKE_SULIB__ +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) { long id = htonl(object->object_id); unsigned char cryptkey[8]; @@ -1907,7 +2813,8 @@ long ncp_change_login_passwd(struct ncp_conn *conn, nw_encrypt(cryptkey, oldpwd, cryptkey); newpassencrypt(oldpwd, newpwd, newpwd); newpassencrypt(oldpwd + 8, newpwd + 8, newpwd + 8); - if ((len = strlen(newpasswd)) > 63) { + if ((len = strlen(newpasswd)) > 63) + { len = 63; } len = ((len ^ oldpwd[0] ^ oldpwd[1]) & 0x7f) | 0x40; @@ -1922,38 +2829,45 @@ long ncp_change_login_passwd(struct ncp_conn *conn, ncp_unlock_conn(conn); return result; } +#endif /* not __MAKE_SULIB__ */ -long ncp_login_user(struct ncp_conn *conn, - const unsigned char *username, - const unsigned char *password) +long +ncp_login_user(struct ncp_conn *conn, + const unsigned char *username, + const unsigned char *password) { return ncp_login_object(conn, username, NCP_BINDERY_USER, password); } -static long ncp_login_object(struct ncp_conn *conn, - const unsigned char *username, - int login_type, - const unsigned char *password) +static long +ncp_login_object(struct ncp_conn *conn, + const unsigned char *username, + int login_type, + const unsigned char *password) { long result; unsigned char ncp_key[8]; struct ncp_bindery_object user; - if ((result = ncp_get_encryption_key(conn, ncp_key)) != 0) { + if ((result = ncp_get_encryption_key(conn, ncp_key)) != 0) + { return ncp_login_unencrypted(conn, login_type, username, password); } if ((result = ncp_get_bindery_object_id(conn, login_type, - username, &user)) != 0) { + username, &user)) != 0) + { return result; } if ((result = ncp_login_encrypted(conn, &user, - ncp_key, password)) != 0) { + ncp_key, password)) != 0) + { struct nw_property p; struct ncp_prop_login_control *l = (struct ncp_prop_login_control *) &p; - if (conn->completion != NCP_GRACE_PERIOD) { + if (conn->completion != NCP_GRACE_PERIOD) + { return result; } fprintf(stderr, "Your password has expired\n"); @@ -1961,7 +2875,8 @@ static long ncp_login_object(struct ncp_conn *conn, if ((result = ncp_read_property_value(conn, NCP_BINDERY_USER, username, 1, "LOGIN_CONTROL", - &p)) == 0) { + &p)) == 0) + { fprintf(stderr, "You have %d login attempts left\n", l->GraceLogins); } @@ -1969,8 +2884,10 @@ static long ncp_login_object(struct ncp_conn *conn, return 0; } -long ncp_get_volume_info_with_number(struct ncp_conn *conn, int n, - struct ncp_volume_info *target) +#ifndef __MAKE_SULIB__ +long +ncp_get_volume_info_with_number(struct ncp_conn *conn, int n, + struct ncp_volume_info *target) { long result; int len; @@ -1978,7 +2895,8 @@ long ncp_get_volume_info_with_number(struct ncp_conn *conn, int n, ncp_init_request_s(conn, 44); ncp_add_byte(conn, n); - if ((result = ncp_request(conn, 22)) != 0) { + if ((result = ncp_request(conn, 22)) != 0) + { ncp_unlock_conn(conn); return result; } @@ -1993,24 +2911,27 @@ long ncp_get_volume_info_with_number(struct ncp_conn *conn, int n, memzero(target->volume_name); len = ncp_reply_byte(conn, 29); - if (len > NCP_VOLNAME_LEN) { + if (len > NCP_VOLNAME_LEN) + { ncp_printf("ncpfs: volume name too long: %d\n", len); ncp_unlock_conn(conn); - return -EIO; + return EIO; } memcpy(&(target->volume_name), ncp_reply_data(conn, 30), len); ncp_unlock_conn(conn); return 0; } -long ncp_get_volume_number(struct ncp_conn *conn, const char *name, int *target) +long +ncp_get_volume_number(struct ncp_conn *conn, const char *name, int *target) { long result; ncp_init_request_s(conn, 5); ncp_add_pstring(conn, name); - if ((result = ncp_request(conn, 22)) != 0) { + if ((result = ncp_request(conn, 22)) != 0) + { ncp_unlock_conn(conn); return result; } @@ -2020,9 +2941,10 @@ long 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) +long +ncp_file_search_init(struct ncp_conn *conn, + int dir_handle, const char *path, + struct ncp_filesearch_info *target) { long result; @@ -2030,7 +2952,8 @@ long ncp_file_search_init(struct ncp_conn *conn, ncp_add_byte(conn, dir_handle); ncp_add_pstring(conn, path); - if ((result = ncp_request(conn, 62)) != 0) { + if ((result = ncp_request(conn, 62)) != 0) + { ncp_unlock_conn(conn); return result; } @@ -2043,10 +2966,11 @@ long ncp_file_search_init(struct ncp_conn *conn, } -long ncp_file_search_continue(struct ncp_conn *conn, - struct ncp_filesearch_info *fsinfo, - int attributes, const char *name, - struct ncp_file_info *target) +long +ncp_file_search_continue(struct ncp_conn *conn, + struct ncp_filesearch_info *fsinfo, + int attributes, const char *name, + struct ncp_file_info *target) { long result; @@ -2059,7 +2983,8 @@ long ncp_file_search_continue(struct ncp_conn *conn, ncp_add_byte(conn, attributes); ncp_add_pstring(conn, name); - if ((result = ncp_request(conn, 63)) != 0) { + if ((result = ncp_request(conn, 63)) != 0) + { ncp_unlock_conn(conn); return result; } @@ -2081,33 +3006,38 @@ long ncp_file_search_continue(struct ncp_conn *conn, return 0; } -long ncp_get_finfo(struct ncp_conn *conn, - int dir_handle, const char *path, const char *name, - 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) { long result; struct ncp_filesearch_info fsinfo; if ((result = ncp_file_search_init(conn, dir_handle, path, - &fsinfo)) != 0) { + &fsinfo)) != 0) + { return result; } if ((result = ncp_file_search_continue(conn, &fsinfo, 0, name, - target)) == 0) { + target)) == 0) + { return result; } if ((result = ncp_file_search_init(conn, dir_handle, path, - &fsinfo)) != 0) { + &fsinfo)) != 0) + { return result; } return ncp_file_search_continue(conn, &fsinfo, aDIR, name, 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_open_file(struct ncp_conn *conn, + int dir_handle, const char *path, + int attr, int access, + struct ncp_file_info *target) { long result; @@ -2117,7 +3047,8 @@ long ncp_open_file(struct ncp_conn *conn, ncp_add_byte(conn, access); ncp_add_pstring(conn, path); - if ((result = ncp_request(conn, 76)) != 0) { + if ((result = ncp_request(conn, 76)) != 0) + { ncp_unlock_conn(conn); return result; } @@ -2140,7 +3071,8 @@ long ncp_open_file(struct ncp_conn *conn, return 0; } -long ncp_close_file(struct ncp_conn *conn, const char *file_id) +long +ncp_close_file(struct ncp_conn *conn, const char *file_id) { long result; @@ -2153,11 +3085,12 @@ long ncp_close_file(struct ncp_conn *conn, const char *file_id) return result; } -static int ncp_do_create(struct ncp_conn *conn, - int dir_handle, const char *path, - int attr, - struct ncp_file_info *target, - int function) +static int +ncp_do_create(struct ncp_conn *conn, + int dir_handle, const char *path, + int attr, + struct ncp_file_info *target, + int function) { long result; @@ -2166,7 +3099,8 @@ static int ncp_do_create(struct ncp_conn *conn, ncp_add_byte(conn, attr); ncp_add_pstring(conn, path); - if ((result = ncp_request(conn, function)) != 0) { + if ((result = ncp_request(conn, function)) != 0) + { ncp_unlock_conn(conn); return result; } @@ -2189,25 +3123,28 @@ static int ncp_do_create(struct ncp_conn *conn, return 0; } -long ncp_create_newfile(struct ncp_conn *conn, - int dir_handle, const char *path, - int attr, - struct ncp_file_info *target) +long +ncp_create_newfile(struct ncp_conn *conn, + int dir_handle, const char *path, + int attr, + struct ncp_file_info *target) { return ncp_do_create(conn, dir_handle, path, attr, target, 77); } -long ncp_create_file(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) { return ncp_do_create(conn, dir_handle, path, attr, target, 67); } -long ncp_erase_file(struct ncp_conn *conn, - int dir_handle, const char *path, - int attr) +long +ncp_erase_file(struct ncp_conn *conn, + int dir_handle, const char *path, + int attr) { long result; @@ -2221,10 +3158,11 @@ long ncp_erase_file(struct ncp_conn *conn, return result; } -long 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_rename_file(struct ncp_conn *conn, + int old_handle, const char *old_path, + int attr, + int new_handle, const char *new_path) { long result; @@ -2235,7 +3173,8 @@ long ncp_rename_file(struct ncp_conn *conn, ncp_add_byte(conn, new_handle); ncp_add_pstring(conn, new_path); - if ((result = ncp_request(conn, 69)) != 0) { + if ((result = ncp_request(conn, 69)) != 0) + { ncp_unlock_conn(conn); return result; } @@ -2243,9 +3182,10 @@ long ncp_rename_file(struct ncp_conn *conn, return 0; } -long ncp_create_directory(struct ncp_conn *conn, - int dir_handle, const char *path, - int inherit_mask) +long +ncp_create_directory(struct ncp_conn *conn, + int dir_handle, const char *path, + int inherit_mask) { long result; @@ -2259,8 +3199,9 @@ long ncp_create_directory(struct ncp_conn *conn, return result; } -long ncp_delete_directory(struct ncp_conn *conn, - int dir_handle, const char *path) +long +ncp_delete_directory(struct ncp_conn *conn, + int dir_handle, const char *path) { long result; @@ -2274,9 +3215,10 @@ long ncp_delete_directory(struct ncp_conn *conn, return result; } -long ncp_add_trustee(struct ncp_conn *conn, - int dir_handle, const char *path, - __u32 object_id, __u8 rights) +long +ncp_add_trustee(struct ncp_conn *conn, + int dir_handle, const char *path, + __u32 object_id, __u8 rights) { long result; @@ -2291,8 +3233,9 @@ long ncp_add_trustee(struct ncp_conn *conn, return result; } -long ncp_delete_trustee(struct ncp_conn *conn, - int dir_handle, const char *path, __u32 object_id) +long +ncp_delete_trustee(struct ncp_conn *conn, + int dir_handle, const char *path, __u32 object_id) { long result; @@ -2307,9 +3250,10 @@ long ncp_delete_trustee(struct ncp_conn *conn, return result; } -long ncp_get_trustee(struct ncp_conn *conn, __u32 object_id, - __u8 vol, char *path, - __u16 * trustee, __u16 * contin) +long +ncp_get_trustee(struct ncp_conn *conn, __u32 object_id, + __u8 vol, char *path, + __u16 * trustee, __u16 * contin) { long result; @@ -2318,7 +3262,8 @@ long ncp_get_trustee(struct ncp_conn *conn, __u32 object_id, ncp_add_word_hl(conn, *contin); ncp_add_dword_hl(conn, object_id); - if ((result = ncp_request(conn, 23)) != 0) { + if ((result = ncp_request(conn, 23)) != 0) + { ncp_unlock_conn(conn); return result; } @@ -2330,9 +3275,10 @@ long ncp_get_trustee(struct ncp_conn *conn, __u32 object_id, return 0; } -long ncp_rename_directory(struct ncp_conn *conn, - int dir_handle, - const char *old_path, const char *new_path) +long +ncp_rename_directory(struct ncp_conn *conn, + int dir_handle, + const char *old_path, const char *new_path) { long result; @@ -2346,44 +3292,53 @@ long ncp_rename_directory(struct ncp_conn *conn, return result; } -static void ncp_add_handle_path(struct ncp_conn *conn, - __u8 vol_num, - __u32 dir_base, int have_dir_base, - const char *path) +static void +ncp_add_handle_path(struct ncp_conn *conn, + __u8 vol_num, + __u32 dir_base, int have_dir_base, + const char *path) { ncp_add_byte(conn, vol_num); ncp_add_dword_lh(conn, dir_base); - if (have_dir_base != 0) { + if (have_dir_base != 0) + { ncp_add_byte(conn, 1); /* dir_base */ - } else { + } else + { ncp_add_byte(conn, 0xff); /* no handle */ } - if (path != NULL) { + if (path != NULL) + { ncp_add_byte(conn, 1); /* 1 component */ ncp_add_pstring(conn, path); - } else { + } else + { ncp_add_byte(conn, 0); } } +#endif /* __MAKE_SULIB */ -static void ncp_extract_file_info(void *structure, struct nw_info_struct *target) +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; + name_len = (u_int8_t*)structure + info_struct_size; target->nameLen = *name_len; strncpy(target->entryName, name_len + 1, *name_len); target->entryName[*name_len] = '\0'; return; } -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) +#ifndef __MAKE_SULIB__ +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) { long result; @@ -2395,7 +3350,8 @@ long ncp_obtain_file_or_subdir_info(struct ncp_conn *conn, ncp_add_dword_lh(conn, rim); ncp_add_handle_path(conn, vol, dirent, 1, path); - if ((result = ncp_request(conn, 87)) != 0) { + if ((result = ncp_request(conn, 87)) != 0) + { ncp_unlock_conn(conn); return result; } @@ -2404,11 +3360,12 @@ long ncp_obtain_file_or_subdir_info(struct ncp_conn *conn, return 0; } -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) +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) { long result; @@ -2420,7 +3377,8 @@ long ncp_get_eff_directory_rights(struct ncp_conn *conn, ncp_add_dword_lh(conn, 0); ncp_add_handle_path(conn, vol, dirent, 1, path); - if ((result = ncp_request(conn, 87)) != 0) { + if ((result = ncp_request(conn, 87)) != 0) + { ncp_unlock_conn(conn); return result; } @@ -2429,20 +3387,23 @@ long ncp_get_eff_directory_rights(struct ncp_conn *conn, return 0; } -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) +long +ncp_do_lookup(struct ncp_conn *conn, + struct nw_info_struct *dir, + const char *path, /* may only be one component */ + struct nw_info_struct *target) { __u8 vol_num; __u32 dir_base; long result; - char *volname = NULL; + const char *volname = NULL; - if (target == NULL) { - return -EINVAL; + if (target == NULL) + { + return EINVAL; } - if (dir == NULL) { + if (dir == NULL) + { /* Access a volume's root directory */ ncp_init_request(conn); @@ -2454,7 +3415,8 @@ long ncp_do_lookup(struct ncp_conn *conn, ncp_add_handle_path(conn, 0, 0, 0, /* no handle */ path); - if ((result = ncp_request(conn, 87)) != 0) { + if ((result = ncp_request(conn, 87)) != 0) + { ncp_unlock_conn(conn); return result; } @@ -2463,7 +3425,8 @@ long ncp_do_lookup(struct ncp_conn *conn, ncp_unlock_conn(conn); volname = path; path = NULL; - } else { + } else + { vol_num = dir->volNumber; dir_base = dir->DosDirNum; } @@ -2477,13 +3440,15 @@ long ncp_do_lookup(struct ncp_conn *conn, ncp_add_handle_path(conn, vol_num, dir_base, 1, path); - if ((result = ncp_request(conn, 87)) != 0) { + if ((result = ncp_request(conn, 87)) != 0) + { ncp_unlock_conn(conn); return result; } ncp_extract_file_info(ncp_reply_data(conn, 0), target); - if (volname != NULL) { + if (volname != NULL) + { target->nameLen = strlen(volname); strcpy(target->entryName, volname); } @@ -2491,10 +3456,11 @@ long ncp_do_lookup(struct ncp_conn *conn, return 0; } -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) +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) { long result; @@ -2514,8 +3480,9 @@ long ncp_modify_file_or_subdir_dos_info(struct ncp_conn *conn, return result; } -long ncp_del_file_or_subdir(struct ncp_conn *conn, - struct nw_info_struct *dir, char *name) +long +ncp_del_file_or_subdir(struct ncp_conn *conn, + struct nw_info_struct *dir, char *name) { long result; @@ -2532,7 +3499,8 @@ long ncp_del_file_or_subdir(struct ncp_conn *conn, return result; } -static inline void ConvertToNWfromDWORD(__u32 sfd, __u8 ret[6]) +static inline void +ConvertToNWfromDWORD(__u32 sfd, __u8 ret[6]) { __u16 *dest = (__u16 *) ret; memcpy(&(dest[1]), &sfd, 4); @@ -2540,12 +3508,13 @@ static inline void ConvertToNWfromDWORD(__u32 sfd, __u8 ret[6]) return; } -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) +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) { long result; @@ -2564,7 +3533,8 @@ long ncp_open_create_file_or_subdir(struct ncp_conn *conn, ncp_add_handle_path(conn, dir->volNumber, dir->DosDirNum, 1, name); - if ((result = ncp_request(conn, 87)) != 0) { + if ((result = ncp_request(conn, 87)) != 0) + { ncp_unlock_conn(conn); return result; } @@ -2578,14 +3548,16 @@ long ncp_open_create_file_or_subdir(struct ncp_conn *conn, return 0; } -long ncp_initialize_search(struct ncp_conn *conn, - const struct nw_info_struct *dir, - int namespace, - struct ncp_search_seq *target) +long +ncp_initialize_search(struct ncp_conn *conn, + const struct nw_info_struct *dir, + int namespace, + struct ncp_search_seq *target) { long result; - if ((namespace < 0) || (namespace > 255)) { + if ((namespace < 0) || (namespace > 255)) + { return EINVAL; } memzero(*target); @@ -2597,7 +3569,8 @@ long ncp_initialize_search(struct ncp_conn *conn, ncp_add_handle_path(conn, dir->volNumber, dir->DosDirNum, 1, NULL); - if ((result = ncp_request(conn, 87)) != 0) { + if ((result = ncp_request(conn, 87)) != 0) + { ncp_unlock_conn(conn); return result; } @@ -2609,9 +3582,12 @@ long ncp_initialize_search(struct ncp_conn *conn, } /* Search for everything */ -long ncp_search_for_file_or_subdir(struct ncp_conn *conn, - struct ncp_search_seq *seq, - struct nw_info_struct *target) +long +ncp_search_for_file_or_subdir2(struct ncp_conn *conn, + int search_attributes, + u_int32_t RIM, + struct ncp_search_seq *seq, + struct nw_info_struct *target) { long result; @@ -2619,33 +3595,44 @@ long ncp_search_for_file_or_subdir(struct ncp_conn *conn, ncp_add_byte(conn, 3); /* subfunction */ ncp_add_byte(conn, seq->namespace); ncp_add_byte(conn, 0); /* data stream (???) */ - ncp_add_word_lh(conn, 0xffff); /* Search attribs */ - ncp_add_dword_lh(conn, RIM_ALL); /* return info mask */ + ncp_add_word_lh(conn, search_attributes); /* Search attribs */ + ncp_add_dword_lh(conn, RIM); /* return info mask */ ncp_add_mem(conn, &(seq->s), 9); ncp_add_byte(conn, 2); /* 2 byte pattern */ ncp_add_byte(conn, 0xff); /* following is a wildcard */ ncp_add_byte(conn, '*'); - if ((result = ncp_request(conn, 87)) != 0) { + if ((result = ncp_request(conn, 87)) != 0) + { ncp_unlock_conn(conn); return result; } - memcpy(seq, ncp_reply_data(conn, 0), sizeof(*seq)); + memcpy(&(seq->s), ncp_reply_data(conn, 0), sizeof(seq->s)); ncp_extract_file_info(ncp_reply_data(conn, 10), target); ncp_unlock_conn(conn); return 0; } -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) +/* Search for everything */ +long +ncp_search_for_file_or_subdir(struct ncp_conn *conn, + struct ncp_search_seq *seq, + struct nw_info_struct *target) +{ + return ncp_search_for_file_or_subdir2(conn, 0x8006, RIM_ALL, seq, 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) { long result; if ((old_dir == NULL) || (old_name == NULL) || (new_dir == NULL) || (new_name == NULL)) - return -EINVAL; + return EINVAL; ncp_init_request(conn); ncp_add_byte(conn, 4); /* subfunction */ @@ -2677,9 +3664,10 @@ long ncp_ren_or_mov_file_or_subdir(struct ncp_conn *conn, /* Create a new job entry */ -long ncp_create_queue_job_and_file(struct ncp_conn *conn, - __u32 queue_id, - struct queue_job *job) +long +ncp_create_queue_job_and_file(struct ncp_conn *conn, + __u32 queue_id, + struct queue_job *job) { long result; @@ -2687,7 +3675,8 @@ long ncp_create_queue_job_and_file(struct ncp_conn *conn, ncp_add_dword_hl(conn, queue_id); ncp_add_mem(conn, &(job->j), sizeof(job->j)); - if ((result = ncp_request(conn, 23)) != 0) { + if ((result = ncp_request(conn, 23)) != 0) + { ncp_unlock_conn(conn); return result; } @@ -2698,9 +3687,10 @@ long ncp_create_queue_job_and_file(struct ncp_conn *conn, return 0; } -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) { long result; @@ -2713,8 +3703,9 @@ long ncp_close_file_and_start_job(struct ncp_conn *conn, return result; } -long ncp_attach_to_queue(struct ncp_conn *conn, - __u32 queue_id) +long +ncp_attach_to_queue(struct ncp_conn *conn, + __u32 queue_id) { long result; @@ -2726,8 +3717,9 @@ long ncp_attach_to_queue(struct ncp_conn *conn, return result; } -long ncp_detach_from_queue(struct ncp_conn *conn, - __u32 queue_id) +long +ncp_detach_from_queue(struct ncp_conn *conn, + __u32 queue_id) { long result; @@ -2739,8 +3731,9 @@ long ncp_detach_from_queue(struct ncp_conn *conn, return result; } -long 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) { long result; @@ -2748,7 +3741,8 @@ long ncp_service_queue_job(struct ncp_conn *conn, __u32 queue_id, __u16 job_type ncp_add_dword_hl(conn, queue_id); ncp_add_word_hl(conn, job_type); - if ((result = ncp_request(conn, 23)) != 0) { + if ((result = ncp_request(conn, 23)) != 0) + { ncp_unlock_conn(conn); return result; } @@ -2759,8 +3753,9 @@ long ncp_service_queue_job(struct ncp_conn *conn, __u32 queue_id, __u16 job_type return 0; } -long 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) { long result; @@ -2774,8 +3769,9 @@ long ncp_finish_servicing_job(struct ncp_conn *conn, __u32 queue_id, return result; } -long 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) { long result; @@ -2788,9 +3784,147 @@ long ncp_abort_servicing_job(struct ncp_conn *conn, __u32 queue_id, return result; } -static int ncp_do_read(struct ncp_conn *conn, const char *file_id, - __u32 offset, __u16 to_read, - char *target, int *bytes_read) +long +ncp_get_queue_length(struct ncp_conn *conn, + __u32 queue_id, + __u32 *queue_length) +{ + long result=-EINVAL; + + ncp_init_request_s(conn, 125); + ncp_add_dword_hl(conn, queue_id); + + if ((result = ncp_request(conn, 23)) != 0) + goto out; + + if (conn->ncp_reply_size < 12) + { + ncp_printf("ncp_reply_size %d < 12\n", + conn->ncp_reply_size); + result=-EINVAL; + goto out; + } + + if (ncp_reply_dword_hl(conn,0) != queue_id) + { + printf("Ouch! Server didn't reply with same queue id in ncp_get_queue_length!\n"); + result=-EINVAL; + } + else + *queue_length = ncp_reply_dword_lh(conn,8); + + out: + ncp_unlock_conn(conn); + return result; +} + +long +ncp_get_queue_job_ids(struct ncp_conn *conn, + __u32 queue_id, + __u32 queue_section, + __u32 *length1, + __u32 *length2, + __u32 ids[]) +{ + long result; + + ncp_init_request_s(conn,129); + ncp_add_dword_hl(conn, queue_id); + ncp_add_dword_lh(conn, queue_section); + + if ((result = ncp_request(conn, 23)) != 0) + goto out; + + if (conn->ncp_reply_size < 8) + { + ncp_printf("ncp_reply_size %d < 8\n", + conn->ncp_reply_size); + result=-EINVAL; + goto out; + } + + *length2 = ncp_reply_dword_lh(conn,4); + if (conn->ncp_reply_size < 8 + 4*(*length2)) + { + ncp_printf("ncp_reply_size %d < %d\n", + conn->ncp_reply_size, 8+4*(*length2)); + result=-EINVAL; + goto out; + } + if (ids) { + int count = min(*length1, *length2)*sizeof(__u32); + int pos; + + for (pos=0; posncp_reply_size < sizeof(struct nw_queue_job_entry)) + { + ncp_printf("ncp_reply_size %d < %d\n", + conn->ncp_reply_size,sizeof(struct nw_queue_job_entry)); + result=-EINVAL; + } + else + memcpy(jobdata,ncp_reply_data(conn,0), sizeof(struct nw_queue_job_entry)); + +out: + ncp_unlock_conn(conn); + return result; +} + +long +NWRemoveJobFromQueue2 +( + struct ncp_conn* conn, + __u32 queueID, + __u32 jobNumber +) { + long result; + + ncp_init_request_s(conn, 0x80); + ncp_add_dword_hl(conn, queueID); + ncp_add_dword_lh(conn, jobNumber); + result = ncp_request(conn, 0x17); + if (result) { + if (result == NCPL_ET_REQUEST_ERROR) { + result = 0x8900 | conn->completion; + } else { + result = 0x88FF; + } + } else { + /* no output */ + } + ncp_unlock_conn(conn); + return result; +} + +static int +ncp_do_read(struct ncp_conn *conn, const char *file_id, + __u32 offset, __u16 to_read, + char *target, int *bytes_read) { long result; @@ -2800,7 +3934,8 @@ static int ncp_do_read(struct ncp_conn *conn, const char *file_id, ncp_add_dword_hl(conn, offset); ncp_add_word_hl(conn, to_read); - if ((result = ncp_request(conn, 72)) != 0) { + if ((result = ncp_request(conn, 72)) != 0) + { ncp_unlock_conn(conn); return result; } @@ -2812,35 +3947,40 @@ static int ncp_do_read(struct ncp_conn *conn, const char *file_id, return 0; } -long ncp_read(struct ncp_conn *conn, const char *file_id, - off_t offset, size_t count, char *target) +long +ncp_read(struct ncp_conn *conn, const char *file_id, + off_t offset, size_t count, char *target) { const int bufsize = conn->i.buffer_size; - int already_read = 0; + size_t already_read = 0; - while (already_read < count) { + while (already_read < count) + { int read_this_time; int to_read = min(bufsize - (offset % bufsize), count - already_read); if (ncp_do_read(conn, file_id, offset, to_read, - target, &read_this_time) != 0) { + target, &read_this_time) != 0) + { return -1; } offset += read_this_time; target += read_this_time; already_read += read_this_time; - if (read_this_time < to_read) { + if (read_this_time < to_read) + { break; } } return already_read; } -static int ncp_do_write(struct ncp_conn *conn, const char *file_id, - __u32 offset, __u16 to_write, - const char *source, int *bytes_written) +static int +ncp_do_write(struct ncp_conn *conn, const char *file_id, + __u32 offset, __u16 to_write, + const char *source, int *bytes_written) { long result; @@ -2851,7 +3991,8 @@ static int ncp_do_write(struct ncp_conn *conn, const char *file_id, ncp_add_word_hl(conn, to_write); ncp_add_mem(conn, source, to_write); - if ((result = ncp_request(conn, 73)) != 0) { + if ((result = ncp_request(conn, 73)) != 0) + { ncp_unlock_conn(conn); return result; } @@ -2861,39 +4002,44 @@ static int ncp_do_write(struct ncp_conn *conn, const char *file_id, return 0; } -long ncp_write(struct ncp_conn *conn, const char *file_id, - off_t offset, size_t count, const char *source) +long +ncp_write(struct ncp_conn *conn, const char *file_id, + off_t offset, size_t count, const char *source) { const int bufsize = conn->i.buffer_size; - int already_written = 0; + size_t already_written = 0; - while (already_written < count) { + while (already_written < count) + { int written_this_time; int to_write = min(bufsize - (offset % bufsize), count - already_written); if (ncp_do_write(conn, file_id, offset, to_write, - source, &written_this_time) != 0) { + source, &written_this_time) != 0) + { return -1; } offset += written_this_time; source += written_this_time; already_written += written_this_time; - if (written_this_time < to_write) { + if (written_this_time < to_write) + { break; } } return already_written; } -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_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 result; @@ -2906,7 +4052,8 @@ long ncp_copy_file(struct ncp_conn *conn, ncp_add_dword_hl(conn, target_offset); ncp_add_dword_hl(conn, count); - if ((result = ncp_request(conn, 74)) != 0) { + if ((result = ncp_request(conn, 74)) != 0) + { ncp_unlock_conn(conn); return result; } @@ -2915,25 +4062,8 @@ long ncp_copy_file(struct ncp_conn *conn, return 0; } -long ncp_get_broadcast_message(struct ncp_conn *conn, char message[256]) -{ - long result; - int length; - - ncp_init_request_s(conn, 1); - - if ((result = ncp_request(conn, 21)) != 0) { - ncp_unlock_conn(conn); - return result; - } - length = ncp_reply_byte(conn, 0); - message[length] = 0; - memcpy(message, ncp_reply_data(conn, 1), length); - ncp_unlock_conn(conn); - return 0; -} - -long ncp_dealloc_dir_handle(struct ncp_conn *conn, __u8 dir_handle) +long +ncp_dealloc_dir_handle(struct ncp_conn *conn, __u8 dir_handle) { long result; @@ -2945,10 +4075,11 @@ long ncp_dealloc_dir_handle(struct ncp_conn *conn, __u8 dir_handle) return result; } -long ncp_alloc_short_dir_handle(struct ncp_conn *conn, - struct nw_info_struct *dir, - word alloc_mode, - byte * target) +long +ncp_alloc_short_dir_handle(struct ncp_conn *conn, + struct nw_info_struct *dir, + word alloc_mode, + byte * target) { long result; @@ -2960,7 +4091,8 @@ long ncp_alloc_short_dir_handle(struct ncp_conn *conn, ncp_add_handle_path(conn, dir->volNumber, dir->DosDirNum, 1, NULL); - if ((result = ncp_request(conn, 87)) != 0) { + if ((result = ncp_request(conn, 87)) != 0) + { ncp_unlock_conn(conn); return result; } @@ -2969,10 +4101,11 @@ long ncp_alloc_short_dir_handle(struct ncp_conn *conn, return result; } -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) +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) { long result = 0; @@ -2985,7 +4118,8 @@ long ncp_add_trustee_set(struct ncp_conn *conn, ncp_add_word_lh(conn, object_count); ncp_add_handle_path(conn, volume_number, dir_entry, 1, NULL); - while (object_count > 0) { + while (object_count > 0) + { ncp_add_dword_hl(conn, rights->object_id); ncp_add_word_lh(conn, rights->rights); object_count -= 1; @@ -2996,3 +4130,537 @@ long ncp_add_trustee_set(struct ncp_conn *conn, ncp_unlock_conn(conn); return result; } +#endif /* not __MAKE_SULIB__ */ + +#ifdef SIGNATURES +long +ncp_sign_start(struct ncp_conn *conn, const char *sign_root) +{ + char init_last[16]={0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef, + 0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10}; + struct ncp_sign_init sign_init; + + if (conn->sign_wanted) + { + memcpy(sign_init.sign_root, sign_root, 8); + memcpy(sign_init.sign_last, init_last, 16); + conn->sign_active = 1; + if (conn->is_connected == CONN_PERMANENT) + { + if (ioctl(conn->mount_fid, NCP_IOC_SIGN_INIT, + &sign_init)) + return NCPL_ET_SIGNATURE_FAILED; + } + else + { + memcpy(conn->sign_root, sign_init.sign_root, 8); + memcpy(conn->sign_last, sign_init.sign_last, 16); + } + + } + return 0; +} +#endif + +#ifdef NDS_SUPPORT +long +ncp_send_nds_frag(struct ncp_conn *conn, + int ndsverb, + const char *inbuf, size_t inbuflen, + char *outbuf, size_t outbufsize, size_t *outbuflen) +{ + long result; + size_t sizeleft, i; + size_t maxdatasize = 514; + int first = 1; + int firstReply = 1; + int fraghnd = -1; + int32_t ndsCode = -399; + size_t replyLen = 0; + size_t fragLen; + + if (outbuflen) *outbuflen = 0; + do + { + sizeleft = maxdatasize; + ncp_init_request(conn); + ncp_add_byte(conn, 2); + ncp_add_dword_lh(conn, fraghnd); + if (first) + { + ncp_add_dword_lh(conn, maxdatasize - 8); + ncp_add_dword_lh(conn, inbuflen + 12); + ncp_add_dword_lh(conn, 0); + ncp_add_dword_lh(conn, ndsverb); + ncp_add_dword_lh(conn, outbufsize); + sizeleft -= 25; + first = 0; + } + else + sizeleft -= 5; + i = (sizeleft > inbuflen) ? inbuflen : sizeleft; + if (i) ncp_add_mem(conn, inbuf, i); + inbuflen -= i; + inbuf += i; + if ((result = ncp_request(conn, 0x68)) != 0) + { + ncp_unlock_conn(conn); + ncp_dprintf("Error in ncp_request\n"); + return result; + } + fragLen = ncp_reply_dword_lh(conn, 0); + if (fragLen < 4) { + ncp_unlock_conn(conn); + ncp_dprintf("Fragment too short\n"); + return NCPL_ET_REPLY_FORMAT; + } + fraghnd = ncp_reply_dword_lh(conn, 4); + fragLen -= 4; + if (fragLen) { + int hdr; + + if (firstReply) { + ndsCode = ncp_reply_dword_lh(conn, 8); + hdr = 12; + fragLen -= 4; + firstReply = 0; + } else { + hdr = 8; + } + if (fragLen > outbufsize) { + ncp_unlock_conn(conn); + ncp_dprintf("Fragment too large, len=%d, max=%d\n", fragLen, outbufsize); + return NCPL_ET_REPLY_TOO_LARGE; + } + if (outbuf) { + memcpy(outbuf, ncp_reply_data(conn, hdr), fragLen); + outbuf += fragLen; + } + replyLen += fragLen; + } else { + /* if reply len == 0 then we must have something to transmit */ + /* otherwise it can cause endless loop */ + if ((fraghnd != -1) && (inbuflen == 0)) { + ncp_unlock_conn(conn); + ncp_dprintf("Why next fragment?\n"); + return NCPL_ET_REPLY_FORMAT; + } + } + ncp_unlock_conn(conn); + if (fraghnd != -1) { + ncp_dprintf("Fragmented\n"); + } + } while (fraghnd != -1); + if (inbuflen || firstReply) { + ncp_dprintf("InBufLen after request=%d, FirstReply=%d\n", inbuflen, firstReply); + return NCPL_ET_REPLY_FORMAT; + } + if (outbuflen) *outbuflen = replyLen; + if ((conn->completion = ndsCode) != 0) { + ncp_dprintf("NDS error %d\n", ndsCode); + return NCPL_ET_REQUEST_ERROR; + } + return 0; +} + +long +ncp_send_nds(struct ncp_conn *conn, int fn, + const char *data_in, size_t data_in_len, + char *data_out, size_t data_out_max, size_t *data_out_len) +{ + size_t i; + long err; + + ncp_init_request(conn); + ncp_add_byte(conn, fn); + if (data_in) ncp_add_mem(conn, data_in, data_in_len); + if (!(err = ncp_request(conn, 0x68))) + { + i = conn->ncp_reply_size; + if (i > data_out_max) i = data_out_max; + if (data_out) + memcpy(data_out, ncp_reply_data(conn, 0), i); + if (data_out_len) *data_out_len = i; + } + else + if (data_out_len) *data_out_len = 0; + ncp_unlock_conn(conn); + return err; +} + +long +ncp_change_conn_state(struct ncp_conn *conn, int new_state) +{ + long err; + + ncp_init_request_s(conn, 0x1d); + ncp_add_dword_lh(conn, new_state); + err = ncp_request(conn, 0x17); + ncp_unlock_conn(conn); + return err; +} +#endif /* NDS_SUPPORT */ + +struct ncp_conn * +ncp_open_addr(struct sockaddr *target, long *err) { + struct ncp_conn *conn; + + if (!(conn = malloc(sizeof(struct ncp_conn)))) { + *err = ENOMEM; + return NULL; + } + memzero(*conn); + + *err = ncp_connect_addr(conn, target, 1); + if (*err) { + free(conn); + return NULL; + } + return conn; +} + +int +ncp_attach_by_addr(struct sockaddr *target, struct ncp_conn** conn) +{ + long err; + + *conn = ncp_open_addr(target, &err); + return err; +} + +long +ncp_get_broadcast_message(struct ncp_conn *conn, char message[256]) +{ + long result; + int length; + + ncp_init_request_s(conn, 0x0B); + if ((result = ncp_request(conn, 0x15)) != 0) + { + ncp_unlock_conn(conn); + ncp_init_request_s(conn, 0x01); + if ((result = ncp_request(conn, 0x15)) != 0) + { + ncp_unlock_conn(conn); + return result; + } + } + length = ncp_reply_byte(conn, 0); + message[length] = 0; + memcpy(message, ncp_reply_data(conn, 1), length); + ncp_unlock_conn(conn); + return 0; +} + +static void +ncp_add_handle_path2(struct ncp_conn *conn, + __u8 vol_num, + __u32 dir_base, int dir_style, + const unsigned char *encpath, int pathlen) +{ + ncp_add_byte(conn, vol_num); + ncp_add_dword_lh(conn, dir_base); + ncp_add_byte(conn, dir_style); /* 1 = dir_base, 0xFF = no handle, 0 = handle */ + if (encpath) { + ncp_add_mem(conn, encpath, pathlen); + } else { + ncp_add_byte(conn, 0); /* empty path */ + } +} + +#ifndef __MAKE_SULIB__ +long +ncp_ns_scan_salvageable_file(struct ncp_conn* conn, __u8 src_ns, + int dirstyle, + __u8 vol_num, __u32 dir_base, + const unsigned char *encpath, int pathlen, + struct ncp_deleted_file* finfo, + char* name, int maxnamelen) +{ + long result; + __u8 namelen; + + ncp_init_request(conn); + ncp_add_byte(conn, 0x10); + ncp_add_byte(conn, src_ns); + ncp_add_byte(conn, 0); + ncp_add_dword_lh(conn, RIM_NAME); + ncp_add_dword_lh(conn, finfo->seq); + ncp_add_handle_path2(conn, vol_num, dir_base, dirstyle, encpath, pathlen); + result = ncp_request(conn, 0x57); + if (result) { + ncp_unlock_conn(conn); + return result; + } + /* reply format: * == returned by RIM_NAME + +00 __u32 lh next sequence * + +04 __u16 deletion time * + +06 __u16 deletion date * + +08 __u32 lh deletor ID * + +0C __u32 lh volume * + +10 __u32 lh directory base * + +14 __u32 ? + +18 __u32 lh attributes + +1C __u16 hl flags ? + +1E __u32 lh size + +22 __u32 ? + +26 __u16 ? + +28 __u16 creation time + +2A __u16 creation date + +2C __u32 lh creator ID + +30 __u16 modify time + +32 __u16 modify date + +34 __u32 lh modifier ID + +38 __u16 last access date + +3A __u16 last archive time + +3C __u16 last archive date + +3E __u32 lh last archiver ID + +42 __u16 inherited right mask + +44 __u8[0x18] ? + +5C __u32 lh owning namespace + +60 __u8[var] name, length preceeded * + */ + + if (conn->ncp_reply_size < 0x61) { + ncp_unlock_conn(conn); + return NCPL_ET_REPLY_FORMAT; + } + finfo->seq = ncp_reply_dword_lh(conn, 0x00); + finfo->vol = ncp_reply_dword_lh(conn, 0x0C); + finfo->base = ncp_reply_dword_lh(conn, 0x10); + if (name) { + namelen = ncp_reply_byte(conn, 0x60); + if (namelen >= maxnamelen) { + result = NCPL_ET_NAMETOOLONG; + namelen = maxnamelen-1; + } + memcpy(name, ncp_reply_data(conn, 0x61), namelen); + name[namelen] = 0; + } + ncp_unlock_conn(conn); + return result; +} + +long +ncp_ns_purge_file(struct ncp_conn* conn, + const struct ncp_deleted_file* finfo) +{ + long result; + + ncp_init_request(conn); + ncp_add_byte(conn, 0x12); + ncp_add_byte(conn, NW_NS_DOS); + ncp_add_byte(conn, 0); /* reserved? */ + ncp_add_dword_lh(conn, finfo->seq); + ncp_add_dword_lh(conn, finfo->vol); + ncp_add_dword_lh(conn, finfo->base); + result = ncp_request(conn, 87); + ncp_unlock_conn(conn); + return result; +} + +struct ncpi_gfn_cookies { + int flag; + int32_t cookie1; + int32_t cookie2; + }; +static long +ncp_ns_get_full_name_int(struct ncp_conn* conn, __u8 src_ns, __u8 dst_ns, + int dirstyle, __u8 vol_num, __u32 dir_base, + const unsigned char* encpath, size_t pathlen, + struct ncpi_gfn_cookies* cookies, + unsigned char* name, size_t maxnamelen, unsigned char** begin) +{ + long result; + size_t comps; + unsigned char* putpos; + unsigned char* getpos; + unsigned char* getend; + + ncp_init_request(conn); + ncp_add_byte(conn, 0x1C); + ncp_add_byte(conn, src_ns); + ncp_add_byte(conn, dst_ns); + ncp_add_word_lh(conn, cookies->flag); + ncp_add_dword_lh(conn, cookies->cookie1); + ncp_add_dword_lh(conn, cookies->cookie2); + ncp_add_handle_path2(conn, vol_num, dir_base, dirstyle, encpath, pathlen); + result = ncp_request(conn, 0x57); + if (result) { + ncp_unlock_conn(conn); + return result; + } + if (conn->ncp_reply_size < 14) { + ncp_unlock_conn(conn); + return NCPL_ET_REPLY_FORMAT; + } + cookies->flag = ncp_reply_word_lh(conn, 0); + cookies->cookie1 = ncp_reply_dword_lh(conn, 2); + cookies->cookie2 = ncp_reply_dword_lh(conn, 6); + comps = ncp_reply_word_lh(conn, 12); + getpos = ncp_reply_data(conn, 14); + getend = getpos + ncp_reply_word_lh(conn, 10); + putpos = name + maxnamelen; + while (comps--) { + size_t partl; + + if (getpos >= getend) { + ncp_unlock_conn(conn); + return NCPL_ET_REPLY_FORMAT; + } + partl = *getpos++; + if (getpos + partl > getend) { + ncp_unlock_conn(conn); + return NCPL_ET_REPLY_FORMAT; + } + putpos -= partl+1; + if (putpos < name) { + ncp_unlock_conn(conn); + return NCPL_ET_NAMETOOLONG; + } + memcpy(putpos + 1, getpos, partl); + *putpos = partl; + getpos += partl; + } + ncp_unlock_conn(conn); + *begin = putpos; + return 0; +} + +static long +ncp_ns_NW_to_path(char* name, size_t maxnamelen, + const unsigned char* encpath, const unsigned char* encend) +{ + char* nameend = name + maxnamelen; + int pos = 0; + + while (encpath < encend) { + int namel; + + if (pos >= 2) { + if (name >= nameend) return NCPL_ET_NAMETOOLONG; + *name++ = '/'; + } + namel = *encpath++; + if (encpath + namel > encend) { + return NCPL_ET_REPLY_FORMAT; + } + if (name + namel >= nameend) { + return NCPL_ET_NAMETOOLONG; + } + memcpy(name, encpath, namel); + encpath += namel; + name += namel; + if (pos == 0) { + if (name >= nameend) return NCPL_ET_NAMETOOLONG; + *name++ = ':'; + } + pos++; + } + if (name >= nameend) return NCPL_ET_NAMETOOLONG; + *name = 0; + return 0; +} + +long +ncp_ns_get_full_name(struct ncp_conn* conn, __u8 src_ns, __u8 dst_ns, + int dirstyle, __u8 vol_num, __u32 dir_base, + const unsigned char* encpath, size_t pathlen, + char* name, size_t maxnamelen) +{ + unsigned char space[1024]; + struct ncpi_gfn_cookies cookie = { 0, -1, -1}; + size_t len = sizeof(space); + long results; + + do { + unsigned char* npos; + + results = ncp_ns_get_full_name_int(conn, src_ns, dst_ns, + dirstyle, vol_num, dir_base, encpath, pathlen, + &cookie, space, len, &npos); + if (results) return results; + len = npos-space; + } while (cookie.cookie2 != -1); + return ncp_ns_NW_to_path(name, maxnamelen, space+len, space+sizeof(space)); +} + +#endif /* not __MAKE_SULIB__ */ + +#ifdef __MAKE_SULIB__ +int +ncp_path_to_NW_format(const char* path, unsigned char* buff, int buffsize) +{ + int components = 0; + unsigned char* pos = buff+1; + buffsize--; + + if (path != NULL) { + if (*path == '/') path++; /* skip optional leading / */ + while (*path) { + const char *c; + const char *d; + int l; + + c = strchr(path, '/'); + if (!c) c=path+strlen(path); + l = c-path; + if (components == 0) { /* volume */ + d = strchr(path, ':'); /* can be separated by :, / or :/ */ + if (!d) d=path+strlen(path); + if (d < c) { + c=d; + if (c[1]=='/') c++; /* skip optional / after : */ + l = d-path; + } + } + if (l == 0) + return -EINVAL; + if (l > 255) + return -ENAMETOOLONG; + if ((l != 1)||(*path!='.')) { + if (buffsize <= l) return -ENOBUFS; + buffsize -= l+1; + *pos++ = l; + memcpy(pos, path, l); + pos+=l; + components++; + } + path = c; + if (!*c) break; + path++; + } + } + *buff = components; + return pos-buff; +} + +long +ncp_obtain_file_or_subdir_info2(struct ncp_conn *conn, + __u8 source_ns, __u8 target_ns, + __u16 search_attribs, __u32 rim, + int dir_style, + __u8 vol, __u32 dirent, const unsigned char *path, + int pathlen, struct nw_info_struct *target) +{ + long result; + + ncp_init_request(conn); + ncp_add_byte(conn, 6); + ncp_add_byte(conn, source_ns); + ncp_add_byte(conn, target_ns); + ncp_add_word_lh(conn, search_attribs); + ncp_add_dword_lh(conn, rim); + ncp_add_handle_path2(conn, vol, dirent, dir_style, path, pathlen); + + if ((result = ncp_request(conn, 87)) != 0) + { + ncp_unlock_conn(conn); + return result; + } + ncp_extract_file_info(ncp_reply_data(conn, 0), target); + ncp_unlock_conn(conn); + return 0; +} + +#endif /* __MAKE_SULIB__ */ diff --git a/lib/ncplib_err.et b/lib/ncplib_err.et index 2eee6e3..233ae5d 100644 --- a/lib/ncplib_err.et +++ b/lib/ncplib_err.et @@ -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 \ No newline at end of file +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 diff --git a/lib/ncpsign.c b/lib/ncpsign.c new file mode 100644 index 0000000..880e515 --- /dev/null +++ b/lib/ncpsign.c @@ -0,0 +1,103 @@ +#ifdef SIGNATURES +/* + * ncpsign.c + * + * Arne de Bruijn (arne@knoware.nl), 1997 + * + */ + +#include +#include "ncplib.h" +#include "ncpsign.h" + +#define rol32(i,c) (((((i)&0xffffffff)<>(32-c))) +/* i386: 32-bit, little endian, handles mis-alignment */ +#ifdef __i386__ +#define GET_LE32(p) (*(const int *)(p)) +#define PUT_LE32(p,v) { *(int *)(p)=v; } +#else +#define GET_LE32(p) DVAL_LH(p,0) +#define PUT_LE32(p,v) DSET_LH(p,0,v) +#endif + +#define min(a,b) ((a)<(b)?(a):(b)) + +static void nwsign(const char *r_data1, char *r_data2, char *outdata) { + int i; + unsigned int w0,w1,w2,w3; + static int rbit[4]={0, 2, 1, 3}; +#ifdef __i386__ + unsigned int *data2=(int *)r_data2; +#else + unsigned int data2[16]; + for (i=0;i<16;i++) + data2[i]=GET_LE32(r_data2+(i<<2)); +#endif + w0=GET_LE32(r_data1); + w1=GET_LE32(r_data1+4); + w2=GET_LE32(r_data1+8); + w3=GET_LE32(r_data1+12); + for (i=0;i<16;i+=4) { + w0=rol32(w0 + ((w1 & w2) | ((~w1) & w3)) + data2[i+0],3); + w3=rol32(w3 + ((w0 & w1) | ((~w0) & w2)) + data2[i+1],7); + w2=rol32(w2 + ((w3 & w0) | ((~w3) & w1)) + data2[i+2],11); + w1=rol32(w1 + ((w2 & w3) | ((~w2) & w0)) + data2[i+3],19); + } + for (i=0;i<4;i++) { + w0=rol32(w0 + (((w2 | w3) & w1) | (w2 & w3)) + 0x5a827999 + data2[i+0],3); + w3=rol32(w3 + (((w1 | w2) & w0) | (w1 & w2)) + 0x5a827999 + data2[i+4],5); + w2=rol32(w2 + (((w0 | w1) & w3) | (w0 & w1)) + 0x5a827999 + data2[i+8],9); + w1=rol32(w1 + (((w3 | w0) & w2) | (w3 & w0)) + 0x5a827999 + data2[i+12],13); + } + for (i=0;i<4;i++) { + w0=rol32(w0 + ((w1 ^ w2) ^ w3) + 0x6ed9eba1 + data2[rbit[i]+0],3); + w3=rol32(w3 + ((w0 ^ w1) ^ w2) + 0x6ed9eba1 + data2[rbit[i]+8],9); + w2=rol32(w2 + ((w3 ^ w0) ^ w1) + 0x6ed9eba1 + data2[rbit[i]+4],11); + w1=rol32(w1 + ((w2 ^ w3) ^ w0) + 0x6ed9eba1 + data2[rbit[i]+12],15); + } + PUT_LE32(outdata,(w0+GET_LE32(r_data1)) & 0xffffffff); + PUT_LE32(outdata+4,(w1+GET_LE32(r_data1+4)) & 0xffffffff); + PUT_LE32(outdata+8,(w2+GET_LE32(r_data1+8)) & 0xffffffff); + PUT_LE32(outdata+12,(w3+GET_LE32(r_data1+12)) & 0xffffffff); +} + +/* + * Initialize packet signatures + * The first 16 bytes of logindata are the shuffled password, + * the last 8 bytes the encryption key as received from the server. + */ +void sign_init(const char *logindata, char *sign_root) { + static const char initlast[16]={0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef, + 0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10}; + static const char *initdata="Authorized NetWare Client"; + char msg[64]; + char hash[16]; + + memset(msg, 0, 64); + memcpy(msg, logindata, 24); + memcpy(msg + 24, initdata, 25); + nwsign(initlast, msg, hash); + + memcpy(sign_root, hash, 8); +} + +/* + * Make a signature for the current packet and add it at the end of the + * packet. + */ +void sign_packet(struct ncp_conn *conn, int *size) { + char data[64]; + + memset(data,0,64); + memcpy(data,conn->sign_root,8); + PUT_LE32(data+8,(*size)); + memcpy(data+12,conn->packet+sizeof(struct ncp_request_header)-1, + min((*size)-sizeof(struct ncp_request_header)+1,52)); + + nwsign(conn->sign_last,data,conn->sign_last); + + memcpy(conn->packet+(*size),conn->sign_last,8); + (*size)+=8; +} +#endif diff --git a/lib/ndscrypt.c b/lib/ndscrypt.c new file mode 100644 index 0000000..1420d4e --- /dev/null +++ b/lib/ndscrypt.c @@ -0,0 +1,297 @@ +/* + NDS client for ncpfs + Copyright (C) 1997 Arne de Bruijn + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include +#include "ndscrypt.h" +#include "ncplib.h" + +static unsigned int rol16(unsigned int i, int c) { + return ((i << c) & 65535) | ((unsigned int)(i & 65535) >> (16 - c)); +} +static unsigned int ror16(unsigned int i, int c) { + return ((unsigned int)(i & 65535) >> c) | ((i << (16 - c)) & 65535); +} + +static unsigned char nwcryptdata[256]={ + 0xD9,0x78,0xF9,0xC4,0x19,0xDD,0xB5,0xED,0x28,0xE9,0xFD,0x79, + 0x4A,0xA0,0xD8,0x9D,0xC6,0x7E,0x37,0x83,0x2B,0x76,0x53,0x8E, + 0x62,0x4C,0x64,0x88,0x44,0x8B,0xFB,0xA2,0x17,0x9A,0x59,0xF5, + 0x87,0xB3,0x4F,0x13,0x61,0x45,0x6D,0x8D,0x09,0x81,0x7D,0x32, + 0xBD,0x8F,0x40,0xEB,0x86,0xB7,0x7B,0x0B,0xF0,0x95,0x21,0x22, + 0x5C,0x6B,0x4E,0x82,0x54,0xD6,0x65,0x93,0xCE,0x60,0xB2,0x1C, + 0x73,0x56,0xC0,0x14,0xA7,0x8C,0xF1,0xDC,0x12,0x75,0xCA,0x1F, + 0x3B,0xBE,0xE4,0xD1,0x42,0x3D,0xD4,0x30,0xA3,0x3C,0xB6,0x26, + 0x6F,0xBF,0x0E,0xDA,0x46,0x69,0x07,0x57,0x27,0xF2,0x1D,0x9B, + 0xBC,0x94,0x43,0x03,0xF8,0x11,0xC7,0xF6,0x90,0xEF,0x3E,0xE7, + 0x06,0xC3,0xD5,0x2F,0xC8,0x66,0x1E,0xD7,0x08,0xE8,0xEA,0xDE, + 0x80,0x52,0xEE,0xF7,0x84,0xAA,0x72,0xAC,0x35,0x4D,0x6A,0x2A, + 0x96,0x1A,0xD2,0x71,0x5A,0x15,0x49,0x74,0x4B,0x9F,0xD0,0x5E, + 0x04,0x18,0xA4,0xEC,0xC2,0xE0,0x41,0x6E,0x0F,0x51,0xCB,0xCC, + 0x24,0x91,0xAF,0x50,0xA1,0xF4,0x70,0x39,0x99,0x7C,0x3A,0x85, + 0x23,0xB8,0xB4,0x7A,0xFC,0x02,0x36,0x5B,0x25,0x55,0x97,0x31, + 0x2D,0x5D,0xFA,0x98,0xE3,0x8A,0x92,0xAE,0x05,0xDF,0x29,0x10, + 0x67,0x6C,0xBA,0xC9,0xD3,0x00,0xE6,0xCF,0xE1,0x9E,0xA8,0x2C, + 0x63,0x16,0x01,0x3F,0x58,0xE2,0x89,0xA9,0x0D,0x38,0x34,0x1B, + 0xAB,0x33,0xFF,0xB0,0xBB,0x48,0x0C,0x5F,0xB9,0xB1,0xCD,0x2E, + 0xC5,0xF3,0xDB,0x47,0xE5,0xA5,0x9C,0x77,0x0A,0xA6,0x20,0x68, + 0xFE,0x7F,0xC1,0xAD}; + +#if 0 +static unsigned char shuffle_table[32]= + {0x48,0x93,0x46,0x67,0x98,0x3D,0xE6,0x8D, + 0xB7,0x10,0x7A,0x26,0x5A,0xB9,0xB1,0x35, + 0x6B,0x0F,0xD5,0x70,0xAE,0xFB,0xAD,0x11, + 0xF4,0x47,0xDC,0xA7,0xEC,0xCF,0x50,0xC0}; + +static unsigned char shuffle_table2[256] = + {0x7,0x8,0x0,0x8,0x6,0x4,0xE,0x4,0x5,0xC,0x1,0x7,0xB,0xF,0xA,0x8, + 0xF,0x8,0xC,0xC,0x9,0x4,0x1,0xE,0x4,0x6,0x2,0x4,0x0,0xA,0xB,0x9, + 0x2,0xF,0xB,0x1,0xD,0x2,0x1,0x9,0x5,0xE,0x7,0x0,0x0,0x2,0x6,0x6, + 0x0,0x7,0x3,0x8,0x2,0x9,0x3,0xF,0x7,0xF,0xC,0xF,0x6,0x4,0xA,0x0, + 0x2,0x3,0xA,0xB,0xD,0x8,0x3,0xA,0x1,0x7,0xC,0xF,0x1,0x8,0x9,0xD, + 0x9,0x1,0x9,0x4,0xE,0x4,0xC,0x5,0x5,0xC,0x8,0xB,0x2,0x3,0x9,0xE, + 0x7,0x7,0x6,0x9,0xE,0xF,0xC,0x8,0xD,0x1,0xA,0x6,0xE,0xD,0x0,0x7, + 0x7,0xA,0x0,0x1,0xF,0x5,0x4,0xB,0x7,0xB,0xE,0xC,0x9,0x5,0xD,0x1, + 0xB,0xD,0x1,0x3,0x5,0xD,0xE,0x6,0x3,0x0,0xB,0xB,0xF,0x3,0x6,0x4, + 0x9,0xD,0xA,0x3,0x1,0x4,0x9,0x4,0x8,0x3,0xB,0xE,0x5,0x0,0x5,0x2, + 0xC,0xB,0xD,0x5,0xD,0x5,0xD,0x2,0xD,0x9,0xA,0xC,0xA,0x0,0xB,0x3, + 0x5,0x3,0x6,0x9,0x5,0x1,0xE,0xE,0x0,0xE,0x8,0x2,0xD,0x2,0x2,0x0, + 0x4,0xF,0x8,0x5,0x9,0x6,0x8,0x6,0xB,0xA,0xB,0xF,0x0,0x7,0x2,0x8, + 0xC,0x7,0x3,0xA,0x1,0x4,0x2,0x5,0xF,0x7,0xA,0xC,0xE,0x5,0x9,0x3, + 0xE,0x7,0x1,0x2,0xE,0x1,0xF,0x4,0xA,0x6,0xC,0x6,0xF,0x4,0x3,0x0, + 0xC,0x0,0x3,0x6,0xF,0x8,0x7,0xB,0x2,0xD,0xC,0x6,0xA,0xA,0x8,0xD}; +#endif + +static unsigned char nwhashdata[256] = + {0xBD,0x56,0xEA,0xF2,0xA2,0xF1,0xAC,0x2A,0xB0,0x93,0xD1,0x9C, + 0x1B,0x33,0xFD,0xD0,0x30,0x04,0xB6,0xDC,0x7D,0xDF,0x32,0x4B, + 0xF7,0xCB,0x45,0x9B,0x31,0xBB,0x21,0x5A,0x41,0x9F,0xE1,0xD9, + 0x4A,0x4D,0x9E,0xDA,0xA0,0x68,0x2C,0xC3,0x27,0x5F,0x80,0x36, + 0x3E,0xEE,0xFB,0x95,0x1A,0xFE,0xCE,0xA8,0x34,0xA9,0x13,0xF0, + 0xA6,0x3F,0xD8,0x0C,0x78,0x24,0xAF,0x23,0x52,0xC1,0x67,0x17, + 0xF5,0x66,0x90,0xE7,0xE8,0x07,0xB8,0x60,0x48,0xE6,0x1E,0x53, + 0xF3,0x92,0xA4,0x72,0x8C,0x08,0x15,0x6E,0x86,0x00,0x84,0xFA, + 0xF4,0x7F,0x8A,0x42,0x19,0xF6,0xDB,0xCD,0x14,0x8D,0x50,0x12, + 0xBA,0x3C,0x06,0x4E,0xEC,0xB3,0x35,0x11,0xA1,0x88,0x8E,0x2B, + 0x94,0x99,0xB7,0x71,0x74,0xD3,0xE4,0xBF,0x3A,0xDE,0x96,0x0E, + 0xBC,0x0A,0xED,0x77,0xFC,0x37,0x6B,0x03,0x79,0x89,0x62,0xC6, + 0xD7,0xC0,0xD2,0x7C,0x6A,0x8B,0x22,0xA3,0x5B,0x05,0x5D,0x02, + 0x75,0xD5,0x61,0xE3,0x18,0x8F,0x55,0x51,0xAD,0x1F,0x0B,0x5E, + 0x85,0xE5,0xC2,0x57,0x63,0xCA,0x3D,0x6C,0xB4,0xC5,0xCC,0x70, + 0xB2,0x91,0x59,0x0D,0x47,0x20,0xC8,0x4F,0x58,0xE0,0x01,0xE2, + 0x16,0x38,0xC4,0x6F,0x3B,0x0F,0x65,0x46,0xBE,0x7E,0x2D,0x7B, + 0x82,0xF9,0x40,0xB5,0x1D,0x73,0xF8,0xEB,0x26,0xC7,0x87,0x97, + 0x25,0x54,0xB1,0x28,0xAA,0x98,0x9D,0xA5,0x64,0x6D,0x7A,0xD4, + 0x10,0x81,0x44,0xEF,0x49,0xD6,0xAE,0x2E,0xDD,0x76,0x5C,0x2F, + 0xA7,0x1C,0xC9,0x09,0x69,0x9A,0x83,0xCF,0x29,0x39,0xB9,0xE9, + 0x4C,0xFF,0x43,0xAB}; + + +void nwencrypt(const unsigned short *cryptbuf, const char *in, char *out) { + int i, j; + register unsigned int i1, i2, i3, i4; + const unsigned short *p; + + i1 = WVAL_LH(in, 0); + i2 = WVAL_LH(in, 2); + i3 = WVAL_LH(in, 4); + i4 = WVAL_LH(in, 6); + p = cryptbuf; + for (j = 3; j; j--) { + for (i = (j == 2) ? 6 : 5; i; i--) { + i1 = rol16(i1 + (*p++) + (i4 & i3) + (~i4 & i2), 1); + i2 = rol16(i2 + (*p++) + (i1 & i4) + (~i1 & i3), 2); + i3 = rol16(i3 + (*p++) + (i2 & i1) + (~i2 & i4), 3); + i4 = rol16(i4 + (*p++) + (i3 & i2) + (~i3 & i1), 5); + } + if (j > 1) { + i1 += cryptbuf[i4 & 63]; + i2 += cryptbuf[i1 & 63]; + i3 += cryptbuf[i2 & 63]; + i4 += cryptbuf[i3 & 63]; + } + } + WSET_LH(out, 0, i1); + WSET_LH(out, 2, i2); + WSET_LH(out, 4, i3); + WSET_LH(out, 6, i4); +} + +void nwdecrypt(const unsigned short *cryptbuf, const char *in, char *out) { + int i, j; + const unsigned short *p; + register unsigned int i1, i2, i3, i4; + + i1 = WVAL_LH(in, 0); + i2 = WVAL_LH(in, 2); + i3 = WVAL_LH(in, 4); + i4 = WVAL_LH(in, 6); + p = cryptbuf + 64; + for (j = 3; j; j--) { + for (i = (j == 2) ? 6 : 5; i; i--) { + i4 = ror16(i4, 5) - (~i3 & i1) - (i3 & i2) - (*--p); + i3 = ror16(i3, 3) - (~i2 & i4) - (i2 & i1) - (*--p); + i2 = ror16(i2, 2) - (~i1 & i3) - (i1 & i4) - (*--p); + i1 = ror16(i1, 1) - (~i4 & i2) - (i4 & i3) - (*--p); + } + if (j > 1) { + i4 -= cryptbuf[i3 & 63]; + i3 -= cryptbuf[i2 & 63]; + i2 -= cryptbuf[i1 & 63]; + i1 -= cryptbuf[i4 & 63]; + } + } + WSET_LH(out, 0, i1); + WSET_LH(out, 2, i2); + WSET_LH(out, 4, i3); + WSET_LH(out, 6, i4); +} + +void nwcryptinit(unsigned short *scryptbuf, const char *key) { + int i; + unsigned char cryptbuf[128], *p; + + memcpy(cryptbuf, key, 8); + for (i = 0; i < 120; i++) + cryptbuf[i + 8] = + nwcryptdata[(unsigned char)(cryptbuf[i] + cryptbuf[i + 7]) & 255]; + cryptbuf[128 - 8] = nwcryptdata[(unsigned char)cryptbuf[128 - 8] & 255]; + for (i = 127 - 8; i >= 0; i--) + cryptbuf[i] = nwcryptdata[(unsigned char)cryptbuf[i + 1] ^ + (unsigned char)cryptbuf[i + 8]]; + for (i = 0, p = cryptbuf; i < 64; i++, p += 2) + scryptbuf[i] = (*p) | (*(p+1)) << 8; +} + +void nwencryptblock(const char *cryptkey, const char *buf, int buflen, + char *outbuf) { + int i; + char nhash[8]; + unsigned short cryptbuf[64]; + + nwcryptinit(cryptbuf, cryptkey); + memset(nhash, 0, 8); + while (buflen >= 8) { + for (i = 0; i < 8; i++, buf++) + nhash[i] ^= *buf; + nwencrypt(cryptbuf, nhash, nhash); + memcpy(outbuf, nhash, 8); + outbuf += 8; + buflen -= 8; + } + memset(cryptbuf, 0, sizeof(cryptbuf)); +} + +void nwdecryptblock(const char *cryptkey, const char *buf, int buflen, + char *outbuf) { + int i; + char nhash[16], *p; + unsigned short cryptbuf[64]; + + nwcryptinit(cryptbuf, cryptkey); + memset(nhash, 0, 16); + p = nhash; + while (buflen >= 8) { + memcpy(p, buf, 8); + p = nhash + 8 - (p - nhash); + nwdecrypt(cryptbuf, buf, outbuf); + for (i = 0; i < 8; i++, outbuf++) + *outbuf ^= p[i]; + buf += 8; + buflen -= 8; + } + memset(cryptbuf, 0, sizeof(cryptbuf)); +} + +void nwhash1(char *hash, int hashlen, const char *data, int datalen) { + unsigned char *hp, *hp1, *hend, c; + const unsigned char *dp; + + hp1 = (hp = (unsigned char *)hash) + 1; + hend = hp + hashlen; + dp = (const unsigned char *)data; + while (datalen--) { + *hp = nwhashdata[*hp1 ^ *hp] ^ *dp++; + hp = hp1++; + if (hp1 == hend) + hp1 = (unsigned char *)hash; + } + while (hp-- > (unsigned char *)hash) { + hp1 = (unsigned char *)hash; + c = *hp1++; + while (*(hp1 - 1) = *hp1, ++hp1 < (unsigned char *)hash + hashlen); + *(hp1 - 1) = c; + } +} + +void nwhash2(char *hashbuf, char c) { + int i, j; + char *p = hashbuf + hashbuf[0x40]; + + p[0x20] = p[0x00] ^ (p[0x10] = c); + hashbuf[0x41] = (p[0x30] ^= nwhashdata[(unsigned char)(c ^ hashbuf[0x41])]); + if (!(hashbuf[0x40] = (hashbuf[0x40] + 1) & 15)) { + c = 0; + for (i = 18; i; i--) + for (j = 48, p = hashbuf; j; j--) + c = (*(p++) ^= nwhashdata[((unsigned char)c + j) & 255]); + } +} + +void nwhash2block(char *hashbuf, const char *data, int datalen) { + while (datalen--) + nwhash2(hashbuf, *data++); +} + +void nwhash2end(char *hashbuf) { + int i, j; + + for(j = i = 16 - hashbuf[0x40]; j; j--) + nwhash2(hashbuf, i); + for(i = 0x30; i < 0x40; i++) + nwhash2(hashbuf, hashbuf[i]); +} + +#if 0 +void shuffle(const char *objid, const char *pwd, char *out) { + unsigned char temp[32]; + int i, j, k; + i = strlen(pwd); + memset(temp, 0, 32); + for (j = 0; j < i; j++) + temp[j & 31] ^= pwd[j]; + if (i) + for (j = i; j < 32; j += i) { + temp[j++] = shuffle_table[j]; + k = 32 - j; + memcpy(temp + j, pwd, (k > i) ? i : k); + } + for (i = 0; i < 32; i++) + temp[i] ^= objid[i & 3]; + j = 0; + for (k = 0; k < 2; k++) + for (i = 0; i < 32; i++) + (char)j += temp[i] = (temp[i] + j) ^ + (temp[(i + j) & 31] - shuffle_table[i]); + for (i = 0; i < 16; i++) + out[i] = shuffle_table2[temp[i * 2]] | + (shuffle_table2[temp[i * 2 + 1]] << 4); +} +#endif + diff --git a/lib/ndscrypt.h b/lib/ndscrypt.h new file mode 100644 index 0000000..07fc788 --- /dev/null +++ b/lib/ndscrypt.h @@ -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 + +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 */ diff --git a/lib/ndslib.c b/lib/ndslib.c new file mode 100644 index 0000000..51b88cd --- /dev/null +++ b/lib/ndslib.c @@ -0,0 +1,1253 @@ +/* + 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. +*/ + +#define RANDBUF /* if defined: read random data once from /dev/urandom */ +/*#define ERR_MSG*/ /* if defined: show error messages in nds_login_auth */ + +#include +#include +#include +#ifdef ERR_MSG +#include +#endif +#include +#include +#ifdef RANDBUF +#include +#endif +#include "ncplib.h" +#include "ncplib_err.h" +#include "ndslib.h" +#include "ndscrypt.h" + +#define USUALS +typedef u_int32_t word32; +typedef u_int16_t word16; +typedef unsigned char boolean; + +#include "mpilib.h" +#include +#include +#include "kernel/ipx.h" +#include +#include "ndslib.h" + +int bindery_only = 0; + +static int buf_get_dword_lh(char **buf, char *bufend, u_int32_t *v) { + if ((*buf) + 4 <= bufend) { + if (v) + *v = DVAL_LH(*buf, 0); + (*buf) += 4; + return 0; + } else + return -1; +} + +static int buf_get_lbuf(char **buf, char *bufend, char *out, int outmax, + int *outlen) { + int i, j; + + if ((!buf_get_dword_lh(buf, bufend, &i)) && (*buf + i <= bufend)) { + j = i; + if (out) { + if (j > outmax) j = outmax; + memcpy(out, *buf, j); + } + if (outlen) *outlen = j; + *buf += (i + 3) & (~3); + return 0; + } else + return -1; +} + +static int buf_put_word_lh2(char **buf, char *bufend, u_int16_t v) { + if ((*buf) + 2 <= bufend) { + WSET_LH(*buf, 0, v); + *buf += 2; + return 0; + } else + return -1; +} + +static int buf_put_dword_lh(char **buf, char *bufend, u_int32_t v) { + if ((buf) && ((*buf) + 4 <= bufend)) { + DSET_LH(*buf, 0, v); + *buf += 4; + return 0; + } else + return -1; +} + +static int buf_put_dword_hl(char **buf, char *bufend, u_int32_t v) { + if ((*buf) + 4 <= bufend) { + DSET_HL(*buf, 0, v); + *buf += 4; + return 0; + } else + return -1; +} + +static int buf_put_lbuf(char **buf, char *bufend, const char *databuf, + size_t buflen) { + if ((!buf_put_dword_lh(buf, bufend, buflen)) && + (*buf + buflen <= bufend)) { + if (!buflen) return 0; /* explicitly allow {NULL, 0} buffer */ + if (!databuf) return -1; + memcpy(*buf, databuf, buflen); + (*buf) += buflen; + while (buflen++ & 3) + *(*buf)++ = 0; + return 0; + } else + return -1; +} + +static int buf_put_buf(char **buf, char *bufend, const char *databuf, + size_t buflen) { + if ((databuf) && (*buf + buflen <= bufend)) { + memcpy(*buf, databuf, buflen); + (*buf) += buflen; + while (buflen++ & 3) + *(*buf)++ = 0; + return 0; + } else + return -1; +} + +static int buf_put_unistr(char **buf, char *bufend, const uni_char *str) { + int i = (strlen_u(str) + 1) * 2; + + if ((str) && (!buf_put_dword_lh(buf, bufend, i)) && + (*buf + i <= bufend)) { + memcpy(*buf, str, i); + (*buf) += i; + while (i++ & 3) + *(*buf)++ = 0; + return 0; + } else + return -1; +} + +static int buf_get_dword_hl(char **buf, char *bufend, u_int32_t *v) { + if ((*buf) + 4 <= bufend) { + if (v) { + *v = DVAL_HL(*buf, 0); + } + (*buf) += 4; + return 0; + } else + return -1; +} + +static int buf_get_word_lh(char **buf, char *bufend, u_int16_t *v) { + if (((*buf) + 2 <= bufend)) { + if (v) { + *v = WVAL_LH(*buf, 0); + } + (*buf) += 4; + return 0; + } else + return -1; +} + +static int buf_get_word_lh2(char **buf, char *bufend, u_int16_t *v) { + if (((*buf) + 2 <= bufend)) { + if (v) { + *v = WVAL_LH(*buf, 0); + } + (*buf) += 2; + return 0; + } else + return -1; +} + +static int buf_get_lbuf_alloc(char **buf, char *bufend, + char **outbuf, int *bufsize) { + int i, err = 0; + + if ((!buf_get_dword_lh(buf, bufend, &i)) && (*buf + i <= bufend)) { + if (outbuf) { + if (((*outbuf) = malloc(i))) + memcpy(*outbuf, *buf, i); + else + err = ENOMEM; + } + (*buf) += (i + 3) & (~3); + if (bufsize) *bufsize = i; + return err; + } else { + if (outbuf) *outbuf = NULL; + if (bufsize) *bufsize = 0; + return -1; + } +} + +static int buf_get_buf(char **buf, char *bufend, char *outbuf, size_t bufsize) { + if (*buf + bufsize <= bufend) { + if (outbuf) memcpy(outbuf, *buf, bufsize); + *buf += (bufsize + 3) & (~3); + return 0; + } else + return -1; +} + +int strlen_u(const uni_char *s) { + int i = 0; + while (*s++) i++; + return i; +} + +void strcpy_uc(char *d, const uni_char *s) { + while ((*d++ = *s++)); +} + +void strcpy_cu(uni_char *d, const char *s) { + while ((*d++ = *s++)); +} + +long nds_get_server_name(struct ncp_conn *conn, uni_char **server_name) { + long err; + int outlen; + char *p, *pend, *outbuf; + + if (!(outbuf = malloc(4096))) + return ENOMEM; + if (server_name) *server_name = NULL; + if ((err = ncp_send_nds_frag(conn, 53, NULL, 0, + outbuf, 4096, &outlen)) == 0) { + pend = (p = outbuf) + outlen; + if (buf_get_dword_lh(&p, pend, &outlen)) + err = NCPL_ET_REPLY_FORMAT; + else { + if (!((*server_name) = malloc(outlen))) + err = ENOMEM; + else + memcpy(*server_name, p, outlen); + } + } + free(outbuf); + return err; +} + +long nds_get_tree_name(struct ncp_conn *conn, char *name, int name_buf_len) { + char buf[128]; + int size; + long err; + char *p, *pend; + + if (bindery_only) return -1; + + if (!(err = ncp_send_nds(conn, 1, "\0\0\0", 3, buf, sizeof(buf), + &size))) { + p = buf + 4; + pend = buf + size; + if (buf_get_lbuf(&p, pend, name, name_buf_len, &size)) + return NCPL_ET_REPLY_FORMAT; + if (name) { + p = name + size - 1; + while ((p >= name) && (!*p)) + p--; + while ((p >= name) && (*p == '_')) + p--; + *(p + 1) = 0; + } + } + return err; +} + +/* for login */ +long nds_resolve_name(struct ncp_conn *conn, int flags, uni_char *entry_name, + int *entry_id, int *remote, struct sockaddr *serv_addr, size_t *addr_len) { + char *buf, *p, *pend, addr_buf[12]; + long err; + int i; + + if (!(buf = malloc(4096))) + return ENOMEM; + pend = (p = buf) + 2048; + buf_put_dword_lh(&p, pend, 0); + buf_put_dword_lh(&p, pend, flags); + buf_put_dword_lh(&p, pend, 0); + buf_put_unistr(&p, pend, entry_name); + buf_put_dword_lh(&p, pend, 1); + buf_put_dword_lh(&p, pend, 0); + buf_put_dword_lh(&p, pend, 1); + buf_put_dword_lh(&p, pend, 0); + if ((err = ncp_send_nds_frag(conn, 1, buf, p - buf, buf + 2048, 2048, + &i)) == 0) { + pend = (p = buf + 2048) + i; + if (buf_get_dword_lh(&p, pend, &i) || (i < 0) || (i > 2)) + err = NCPL_ET_REPLY_FORMAT; + else if (i == 1) { + if (remote) *remote = 0; + if (buf_get_dword_hl(&p, pend, entry_id)) + err = NCPL_ET_REPLY_FORMAT; + } else { + if (remote) *remote = 1; + if ((!serv_addr) || (!addr_len)) { + free(buf); + return 0; + } + if (buf_get_dword_hl(&p, pend, entry_id) || + buf_get_dword_lh(&p, pend, &i) || (i != 0) || + buf_get_dword_lh(&p, pend, &i) || (i == 0) || + buf_get_dword_lh(&p, pend, &i)) + err = NCPL_ET_REPLY_FORMAT; + else if (i != 0) /* no ipx? */ + err = NCPL_ET_TRANSPORT_UNKNOWN; + else if (buf_get_dword_lh(&p, pend, &i) || (i != 12) || + buf_get_buf(&p, pend, addr_buf, 12)) + err = NCPL_ET_REPLY_FORMAT; + else if (*addr_len < sizeof(struct sockaddr_ipx)) + err = EINVAL; + else { + ((struct sockaddr_ipx *)serv_addr)->sipx_family = AF_IPX; + ((struct sockaddr_ipx *)serv_addr)->sipx_type = NCP_PTYPE; + /* buf and addr both in network order */ + memcpy(&((struct sockaddr_ipx *)serv_addr)->sipx_network, + addr_buf, 4); + memcpy(((struct sockaddr_ipx *)serv_addr)->sipx_node, + addr_buf + 4, 6); + memcpy(&((struct sockaddr_ipx *)serv_addr)->sipx_port, + addr_buf + 10, 2); + *addr_len = sizeof(struct sockaddr_ipx); + } + } + } + free(buf); + return err; +} + +long nds_readentryname(struct ncp_conn *conn, int obj_id, + uni_char **name, int *namelen) { + char reqbuf[16], *p, *pend, *buf; + uni_char *p2; + long err; + int outlen; + + if (name) *name = NULL; + if (namelen) *namelen = 0; + pend = (p = reqbuf) + 16; + buf_put_dword_lh(&p, pend, 2); + buf_put_dword_lh(&p, pend, 0); + buf_put_dword_lh(&p, pend, 0x281d); + buf_put_dword_hl(&p, pend, obj_id); + if (!(buf = malloc(4096))) + return ENOMEM; + if ((err = ncp_send_nds_frag(conn, 2, reqbuf, 16, buf, 4096, &outlen))) { + free(buf); + return err; + } + pend = (p = buf) + outlen; + p += 16; + buf_get_lbuf(&p, pend, NULL, 0, NULL); + if ((buf_get_dword_lh(&p, pend, &outlen)) || + (outlen > pend - p)) { + free(buf); + return NCPL_ET_REPLY_FORMAT; + } + if (name) { + if (!(p2 = malloc(outlen))) { + free(buf); + return ENOMEM; + } + memcpy(p2, p, outlen); + *name = p2; + } + if (namelen) *namelen = outlen; + free(buf); + return 0; +} + +long nds_read(struct ncp_conn *conn, int obj_id, uni_char *propname, + char **outbuf, int *outlen) { + long err; + char *buf, *p, *pend; + int n1, n2, n3, n4, n5; + + if (outbuf) *outbuf = NULL; + if (outlen) *outlen = 0; + if (!(buf = malloc(4096))) + return ENOMEM; + pend = (p = buf) + 2048; + buf_put_dword_lh(&p, pend, 0); + buf_put_dword_lh(&p, pend, -1L); + buf_put_dword_hl(&p, pend, obj_id); + buf_put_dword_lh(&p, pend, 1); + buf_put_dword_lh(&p, pend, 0); + buf_put_dword_lh(&p, pend, 1); + buf_put_unistr(&p, pend, propname); + if (!(err = ncp_send_nds_frag(conn, 3, buf, p - buf, + buf + 2048, 2048, &n1))) { + pend = (p = (buf + 2048)) + n1; + if (!(err = buf_get_dword_lh(&p, pend, &n1)) && + !(err = buf_get_dword_lh(&p, pend, &n2)) && + !(err = buf_get_dword_lh(&p, pend, &n3)) && + !(err = buf_get_dword_lh(&p, pend, &n4)) && + !(err = buf_get_lbuf(&p, pend, NULL, 0, NULL)) && + !(err = buf_get_dword_lh(&p, pend, &n5))) { + if ((n1 != -1) || (n2 != 1) || (n3 != 1) || + (n4 != 9) || (n5 != 1)) + err = -1; + else + err = buf_get_lbuf_alloc(&p, pend, outbuf, outlen); + } + } + free(buf); + return err; +} + +#ifdef RANDBUF +#define RANDBUFSIZE 1236 /* total size of all fillrandom's for login+auth */ +char global_randbuf[RANDBUFSIZE]; +char *g_rndp = global_randbuf + RANDBUFSIZE; + +void fillrandom(char *buf, int buflen) { + int fh,i; + + do { + if (g_rndp == global_randbuf + RANDBUFSIZE) { + if ((fh = open("/dev/urandom", O_RDONLY)) >=0) { + read(fh, global_randbuf, RANDBUFSIZE); + close(fh); + } else { + g_rndp = global_randbuf; + while (g_rndp - global_randbuf < RANDBUFSIZE) + *(g_rndp++) = rand() / ((((unsigned)RAND_MAX)+255) / 256); + } + g_rndp = global_randbuf; + } + if ((i = RANDBUFSIZE - (g_rndp - global_randbuf)) > buflen) i = buflen; + memcpy(buf, g_rndp, i); + buf += i; + g_rndp += i; + buflen -= i; + } while (buflen); +} +#else +void fillrandom(char *buf, int buflen) { + int fh; + char *p; + + if (((fh = open("/dev/urandom", O_RDONLY)) >= 0) { + read(fh, buf, buflen); + close(fh); + } else { + p = buf; + while (p - buf < buflen) + *(p++) = rand() / ((((unsigned)RAND_MAX)+255) / 256); + } +} +#endif + +static int countbits_l(char *buf, int bufsize) { + unsigned char b; + + while ((--bufsize) && (!buf[bufsize])); + b = (unsigned char)buf[bufsize]; + bufsize <<= 3; + while (b) { + b >>= 2; bufsize++; + } + return bufsize; +} + +static void copyfill(void *outbuf, int outsize, const void *inbuf, int insize) { + if (outsize < insize) insize = outsize; + memcpy(outbuf, inbuf, insize); + memset((char *)outbuf + insize, 0, outsize - insize); +} + +static uni_char c_public_key[] = {'P','u','b','l','i','c',' ','K','e','y',0}; + +static char keyprefix[] = {1, 0, 0, 0, 3, 0, 1, 0}; + +static int initkey(const char *key, char **keyptr, int *keylen) { /* 1=ok, 0=err */ + if (!memcmp(key, keyprefix, 8)) { + if (keylen) *keylen = WVAL_LH(key, 8); + if (keyptr) (const char *)(*keyptr) = key + 10; + return 1; + } else + return 0; +} + +static void clearkey(char *key) { + char *keyptr; + int keylen; + if (initkey(key, &keyptr, &keylen)) + memset(key, 0, keylen + 10); +} + +static int findchunk(const char *keyptr, int keylen, const char *chunk, + char **chunkptr) { + const char *p; + + if ((p = keyptr)) { + while (p - keyptr < keylen) { + if ((p[0] != chunk[0]) || (p[1] != chunk[1])) + p += 4 + (unsigned char)p[2] + (unsigned char)p[3]; + else { + if (chunkptr) (const char *)(*chunkptr) = p + 4; + return (unsigned char)p[2] + (unsigned char)p[3]; + } + } + } + if (chunkptr) *chunkptr = NULL; + return 0; +} + +static int checkkey(const char *key) { /* 0 - wrong key, != 0 - key ok */ + char temp[8]; + char *keyptr, *p; + int keylen; + + if ((initkey(key, &keyptr, &keylen)) && + (findchunk(keyptr, keylen, "MA", &p))) { + nwhash1init(temp, 8); + nwhash1(temp, 8, key + 10, WVAL_LH(key, 8) - 20); + return (!memcmp(p, temp, 8)); + } else + return 0; + +} + +static long modexpkey(const char *s_key, char *buf, char *outbuf, int bufsize) { + char *s_keyptr; + int s_keylen, i, nbits, nblocksize; + int err = -1; + unitptr nmod, nexp, nin, nout; + char *p; + + nmod = nexp = nin = nout = NULL; + + if (!initkey(s_key, &s_keyptr, &s_keylen)) + return NCPL_ET_REPLY_FORMAT; + i = findchunk(s_keyptr, s_keylen, "NN", &p); + if (!p) + return NCPL_ET_REPLY_FORMAT; + nbits = countbits_l(p, i); + nblocksize = ((nbits + 31) & (~31)) >> 3; + if (!(nmod = malloc(nblocksize))) + return ENOMEM; + copyfill(nmod, nblocksize, p, i); + i = findchunk(s_keyptr, s_keylen, "EN", &p); + err = NCPL_ET_REPLY_FORMAT; + if (!p) goto end; + err = ENOMEM; + if (!(nexp = malloc(nblocksize))) goto end; + copyfill(nexp, nblocksize, p, i); + if (!(nin = malloc(nblocksize))) goto end; + copyfill(nin, nblocksize, buf, bufsize); + if (!(nout = malloc(nblocksize))) goto end; + set_precision(bytes2units(nblocksize)); + if (mp_modexp((unitptr) nout, (unitptr) nin, (unitptr) nexp, + (unitptr) nmod)) + err = NCPL_ET_REPLY_FORMAT; + else { + copyfill(outbuf, bufsize, nout, nblocksize); + err = 0; + } +end: + if (nout) { mp_init0(nout); free(nout); } + if (nin) { mp_init0(nin); free(nin); } + if (nexp) free(nexp); + if (nmod) free(nmod); + return err; +} + +long get_public_key(struct ncp_conn *conn, long obj_id, char **key) { + char *keybuf, *kptr; + long err; + int keylen, ofs, klen; + + if ((err = nds_read(conn, obj_id, c_public_key, &keybuf, &keylen))) { + return err; + } + ofs = WVAL_LH(keybuf, 10) + 0x1a; + if ((ofs > keylen) || (!initkey(keybuf + ofs, &kptr, &klen)) || + (klen + ofs > keylen) || (!checkkey(keybuf + ofs))) { + err = NCPL_ET_REPLY_FORMAT; + goto err_exit; + } + if (key) { + if (!(kptr = malloc(klen + 10))) { + err = ENOMEM; + goto err_exit; + } + memcpy(kptr, keybuf + ofs, klen + 10); + *key = kptr; + } + err = 0; +err_exit: + free(keybuf); + return err; +} + +char buf2str1[8] = {1,0,0,0,9,0,2,0}; +char buf2str2[16] = {65,0,0,0,1,0,0,0,1,0,9,0,53,0,28,0}; +char buf2str3[8] = {1,0,0,0,1,0,6,0}; +static long rsa_crypt(struct ncp_conn *conn, char *data, int datalen, + long serv_id, char **outp, char *pend) { + char rand[28]; + char hashrand[8], temp[8]; + unsigned short cryptbuf[128]; + char buf2[56]; + int i; + long err; + char *s_key; + char *p; + + if ((*outp + datalen + 108) > pend) + return -1; + if ((err = get_public_key(conn, serv_id, &s_key))) + return err; + + fillrandom(rand, 28); + nwhash1init(hashrand, 8); + for (i = 10; i; i--) + nwhash1(hashrand, 8, rand, 28); + + memset(buf2 + 40, 0, 16); + buf2[0] = 11; + memcpy(buf2 + 1, rand, 28); + memset(buf2 + 29, 11, 11); + nwhash1(buf2 + 40, 5, buf2 + 1, 39); + nwhash1(buf2 + 45, 2, buf2, 45); + fillrandom(buf2 + 47, 5); + + err = modexpkey(s_key, buf2, buf2, 56); + free(s_key); + if (err) + return err; + + buf_put_dword_lh(outp, pend, datalen + 108); + buf_put_buf(outp, pend, buf2str1, sizeof(buf2str1)); + buf_put_dword_lh(outp, pend, datalen + 96); + buf_put_buf(outp, pend, buf2str2, sizeof(buf2str2)); + buf_put_buf(outp, pend, buf2, 56); + buf_put_dword_lh(outp, pend, datalen + 20); + buf_put_buf(outp, pend, buf2str3, sizeof(buf2str3)); + buf_put_dword_lh(outp, pend, (datalen + 8) | (datalen << 16)); + + memset(temp, 3, 3); + nwhash1init(temp + 3, 5); + nwhash1(temp + 3, 5, data, datalen); + nwhash1(temp + 3, 5, temp, 3); + nwencryptblock(hashrand, data, datalen, *outp); + *outp += datalen; + for (i = 0, p = *outp - 8; i < 8; i++, p++) + temp[i] ^= *p; + nwcryptinit(cryptbuf, hashrand); + nwencrypt(cryptbuf, temp, *outp); + *outp += 8; + memzero(rand); + memzero(hashrand); + memzero(temp); + memzero(cryptbuf); + memzero(buf2); + return 0; +} + +static char bufstr[16]={28, 0, 0, 0, 1, 0, 0, 0, 1, 0, 6, 0, 16, 0, 4, 0}; +long nds_login(struct ncp_conn *conn, long user_id, const char *pwd, + long serv_id, char *logindata, char **u_priv_key) { + char *buf, *p, *pend; + char temp[16]; + char hashshuf[8]; + char loginid[4]; + char crypt1strc[28]; + char randno[4]; + char randbuf[1024]; + char *tempbuf; + int i, outlen; + int n1, n2; + u_int16_t n2a, n3; + long err; + int grace_period = 0; + + if (u_priv_key) *u_priv_key = NULL; + if (!(buf = malloc(4096))) + return ENOMEM; + pend = (p = buf) + 2048; + buf_put_dword_lh(&p, pend, 0); + buf_put_dword_hl(&p, pend, user_id); + if ((err = ncp_send_nds_frag(conn, 57, buf, p - buf, buf + 2048, 2048, + &outlen))) { + free(buf); + return err; + } + pend = (p = buf + 2048) + outlen; + if ((buf_get_buf(&p, pend, temp, 4)) || + (buf_get_buf(&p, pend, loginid, 4))) { + free(buf); + return NCPL_ET_REPLY_FORMAT; + } + free(buf); + if (strlen(pwd) > 127) + return NCPL_ET_PWD_TOO_LONG; + if (!(tempbuf = malloc(1064))) + return ENOMEM; + if (!(buf = malloc(4096))) { + free(tempbuf); + return ENOMEM; + } + strcpy(randbuf, pwd); + for (p = randbuf; *p; p++) + *p = toupper(*p); +#if 0 + shuffle(temp, randbuf, temp); +#else + shuffle(temp, randbuf, strlen(randbuf), temp); +#endif + nwhash1init(hashshuf, 8); + for (i = 10; i; i--) + nwhash1(hashshuf, 8, temp, 16); + memcpy(temp, loginid, 4); + memset(temp + 4, 7, 7); + nwhash1init(temp + 11, 5); + nwhash1(temp + 11, 5, temp, 11); + memcpy(crypt1strc, bufstr + 4, 12); + nwencryptblock(hashshuf, temp, 16, crypt1strc + 12); + + fillrandom(randno, 4); + fillrandom(randbuf, 1024); + pend = (p = tempbuf) + 1064; + buf_put_buf(&p, pend, randno, 4); + buf_put_dword_lh(&p, pend, 1024); + buf_put_buf(&p, pend, randbuf, 1024); + buf_put_buf(&p, pend, bufstr, sizeof(bufstr)); + buf_put_buf(&p, pend, crypt1strc + 12, 16); + + pend = (p = buf) + 2048; + buf_put_dword_lh(&p, pend, 2); + buf_put_dword_lh(&p, pend, 0); + buf_put_dword_hl(&p, pend, user_id); + + rsa_crypt(conn, tempbuf, 1064, serv_id, &p, pend); + memset(tempbuf, 0, 1064); + free(tempbuf); + + if ((err = ncp_send_nds_frag(conn, 58, buf, p - buf, buf + 2048, 2048, + &outlen))) { + if ((err != NCPL_ET_REQUEST_ERROR) || + (conn->completion != NDS_GRACE_PERIOD)) + goto err_exit; + grace_period = 1; + } + err = NCPL_ET_REPLY_FORMAT; + pend = (p = buf + 2048) + outlen; + if ((buf_get_buf(&p, pend, logindata, 8)) || + (buf_get_dword_lh(&p, pend, &n1)) || + (n1 > pend - p)) + goto err_exit; + pend = p + n1; + if ((buf_get_dword_lh(&p, pend, &n1)) || + (buf_get_dword_lh(&p, pend, &n2)) || + (buf_get_word_lh(&p, pend, &n3)) || + (n1 != 1) || (n2 != 0x060001) || (n3 > pend - p)) + goto err_exit; + + nwhash1init(temp, 8); + for (i = 10; i; i--) + nwhash1(temp, 8, crypt1strc, 28); + nwdecryptblock(temp, p, n3, p); + nwhash1init(temp, 5); + nwhash1(temp, 5, p, n3 - 5); + if (memcmp(temp, p + n3 - 5, 5)) + goto err_exit; + pend = p + n3 - 12; + if ((buf_get_buf(&p, pend, loginid, 4)) || + (buf_get_dword_lh(&p, pend, &n2)) || + (memcmp(loginid, randno, 4)) || (n2 > pend - p)) + goto err_exit; + pend = p + n2; + for (i = 0; i < n2; i++) + p[i] ^= randbuf[i]; + if ((buf_get_dword_lh(&p, pend, &n1)) || + (buf_get_dword_lh(&p, pend, &n2)) || + (buf_get_word_lh(&p, pend, &n3)) || + (n1 != 1) || (n2 != 0x060001) || (n3 > pend - p)) + goto err_exit; + pend = p + n3; + nwdecryptblock(hashshuf, p, n3, p); + if ((buf_get_dword_lh(&p, pend, &n1)) || + (buf_get_word_lh2(&p, pend, &n2a)) || + (buf_get_word_lh2(&p, pend, &n3)) || + (n1 != 1) || (n2a != 2) || (n3 > pend - p)) + goto err_exit; + if (u_priv_key) { + if (!(tempbuf = malloc(n3 + 10))) { + err = ENOMEM; + goto err_exit; + } + memset(tempbuf, 0, 8); + tempbuf[0] = 1; + tempbuf[4] = 3; + tempbuf[6] = 1; + WSET_LH(tempbuf, 8, n3); + memcpy(tempbuf + 10, p, n3); + if (!checkkey(tempbuf)) { + free(tempbuf); + goto err_exit; + } + *u_priv_key = tempbuf; + } + err = 0; + if (grace_period) { + conn->completion = NDS_GRACE_PERIOD; + err = NCPL_ET_REQUEST_ERROR; + } + +err_exit: + memzero(hashshuf); + memzero(randbuf); + memzero(crypt1strc); + memzero(randno); + memzero(temp); + if (buf) free(buf); + return err; +} + +long nds_beginauth(struct ncp_conn *conn, long user_id, struct ncp_conn *readkey_conn, + long serv_id, char *authid) { + char *buf, *p, *pend, *n_temp, temp[8]; + char *s_key; + char randno[4]; + long err; + int outlen, n1, n2, n3, n4; + u_int16_t n3a; + + if (!(buf = malloc(2048))) + return ENOMEM; + n_temp = NULL; + fillrandom(randno, 4); + pend = (p = buf) + 512; + buf_put_dword_lh(&p, pend, 0); + buf_put_dword_hl(&p, pend, user_id); + buf_put_buf(&p, pend, randno, 4); + if ((err = ncp_send_nds_frag(conn, 59, buf, p - buf, buf + 1024, 1024, + &outlen))) + goto err_exit; + + err = NCPL_ET_REPLY_FORMAT; + pend = (p = buf + 1024) + outlen; + if ((buf_get_buf(&p, pend, authid, 4)) || + (buf_get_dword_lh(&p, pend, &outlen)) || + (outlen > pend - p)) + goto err_exit; + pend = p + outlen; + if ((buf_get_dword_lh(&p, pend, &n1)) || + (buf_get_dword_lh(&p, pend, &n2)) || + (buf_get_dword_lh(&p, pend, &n3)) || + (n1 != 1) || (n2 != 0x020009) || (n3 > pend - p)) + goto err_exit; + pend = p + n3; + if ((buf_get_dword_lh(&p, pend, &n1)) || + (buf_get_dword_lh(&p, pend, &n1)) || + (buf_get_dword_lh(&p, pend, &n2)) || + (buf_get_word_lh(&p, pend, &n3a)) || + (n1 != 1) || (n2 != 0x0a0001) || (n3a > pend - p)) + goto err_exit; + n1 = ((countbits_l(p, n3a) + 31) & (~31)) >> 3; + if (n1 < 52) + goto err_exit; + if (!(n_temp = malloc(n1))) { + err = ENOMEM; + goto err_exit; + } + copyfill(n_temp, n1, p, n3a); + p += (n3a + 3) & (~3); + + if ((err = get_public_key(readkey_conn, serv_id, &s_key))) + goto err_exit; + err = modexpkey(s_key, n_temp, n_temp, n1); + free(s_key); + if (err) + goto err_exit; + err = NCPL_ET_REPLY_FORMAT; + nwhash1init(temp, 7); + nwhash1(temp + 5, 2, n_temp, 45); + nwhash1(temp, 5, n_temp + 1, 39); + if (memcmp(temp, n_temp + 40, 7)) + goto err_exit; + nwhash1init(temp, 8); + for (n1 = 10; n1; n1--) + nwhash1(temp, 8, n_temp + 1, 28); + free(n_temp); n_temp = NULL; + if ((buf_get_dword_lh(&p, pend, &n1)) || + (buf_get_dword_lh(&p, pend, &n2)) || + (buf_get_dword_lh(&p, pend, &n3)) || + (buf_get_dword_lh(&p, pend, &n4)) || + (n1 != 28) || (n2 != 1) || (n3 != 0x060001) || (n4 != 0x040010) || + (pend - p < 16)) + goto err_exit; + nwdecryptblock(temp, p, 16, p); + nwhash1init(temp, 5); + nwhash1(temp, 5, p, 11); + if ((!memcmp(temp, p + 11, 5)) || (!memcmp(p, randno, 4))) + err = 0; +err_exit: + if (n_temp) free(n_temp); + if (buf) free(buf); + return err; +} + +static char *allocfillchunk(const char *keyptr, int keylen, const char *chunk, + int destsize) { + char *p, *p2; + int i; + i = findchunk(keyptr, keylen, chunk, &p); + if (!p) + return NULL; + if (!(p2 = malloc(destsize))) + return NULL; + copyfill(p2, destsize, p, i); + return p2; +} + +static long gen_auth_data(char **outp, char *outend, + const char *u_key, const char *u_priv_key, + const char *authid, char *loginstrc, int loginstrc_len) { + char *keyptr; + int keylen, i, j; + int nbits, nblocksize, nbytes; + unsigned char nmask; + unitptr n_mod, n_exp, n_pn, n_qn, n_dp, n_dq, n_cr, n_key, n_temp; + unitptr n_key_dp, n_key_dq; + unitptr up, up2; + char *p, *tempbuf; + char *randbuf = NULL; + char hashbuf[0x42]; + long err; + + n_temp = n_mod = n_exp = n_pn = n_qn = n_dp = n_dq = n_cr = n_key = + n_key_dp = n_key_dq = NULL; + if (!initkey(u_key, &keyptr, &keylen)) + return NCPL_ET_REPLY_FORMAT; + i = findchunk(keyptr, keylen, "NN", &p); + if (!p) + return NCPL_ET_REPLY_FORMAT; + nbits = countbits_l(p, i); + nbytes = (nbits + 7) >> 3; + nmask = (unsigned char)(255 >> (8 - (nbits & 7))); + nblocksize = ((nbits + 31) & (~31)) >> 3; + + set_precision(bytes2units(nblocksize)); + + n_mod = (unitptr)allocfillchunk(keyptr, keylen, "NN", nblocksize); + n_exp = (unitptr)allocfillchunk(keyptr, keylen, "EN", nblocksize); + if (!initkey(u_priv_key, &keyptr, &keylen)) { + err = NCPL_ET_REPLY_FORMAT; + goto err_exit; + } + n_pn = (unitptr)allocfillchunk(keyptr, keylen, "PN", nblocksize); + n_qn = (unitptr)allocfillchunk(keyptr, keylen, "QN", nblocksize); + n_dp = (unitptr)allocfillchunk(keyptr, keylen, "DP", nblocksize); + n_dq = (unitptr)allocfillchunk(keyptr, keylen, "DQ", nblocksize); + n_cr = (unitptr)allocfillchunk(keyptr, keylen, "CR", nblocksize); + n_key = malloc(nblocksize); + + nwhash2init(hashbuf); + nwhash2block(hashbuf, loginstrc, loginstrc_len); + nwhash2end(hashbuf); + copyfill(n_key, nblocksize, hashbuf, 16); + + if (!(tempbuf = malloc(loginstrc_len + 16))) { + err = ENOMEM; + goto err_exit; + } + memset(tempbuf, 0, 16); + tempbuf[4] = 0x3c; + memcpy(tempbuf + 8, authid, 4); + p = tempbuf + 12; + buf_put_dword_lh(&p, tempbuf + 16, loginstrc_len); + memcpy(p, loginstrc, loginstrc_len); + + nwhash2init(hashbuf); + nwhash2block(hashbuf, tempbuf, loginstrc_len + 16); + free(tempbuf); + + n_temp = malloc(nblocksize); + n_key_dp = malloc(nblocksize); + n_key_dq = malloc(nblocksize); + mp_mult(n_temp, n_pn, n_qn); + mp_modexp(n_key_dp, n_key, n_dp, n_pn); + mp_modexp(n_key_dq, n_key, n_dq, n_qn); + mp_move(n_temp, n_key_dp); + mp_add(n_temp, n_pn); + mp_sub(n_temp, n_key_dq); + stage_modulus(n_pn); + mp_modmult(n_temp, n_temp, n_cr); + mp_mult(n_key, n_temp, n_qn); + mp_add(n_key, n_key_dq); + + randbuf = malloc(nblocksize * 3); + memset(randbuf, 0, nblocksize * 3); + + buf_put_dword_lh(outp, outend, 12 + nblocksize * 6); + buf_put_dword_lh(outp, outend, 1); + buf_put_dword_lh(outp, outend, 0x100008); + buf_put_word_lh2(outp, outend, 3); + buf_put_word_lh2(outp, outend, nblocksize * 3); + memset(*outp, 0, nblocksize * 6); + + up = (unitptr)randbuf; up2 = (unitptr)*outp; + for (i = 3; i; i--) { + fillrandom((char *)up, nbytes); + ((char *)up)[nbytes - 1] &= nmask; + if (!(j = mp_compare(up, n_mod))) + mp_dec(up); + else if (j > 0) { + mp_sub(up, n_mod); + mp_neg(up); + mp_add(up, n_mod); + } + mp_modexp(up2, up, n_exp, n_mod); + ((char *)up) += nblocksize; + ((char *)up2) += nblocksize; + } + nwhash2block(hashbuf, *outp, nblocksize * 3); + nwhash2end(hashbuf); + + up = (unitptr)randbuf; + for (i = 0; i < 3; i++) { + mp_init(n_temp, (unsigned char)hashbuf[i << 1] | + ((unsigned char)hashbuf[(i << 1) + 1] << 8)); + mp_modexp(up2, n_key, n_temp, n_mod); + stage_modulus(n_mod); + mp_modmult(up2, up2, up); + ((char *)up) += nblocksize; + ((char *)up2) += nblocksize; + } + *outp = (char *)up2; + err = 0; +err_exit: + memzero(hashbuf); + free(randbuf); + if (n_temp) { mp_init0(n_temp); free(n_temp); } + if (n_key_dp) { mp_init0(n_key_dp); free(n_key_dp); } + if (n_key_dq) { mp_init0(n_key_dq); free(n_key_dq); } + if (n_pn) { mp_init0(n_pn); free(n_pn); } + if (n_qn) { mp_init0(n_qn); free(n_qn); } + if (n_dp) { mp_init0(n_dp); free(n_dp); } + if (n_dq) { mp_init0(n_dq); free(n_dq); } + if (n_cr) { mp_init0(n_cr); free(n_cr); } + free(n_mod); + free(n_exp); + return err; +} + + +long nds_authenticate(struct ncp_conn *conn, long user_id, struct ncp_conn* readkey_conn, + long serv_id, const char *logindata, const char *u_priv_key) { + char authid[4]; + long err; + int user_name_len; + uni_char *user_name = NULL; + char *loginstrc; + int loginstrc_len; + char *buf, *p, *pend; + char *u_key; +#ifdef SIGNATURES + char signkey[8]; +#endif + + if (!readkey_conn) readkey_conn = conn; + u_key = loginstrc = buf = NULL; + if ((err = nds_beginauth(conn, user_id, readkey_conn, serv_id, authid))) + return err; + if ((err = nds_readentryname(conn, user_id, &user_name, &user_name_len))) + return err; + loginstrc_len = user_name_len + 22; + if (!(loginstrc = malloc(loginstrc_len))) { + err = ENOMEM; + goto err_exit; + } + memset(loginstrc, 0, 22); + loginstrc[0] = 1; + loginstrc[4] = 6; + memcpy(loginstrc + 6, logindata, 8); + fillrandom(loginstrc + 14, 4); + WSET_LH(loginstrc, 20, user_name_len); + memcpy(loginstrc + 22, user_name, user_name_len); + free(user_name); user_name = NULL; + if ((err = get_public_key(conn, user_id, &u_key))) + goto err_exit; + if (!(buf = malloc(2048))) { + err = ENOMEM; + goto err_exit; + } + pend = (p = buf) + 2048; + buf_put_dword_lh(&p, pend, 0); +#ifdef SIGNATURES + if (conn->sign_wanted) { + fillrandom(signkey, 8); + rsa_crypt(readkey_conn, signkey, 8, serv_id, &p, pend); + } else +#endif + buf_put_dword_lh(&p, pend, 0); + buf_put_lbuf(&p, pend, loginstrc, loginstrc_len); + + if ((err = gen_auth_data(&p, pend, u_key, u_priv_key, + authid, loginstrc, loginstrc_len))) + goto err_exit; + if ((err = ncp_send_nds_frag(conn, 60, buf, p - buf, NULL, 0, NULL))) + goto err_exit; +#ifdef SIGNATURES + if ((err = ncp_sign_start(conn, signkey))) + goto err_exit; +#endif + err = ncp_change_conn_state(conn, 1); + +err_exit: + if (loginstrc) free(loginstrc); + if (buf) free(buf); + if (u_key) free(u_key); + if (user_name) free(user_name); + return err; +} + +long nds_login_auth(struct ncp_conn *conn, const char *user, + const char *pwd) { + long err; + uni_char user_u[200]; + char *u_priv_key = NULL; + char logindata[8]; + uni_char *server_name = NULL; + __u32 serv_id, user_id; + struct sockaddr_ipx wserv_addr; + struct ncp_conn *login_conn, *wserv_conn = NULL, *readkey_conn = NULL; + int not_wserv; /* =1: current server doesn't have a writable replica */ + int i; + struct timeval tv; + int grace_period = 0; +#ifdef ERR_MSG + char buf[200]; /* to print username */ +#endif + gettimeofday(&tv, NULL); + srand(tv.tv_usec); + + if (strlen(user) >= 200) + return NCPL_ET_NAMETOOLONG; + strcpy_cu(user_u, user); + i = sizeof(wserv_addr); + err = nds_resolve_name(conn, 0x64, user_u, &user_id, ¬_wserv, + (struct sockaddr *)&wserv_addr, &i); + if ((err == NCPL_ET_REQUEST_ERROR) && (conn->completion == -601) && + (user_u[strlen_u(user_u)-1] != '.')) { +#ifdef ERR_MSG + strcpy_uc(buf, user_u); + printf("User %s not found in current context.\n" + "Trying server context...\n", buf); +#endif + if ((err = nds_get_server_name(conn, &server_name)) != 0) + goto err_exit; + i = 0; + while ((server_name[i]) && (server_name[i] != '.')) + i++; + memcpy(user_u + strlen_u(user_u), server_name + i, + (strlen_u(server_name) - i + 1) * 2); + free(server_name); + server_name = NULL; + i = sizeof(wserv_addr); + err = nds_resolve_name(conn, 0x64, user_u, &user_id, ¬_wserv, + (struct sockaddr *)&wserv_addr, &i); + } + if (err) { +#ifdef ERR_MSG + if (err == NCPL_ET_REQUEST_ERROR) + fprintf(stderr, "error %d finding user\n", conn->completion); +#endif + goto err_exit; + } + if (not_wserv) { + if (!(login_conn = wserv_conn = ncp_open_addr((struct sockaddr*)&wserv_addr, &err))) + goto err_exit; + } else + login_conn = conn; + if ((err = nds_get_server_name(login_conn, &server_name)) != 0) + goto err_exit2; + if ((err = nds_resolve_name(login_conn, 0x62, server_name, &serv_id, + NULL, NULL, NULL)) != 0) + goto err_exit2; + if ((err = nds_login(login_conn, user_id, pwd, serv_id, logindata, + &u_priv_key))) { + if ((err != NCPL_ET_REQUEST_ERROR) || + (login_conn->completion != NDS_GRACE_PERIOD)) { +#ifdef ERR_MSG + if (err == NCPL_ET_REQUEST_ERROR) + fprintf(stderr, "error %d logging in\n", login_conn->completion); +#endif +err_exit2:; + conn->completion = login_conn->completion; + goto err_exit; + } + grace_period = 1; + } + if (not_wserv) { + struct sockaddr xaddr; + int remoteserver; + int i; + + free(server_name); + if ((err = nds_get_server_name(conn, &server_name)) != 0) + goto err_exit; + i = sizeof(xaddr); + if ((err = nds_resolve_name(conn, 0x62, server_name, &serv_id, + &remoteserver, (struct sockaddr*)&xaddr, &i)) != 0) + goto err_exit; + if (remoteserver) { + if (!(readkey_conn = ncp_open_addr((struct sockaddr*)&xaddr, &err))) + goto err_exit; + } + if ((err = nds_resolve_name(conn, 0x51, user_u, &user_id, + NULL, NULL, NULL)) !=0) + goto err_exit; + } + if ((err = nds_authenticate(conn, user_id, readkey_conn, serv_id, logindata, + u_priv_key))) { +#ifdef ERR_MSG + if (err == NCPL_ET_REQUEST_ERROR) + fprintf(stderr, "error %d authenticating\n", conn->completion); +#endif + goto err_exit; + } + if (grace_period && (!err)) { + conn->completion = NDS_GRACE_PERIOD; + err = NCPL_ET_REQUEST_ERROR; + } +err_exit: + if (readkey_conn) ncp_close(readkey_conn); + if (wserv_conn) ncp_close(wserv_conn); + if (u_priv_key) { clearkey(u_priv_key); free(u_priv_key); } + free(server_name); +#ifdef RANDBUF + memset(global_randbuf, 0, RANDBUFSIZE); + g_rndp = global_randbuf + RANDBUFSIZE; +#endif + return err; +} + +#ifdef NDS_PRIVATEKEY +long +nds_authenticate(struct ncp_conn* conn, uni_char* name, u_int8_t* code1, void* privateKey, size_t privateKeyLen) { +} +#endif /* NDS_PRIVATE_KEY */ + diff --git a/lib/nwcrypt.c b/lib/nwcrypt.c index 07d8ff7..48b80e4 100644 --- a/lib/nwcrypt.c +++ b/lib/nwcrypt.c @@ -92,20 +92,20 @@ typedef unsigned char buf4[4]; static unsigned char encrypttable[256] = {0x7, 0x8, 0x0, 0x8, 0x6, 0x4, 0xE, 0x4, 0x5, 0xC, 0x1, 0x7, 0xB, 0xF, 0xA, 0x8, - 0xF, 0x8, 0xC, 0xC, 0x9, 0x4, 0x1, 0xE, 0x4, 0x6, 0x2, 0x4, 0x0, 0xA, 0xB, 0x9, - 0x2, 0xF, 0xB, 0x1, 0xD, 0x2, 0x1, 0x9, 0x5, 0xE, 0x7, 0x0, 0x0, 0x2, 0x6, 0x6, - 0x0, 0x7, 0x3, 0x8, 0x2, 0x9, 0x3, 0xF, 0x7, 0xF, 0xC, 0xF, 0x6, 0x4, 0xA, 0x0, - 0x2, 0x3, 0xA, 0xB, 0xD, 0x8, 0x3, 0xA, 0x1, 0x7, 0xC, 0xF, 0x1, 0x8, 0x9, 0xD, - 0x9, 0x1, 0x9, 0x4, 0xE, 0x4, 0xC, 0x5, 0x5, 0xC, 0x8, 0xB, 0x2, 0x3, 0x9, 0xE, - 0x7, 0x7, 0x6, 0x9, 0xE, 0xF, 0xC, 0x8, 0xD, 0x1, 0xA, 0x6, 0xE, 0xD, 0x0, 0x7, - 0x7, 0xA, 0x0, 0x1, 0xF, 0x5, 0x4, 0xB, 0x7, 0xB, 0xE, 0xC, 0x9, 0x5, 0xD, 0x1, - 0xB, 0xD, 0x1, 0x3, 0x5, 0xD, 0xE, 0x6, 0x3, 0x0, 0xB, 0xB, 0xF, 0x3, 0x6, 0x4, - 0x9, 0xD, 0xA, 0x3, 0x1, 0x4, 0x9, 0x4, 0x8, 0x3, 0xB, 0xE, 0x5, 0x0, 0x5, 0x2, - 0xC, 0xB, 0xD, 0x5, 0xD, 0x5, 0xD, 0x2, 0xD, 0x9, 0xA, 0xC, 0xA, 0x0, 0xB, 0x3, - 0x5, 0x3, 0x6, 0x9, 0x5, 0x1, 0xE, 0xE, 0x0, 0xE, 0x8, 0x2, 0xD, 0x2, 0x2, 0x0, - 0x4, 0xF, 0x8, 0x5, 0x9, 0x6, 0x8, 0x6, 0xB, 0xA, 0xB, 0xF, 0x0, 0x7, 0x2, 0x8, - 0xC, 0x7, 0x3, 0xA, 0x1, 0x4, 0x2, 0x5, 0xF, 0x7, 0xA, 0xC, 0xE, 0x5, 0x9, 0x3, - 0xE, 0x7, 0x1, 0x2, 0xE, 0x1, 0xF, 0x4, 0xA, 0x6, 0xC, 0x6, 0xF, 0x4, 0x3, 0x0, +0xF, 0x8, 0xC, 0xC, 0x9, 0x4, 0x1, 0xE, 0x4, 0x6, 0x2, 0x4, 0x0, 0xA, 0xB, 0x9, +0x2, 0xF, 0xB, 0x1, 0xD, 0x2, 0x1, 0x9, 0x5, 0xE, 0x7, 0x0, 0x0, 0x2, 0x6, 0x6, +0x0, 0x7, 0x3, 0x8, 0x2, 0x9, 0x3, 0xF, 0x7, 0xF, 0xC, 0xF, 0x6, 0x4, 0xA, 0x0, +0x2, 0x3, 0xA, 0xB, 0xD, 0x8, 0x3, 0xA, 0x1, 0x7, 0xC, 0xF, 0x1, 0x8, 0x9, 0xD, +0x9, 0x1, 0x9, 0x4, 0xE, 0x4, 0xC, 0x5, 0x5, 0xC, 0x8, 0xB, 0x2, 0x3, 0x9, 0xE, +0x7, 0x7, 0x6, 0x9, 0xE, 0xF, 0xC, 0x8, 0xD, 0x1, 0xA, 0x6, 0xE, 0xD, 0x0, 0x7, +0x7, 0xA, 0x0, 0x1, 0xF, 0x5, 0x4, 0xB, 0x7, 0xB, 0xE, 0xC, 0x9, 0x5, 0xD, 0x1, +0xB, 0xD, 0x1, 0x3, 0x5, 0xD, 0xE, 0x6, 0x3, 0x0, 0xB, 0xB, 0xF, 0x3, 0x6, 0x4, +0x9, 0xD, 0xA, 0x3, 0x1, 0x4, 0x9, 0x4, 0x8, 0x3, 0xB, 0xE, 0x5, 0x0, 0x5, 0x2, +0xC, 0xB, 0xD, 0x5, 0xD, 0x5, 0xD, 0x2, 0xD, 0x9, 0xA, 0xC, 0xA, 0x0, 0xB, 0x3, +0x5, 0x3, 0x6, 0x9, 0x5, 0x1, 0xE, 0xE, 0x0, 0xE, 0x8, 0x2, 0xD, 0x2, 0x2, 0x0, +0x4, 0xF, 0x8, 0x5, 0x9, 0x6, 0x8, 0x6, 0xB, 0xA, 0xB, 0xF, 0x0, 0x7, 0x2, 0x8, +0xC, 0x7, 0x3, 0xA, 0x1, 0x4, 0x2, 0x5, 0xF, 0x7, 0xA, 0xC, 0xE, 0x5, 0x9, 0x3, +0xE, 0x7, 0x1, 0x2, 0xE, 0x1, 0xF, 0x4, 0xA, 0x6, 0xC, 0x6, 0xF, 0x4, 0x3, 0x0, 0xC, 0x0, 0x3, 0x6, 0xF, 0x8, 0x7, 0xB, 0x2, 0xD, 0xC, 0x6, 0xA, 0xA, 0x8, 0xD}; static buf32 encryptkeys = @@ -115,7 +115,8 @@ static buf32 encryptkeys = 0xF4, 0x47, 0xDC, 0xA7, 0xEC, 0xCF, 0x50, 0xC0}; -static void shuffle1(buf32 temp, unsigned char *target) +static void +shuffle1(buf32 temp, unsigned char *target) { short b4; unsigned char b3; @@ -123,51 +124,63 @@ static void shuffle1(buf32 temp, unsigned char *target) b4 = 0; - for (b2 = 0; b2 <= 1; ++b2) { - for (s = 0; s <= 31; ++s) { + for (b2 = 0; b2 <= 1; ++b2) + { + for (s = 0; s <= 31; ++s) + { b3 = (temp[s] + b4) ^ (temp[(s + b4) & 31] - encryptkeys[s]); b4 = b4 + b3; temp[s] = b3; } } - for (i = 0; i <= 15; ++i) { + for (i = 0; i <= 15; ++i) + { target[i] = encrypttable[temp[2 * i]] | (encrypttable[temp[2 * i + 1]] << 4); } } -static void shuffle(const unsigned char *lon, const unsigned char *buf, int buflen, - unsigned char *target) +void +shuffle(const unsigned char *lon, const unsigned char *buf, int buflen, + unsigned char *target) { int b2, d, s; buf32 temp; while ((buflen > 0) - && (buf[buflen - 1] == 0)) { + && (buf[buflen - 1] == 0)) + { buflen = buflen - 1; } - for (s = 0; s < 32; s++) { + for (s = 0; s < 32; s++) + { temp[s] = 0; } d = 0; - while (buflen >= 32) { - for (s = 0; s <= 31; ++s) { + while (buflen >= 32) + { + for (s = 0; s <= 31; ++s) + { temp[s] = temp[s] ^ buf[d]; d = d + 1; } buflen = buflen - 32; } b2 = d; - if (buflen > 0) { - for (s = 0; s <= 31; ++s) { - if (d + buflen == b2) { + if (buflen > 0) + { + for (s = 0; s <= 31; ++s) + { + if (d + buflen == b2) + { b2 = d; temp[s] = temp[s] ^ encryptkeys[s]; - } else { + } else + { temp[s] = temp[s] ^ buf[b2]; b2 = b2 + 1; } @@ -180,9 +193,10 @@ static void shuffle(const unsigned char *lon, const unsigned char *buf, int bufl } -static void nw_encrypt(const unsigned char *fra, - const unsigned char *buf, - unsigned char *til) +static void +nw_encrypt(const unsigned char *fra, + const unsigned char *buf, + unsigned char *til) { buf32 k; int s; @@ -197,6 +211,7 @@ static void nw_encrypt(const unsigned char *fra, til[s] = k[s] ^ k[15 - s]; } +#ifndef __MAKE_SULIB__ /*****************************************************************************/ /* */ @@ -288,7 +303,8 @@ static char * in ncplib.c. */ -static void newpassencrypt(char *old, char *new, char *out) +static void +newpassencrypt(char *old, char *new, char *out) { char *p, *bx; char copy[8]; @@ -297,22 +313,26 @@ static void newpassencrypt(char *old, char *new, char *out) memcpy(copy, new, 8); - for (i = 0; i < 16; i++) { - for (di = 0, ax = 0, p = old; di < 8; di++, ax += 0x20, p++) { + for (i = 0; i < 16; i++) + { + for (di = 0, ax = 0, p = old; di < 8; di++, ax += 0x20, p++) + { cl = newshuffle[(((copy[di] ^ *p) >> 4) & 0x0f) + ax + 0x10] << 4; dl = newshuffle[((copy[di] ^ *p) & 0xf) + ax]; copy[di] = cl | dl; } ch = old[7]; - for (bx = old + 7; bx > old; bx--) { + for (bx = old + 7; bx > old; bx--) + { *bx = ((bx[-1] >> 4) & 0x0f) | ((*bx) << 4); } *old = ((ch >> 4) & 0x0f) | (*old) << 4; memset(out, '\0', 8); - for (di = 0; di < 16; di++) { + for (di = 0; di < 16; di++) + { if (newshuffle[di + 0x100] & 1) ch = ((copy[newshuffle[di + 0x100] / 2] >> 4) & 0x0f); else @@ -322,3 +342,5 @@ static void newpassencrypt(char *old, char *new, char *out) memcpy(copy, out, 8); } } +#endif /* __MAKE_SULIB__ */ + diff --git a/lib/platform.h b/lib/platform.h new file mode 100644 index 0000000..2358c99 --- /dev/null +++ b/lib/platform.h @@ -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 */ + diff --git a/lib/usuals.h b/lib/usuals.h new file mode 100644 index 0000000..80ef96f --- /dev/null +++ b/lib/usuals.h @@ -0,0 +1,39 @@ +/* usuals.h - The usual typedefs, etc. +*/ +#ifndef USUALS /* Assures no redefinitions of usual types...*/ +#define USUALS + +#include + +typedef unsigned char boolean; /* values are TRUE or FALSE */ +typedef u_int8_t byte; /* values are 0-255 */ +typedef byte *byteptr; /* pointer to byte */ +typedef char *string; /* pointer to ASCII character string */ +typedef u_int16_t word16; /* values are 0-65535 */ +typedef u_int32_t word32; /* values are 0-4294967295 */ + +#ifndef TRUE +#define FALSE 0 +#define TRUE (!FALSE) +#endif /* if TRUE not already defined */ + +#ifndef min /* if min macro not already defined */ +#define min(a,b) (((a)<(b)) ? (a) : (b) ) +#define max(a,b) (((a)>(b)) ? (a) : (b) ) +#endif /* if min macro not already defined */ + +/* void for use in pointers */ +#ifndef NO_VOID_STAR +#define VOID void +#else +#define VOID char +#endif + + /* Zero-fill the byte buffer. */ +#define fill0(buffer,count) memset( buffer, 0, count ) + + /* This macro is for burning sensitive data. Many of the + file I/O routines use it for zapping buffers */ +#define burn(x) fill0((VOID *)&(x),sizeof(x)) + +#endif /* if USUALS not already defined */ diff --git a/man/Makefile b/man/Makefile index 5cdd1a7..18c608f 100644 --- a/man/Makefile +++ b/man/Makefile @@ -1,12 +1,22 @@ +include ../Makeinit + +MAN1 = ncopy nwbols nwfsinfo nwsfind pqlist nprint nwboprops nwfstime \ + nwtrustee pserver nsend nwbpset nwpasswd nwuserlist slist \ + nwauth nwbpvalues nwrights nwvolinfo pqrm pqstat nwpurge +MAN5 = nwclient +MAN8 = ncpmount nwbpadd nwmsg ncpumount nwbpcreate nwrevoke nwbocreate \ + nwbprm nwborm nwgrant all: dep: install: - for i in *.1; do install $$i -m 755 /usr/local/man/man1; done - for i in *.5; do install $$i -m 755 /usr/local/man/man5; done - for i in *.8; do install $$i -m 755 /usr/local/man/man8; done + for i in $(MAN1); do install $$i.1 -m 644 $(MANDIR)/man1; done + for i in $(MAN5); do install $$i.5 -m 644 $(MANDIR)/man5; done + for i in $(MAN8); do install $$i.8 -m 644 $(MANDIR)/man8; done clean: - rm -f *~ \ No newline at end of file + rm -f *~ + +mrproper: clean diff --git a/man/nwmsg.8 b/man/nwmsg.8 new file mode 100644 index 0000000..a4d538b --- /dev/null +++ b/man/nwmsg.8 @@ -0,0 +1,33 @@ +.TH NWMSG 8 02/29/1996 nwmsg nwmsg +.SH NAME +nwmsg \- Deliver NetWare user broadcast messages +.SH SYNOPSIS +.B nwmsg +.I mount-point +.SH DESCRIPTION +.B nwmsg +is called by kerneld when a broadcast message arrives from a NetWare +server. +.B nwmsg +fetches this message via the mount point and delivers it to +the user using the same way write(1) uses. + +Please note that +.I kerneld +must run when broadcast messages should be delivered to users. + +NetWare servers can send asynchronous broadcast messages to users, +either on explicit request by another user, or when the server is +shutdown. The client workstation is informed about this event by an +IPX packet on a special socket, the message socket. + +This can happen at any time, so the user has to be informed about this +event whenever it appears. I chose to use the kerneld feature of the +Linux kernel to call the program nwmsg. For nwmsg, I used the relevant +parts of the +.I write +program, so you can expect the NetWare broadcast +messages to appear where user messages would appear. + +.SH SEE ALSO +ncpmount(8), kerneld(8), write(1) \ No newline at end of file diff --git a/man/nwpurge.1 b/man/nwpurge.1 new file mode 100644 index 0000000..82e9294 --- /dev/null +++ b/man/nwpurge.1 @@ -0,0 +1,65 @@ +.TH NWPURGE 1 4/2/1998 nwpurge nwpurge +.SH NAME +nwpurge \- Permanently delete previously erased files +.SH SYNOPSIS +.B nwpurge +[ +.B -h +] [ +.B -a +] [ +.B -l +] [ +.B -s +] [ +.B directory +] + +.SH DESCRIPTION +.B nwpurge +purges files from specified NetWare directory. + +.SH OPTIONS + +.B -h +.RS 3 +.B -h +is used to print out a short help text. +.RE + +.B -a +.RS 3 +.B -a +is used to specify that not only specified directory, but also its +subdirectories have to be purged. +.RE + +.B -l +.RS 3 +.B -l +is used to disable purge. Files are only printed out. +.RE + +.B -s +.RS 3 +.B -s +specifies silent mode (no print output, only total is printed). +.RE + +.B directory +.RS 3 +You can specify the directory in which you want to purge files. Current +working directory is used by default. You have to specify path in +Linux format, not in NetWare format. + +.SH EXAMPLES + +nwpurge -a /NetWare/server/sys + +With this example, all files from directory /NetWare/server/sys and from +all its subdirectories are purged. + +.SH AUTHORS +nwpurge was written by Petr Vandrovec with the corresponding NetWare +utility in mind. See the Changes file of ncpfs for other contributors. + diff --git a/man/pqrm.1 b/man/pqrm.1 new file mode 100644 index 0000000..7a3288e --- /dev/null +++ b/man/pqrm.1 @@ -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) + diff --git a/man/pqstat.1 b/man/pqstat.1 new file mode 100644 index 0000000..6f647fd --- /dev/null +++ b/man/pqstat.1 @@ -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) + diff --git a/man/pserver.1 b/man/pserver.1 index b8358a0..be34f9f 100644 --- a/man/pserver.1 +++ b/man/pserver.1 @@ -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 diff --git a/ncpfs-2.1.1.lsm b/ncpfs-2.2.0.lsm similarity index 50% rename from ncpfs-2.1.1.lsm rename to ncpfs-2.2.0.lsm index 171ddd3..d92a363 100644 --- a/ncpfs-2.1.1.lsm +++ b/ncpfs-2.2.0.lsm @@ -1,19 +1,19 @@ Begin3 Title: ncpfs -Version: 2.1.1 -Entered-date: 23. March 1997 +Version: 2.2.0 +Entered-date: May 1, 1998 Description: With ncpfs you can mount volumes of your netware server under Linux. You can also print to netware print queues and spool netware print queues to the - Linux printing system. You need kernel 1.2.x or - 1.3.71 and above. ncpfs does NOT work with any 1.3.x - kernel below 1.3.71. + Linux printing system. Keywords: filesystem ncp novell netware printing -Author: lendecke@namu01.Num.Math.Uni-Goettingen.de (Volker Lendecke) -Maintained-by: lendecke@namu01.Num.Math.Uni-Goettingen.de (Volker Lendecke) +Author: lendecke@Math.Uni-Goettingen.de (Volker Lendecke) +Maintained-by: lendecke@Math.Uni-Goettingen.de (Volker Lendecke), + vandrove@vc.cvut.cz (Petr Vandrovec) Primary-site: ftp.gwdg.de:/pub/linux/misc/ncpfs Alternate-site: sunsite.unc.edu:/pub/Linux/system/Filesystems/ncpfs - ~177k ncpfs-2.1.1.tgz - ~ 1k ncpfs-2.1.1.lsm + platan.vc.cvut.cz:/pub/linux/ncpfs + ~190k ncpfs-2.2.0.tgz + ~ 1k ncpfs-2.2.0.lsm Copying-policy: GPL End diff --git a/ncpfs-nds-0.06.CHANGES b/ncpfs-nds-0.06.CHANGES new file mode 100644 index 0000000..3b70f7a --- /dev/null +++ b/ncpfs-nds-0.06.CHANGES @@ -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 diff --git a/ncpfs-nds-0.06.README b/ncpfs-nds-0.06.README new file mode 100644 index 0000000..625d515 --- /dev/null +++ b/ncpfs-nds-0.06.README @@ -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 diff --git a/patches/README b/patches/README index 85432ae..5db9985 100644 --- a/patches/README +++ b/patches/README @@ -4,10 +4,11 @@ and do: patch -p1 < patch-file -lockup-2.0.28.diff: -An *extremely* dirty fix to the lockup bug mentioned in the BUGS -file. Please only apply it if you experience the problem. Should apply -to 2.0.28 and above in the 2.0.x series. NOT TESTED with 2.1.x. +lockup-2.0.30.diff: +Please apply this patch to your 2.0.30 kernel to get rid of the ncpfs +lockups. See ../BUGS for the symptoms. -linux-2.1.26.diff: -Development version of ncpfs +Patches for other kernels to support new features must be downloaded +separately because of kernel changes have no relations to ncpfs changes. +Kernel patches should be available on same place as this package or +at ftp://platan.vc.cvut.cz/pub/linux/ncpfs/latest. diff --git a/patches/linux-2.1.26.diff b/patches/linux-2.1.26.diff deleted file mode 100644 index 3b6e7fb..0000000 --- a/patches/linux-2.1.26.diff +++ /dev/null @@ -1,35 +0,0 @@ ---- 2.1.26/fs/ncpfs/sock.c Sun Jan 26 11:07:44 1997 -+++ 2.1.26-patched/fs/ncpfs/sock.c Sun Feb 16 17:05:13 1997 -@@ -24,6 +24,7 @@ - #include - #include - #include -+#include - #include - - -@@ -343,7 +344,6 @@ - char *start = server->packet; - poll_table wait_table; - struct poll_table_entry entry; -- int (*select) (struct inode *, poll_table *); - int init_timeout, max_timeout; - int timeout; - int retrans; -@@ -362,7 +362,6 @@ - - file = server->ncp_filp; - inode = file->f_inode; -- select = file->f_op->poll; - sock = &inode->u.socket_i; - if (!sock) - { -@@ -418,7 +417,7 @@ - wait_table.nr = 0; - wait_table.entry = &entry; - current->state = TASK_INTERRUPTIBLE; -- if (!select(inode, &wait_table)) -+ if (!(file->f_op->poll(file, &wait_table) & POLLIN)) - { - if (timeout > max_timeout) - { diff --git a/patches/linux-2.1.29.diff b/patches/linux-2.1.29.diff deleted file mode 100644 index ce7d1b8..0000000 --- a/patches/linux-2.1.29.diff +++ /dev/null @@ -1,5281 +0,0 @@ -diff -urN 2.1.29/fs/ncpfs/dir.c 2.1.29-patched/fs/ncpfs/dir.c ---- 2.1.29/fs/ncpfs/dir.c Sun Jan 26 11:07:44 1997 -+++ 2.1.29-patched/fs/ncpfs/dir.c Sun Mar 23 09:38:45 1997 -@@ -23,95 +23,88 @@ - - struct ncp_dirent { - struct nw_info_struct i; -- struct nw_search_sequence s; /* given back for i */ -+ struct nw_search_sequence s; /* given back for i */ - unsigned long f_pos; - }; - - static long --ncp_dir_read(struct inode *inode, struct file *filp, char *buf, unsigned long count); -+ ncp_dir_read(struct inode *inode, struct file *filp, char *buf, unsigned long count); - --static int --ncp_readdir(struct inode *inode, struct file *filp, -- void *dirent, filldir_t filldir); -+static int -+ ncp_readdir(struct inode *inode, struct file *filp, -+ void *dirent, filldir_t filldir); - - static int --ncp_read_volume_list(struct ncp_server *server, int start_with, -- int cache_size); -+ ncp_read_volume_list(struct ncp_server *server, int start_with, -+ int cache_size); - - static int --ncp_do_readdir(struct ncp_server *server, struct inode *dir, int fpos, -- int cache_size, struct ncp_dirent *entry); -+ ncp_do_readdir(struct ncp_server *server, struct inode *dir, int fpos, -+ int cache_size, struct ncp_dirent *entry); - - static struct inode * --ncp_iget(struct inode *dir, struct nw_file_info *finfo); -+ ncp_iget(struct inode *dir, struct nw_file_info *finfo); - - static struct ncp_inode_info * --ncp_find_dir_inode(struct inode *dir, const char *name); -+ ncp_find_dir_inode(struct inode *dir, const char *name); - - static int --ncp_lookup(struct inode *dir, const char *__name, -- int len, struct inode **result); -+ ncp_lookup(struct inode *dir, const char *__name, -+ int len, struct inode **result); - --static int --ncp_create(struct inode *dir, const char *name, int len, int mode, -- struct inode **result); -+static int -+ ncp_create(struct inode *dir, const char *name, int len, int mode, -+ struct inode **result); - --static int --ncp_mkdir(struct inode *dir, const char *name, int len, int mode); -+static int -+ ncp_mkdir(struct inode *dir, const char *name, int len, int mode); - --static int --ncp_rmdir(struct inode *dir, const char *name, int len); -+static int -+ ncp_rmdir(struct inode *dir, const char *name, int len); - - static int --ncp_unlink(struct inode *dir, const char *name, int len); -+ ncp_unlink(struct inode *dir, const char *name, int len); - - static int --ncp_rename(struct inode *old_dir, const char *old_name, int old_len, -- struct inode *new_dir, const char *new_name, int new_len, -- int must_be_dir); -- --static inline void --str_upper(char *name) --{ -- while (*name) -- { -- if (*name >= 'a' && *name <= 'z') -- { -+ ncp_rename(struct inode *old_dir, const char *old_name, int old_len, -+ struct inode *new_dir, const char *new_name, int new_len, -+ int must_be_dir); -+ -+static inline void str_upper(char *name) -+{ -+ while (*name) { -+ if (*name >= 'a' && *name <= 'z') { - *name -= ('a' - 'A'); - } - name++; - } - } - --static inline void --str_lower(char *name) -+static inline void str_lower(char *name) - { -- while (*name) -- { -- if (*name >= 'A' && *name <= 'Z') -- { -+ while (*name) { -+ if (*name >= 'A' && *name <= 'Z') { - *name += ('a' - 'A'); - } -- name ++; -+ name++; - } - } - --static inline int --ncp_namespace(struct inode *i) -+static inline int ncp_namespace(struct inode *i) - { -- struct ncp_server *server = NCP_SERVER(i); -+ struct ncp_server *server = NCP_SERVER(i); - struct nw_info_struct *info = NCP_ISTRUCT(i); - return server->name_space[info->volNumber]; - } - --static inline int --ncp_preserve_case(struct inode *i) -+static inline int ncp_preserve_case(struct inode *i) - { - return (ncp_namespace(i) == NW_NS_OS2); - } - --static struct file_operations ncp_dir_operations = { -- NULL, /* lseek - default */ -+static struct file_operations ncp_dir_operations = -+{ -+ NULL, /* lseek - default */ - ncp_dir_read, /* read - bad */ - NULL, /* write - bad */ - ncp_readdir, /* readdir */ -@@ -123,23 +116,24 @@ - NULL /* fsync */ - }; - --struct inode_operations ncp_dir_inode_operations = { -+struct inode_operations ncp_dir_inode_operations = -+{ - &ncp_dir_operations, /* default directory file ops */ - ncp_create, /* create */ -- ncp_lookup, /* lookup */ -+ ncp_lookup, /* lookup */ - NULL, /* link */ -- ncp_unlink, /* unlink */ -+ ncp_unlink, /* unlink */ - NULL, /* symlink */ -- ncp_mkdir, /* mkdir */ -- ncp_rmdir, /* rmdir */ -+ ncp_mkdir, /* mkdir */ -+ ncp_rmdir, /* rmdir */ - NULL, /* mknod */ -- ncp_rename, /* rename */ -+ ncp_rename, /* rename */ - NULL, /* readlink */ - NULL, /* follow_link */ - NULL, /* bmap */ - NULL, /* truncate */ - NULL, /* permission */ -- NULL /* smap */ -+ NULL /* smap */ - }; - - -@@ -151,223 +145,181 @@ - * enable the NFS exportability of a ncpfs-mounted volume. - */ - --static inline int --ncp_single_volume(struct ncp_server *server) -+static inline int ncp_single_volume(struct ncp_server *server) - { - return (server->m.mounted_vol[0] != '\0'); - } - - inline ino_t --ncp_info_ino(struct ncp_server *server, struct ncp_inode_info *info) -+ ncp_info_ino(struct ncp_server * server, struct ncp_inode_info * info) - { - return ncp_single_volume(server) -- ? info->finfo.i.dirEntNum : (ino_t)info; -+ ? info->finfo.i.dirEntNum : (ino_t) info; - } - --static inline int --ncp_is_server_root(struct inode *inode) -+static inline int ncp_is_server_root(struct inode *inode) - { - struct ncp_server *s = NCP_SERVER(inode); - -- return ( (!ncp_single_volume(s)) -+ return ((!ncp_single_volume(s)) - && (inode->i_ino == ncp_info_ino(s, &(s->root)))); - } - - struct ncp_inode_info * --ncp_find_inode(struct inode *inode) -+ ncp_find_inode(struct inode *inode) - { - struct ncp_server *server = NCP_SERVER(inode); -- struct ncp_inode_info *root = &(server->root); -- struct ncp_inode_info *this = root; -+ struct ncp_inode_info *root = &(server->root); -+ struct ncp_inode_info *this = root; - - ino_t ino = inode->i_ino; - -- do -- { -- if (ino == ncp_info_ino(server, this)) -- { -+ do { -+ if (ino == ncp_info_ino(server, this)) { - return this; - } - this = this->next; -- } -+ } - while (this != root); - - return NULL; - } -- --static long --ncp_dir_read(struct inode *inode, struct file *filp, char *buf, unsigned long count) -+ -+static long ncp_dir_read(struct inode *inode, struct file *filp, char *buf, unsigned long count) - { - return -EISDIR; - } - --static kdev_t c_dev = 0; --static unsigned long c_ino = 0; --static int c_size; --static int c_seen_eof; --static int c_last_returned_index; --static struct ncp_dirent* c_entry = NULL; --static int c_lock = 0; -+static kdev_t c_dev = 0; -+static unsigned long c_ino = 0; -+static int c_size; -+static int c_seen_eof; -+static int c_last_returned_index; -+static struct ncp_dirent *c_entry = NULL; -+static int c_lock = 0; - static struct wait_queue *c_wait = NULL; - --static inline void --ncp_lock_dircache(void) -+static inline void ncp_lock_dircache(void) - { - while (c_lock) - sleep_on(&c_wait); - c_lock = 1; - } - --static inline void --ncp_unlock_dircache(void) -+static inline void ncp_unlock_dircache(void) - { - c_lock = 0; - wake_up(&c_wait); - } - --static int --ncp_readdir(struct inode *inode, struct file *filp, -- void *dirent, filldir_t filldir) -+static int ncp_readdir(struct inode *inode, struct file *filp, -+ void *dirent, filldir_t filldir) - { - int result = 0; - int i = 0; -- int index = 0; -+ int index = 0; - struct ncp_dirent *entry = NULL; -- struct ncp_server *server = NCP_SERVER(inode); -+ struct ncp_server *server = NCP_SERVER(inode); - struct ncp_inode_info *dir = NCP_INOP(inode); - -- DDPRINTK("ncp_readdir: filp->f_pos = %d\n", (int)filp->f_pos); -+ DDPRINTK("ncp_readdir: filp->f_pos = %d\n", (int) filp->f_pos); - DDPRINTK("ncp_readdir: inode->i_ino = %ld, c_ino = %ld\n", - inode->i_ino, c_ino); - -- if (!inode || !S_ISDIR(inode->i_mode)) -- { -+ if (!inode || !S_ISDIR(inode->i_mode)) { - printk("ncp_readdir: inode is NULL or not a directory\n"); - return -EBADF; - } -- -- if (!ncp_conn_valid(server)) -- { -+ if (!ncp_conn_valid(server)) { - return -EIO; - } -- - ncp_lock_dircache(); - -- if (c_entry == NULL) -- { -- i = sizeof (struct ncp_dirent) * NCP_READDIR_CACHE_SIZE; -+ if (c_entry == NULL) { -+ i = sizeof(struct ncp_dirent) * NCP_READDIR_CACHE_SIZE; - c_entry = (struct ncp_dirent *) vmalloc(i); -- if (c_entry == NULL) -- { -+ if (c_entry == NULL) { - printk("ncp_readdir: no MEMORY for cache\n"); - result = -ENOMEM; - goto finished; - } - } -- -- if (filp->f_pos == 0) -- { -- ncp_invalid_dir_cache(inode); -- if (filldir(dirent,".",1, filp->f_pos, -- ncp_info_ino(server, dir)) < 0) -- { -+ if (filp->f_pos == 0) { -+ ncp_invalid_dir_cache(inode); -+ if (filldir(dirent, ".", 1, filp->f_pos, -+ ncp_info_ino(server, dir)) < 0) { - goto finished; - } - filp->f_pos += 1; -- } -- -- if (filp->f_pos == 1) -- { -- if (filldir(dirent,"..",2, filp->f_pos, -- ncp_info_ino(server, dir->dir)) < 0) -- { -+ } -+ if (filp->f_pos == 1) { -+ if (filldir(dirent, "..", 2, filp->f_pos, -+ ncp_info_ino(server, dir->dir)) < 0) { - goto finished; - } - filp->f_pos += 1; - } -- -- if ((inode->i_dev == c_dev) && (inode->i_ino == c_ino)) -- { -- for (i = 0; i < c_size; i++) -- { -- if (filp->f_pos == c_entry[i].f_pos) -- { -- entry = &c_entry[i]; -- c_last_returned_index = i; -- index = i; -- break; -+ if ((inode->i_dev == c_dev) && (inode->i_ino == c_ino)) { -+ for (i = 0; i < c_size; i++) { -+ if (filp->f_pos == c_entry[i].f_pos) { -+ entry = &c_entry[i]; -+ c_last_returned_index = i; -+ index = i; -+ break; - } - } -- if ((entry == NULL) && c_seen_eof) -- { -+ if ((entry == NULL) && c_seen_eof) { - goto finished; - } - } -- -- if (entry == NULL) -- { -+ if (entry == NULL) { - int entries; - DDPRINTK("ncp_readdir: Not found in cache.\n"); - -- if (ncp_is_server_root(inode)) -- { -+ if (ncp_is_server_root(inode)) { - entries = ncp_read_volume_list(server, filp->f_pos, -- NCP_READDIR_CACHE_SIZE); -+ NCP_READDIR_CACHE_SIZE); - DPRINTK("ncp_read_volume_list returned %d\n", entries); - -- } -- else -- { -+ } else { - entries = ncp_do_readdir(server, inode, filp->f_pos, - NCP_READDIR_CACHE_SIZE, - c_entry); - DPRINTK("ncp_readdir returned %d\n", entries); - } - -- if (entries < 0) -- { -+ if (entries < 0) { - c_dev = 0; - c_ino = 0; - result = entries; - goto finished; - } -- -- if (entries > 0) -- { -- c_seen_eof = (entries < NCP_READDIR_CACHE_SIZE); -- c_dev = inode->i_dev; -- c_ino = inode->i_ino; -+ if (entries > 0) { -+ c_seen_eof = (entries < NCP_READDIR_CACHE_SIZE); -+ c_dev = inode->i_dev; -+ c_ino = inode->i_ino; - c_size = entries; - entry = c_entry; -- c_last_returned_index = 0; -- index = 0; -+ c_last_returned_index = 0; -+ index = 0; - -- if (!ncp_preserve_case(inode)) -- { -- for (i = 0; i < c_size; i++) -- { -+ if (!ncp_preserve_case(inode)) { -+ for (i = 0; i < c_size; i++) { - str_lower(c_entry[i].i.entryName); - } - } - } - } -- -- if (entry == NULL) -- { -- /* Nothing found, even from a ncp call */ -+ if (entry == NULL) { -+ /* Nothing found, even from a ncp call */ - goto finished; -- } -- -- while (index < c_size) -- { -+ } -+ while (index < c_size) { - ino_t ino; - -- if (ncp_single_volume(server)) -- { -- ino = (ino_t)(entry->i.dirEntNum); -- } -- else -- { -+ if (ncp_single_volume(server)) { -+ ino = (ino_t) (entry->i.dirEntNum); -+ } else { - /* For getwd() we have to return the correct - * inode in d_ino if the inode is currently in - * use. Otherwise the inode number does not -@@ -379,41 +331,36 @@ - /* Some programs seem to be confused about a - * zero inode number, so we set it to one. - * Thanks to Gordon Chaffee for this one. */ -- if (ino_info == NULL) -- { -+ if (ino_info == NULL) { - ino_info = (struct ncp_inode_info *) 1; - } -- ino = (ino_t)(ino_info); -+ ino = (ino_t) (ino_info); - } - - DDPRINTK("ncp_readdir: entry->path= %s\n", entry->i.entryName); - DDPRINTK("ncp_readdir: entry->f_pos = %ld\n", entry->f_pos); - -- if (filldir(dirent, entry->i.entryName, entry->i.nameLen, -- entry->f_pos, ino) < 0) -- { -+ if (filldir(dirent, entry->i.entryName, entry->i.nameLen, -+ entry->f_pos, ino) < 0) { - break; -- } -- -- if ( (inode->i_dev != c_dev) -+ } -+ if ((inode->i_dev != c_dev) - || (inode->i_ino != c_ino) -- || (entry->f_pos != filp->f_pos)) -- { -+ || (entry->f_pos != filp->f_pos)) { - /* Someone has destroyed the cache while we slept - in filldir */ - break; - } -- filp->f_pos += 1; -- index += 1; -- entry += 1; -+ filp->f_pos += 1; -+ index += 1; -+ entry += 1; - } -- finished: -+ finished: - ncp_unlock_dircache(); - return result; - } - --static int --ncp_read_volume_list(struct ncp_server *server, int fpos, int cache_size) -+static int ncp_read_volume_list(struct ncp_server *server, int fpos, int cache_size) - { - struct ncp_dirent *entry = c_entry; - -@@ -421,47 +368,35 @@ - int i; - - #if 1 -- if (fpos < 2) -- { -+ if (fpos < 2) { - printk("OOPS, we expect fpos >= 2"); - fpos = 2; - } - #endif - -- for (i=0; i 0) -- { -- if (total_count < fpos) -- { -+ if (strlen(info.volume_name) > 0) { -+ if (total_count < fpos) { - DPRINTK("ncp_read_volumes: skipped vol: %s\n", - info.volume_name); -- } -- else if (total_count >= fpos + cache_size) -- { -+ } else if (total_count >= fpos + cache_size) { - return (total_count - fpos); -- } -- else -- { -+ } else { - DPRINTK("ncp_read_volumes: found vol: %s\n", - info.volume_name); - - if (ncp_lookup_volume(server, - info.volume_name, -- &(entry->i)) != 0) -- { -+ &(entry->i)) != 0) { - DPRINTK("ncpfs: could not lookup vol " - "%s\n", info.volume_name); - continue; - } -- - entry->f_pos = total_count; - entry += 1; - } -@@ -471,59 +406,46 @@ - return (total_count - fpos); - } - --static int --ncp_do_readdir(struct ncp_server *server, struct inode *dir, int fpos, -- int cache_size, struct ncp_dirent *entry) -+static int ncp_do_readdir(struct ncp_server *server, struct inode *dir, int fpos, -+ int cache_size, struct ncp_dirent *entry) - { - static struct nw_search_sequence seq; - static struct inode *last_dir; - static int total_count; - - #if 1 -- if (fpos < 2) -- { -+ if (fpos < 2) { - printk("OOPS, we expect fpos >= 2"); - fpos = 2; - } - #endif - DPRINTK("ncp_do_readdir: fpos = %d\n", fpos); - -- if (fpos == 2) -- { -+ if (fpos == 2) { - last_dir = NULL; - total_count = 2; - } -- -- if ((fpos != total_count) || (dir != last_dir)) -- { -+ if ((fpos != total_count) || (dir != last_dir)) { - total_count = 2; - last_dir = dir; - - DPRINTK("ncp_do_readdir: re-used seq for %s\n", - NCP_ISTRUCT(dir)->entryName); - -- if (ncp_initialize_search(server, NCP_ISTRUCT(dir), &seq)!=0) -- { -+ if (ncp_initialize_search(server, NCP_ISTRUCT(dir), &seq) != 0) { - DPRINTK("ncp_init_search failed\n"); - return total_count - fpos; - } - } -- -- while (total_count < fpos + cache_size) -- { -+ while (total_count < fpos + cache_size) { - if (ncp_search_for_file_or_subdir(server, &seq, -- &(entry->i)) != 0) -- { -+ &(entry->i)) != 0) { - return total_count - fpos; - } -- -- if (total_count < fpos) -- { -+ if (total_count < fpos) { - DPRINTK("ncp_do_readdir: skipped file: %s\n", - entry->i.entryName); -- } -- else -- { -+ } else { - DDPRINTK("ncp_do_r: file: %s, f_pos=%d,total_count=%d", - entry->i.entryName, fpos, total_count); - entry->s = seq; -@@ -535,143 +457,124 @@ - return (total_count - fpos); - } - --void --ncp_init_dir_cache(void) -+void ncp_init_dir_cache(void) - { -- c_dev = 0; -- c_ino = 0; -- c_entry = NULL; -+ c_dev = 0; -+ c_ino = 0; -+ c_entry = NULL; - } - --void --ncp_invalid_dir_cache(struct inode *ino) -+void ncp_invalid_dir_cache(struct inode *ino) - { -- if ((ino->i_dev == c_dev) && (ino->i_ino == c_ino)) -- { -+ if ((ino->i_dev == c_dev) && (ino->i_ino == c_ino)) { - c_dev = 0; -- c_ino = 0; -- c_seen_eof = 0; -- } -+ c_ino = 0; -+ c_seen_eof = 0; -+ } - } - --void --ncp_free_dir_cache(void) --{ -- DPRINTK("ncp_free_dir_cache: enter\n"); -- -- if (c_entry == NULL) -- { -- return; -- } -+void ncp_free_dir_cache(void) -+{ -+ DPRINTK("ncp_free_dir_cache: enter\n"); - -+ if (c_entry == NULL) { -+ return; -+ } - vfree(c_entry); - c_entry = NULL; - -- DPRINTK("ncp_free_dir_cache: exit\n"); -+ DPRINTK("ncp_free_dir_cache: exit\n"); - } - - - static struct inode * --ncp_iget(struct inode *dir, struct nw_file_info *finfo) -+ ncp_iget(struct inode *dir, struct nw_file_info *finfo) - { - struct inode *inode; -- struct ncp_inode_info *new_inode_info; -- struct ncp_inode_info *root; -+ struct ncp_inode_info *new_inode_info; -+ struct ncp_inode_info *root; - -- if (dir == NULL) -- { -+ if (dir == NULL) { - printk("ncp_iget: dir is NULL\n"); - return NULL; - } -- -- if (finfo == NULL) -- { -+ if (finfo == NULL) { - printk("ncp_iget: finfo is NULL\n"); - return NULL; - } -+ new_inode_info = ncp_kmalloc(sizeof(struct ncp_inode_info), -+ GFP_KERNEL); - -- new_inode_info = ncp_kmalloc(sizeof(struct ncp_inode_info), -- GFP_KERNEL); -- -- if (new_inode_info == NULL) -- { -- printk("ncp_iget: could not alloc mem for %s\n", -+ if (new_inode_info == NULL) { -+ printk("ncp_iget: could not alloc mem for %s\n", - finfo->i.entryName); -- return NULL; -- } -+ return NULL; -+ } -+ new_inode_info->state = NCP_INODE_LOOKED_UP; -+ new_inode_info->nused = 0; -+ new_inode_info->dir = NCP_INOP(dir); -+ new_inode_info->finfo = *finfo; -+ -+ NCP_INOP(dir)->nused += 1; -+ -+ /* We have to link the new inode_info into the doubly linked -+ list of inode_infos to make a complete linear search -+ possible. */ -+ -+ root = &(NCP_SERVER(dir)->root); -+ -+ new_inode_info->prev = root; -+ new_inode_info->next = root->next; -+ root->next->prev = new_inode_info; -+ root->next = new_inode_info; - -- new_inode_info->state = NCP_INODE_LOOKED_UP; -- new_inode_info->nused = 0; -- new_inode_info->dir = NCP_INOP(dir); -- new_inode_info->finfo = *finfo; -- -- NCP_INOP(dir)->nused += 1; -- -- /* We have to link the new inode_info into the doubly linked -- list of inode_infos to make a complete linear search -- possible. */ -- -- root = &(NCP_SERVER(dir)->root); -- -- new_inode_info->prev = root; -- new_inode_info->next = root->next; -- root->next->prev = new_inode_info; -- root->next = new_inode_info; -- - if (!(inode = iget(dir->i_sb, ncp_info_ino(NCP_SERVER(dir), -- new_inode_info)))) -- { -+ new_inode_info)))) { - printk("ncp_iget: iget failed!"); - return NULL; - } -- - return inode; - } - --void --ncp_free_inode_info(struct ncp_inode_info *i) -+void ncp_free_inode_info(struct ncp_inode_info *i) - { -- if (i == NULL) -- { -- printk("ncp_free_inode: i == NULL\n"); -- return; -- } -- -- i->state = NCP_INODE_CACHED; -- while ((i->nused == 0) && (i->state == NCP_INODE_CACHED)) -- { -- struct ncp_inode_info *dir = i->dir; -+ if (i == NULL) { -+ printk("ncp_free_inode: i == NULL\n"); -+ return; -+ } -+ i->state = NCP_INODE_CACHED; -+ while ((i->nused == 0) && (i->state == NCP_INODE_CACHED)) { -+ struct ncp_inode_info *dir = i->dir; - -- i->next->prev = i->prev; -- i->prev->next = i->next; -+ i->next->prev = i->prev; -+ i->prev->next = i->next; - - DDPRINTK("ncp_free_inode_info: freeing %s\n", - i->finfo.i.entryName); - -- ncp_kfree_s(i, sizeof(struct ncp_inode_info)); -+ ncp_kfree_s(i, sizeof(struct ncp_inode_info)); - -- if (dir == i) return; -+ if (dir == i) -+ return; - -- (dir->nused)--; -- i = dir; -- } -+ (dir->nused)--; -+ i = dir; -+ } - } -- --void --ncp_init_root(struct ncp_server *server) -+ -+void ncp_init_root(struct ncp_server *server) - { -- struct ncp_inode_info *root = &(server->root); -+ struct ncp_inode_info *root = &(server->root); - struct nw_info_struct *i = &(root->finfo.i); - unsigned short dummy; - -- DPRINTK("ncp_init_root: server %s\n", server->m.server_name); -- DPRINTK("ncp_init_root: i = %x\n", (int)i); -+ DPRINTK("ncp_init_root: i = %x\n", (int) i); - -- root->finfo.opened = 0; -- i->attributes = aDIR; -+ root->finfo.opened = 0; -+ i->attributes = aDIR; - i->dataStreamSize = 1024; - i->dirEntNum = i->DosDirNum = 0; -- i->volNumber = NCP_NUMBER_OF_VOLUMES+1; /* illegal volnum */ -+ i->volNumber = NCP_NUMBER_OF_VOLUMES + 1; /* illegal volnum */ - ncp_date_unix2dos(0, &(i->creationTime), &(i->creationDate)); - ncp_date_unix2dos(0, &(i->modifyTime), &(i->modifyDate)); - ncp_date_unix2dos(0, &dummy, &(i->lastAccessDate)); -@@ -683,25 +586,21 @@ - i->nameLen = 0; - i->entryName[0] = '\0'; - -- root->state = NCP_INODE_LOOKED_UP; -- root->nused = 1; -- root->dir = root; -- root->next = root->prev = root; -- return; -+ root->state = NCP_INODE_LOOKED_UP; -+ root->nused = 1; -+ root->dir = root; -+ root->next = root->prev = root; -+ return; - } - --int --ncp_conn_logged_in(struct ncp_server *server) -+int ncp_conn_logged_in(struct ncp_server *server) - { -- if (server->m.mounted_vol[0] == '\0') -- { -+ if (server->m.mounted_vol[0] == '\0') { - return 0; - } -- - str_upper(server->m.mounted_vol); - if (ncp_lookup_volume(server, server->m.mounted_vol, -- &(server->root.finfo.i)) != 0) -- { -+ &(server->root.finfo.i)) != 0) { - return -ENOENT; - } - str_lower(server->root.finfo.i.entryName); -@@ -709,202 +608,166 @@ - return 0; - } - --void --ncp_free_all_inodes(struct ncp_server *server) -+void ncp_free_all_inodes(struct ncp_server *server) - { -- /* Here nothing should be to do. I do not know whether it's -- better to leave some memory allocated or be stuck in an -- endless loop */ -+ /* Here nothing should be to do. I do not know whether it's -+ better to leave some memory allocated or be stuck in an -+ endless loop */ - #if 1 -- struct ncp_inode_info *root = &(server->root); -+ struct ncp_inode_info *root = &(server->root); - -- if (root->next != root) -- { -- printk("ncp_free_all_inodes: INODES LEFT!!!\n"); -- } -- -- while (root->next != root) -- { -- printk("ncp_free_all_inodes: freeing inode\n"); -- ncp_free_inode_info(root->next); -- /* In case we have an endless loop.. */ -- schedule(); -- } --#endif -- -- return; -+ if (root->next != root) { -+ printk("ncp_free_all_inodes: INODES LEFT!!!\n"); -+ } -+ while (root->next != root) { -+ printk("ncp_free_all_inodes: freeing inode\n"); -+ ncp_free_inode_info(root->next); -+ /* In case we have an endless loop.. */ -+ schedule(); -+ } -+#endif -+ -+ return; - } - - /* We will search the inode that belongs to this name, currently by a - complete linear search through the inodes belonging to this - filesystem. This has to be fixed. */ - static struct ncp_inode_info * --ncp_find_dir_inode(struct inode *dir, const char *name) -+ ncp_find_dir_inode(struct inode *dir, const char *name) - { - struct ncp_server *server = NCP_SERVER(dir); - struct nw_info_struct *dir_info = NCP_ISTRUCT(dir); -- struct ncp_inode_info *result = &(server->root); -+ struct ncp_inode_info *result = &(server->root); - -- if (name == NULL) -- { -- return NULL; -+ if (name == NULL) { -+ return NULL; - } -- -- do -- { -- if ( (result->dir->finfo.i.dirEntNum == dir_info->dirEntNum) -- && (result->dir->finfo.i.volNumber == dir_info->volNumber) -+ do { -+ if ((result->dir->finfo.i.dirEntNum == dir_info->dirEntNum) -+ && (result->dir->finfo.i.volNumber == dir_info->volNumber) - && (strcmp(result->finfo.i.entryName, name) == 0) -- /* The root dir is never looked up using this -- * routine. Without the following test a root -- * directory 'sys' in a volume named 'sys' could -- * never be looked up, because -- * server->root->dir==server->root. */ -- && (result != &(server->root))) -- { -- return result; -+ /* The root dir is never looked up using this -+ * routine. Without the following test a root -+ * directory 'sys' in a volume named 'sys' could -+ * never be looked up, because -+ * server->root->dir==server->root. */ -+ && (result != &(server->root))) { -+ return result; - } -- result = result->next; -+ result = result->next; - -- } -+ } - while (result != &(server->root)); - -- return NULL; -+ return NULL; - } - --static int --ncp_lookup(struct inode *dir, const char *__name, int len, -- struct inode **result) -+static int ncp_lookup(struct inode *dir, const char *__name, int len, -+ struct inode **result) - { - struct nw_file_info finfo; - struct ncp_server *server; - struct ncp_inode_info *result_info; - int found_in_cache; - int down_case = 0; -- char name[len+1]; -+ char name[len + 1]; - - *result = NULL; - -- if (!dir || !S_ISDIR(dir->i_mode)) -- { -+ if (!dir || !S_ISDIR(dir->i_mode)) { - printk("ncp_lookup: inode is NULL or not a directory.\n"); - iput(dir); - return -ENOENT; - } -- - server = NCP_SERVER(dir); - -- if (!ncp_conn_valid(server)) -- { -+ if (!ncp_conn_valid(server)) { - iput(dir); - return -EIO; - } -- - DPRINTK("ncp_lookup: %s, len %d\n", __name, len); - - /* Fast cheat for . */ -- if (len == 0 || (len == 1 && __name[0] == '.')) -- { -+ if (len == 0 || (len == 1 && __name[0] == '.')) { - *result = dir; - return 0; - } -- - /* ..and for .. */ -- if (len == 2 && __name[0] == '.' && __name[1] == '.') -- { -+ if (len == 2 && __name[0] == '.' && __name[1] == '.') { - struct ncp_inode_info *parent = NCP_INOP(dir)->dir; - -- if (parent->state == NCP_INODE_CACHED) -- { -+ if (parent->state == NCP_INODE_CACHED) { - parent->state = NCP_INODE_LOOKED_UP; - } -- - *result = iget(dir->i_sb, ncp_info_ino(server, parent)); - iput(dir); -- if (*result == 0) -- { -+ if (*result == 0) { - return -EACCES; -- } -- else -- { -+ } else { - return 0; - } - } -- - memcpy(name, __name, len); - name[len] = 0; - lock_super(dir->i_sb); - result_info = ncp_find_dir_inode(dir, name); - -- if (result_info != 0) -- { -- if (result_info->state == NCP_INODE_CACHED) -- { -- result_info->state = NCP_INODE_LOOKED_UP; -+ if (result_info != 0) { -+ if (result_info->state == NCP_INODE_CACHED) { -+ result_info->state = NCP_INODE_LOOKED_UP; - } -+ /* Here we convert the inode_info address into an -+ inode number */ - -- /* Here we convert the inode_info address into an -- inode number */ -- -- *result = iget(dir->i_sb, ncp_info_ino(server, result_info)); -+ *result = iget(dir->i_sb, ncp_info_ino(server, result_info)); - unlock_super(dir->i_sb); -- iput(dir); -- -- if (*result == NULL) -- { -- return -EACCES; -- } -+ iput(dir); - -+ if (*result == NULL) { -+ return -EACCES; -+ } - return 0; -- } -- -- /* If the file is in the dir cache, we do not have to ask the -- server. */ -+ } -+ /* If the file is in the dir cache, we do not have to ask the -+ server. */ - -- found_in_cache = 0; -+ found_in_cache = 0; - ncp_lock_dircache(); - -- if ((dir->i_dev == c_dev) && (dir->i_ino == c_ino)) -- { -- int first = c_last_returned_index; -- int i; -- -- i = first; -- do -- { -- DDPRINTK("ncp_lookup: trying index: %d, name: %s\n", -+ if ((dir->i_dev == c_dev) && (dir->i_ino == c_ino)) { -+ int first = c_last_returned_index; -+ int i; -+ -+ i = first; -+ do { -+ DDPRINTK("ncp_lookup: trying index: %d, name: %s\n", - i, c_entry[i].i.entryName); - -- if (strcmp(c_entry[i].i.entryName, name) == 0) -- { -- DPRINTK("ncp_lookup: found in cache!\n"); -+ if (strcmp(c_entry[i].i.entryName, name) == 0) { -+ DPRINTK("ncp_lookup: found in cache!\n"); - finfo.i = c_entry[i].i; - found_in_cache = 1; - break; -- } -- i = (i + 1) % c_size; -- } -+ } -+ i = (i + 1) % c_size; -+ } - while (i != first); -- } -+ } - ncp_unlock_dircache(); - -- if (found_in_cache == 0) -- { -+ if (found_in_cache == 0) { - int res; - - DDPRINTK("ncp_lookup: do_lookup on %s/%s\n", - NCP_ISTRUCT(dir)->entryName, name); - -- if (ncp_is_server_root(dir)) -- { -+ if (ncp_is_server_root(dir)) { - str_upper(name); - down_case = 1; - res = ncp_lookup_volume(server, name, &(finfo.i)); -- } -- else -- { -- if (!ncp_preserve_case(dir)) -- { -+ } else { -+ if (!ncp_preserve_case(dir)) { - str_upper(name); - down_case = 1; - } -@@ -913,313 +776,246 @@ - NCP_ISTRUCT(dir)->dirEntNum, - name, &(finfo.i)); - } -- if (res != 0) -- { -+ if (res != 0) { - unlock_super(dir->i_sb); -- iput(dir); -- return -ENOENT; -- } -- } -- -+ iput(dir); -+ return -ENOENT; -+ } -+ } - finfo.opened = 0; - -- if (down_case != 0) -- { -+ if (down_case != 0) { - str_lower(finfo.i.entryName); - } -- -- if (!(*result = ncp_iget(dir, &finfo))) -- { -+ if (!(*result = ncp_iget(dir, &finfo))) { - unlock_super(dir->i_sb); - iput(dir); - return -EACCES; - } -- - unlock_super(dir->i_sb); - iput(dir); - return 0; - } - --static int --ncp_create(struct inode *dir, const char *name, int len, int mode, -- struct inode **result) -+static int ncp_create(struct inode *dir, const char *name, int len, int mode, -+ struct inode **result) - { - struct nw_file_info finfo; -- __u8 _name[len+1]; -+ __u8 _name[len + 1]; - - *result = NULL; - -- if (!dir || !S_ISDIR(dir->i_mode)) -- { -+ if (!dir || !S_ISDIR(dir->i_mode)) { - printk("ncp_create: inode is NULL or not a directory\n"); - iput(dir); - return -ENOENT; - } -- if (!ncp_conn_valid(NCP_SERVER(dir))) -- { -+ if (!ncp_conn_valid(NCP_SERVER(dir))) { - iput(dir); - return -EIO; - } -- - strncpy(_name, name, len); - _name[len] = '\0'; - -- if (!ncp_preserve_case(dir)) -- { -+ if (!ncp_preserve_case(dir)) { - str_upper(_name); - } -- - lock_super(dir->i_sb); - if (ncp_open_create_file_or_subdir(NCP_SERVER(dir), - NCP_ISTRUCT(dir), _name, -- OC_MODE_CREATE|OC_MODE_OPEN| -+ OC_MODE_CREATE | OC_MODE_OPEN | - OC_MODE_REPLACE, -- 0, AR_READ|AR_WRITE, -- &finfo) != 0) -- { -+ 0, AR_READ | AR_WRITE, -+ &finfo) != 0) { - unlock_super(dir->i_sb); - iput(dir); - return -EACCES; - } -- - ncp_invalid_dir_cache(dir); - -- if (!ncp_preserve_case(dir)) -- { -+ if (!ncp_preserve_case(dir)) { - str_lower(finfo.i.entryName); - } -- - finfo.access = O_RDWR; - -- if (!(*result = ncp_iget(dir, &finfo)) < 0) -- { -+ if (!(*result = ncp_iget(dir, &finfo)) < 0) { - ncp_close_file(NCP_SERVER(dir), finfo.file_handle); - unlock_super(dir->i_sb); - iput(dir); - return -EINVAL; - } -- - unlock_super(dir->i_sb); - iput(dir); -- return 0; -+ return 0; - } - --static int --ncp_mkdir(struct inode *dir, const char *name, int len, int mode) -+static int ncp_mkdir(struct inode *dir, const char *name, int len, int mode) - { - int error; - struct nw_file_info new_dir; -- __u8 _name[len+1]; -+ __u8 _name[len + 1]; - -- if ( (name[0] == '.') -- && ( (len == 1) -- || ( (len == 2) -- && (name[1] == '.')))) -- { -+ if ((name[0] == '.') -+ && ((len == 1) -+ || ((len == 2) -+ && (name[1] == '.')))) { - iput(dir); - return -EEXIST; - } -- - strncpy(_name, name, len); - _name[len] = '\0'; - -- if (!ncp_preserve_case(dir)) -- { -+ if (!ncp_preserve_case(dir)) { - str_upper(_name); - } -- -- if (!dir || !S_ISDIR(dir->i_mode)) -- { -+ if (!dir || !S_ISDIR(dir->i_mode)) { - printk("ncp_mkdir: inode is NULL or not a directory\n"); - iput(dir); - return -ENOENT; - } -- if (!ncp_conn_valid(NCP_SERVER(dir))) -- { -+ if (!ncp_conn_valid(NCP_SERVER(dir))) { - iput(dir); - return -EIO; - } -- - if (ncp_open_create_file_or_subdir(NCP_SERVER(dir), - NCP_ISTRUCT(dir), _name, - OC_MODE_CREATE, aDIR, 0xffff, -- &new_dir) != 0) -- { -+ &new_dir) != 0) { - error = -EACCES; -- } -- else -- { -+ } else { - error = 0; -- ncp_invalid_dir_cache(dir); -- } -+ ncp_invalid_dir_cache(dir); -+ } - - iput(dir); - return error; - } - --static int --ncp_rmdir(struct inode *dir, const char *name, int len) -+static int ncp_rmdir(struct inode *dir, const char *name, int len) - { - int error; -- __u8 _name[len+1]; -+ __u8 _name[len + 1]; - -- if (!dir || !S_ISDIR(dir->i_mode)) -- { -+ if (!dir || !S_ISDIR(dir->i_mode)) { - printk("ncp_rmdir: inode is NULL or not a directory\n"); - iput(dir); - return -ENOENT; - } -- if (!ncp_conn_valid(NCP_SERVER(dir))) -- { -+ if (!ncp_conn_valid(NCP_SERVER(dir))) { - iput(dir); - return -EIO; - } -- if (ncp_find_dir_inode(dir, name) != NULL) -- { -+ if (ncp_find_dir_inode(dir, name) != NULL) { - iput(dir); -- error = -EBUSY; -- } -- else -- { -+ error = -EBUSY; -+ } else { - - strncpy(_name, name, len); - _name[len] = '\0'; - -- if (!ncp_preserve_case(dir)) -- { -+ if (!ncp_preserve_case(dir)) { - str_upper(_name); - } -- -- if ((error = ncp_del_file_or_subdir(NCP_SERVER(dir), -+ if ((error = ncp_del_file_or_subdir(NCP_SERVER(dir), - NCP_ISTRUCT(dir), -- _name)) == 0) -- { -- ncp_invalid_dir_cache(dir); -- } -- else -- { -+ _name)) == 0) { -+ ncp_invalid_dir_cache(dir); -+ } else { - error = -EACCES; - } -- } -+ } - iput(dir); - return error; - } - --static int --ncp_unlink(struct inode *dir, const char *name, int len) -+static int ncp_unlink(struct inode *dir, const char *name, int len) - { - int error; -- __u8 _name[len+1]; -+ __u8 _name[len + 1]; - -- if (!dir || !S_ISDIR(dir->i_mode)) -- { -+ if (!dir || !S_ISDIR(dir->i_mode)) { - printk("ncp_unlink: inode is NULL or not a directory\n"); - iput(dir); - return -ENOENT; - } -- if (!ncp_conn_valid(NCP_SERVER(dir))) -- { -+ if (!ncp_conn_valid(NCP_SERVER(dir))) { - iput(dir); - return -EIO; - } -- if (ncp_find_dir_inode(dir, name) != NULL) -- { -+ if (ncp_find_dir_inode(dir, name) != NULL) { - iput(dir); -- error = -EBUSY; -- } -- else -- { -+ error = -EBUSY; -+ } else { - strncpy(_name, name, len); - _name[len] = '\0'; - -- if (!ncp_preserve_case(dir)) -- { -+ if (!ncp_preserve_case(dir)) { - str_upper(_name); - } -- -- if ((error = ncp_del_file_or_subdir(NCP_SERVER(dir), -+ if ((error = ncp_del_file_or_subdir(NCP_SERVER(dir), - NCP_ISTRUCT(dir), -- _name)) == 0) -- { -- ncp_invalid_dir_cache(dir); -- } -- else -- { -+ _name)) == 0) { -+ ncp_invalid_dir_cache(dir); -+ } else { - error = -EACCES; - } -- } -+ } - iput(dir); - return error; - } - --static int --ncp_rename(struct inode *old_dir, const char *old_name, int old_len, -- struct inode *new_dir, const char *new_name, int new_len, -- int must_be_dir) -+static int ncp_rename(struct inode *old_dir, const char *old_name, int old_len, -+ struct inode *new_dir, const char *new_name, int new_len, -+ int must_be_dir) - { - int res; -- char _old_name[old_len+1]; -- char _new_name[new_len+1]; -+ char _old_name[old_len + 1]; -+ char _new_name[new_len + 1]; - -- if (!old_dir || !S_ISDIR(old_dir->i_mode)) -- { -+ if (!old_dir || !S_ISDIR(old_dir->i_mode)) { - printk("ncp_rename: old inode is NULL or not a directory\n"); -- res = -ENOENT; -- goto finished; -+ res = -ENOENT; -+ goto finished; - } -- -- if (!ncp_conn_valid(NCP_SERVER(old_dir))) -- { -+ if (!ncp_conn_valid(NCP_SERVER(old_dir))) { - res = -EIO; - goto finished; - } -- -- if (!new_dir || !S_ISDIR(new_dir->i_mode)) -- { -+ if (!new_dir || !S_ISDIR(new_dir->i_mode)) { - printk("ncp_rename: new inode is NULL or not a directory\n"); -- res = -ENOENT; -- goto finished; -+ res = -ENOENT; -+ goto finished; -+ } -+ if ((ncp_find_dir_inode(old_dir, old_name) != NULL) -+ || (ncp_find_dir_inode(new_dir, new_name) != NULL)) { -+ res = -EBUSY; -+ goto finished; - } -- -- if ( (ncp_find_dir_inode(old_dir, old_name) != NULL) -- || (ncp_find_dir_inode(new_dir, new_name) != NULL)) -- { -- res = -EBUSY; -- goto finished; -- } -- - strncpy(_old_name, old_name, old_len); - _old_name[old_len] = '\0'; - -- if (!ncp_preserve_case(old_dir)) -- { -+ if (!ncp_preserve_case(old_dir)) { - str_upper(_old_name); - } -- - strncpy(_new_name, new_name, new_len); - _new_name[new_len] = '\0'; - -- if (!ncp_preserve_case(new_dir)) -- { -+ if (!ncp_preserve_case(new_dir)) { - str_upper(_new_name); - } -- - res = ncp_ren_or_mov_file_or_subdir(NCP_SERVER(old_dir), -- NCP_ISTRUCT(old_dir), _old_name, -- NCP_ISTRUCT(new_dir), _new_name); -+ NCP_ISTRUCT(old_dir), _old_name, -+ NCP_ISTRUCT(new_dir), _new_name); - -- if (res == 0) -- { -- ncp_invalid_dir_cache(old_dir); -- ncp_invalid_dir_cache(new_dir); -- } -- else -- { -+ if (res == 0) { -+ ncp_invalid_dir_cache(old_dir); -+ ncp_invalid_dir_cache(new_dir); -+ } else { - res = -EACCES; - } -- -- finished: -- iput(old_dir); -+ -+ finished: -+ iput(old_dir); - iput(new_dir); - return res; - } -@@ -1228,64 +1024,62 @@ - - /* Linear day numbers of the respective 1sts in non-leap years. */ - --static int day_n[] = { 0,31,59,90,120,151,181,212,243,273,304,334,0,0,0,0 }; -+static int day_n[] = -+{0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 0, 0, 0, 0}; - /* JanFebMarApr May Jun Jul Aug Sep Oct Nov Dec */ - - - extern struct timezone sys_tz; - --static int --utc2local(int time) -+static int utc2local(int time) - { -- return time - sys_tz.tz_minuteswest*60 + -+ return time - sys_tz.tz_minuteswest * 60 + - (sys_tz.tz_dsttime ? 3600 : 0); - } - --static int --local2utc(int time) -+static int local2utc(int time) - { -- return time + sys_tz.tz_minuteswest*60 - -+ return time + sys_tz.tz_minuteswest * 60 - - (sys_tz.tz_dsttime ? 3600 : 0); - } - - /* Convert a MS-DOS time/date pair to a UNIX date (seconds since 1 1 70). */ - --int --ncp_date_dos2unix(unsigned short time,unsigned short date) -+int ncp_date_dos2unix(unsigned short time, unsigned short date) - { -- int month,year,secs; -+ int month, year, secs; - -- month = ((date >> 5) & 15)-1; -+ month = ((date >> 5) & 15) - 1; - year = date >> 9; -- secs = (time & 31)*2+60*((time >> 5) & 63)+(time >> 11)*3600+86400* -- ((date & 31)-1+day_n[month]+(year/4)+year*365-((year & 3) == 0 && -- month < 2 ? 1 : 0)+3653); -- /* days since 1.1.70 plus 80's leap day */ -+ secs = (time & 31) * 2 + 60 * ((time >> 5) & 63) + (time >> 11) * 3600 + 86400 * -+ ((date & 31) - 1 + day_n[month] + (year / 4) + year * 365 - ((year & 3) == 0 && -+ month < 2 ? 1 : 0) + 3653); -+ /* days since 1.1.70 plus 80's leap day */ - return local2utc(secs); - } - - - /* Convert linear UNIX date to a MS-DOS time/date pair. */ --void --ncp_date_unix2dos(int unix_date,unsigned short *time, unsigned short *date) -+void ncp_date_unix2dos(int unix_date, unsigned short *time, unsigned short *date) - { -- int day,year,nl_day,month; -+ int day, year, nl_day, month; - - unix_date = utc2local(unix_date); -- *time = (unix_date % 60)/2+(((unix_date/60) % 60) << 5)+ -- (((unix_date/3600) % 24) << 11); -- day = unix_date/86400-3652; -- year = day/365; -- if ((year+3)/4+365*year > day) year--; -- day -= (year+3)/4+365*year; -+ *time = (unix_date % 60) / 2 + (((unix_date / 60) % 60) << 5) + -+ (((unix_date / 3600) % 24) << 11); -+ day = unix_date / 86400 - 3652; -+ year = day / 365; -+ if ((year + 3) / 4 + 365 * year > day) -+ year--; -+ day -= (year + 3) / 4 + 365 * year; - if (day == 59 && !(year & 3)) { - nl_day = day; - month = 2; -- } -- else { -- nl_day = (year & 3) || day <= 59 ? day : day-1; -+ } else { -+ nl_day = (year & 3) || day <= 59 ? day : day - 1; - for (month = 0; month < 12; month++) -- if (day_n[month] > nl_day) break; -+ if (day_n[month] > nl_day) -+ break; - } -- *date = nl_day-day_n[month-1]+1+(month << 5)+(year << 9); -+ *date = nl_day - day_n[month - 1] + 1 + (month << 5) + (year << 9); - } -diff -urN 2.1.29/fs/ncpfs/file.c 2.1.29-patched/fs/ncpfs/file.c ---- 2.1.29/fs/ncpfs/file.c Sun Jan 26 11:07:44 1997 -+++ 2.1.29-patched/fs/ncpfs/file.c Sat Mar 22 19:13:11 1997 -@@ -21,215 +21,172 @@ - - static inline int min(int a, int b) - { -- return aopened = %d\n", finfo->opened); -+ DPRINTK("ncp_make_open: dirent->opened = %d\n", finfo->opened); - - lock_super(i->i_sb); -- if (finfo->opened == 0) -- { -+ if (finfo->opened == 0) { - finfo->access = -1; -- /* tries max. rights */ -+ /* 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) == 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) -- { -+ } 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; -+ 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; -+ return -EACCES; - } - --static long --ncp_file_read(struct inode *inode, struct file *file, char *buf, unsigned long count) -+static long ncp_file_read(struct inode *inode, struct file *file, char *buf, unsigned long count) - { - int bufsize, already_read; - off_t pos; -- int errno; -+ int errno; - -- DPRINTK("ncp_file_read: enter %s\n", NCP_ISTRUCT(inode)->entryName); -- -- if (inode == NULL) -- { -+ 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))) -- { -+ if (!ncp_conn_valid(NCP_SERVER(inode))) { - return -EIO; - } -- -- if (!S_ISREG(inode->i_mode)) -- { -+ if (!S_ISREG(inode->i_mode)) { - DPRINTK("ncp_file_read: read from non-file, mode %07o\n", -- inode->i_mode); -+ inode->i_mode); - return -EINVAL; - } -- - pos = file->f_pos; - -- if (pos + count > inode->i_size) -- { -+ if (pos + count > inode->i_size) { - count = inode->i_size - pos; - } -- -- if (count <= 0) -- { -+ if (count <= 0) { - return 0; - } -- -- if ((errno = ncp_make_open(inode, O_RDONLY)) != 0) -- { -- return errno; -+ if ((errno = ncp_make_open(inode, O_RDONLY)) != 0) { -+ return errno; - } -- - bufsize = NCP_SERVER(inode)->buffer_size; - -- already_read = 0; -+ already_read = 0; - - /* First read in as much as possible for each bufsize. */ -- while (already_read < count) -- { -+ 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, 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; -+ already_read += read_this_time; - -- if (read_this_time < to_read) -- { -- break; -+ if (read_this_time < to_read) { -+ break; - } - } - -- file->f_pos = pos; -+ file->f_pos = pos; - -- if (!IS_RDONLY(inode)) -- { -+ if (!IS_RDONLY(inode)) { - inode->i_atime = CURRENT_TIME; - } -- - inode->i_dirt = 1; - -- DPRINTK("ncp_file_read: exit %s\n", NCP_ISTRUCT(inode)->entryName); -+ DPRINTK("ncp_file_read: exit %s\n", NCP_ISTRUCT(inode)->entryName); - -- return already_read; -+ return already_read; - } - --static long --ncp_file_write(struct inode *inode, struct file *file, const char *buf, -- unsigned long count) -+static long ncp_file_write(struct inode *inode, struct file *file, const char *buf, -+ unsigned long count) - { - int bufsize, already_written; -- off_t pos; -- int errno; -- -- if (inode == NULL) -- { -+ off_t pos; -+ int errno; -+ -+ if (inode == NULL) { - DPRINTK("ncp_file_write: inode = NULL\n"); - return -EINVAL; - } -- if (!ncp_conn_valid(NCP_SERVER(inode))) -- { -+ if (!ncp_conn_valid(NCP_SERVER(inode))) { - return -EIO; - } -- -- if (!S_ISREG(inode->i_mode)) -- { -+ if (!S_ISREG(inode->i_mode)) { - DPRINTK("ncp_file_write: write to non-file, mode %07o\n", -- inode->i_mode); -+ inode->i_mode); - return -EINVAL; - } -+ DPRINTK("ncp_file_write: enter %s\n", NCP_ISTRUCT(inode)->entryName); - -- DPRINTK("ncp_file_write: enter %s\n", NCP_ISTRUCT(inode)->entryName); -- -- if (count <= 0) -- { -+ if (count <= 0) { - return 0; - } -- -- if ((errno = ncp_make_open(inode, O_RDWR)) != 0) -- { -- return errno; -+ if ((errno = ncp_make_open(inode, O_RDWR)) != 0) { -+ return errno; - } -- - pos = file->f_pos; - -- if (file->f_flags & O_APPEND) -- { -+ if (file->f_flags & O_APPEND) { - pos = inode->i_size; - } -- - bufsize = NCP_SERVER(inode)->buffer_size; - -- already_written = 0; -+ already_written = 0; - -- while (already_written < count) -- { -+ 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) -- { -+ 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) -- { -+ if (written_this_time < to_write) { - break; - } - } -@@ -239,18 +196,17 @@ - - file->f_pos = pos; - -- if (pos > inode->i_size) -- { -- inode->i_size = 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); -+ } -+ DPRINTK("ncp_file_write: exit %s\n", NCP_ISTRUCT(inode)->entryName); - - return already_written; - } - --static struct file_operations ncp_file_operations = { -+static struct file_operations ncp_file_operations = -+{ - NULL, /* lseek - default */ - ncp_file_read, /* read */ - ncp_file_write, /* write */ -@@ -258,12 +214,13 @@ - NULL, /* poll - default */ - ncp_ioctl, /* ioctl */ - ncp_mmap, /* mmap */ -- NULL, /* open */ -- NULL, /* release */ -+ NULL, /* open */ -+ NULL, /* release */ - ncp_fsync, /* fsync */ - }; - --struct inode_operations ncp_file_inode_operations = { -+struct inode_operations ncp_file_inode_operations = -+{ - &ncp_file_operations, /* default file operations */ - NULL, /* create */ - NULL, /* lookup */ -diff -urN 2.1.29/fs/ncpfs/inode.c 2.1.29-patched/fs/ncpfs/inode.c ---- 2.1.29/fs/ncpfs/inode.c Sun Jan 19 14:47:26 1997 -+++ 2.1.29-patched/fs/ncpfs/inode.c Sun Mar 23 11:38:08 1997 -@@ -36,8 +36,9 @@ - static void ncp_statfs(struct super_block *sb, struct statfs *buf, int bufsiz); - static int ncp_notify_change(struct inode *inode, struct iattr *attr); - --static struct super_operations ncp_sops = { -- ncp_read_inode, /* read inode */ -+static struct super_operations ncp_sops = -+{ -+ ncp_read_inode, /* read inode */ - ncp_notify_change, /* notify change */ - NULL, /* write inode */ - ncp_put_inode, /* put inode */ -@@ -51,202 +52,150 @@ - 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) -+static void ncp_read_inode(struct inode *inode) - { -- /* Our task should be extremely simple here. We only have to -- look up the information 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. */ -+ /* Our task should be extremely simple here. We only have to -+ look up the information 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); -+ struct ncp_inode_info *inode_info = ncp_find_inode(inode); - -- if (inode_info == NULL) -- { -+ 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; - -- inode_info->state = NCP_INODE_VALID; -- -- NCP_INOP(inode) = inode_info; -+ NCP_INOP(inode) = inode_info; - inode_info->inode = inode; - -- if (NCP_ISTRUCT(inode)->attributes & aDIR) -- { -- inode->i_mode = NCP_SERVER(inode)->m.dir_mode; -+ 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; -+ } else { -+ inode->i_mode = NCP_SERVER(inode)->m.file_mode; - inode->i_size = le32_to_cpu(NCP_ISTRUCT(inode)->dataStreamSize); - } - -- DDPRINTK("ncp_read_inode: inode->i_mode = %u\n", inode->i_mode); -+ 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_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(le16_to_cpu(NCP_ISTRUCT(inode)->modifyTime), -- le16_to_cpu(NCP_ISTRUCT(inode)->modifyDate)); -+ le16_to_cpu(NCP_ISTRUCT(inode)->modifyDate)); - inode->i_ctime = ncp_date_dos2unix(le16_to_cpu(NCP_ISTRUCT(inode)->creationTime), -- le16_to_cpu(NCP_ISTRUCT(inode)->creationDate)); -+ le16_to_cpu(NCP_ISTRUCT(inode)->creationDate)); - inode->i_atime = ncp_date_dos2unix(0, -- le16_to_cpu(NCP_ISTRUCT(inode)->lastAccessDate)); -+ le16_to_cpu(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; -+ 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) -+static void ncp_put_inode(struct inode *inode) - { -- struct nw_file_info *finfo = NCP_FINFO(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"); -- } -- } -- -+ 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); -+ finfo->i.entryName); - -- ncp_free_inode_info(NCP_INOP(inode)); -+ ncp_free_inode_info(NCP_INOP(inode)); - -- if (S_ISDIR(inode->i_mode)) -- { -- DDPRINTK("ncp_put_inode: put directory %ld\n", -+ if (S_ISDIR(inode->i_mode)) { -+ DDPRINTK("ncp_put_inode: put directory %ld\n", - inode->i_ino); -- ncp_invalid_dir_cache(inode); -- } -- -+ 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) -+ 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 ncp_server *server; - struct file *ncp_filp; -- struct file *wdog_filp; -- struct file *msg_filp; - kdev_t dev = sb->s_dev; - int error; - -- if (data == NULL) -- { -+ if (data == NULL) { - printk("ncp_read_super: missing data argument\n"); - sb->s_dev = 0; - return NULL; - } -- -- if (data->version != NCP_MOUNT_VERSION) -- { -+ if (data->version != NCP_MOUNT_VERSION) { - printk("ncp warning: mount version %s than kernel\n", - (data->version < NCP_MOUNT_VERSION) ? -- "older" : "newer"); -+ "older" : "newer"); - sb->s_dev = 0; - return NULL; - } -- -- if ( (data->ncp_fd >= NR_OPEN) -+ if ((data->ncp_fd >= NR_OPEN) - || ((ncp_filp = current->files->fd[data->ncp_fd]) == NULL) -- || (!S_ISSOCK(ncp_filp->f_inode->i_mode))) -- { -+ || (!S_ISSOCK(ncp_filp->f_inode->i_mode))) { - printk("ncp_read_super: invalid ncp 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 ( (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; -+ if (server == NULL) { -+ printk("ncp_read_super: could not alloc ncp_server\n"); - return NULL; - } -- -- if ( (data->message_fd >= NR_OPEN) -- || ((msg_filp = current->files->fd[data->message_fd]) == NULL) -- || (!S_ISSOCK(msg_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; -- msg_filp->f_count += 1; - - lock_super(sb); - -- NCP_SBP(sb) = server; -+ NCP_SBP(sb) = server; - -- sb->s_blocksize = 1024; /* Eh... Is this correct? */ -+ 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->msg_filp = msg_filp; -- server->lock = 0; -- server->wait = NULL; -- server->packet = NULL; -+ server->ncp_filp = ncp_filp; -+ server->lock = 0; -+ server->wait = NULL; -+ server->packet = NULL; - server->buffer_size = 0; - server->conn_status = 0; - -- server->m = *data; -+ server->m = *data; - /* Althought anything producing this is buggy, it happens - now because of PATH_MAX changes.. */ - if (server->m.time_out < 10) { -@@ -254,166 +203,98 @@ - printk("You need to recompile your ncpfs utils..\n"); - } - 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; -- -- /* protect against invalid mount points */ -- server->m.mount_point[sizeof(server->m.mount_point)-1] = '\0'; -+ (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); -+ server->packet = ncp_kmalloc(NCP_PACKET_SIZE, GFP_KERNEL); - -- if (server->packet == NULL) -- { -+ if (server->packet == NULL) { - printk("ncpfs: could not alloc packet\n"); - error = -ENOMEM; - unlock_super(sb); - goto fail; - } -- -- /* -- * 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; -- } -- -- if (ncp_catch_message(server) != 0) -- { -- printk("ncp_read_super: Could not catch messages\n"); -- ncp_dont_catch_watchdog(server); -- 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) -- { -+ 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; -+ "(error = %d).\n", -error); -+ ncp_kfree_s(server->packet, server->packet_size); -+ goto fail; - } -- -- DPRINTK("ncp_read_super: NCP_SBP(sb) = %x\n", (int)NCP_SBP(sb)); -+ DPRINTK("ncp_read_super: NCP_SBP(sb) = %x\n", (int) NCP_SBP(sb)); - - ncp_init_root(server); - -- if (!(sb->s_mounted = iget(sb, ncp_info_ino(server, &(server->root))))) -- { -+ 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; -+ goto disconnect; - } -- - if (ncp_negotiate_buffersize(server, NCP_DEFAULT_BUFSIZE, -- &(server->buffer_size)) != 0) -- { -+ &(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; -+ MOD_INC_USE_COUNT; - return sb; - -- disconnect: -+ 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: -+ fail: - ncp_filp->f_count -= 1; -- wdog_filp->f_count -= 1; -- msg_filp->f_count -= 1; -- ncp_kfree_s(NCP_SBP(sb), sizeof(struct ncp_server)); -- return NULL; -+ ncp_kfree_s(NCP_SBP(sb), sizeof(struct ncp_server)); -+ return NULL; - } - --static void --ncp_put_super(struct super_block *sb) -+static void ncp_put_super(struct super_block *sb) - { -- struct ncp_server *server = NCP_SBP(sb); -+ struct ncp_server *server = NCP_SBP(sb); - - lock_super(sb); - - ncp_lock_server(server); -- ncp_disconnect(server); -+ ncp_disconnect(server); - ncp_unlock_server(server); - - close_fp(server->ncp_filp); -+ kill_proc(server->m.wdog_pid, SIGTERM, 0); - -- ncp_dont_catch_watchdog(server); -- close_fp(server->wdog_filp); -- close_fp(server->msg_filp); -- -- ncp_free_all_inodes(server); -+ ncp_free_all_inodes(server); - -- ncp_kfree_s(server->packet, server->packet_size); -+ ncp_kfree_s(server->packet, server->packet_size); - - sb->s_dev = 0; -- ncp_kfree_s(NCP_SBP(sb), sizeof(struct ncp_server)); -+ ncp_kfree_s(NCP_SBP(sb), sizeof(struct ncp_server)); - NCP_SBP(sb) = NULL; - - unlock_super(sb); - -- MOD_DEC_USE_COUNT; -+ MOD_DEC_USE_COUNT; - } - --/* This routine is called from an interrupt in ncp_msg_data_ready. So -- * we have to be careful NOT to sleep here! */ --void --ncp_trigger_message(struct ncp_server *server) --{ --#ifdef CONFIG_KERNELD -- char command[ sizeof(server->m.mount_point) -- + sizeof(NCP_MSG_COMMAND) + 2]; --#endif -- -- if (server == NULL) -- { -- printk("ncp_trigger_message: invalid server!\n"); -- return; -- } -- -- DPRINTK("ncp_trigger_message: on %s\n", -- server->m.mount_point); -- --#ifdef CONFIG_KERNELD -- strcpy(command, NCP_MSG_COMMAND); -- strcat(command, " "); -- strcat(command, server->m.mount_point); -- DPRINTK("ksystem: %s\n", command); -- ksystem(command, KERNELD_NOWAIT); --#endif --} -- --static void --ncp_statfs(struct super_block *sb, struct statfs *buf, int bufsiz) -+static void ncp_statfs(struct super_block *sb, struct statfs *buf, int bufsiz) - { - 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. */ -+ 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; -@@ -426,18 +307,15 @@ - copy_to_user(buf, &tmp, bufsiz); - } - --static int --ncp_notify_change(struct inode *inode, struct iattr *attr) -+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))) -- { -+ if (!ncp_conn_valid(NCP_SERVER(inode))) { - return -EIO; - } -- - if ((result = inode_change_ok(inode, attr)) < 0) - return result; - -@@ -447,7 +325,7 @@ - - if (((attr->ia_valid & ATTR_GID) && - (attr->ia_uid != NCP_SERVER(inode)->m.gid))) -- return -EPERM; -+ return -EPERM; - - if (((attr->ia_valid & ATTR_MODE) && - (attr->ia_mode & -@@ -457,67 +335,54 @@ - info_mask = 0; - memset(&info, 0, sizeof(info)); - -- if ((attr->ia_valid & ATTR_CTIME) != 0) -- { -- info_mask |= (DM_CREATE_TIME|DM_CREATE_DATE); -+ 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)); -+ &(info.creationTime), &(info.creationDate)); - info.creationTime = le16_to_cpu(info.creationTime); - info.creationDate = le16_to_cpu(info.creationDate); - } -- -- if ((attr->ia_valid & ATTR_MTIME) != 0) -- { -- info_mask |= (DM_MODIFY_TIME|DM_MODIFY_DATE); -+ 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)); - info.modifyTime = le16_to_cpu(info.modifyTime); - info.modifyDate = le16_to_cpu(info.modifyDate); - } -- -- if ((attr->ia_valid & ATTR_ATIME) != 0) -- { -+ if ((attr->ia_valid & ATTR_ATIME) != 0) { - __u16 dummy; - info_mask |= (DM_LAST_ACCESS_DATE); - ncp_date_unix2dos(attr->ia_ctime, - &(dummy), &(info.lastAccessDate)); - info.lastAccessDate = le16_to_cpu(info.lastAccessDate); - } -- -- if (info_mask != 0) -- { -+ if (info_mask != 0) { - if ((result = - ncp_modify_file_or_subdir_dos_info(NCP_SERVER(inode), -- NCP_ISTRUCT(inode), -+ NCP_ISTRUCT(inode), - info_mask, -- &info)) != 0) -- { -+ &info)) != 0) { - result = -EACCES; - -- if (info_mask == (DM_CREATE_TIME|DM_CREATE_DATE)) -- { -+ 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. */ -+ 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) -- { -+ 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) -- { -+ 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); - -@@ -529,8 +394,7 @@ - - result = 0; - } -- -- ncp_invalid_dir_cache(NCP_INOP(inode)->dir->inode); -+ ncp_invalid_dir_cache(NCP_INOP(inode)->dir->inode); - - return result; - } -@@ -540,40 +404,40 @@ - int ncp_current_malloced; - #endif - --static struct file_system_type ncp_fs_type = { -- ncp_read_super, "ncpfs", 0, NULL -- }; -+static struct file_system_type ncp_fs_type = -+{ -+ ncp_read_super, "ncpfs", 0, NULL -+}; - - int init_ncp_fs(void) - { -- return register_filesystem(&ncp_fs_type); -+ return register_filesystem(&ncp_fs_type); - } - - #ifdef MODULE - EXPORT_NO_SYMBOLS; - --int init_module( void) -+int init_module(void) - { -- DPRINTK("ncpfs: init_module called\n"); -+ DPRINTK("ncpfs: init_module called\n"); - - #ifdef DEBUG_NCP_MALLOC -- ncp_malloced = 0; -- ncp_current_malloced = 0; -+ ncp_malloced = 0; -+ ncp_current_malloced = 0; - #endif -- ncp_init_dir_cache(); -+ ncp_init_dir_cache(); - - return init_ncp_fs(); - } - --void --cleanup_module(void) -+void cleanup_module(void) - { -- DPRINTK("ncpfs: cleanup_module called\n"); -- ncp_free_dir_cache(); -- unregister_filesystem(&ncp_fs_type); -+ 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); -+ printk("ncp_malloced: %d\n", ncp_malloced); -+ printk("ncp_current_malloced: %d\n", ncp_current_malloced); - #endif - } - -diff -urN 2.1.29/fs/ncpfs/ioctl.c 2.1.29-patched/fs/ncpfs/ioctl.c ---- 2.1.29/fs/ncpfs/ioctl.c Mon Oct 28 13:29:26 1996 -+++ 2.1.29-patched/fs/ncpfs/ioctl.c Sat Mar 22 19:13:11 1997 -@@ -14,70 +14,41 @@ - #include - #include - --int --ncp_ioctl (struct inode * inode, struct file * filp, -- unsigned int cmd, unsigned long arg) -+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. -- * 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) { -+ switch (cmd) { - case NCP_IOC_NCPREQUEST: - -- if ( (permission(inode, MAY_WRITE) != 0) -- && (current->uid != server->m.mounted_uid)) -- { -+ 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) -- { -+ if ((result = verify_area(VERIFY_READ, (char *) arg, -+ sizeof(request))) != 0) { - return result; - } -+ copy_from_user(&request, (struct ncp_ioctl_request *) arg, -+ sizeof(request)); - -- copy_from_user(&request, (struct ncp_ioctl_request *)arg, -- sizeof(request)); -- -- if ( (request.function > 255) -+ if ((request.function > 255) - || (request.size > -- NCP_PACKET_SIZE - sizeof(struct ncp_request_header))) -- { -+ NCP_PACKET_SIZE - sizeof(struct ncp_request_header))) { - return -EINVAL; - } -- -- if ((result = verify_area(VERIFY_WRITE, (char *)request.data, -- NCP_PACKET_SIZE)) != 0) -- { -+ 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 */ -+ here to be able to use ncp_request */ - - server->has_subfunction = 0; - server->current_size = request.size; -@@ -95,66 +66,55 @@ - - case NCP_IOC_CONN_LOGGED_IN: - -- if ( (permission(inode, MAY_WRITE) != 0) -- && (current->uid != server->m.mounted_uid)) -- { -+ 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)) -- { -+ 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) -- { -+ if ((result = verify_area(VERIFY_WRITE, (char *) arg, -+ sizeof(info))) != 0) { - return result; - } -+ copy_from_user(&info, (struct ncp_fs_info *) arg, -+ sizeof(info)); - -- copy_from_user(&info, (struct ncp_fs_info *)arg, -- sizeof(info)); -- -- if (info.version != NCP_GET_FS_INFO_VERSION) -- { -+ 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; -+ /* TODO: 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; -+ info.directory_id = NCP_ISTRUCT(inode)->DosDirNum; - -- copy_to_user((struct ncp_fs_info *)arg, &info, sizeof(info)); -- return 0; -+ copy_to_user((struct ncp_fs_info *) arg, &info, sizeof(info)); -+ return 0; - -- case NCP_IOC_GETMOUNTUID: -+ case NCP_IOC_GETMOUNTUID: - -- if ( (permission(inode, MAY_READ) != 0) -- && (current->uid != server->m.mounted_uid)) -- { -+ 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_user(server->m.mounted_uid, (uid_t *) arg); -- return 0; -+ if ((result = verify_area(VERIFY_WRITE, (uid_t *) arg, -+ sizeof(uid_t))) != 0) { -+ return result; -+ } -+ put_user(server->m.mounted_uid, (uid_t *) arg); -+ return 0; - - default: - return -EINVAL; - } -- -+ - return -EINVAL; - } -diff -urN 2.1.29/fs/ncpfs/mmap.c 2.1.29-patched/fs/ncpfs/mmap.c ---- 2.1.29/fs/ncpfs/mmap.c Mon Oct 28 13:29:26 1996 -+++ 2.1.29-patched/fs/ncpfs/mmap.c Sat Mar 22 19:13:11 1997 -@@ -23,17 +23,16 @@ - - static inline int min(int a, int b) - { -- return avm_inode; -+ struct inode *inode = area->vm_inode; - unsigned long page; - unsigned int clear; - unsigned long tmp; -@@ -48,37 +47,28 @@ - pos = address - area->vm_start + area->vm_offset; - - clear = 0; -- if (address + PAGE_SIZE > area->vm_end) -- { -+ if (address + PAGE_SIZE > area->vm_end) { - clear = address + PAGE_SIZE - area->vm_end; - } -- -- /* what we can read in one go */ -+ /* 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 -- { -+ 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) -- { -+ while (already_read < count) { - int read_this_time; - -- if ((pos % bufsize) != 0) -- { -+ if ((pos % bufsize) != 0) { - to_read = bufsize - (pos % bufsize); -- } -- else -- { -+ } else { - to_read = bufsize; - } - -@@ -87,33 +77,31 @@ - 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; -+ (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) -- { -+ if (read_this_time < to_read) { - break; - } - } - -- } -+ } - - set_fs(fs); - - tmp = page + PAGE_SIZE; - while (clear--) { -- *(char *)--tmp = 0; -+ *(char *) --tmp = 0; - } - return page; - } - --struct vm_operations_struct ncp_file_mmap = { -+struct vm_operations_struct ncp_file_mmap = -+{ - NULL, /* open */ - NULL, /* close */ - NULL, /* unmap */ -@@ -128,18 +116,15 @@ - - - /* 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) -+int ncp_mmap(struct inode *inode, struct file *file, struct vm_area_struct *vma) - { -- DPRINTK("ncp_mmap: called\n"); -+ DPRINTK("ncp_mmap: called\n"); - -- if (!ncp_conn_valid(NCP_SERVER(inode))) -- { -+ if (!ncp_conn_valid(NCP_SERVER(inode))) { - return -EIO; - } -- -- /* only PAGE_COW or read-only supported now */ -- if (vma->vm_flags & VM_SHARED) -+ /* 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; -@@ -147,7 +132,6 @@ - inode->i_atime = CURRENT_TIME; - inode->i_dirt = 1; - } -- - vma->vm_inode = inode; - inode->i_count++; - vma->vm_ops = &ncp_file_mmap; -diff -urN 2.1.29/fs/ncpfs/ncplib_kernel.c 2.1.29-patched/fs/ncpfs/ncplib_kernel.c ---- 2.1.29/fs/ncpfs/ncplib_kernel.c Mon Dec 30 11:03:22 1996 -+++ 2.1.29-patched/fs/ncpfs/ncplib_kernel.c Sat Mar 22 19:13:11 1997 -@@ -8,53 +8,43 @@ - - #include "ncplib_kernel.h" - --typedef __u8 byte; --typedef __u16 word; --typedef __u32 dword; -- - static inline int min(int a, int b) - { -- return alock == 0) -- { -+ if (server->lock == 0) { - DPRINTK("ncpfs: server not locked!\n"); - } - } - --static void --ncp_add_byte(struct ncp_server *server, byte x) -+static void ncp_add_byte(struct ncp_server *server, __u8 x) - { - assert_server_locked(server); -- *(byte *)(&(server->packet[server->current_size])) = x; -+ *(__u8 *) (&(server->packet[server->current_size])) = x; - server->current_size += 1; - return; - } - --static void --ncp_add_word(struct ncp_server *server, word x) -+static void ncp_add_word(struct ncp_server *server, __u16 x) - { - assert_server_locked(server); -- put_unaligned(x, (word *)(&(server->packet[server->current_size]))); -+ put_unaligned(x, (__u16 *) (&(server->packet[server->current_size]))); - server->current_size += 2; - return; - } - --static void --ncp_add_dword(struct ncp_server *server, dword x) -+static void ncp_add_dword(struct ncp_server *server, __u32 x) - { - assert_server_locked(server); -- put_unaligned(x, (dword *)(&(server->packet[server->current_size]))); -+ put_unaligned(x, (__u32 *) (&(server->packet[server->current_size]))); - server->current_size += 4; - return; - } - --static void --ncp_add_mem(struct ncp_server *server, const void *source, int size) -+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); -@@ -62,8 +52,7 @@ - return; - } - --static void --ncp_add_mem_fromfs(struct ncp_server *server, const char *source, int size) -+static void ncp_add_mem_fromfs(struct ncp_server *server, const char *source, int size) - { - assert_server_locked(server); - copy_from_user(&(server->packet[server->current_size]), source, size); -@@ -71,13 +60,11 @@ - return; - } - --static void --ncp_add_pstring(struct ncp_server *server, const char *s) -+static void ncp_add_pstring(struct ncp_server *server, const char *s) - { - int len = strlen(s); - assert_server_locked(server); -- if (len > 255) -- { -+ if (len > 255) { - DPRINTK("ncpfs: string too long: %s\n", s); - len = 255; - } -@@ -86,8 +73,7 @@ - return; - } - --static void --ncp_init_request(struct ncp_server *server) -+static void ncp_init_request(struct ncp_server *server) - { - ncp_lock_server(server); - -@@ -95,11 +81,10 @@ - server->has_subfunction = 0; - } - --static void --ncp_init_request_s(struct ncp_server *server, int subfunction) -+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_word(server, 0); /* preliminary size */ - - ncp_add_byte(server, subfunction); - -@@ -107,53 +92,49 @@ - } - - static char * --ncp_reply_data(struct ncp_server *server, int offset) -+ 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) -+static __u8 -+ ncp_reply_byte(struct ncp_server *server, int offset) - { -- return *(byte *)(ncp_reply_data(server, offset)); -+ return get_unaligned((__u8 *) ncp_reply_data(server, offset)); - } - --static word --ncp_reply_word(struct ncp_server *server, int offset) -+static __u16 -+ ncp_reply_word(struct ncp_server *server, int offset) - { -- return *(word *)(ncp_reply_data(server, offset)); -+ return get_unaligned((__u16 *) ncp_reply_data(server, offset)); - } - --static dword --ncp_reply_dword(struct ncp_server *server, int offset) -+static __u32 -+ ncp_reply_dword(struct ncp_server *server, int offset) - { -- return *(dword *)(ncp_reply_data(server, offset)); -+ return get_unaligned((__u32 *) ncp_reply_data(server, offset)); - } - --int --ncp_negotiate_buffersize(struct ncp_server *server, -- int size, int *target) -+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) -- { -+ -+ if ((result = ncp_request(server, 33)) != 0) { - ncp_unlock_server(server); - return result; - } -- -- *target =min(ntohs(ncp_reply_word(server, 0)), size); -+ *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 ncp_get_volume_info_with_number(struct ncp_server *server, int n, -+ struct ncp_volume_info *target) - { - int result; - int len; -@@ -161,14 +142,12 @@ - ncp_init_request_s(server, 44); - ncp_add_byte(server, n); - -- if ((result = ncp_request(server, 22)) != 0) -- { -+ 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->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); -@@ -178,20 +157,17 @@ - memset(&(target->volume_name), 0, sizeof(target->volume_name)); - - len = ncp_reply_byte(server, 29); -- if (len > NCP_VOLNAME_LEN) -- { -+ 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 ncp_close_file(struct ncp_server *server, const char *file_id) - { - int result; - -@@ -204,35 +180,27 @@ - return result; - } - --static void --ncp_add_handle_path(struct ncp_server *server, -- __u8 vol_num, -- __u32 dir_base, int have_dir_base, -- char *path) -+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); -+ if (have_dir_base != 0) { -+ ncp_add_byte(server, 1); /* dir_base */ -+ } else { -+ ncp_add_byte(server, 0xff); /* no handle */ - } -- else -- { -+ 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) -+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; -@@ -240,70 +208,60 @@ - memcpy(target, structure, info_struct_size); - name_len = structure + info_struct_size; - target->nameLen = *name_len; -- strncpy(target->entryName, name_len+1, *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 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) -- { -+ if (target == NULL) { - return -EINVAL; - } -- - ncp_init_request(server); -- ncp_add_byte(server, 6); /* subfunction */ -+ 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, htons(0xff00)); /* get all */ -+ ncp_add_word(server, htons(0xff00)); /* 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) -- { -+ 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) -+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_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) -- { -+ 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); -+ while (no_namespaces > 0) { -+ DPRINTK("get_namespaces: found %d on %d\n", *namespace, volume); - -- if (*namespace == 4) -- { -+ if (*namespace == 4) { - DPRINTK("get_namespaces: found OS2\n"); - ncp_unlock_server(server); - return 1; -@@ -315,10 +273,9 @@ - return 0; - } - --int --ncp_lookup_volume(struct ncp_server *server, -- char *volname, -- struct nw_info_struct *target) -+int ncp_lookup_volume(struct ncp_server *server, -+ char *volname, -+ struct nw_info_struct *target) - { - int result; - int volnum; -@@ -326,30 +283,28 @@ - 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_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) -- { -+ 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; -+ server->name_space[volnum] = ncp_has_os2_namespace(server, volnum) ? 4 : 0; - - DPRINTK("lookup_vol: namespace[%d] = %d\n", - volnum, server->name_space[volnum]); -@@ -360,19 +315,18 @@ - 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 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, 7); /* subfunction */ - ncp_add_byte(server, server->name_space[file->volNumber]); -- ncp_add_byte(server, 0); /* reserved */ -- ncp_add_word(server, htons(0x0680)); /* search attribs: all */ -+ ncp_add_byte(server, 0); /* reserved */ -+ ncp_add_word(server, htons(0x0680)); /* search attribs: all */ - - ncp_add_dword(server, info_mask); - ncp_add_mem(server, info, sizeof(*info)); -@@ -384,55 +338,50 @@ - return result; - } - --int --ncp_del_file_or_subdir(struct ncp_server *server, -- struct nw_info_struct *dir, char *name) -+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, 8); /* subfunction */ - ncp_add_byte(server, server->name_space[dir->volNumber]); -- ncp_add_byte(server, 0); /* reserved */ -- ncp_add_word(server, ntohs(0x0680)); /* search attribs: all */ -+ ncp_add_byte(server, 0); /* reserved */ -+ ncp_add_word(server, ntohs(0x0680)); /* search attribs: all */ - ncp_add_handle_path(server, dir->volNumber, - dir->dirEntNum, 1, name); -- -+ - result = ncp_request(server, 87); - ncp_unlock_server(server); - return result; - } - --static inline void --ConvertToNWfromDWORD ( __u32 sfd , __u8 ret[6] ) -+static inline void ConvertToNWfromDWORD(__u32 sfd, __u8 ret[6]) - { -- __u16 *dest = (__u16 *) ret; -- memcpy (ret + 2, &sfd, 4); -- dest[0] = cpu_to_le16((le16_to_cpu(dest[1]) + le16_to_cpu(1))); -- return; -+ __u16 *dest = (__u16 *) ret; -+ memcpy(ret + 2, &sfd, 4); -+ dest[0] = cpu_to_le16((le16_to_cpu(dest[1]) + le16_to_cpu(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 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 = ntohs(0x0600); - __u8 volume = (dir != NULL) ? dir->volNumber : target->i.volNumber; - -- if ((create_attributes & aDIR) != 0) -- { -- search_attribs |= ntohs(0x0080); -+ if ((create_attributes & aDIR) != 0) { -+ search_attribs |= ntohs(0x0080); - } -- - ncp_init_request(server); -- ncp_add_byte(server, 1); /* subfunction */ -+ 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); -@@ -442,89 +391,76 @@ - for directories */ - ncp_add_word(server, desired_acc_rights); - -- if (dir != NULL) -- { -+ if (dir != NULL) { - ncp_add_handle_path(server, volume, dir->dirEntNum, 1, name); -- } -- else -- { -+ } else { - ncp_add_handle_path(server, volume, target->i.dirEntNum, - 1, NULL); -- } -+ } - -- if ((result = ncp_request(server, 87)) != 0) -- { -+ 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) -- { -+ 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 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, 2); /* subfunction */ - ncp_add_byte(server, server->name_space[dir->volNumber]); -- ncp_add_byte(server, 0); /* reserved */ -+ ncp_add_byte(server, 0); /* reserved */ - ncp_add_handle_path(server, dir->volNumber, dir->dirEntNum, 1, NULL); -- -- if ((result = ncp_request(server, 87)) != 0) -- { -+ -+ 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 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, 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_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, 2); /* 2 byte pattern */ -+ ncp_add_byte(server, 0xff); /* following is a wildcard */ - ncp_add_byte(server, '*'); -- -- if ((result = ncp_request(server, 87)) != 0) -- { -+ -+ 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); - -@@ -532,34 +468,33 @@ - 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 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) -+ 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, 4); /* subfunction */ - ncp_add_byte(server, server->name_space[old_dir->volNumber]); -- ncp_add_byte(server, 1); /* rename flag */ -- ncp_add_word(server, ntohs (0x0680)); /* search attributes */ -+ ncp_add_byte(server, 1); /* rename flag */ -+ ncp_add_word(server, ntohs(0x0680)); /* 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 */ -+ 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 */ -+ ncp_add_byte(server, 1); /* 1 destination component */ - - /* source path string */ - ncp_add_pstring(server, old_name); -@@ -570,13 +505,12 @@ - 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 ncp_read(struct ncp_server *server, const char *file_id, -+ __u32 offset, __u16 to_read, -+ char *target, int *bytes_read) - { - int result; - -@@ -586,24 +520,21 @@ - ncp_add_dword(server, htonl(offset)); - ncp_add_word(server, htons(to_read)); - -- if ((result = ncp_request(server, 72)) != 0) -- { -+ if ((result = ncp_request(server, 72)) != 0) { - ncp_unlock_server(server); - return result; - } -- - *bytes_read = ntohs(ncp_reply_word(server, 0)); - -- copy_to_user(target, ncp_reply_data(server, 2+(offset&1)), *bytes_read); -+ copy_to_user(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 ncp_write(struct ncp_server *server, const char *file_id, -+ __u32 offset, __u16 to_write, -+ const char *source, int *bytes_written) - { - int result; - -@@ -614,15 +545,12 @@ - ncp_add_word(server, htons(to_write)); - ncp_add_mem_fromfs(server, source, to_write); - -- if ((result = ncp_request(server, 73)) != 0) -- { -+ if ((result = ncp_request(server, 73)) != 0) { - ncp_unlock_server(server); - return result; - } -- - *bytes_written = to_write; - - ncp_unlock_server(server); - return 0; - } -- -diff -urN 2.1.29/fs/ncpfs/ncplib_kernel.h 2.1.29-patched/fs/ncpfs/ncplib_kernel.h ---- 2.1.29/fs/ncpfs/ncplib_kernel.h Mon Dec 30 11:03:22 1996 -+++ 2.1.29-patched/fs/ncpfs/ncplib_kernel.h Sun Mar 23 13:05:18 1997 -@@ -29,89 +29,11 @@ - 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, -diff -urN 2.1.29/fs/ncpfs/sock.c 2.1.29-patched/fs/ncpfs/sock.c ---- 2.1.29/fs/ncpfs/sock.c Sun Jan 26 11:07:44 1997 -+++ 2.1.29-patched/fs/ncpfs/sock.c Sun Mar 23 09:37:46 1997 -@@ -25,315 +25,59 @@ - #include - #include - #include -+#include - -- --#define _S(nr) (1<<((nr)-1)) --static int _recvfrom(struct socket *sock, unsigned char *ubuf, -- int size, int noblock, unsigned flags, -- struct sockaddr_ipx *sa) -+static int _recv(struct socket *sock, unsigned char *ubuf, int size, -+ unsigned flags) - { -- struct iovec iov; -- struct msghdr msg; -+ struct iovec iov; -+ struct msghdr msg; - struct scm_cookie scm; - - memset(&scm, 0, sizeof(scm)); - -- iov.iov_base = ubuf; -- iov.iov_len = size; -- -- msg.msg_name = (void *)sa; -- msg.msg_namelen = 0; -- if (sa) -- msg.msg_namelen = sizeof(struct sockaddr_ipx); -- msg.msg_control = NULL; -- msg.msg_iov = &iov; -- msg.msg_iovlen = 1; -- if (noblock) { -- flags |= MSG_DONTWAIT; -- } -+ iov.iov_base = ubuf; -+ iov.iov_len = size; - -- return sock->ops->recvmsg(sock, &msg, size, flags, &scm); -+ msg.msg_name = NULL; -+ msg.msg_namelen = 0; -+ msg.msg_control = NULL; -+ msg.msg_iov = &iov; -+ msg.msg_iovlen = 1; -+ return sock->ops->recvmsg(sock, &msg, size, flags, &scm); - } - --static int _sendto(struct socket *sock, const void *buff, -- int len, int noblock, unsigned flags, -- struct sockaddr_ipx *sa) -- -+static int _send(struct socket *sock, const void *buff, int len) - { -- struct iovec iov; -- struct msghdr msg; -+ struct iovec iov; -+ struct msghdr msg; - struct scm_cookie scm; - int err; - -- iov.iov_base = (void *)buff; -- iov.iov_len = len; -- -- msg.msg_name = (void *)sa; -- msg.msg_namelen = sizeof(struct sockaddr_ipx); -- msg.msg_control = NULL; -- msg.msg_iov = &iov; -- msg.msg_iovlen = 1; -+ iov.iov_base = (void *) buff; -+ iov.iov_len = len; - -- if (noblock) { -- flags |= MSG_DONTWAIT; -- } -- -- msg.msg_flags = flags; -+ msg.msg_name = NULL; -+ msg.msg_namelen = 0; -+ msg.msg_control = NULL; -+ msg.msg_iov = &iov; -+ msg.msg_iovlen = 1; -+ msg.msg_flags = 0; - - err = scm_send(sock, &msg, &scm); -- if (err < 0) -+ if (err < 0) { - return err; -- err = sock->ops->sendmsg(sock, &msg, len, &scm); -+ } -+ err = sock->ops->sendmsg(sock, &msg, len, &scm); - scm_destroy(&scm); - return err; - } - -- --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 result; -- unsigned short fs; -- -- fs = get_fs(); -- set_fs(get_ds()); -- -- result = _recvfrom(sock, (void *)packet_buf, 2, 1, 0, -- &sender); -- -- if ( (result != 2) -- || (packet_buf[1] != '?') -- /* How to check connection number here? */ -- ) -- { -- 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 = _sendto(sock, (void *)packet_buf, 2, 1, 0, -- &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_DGRAM\n"); -- server->data_ready = NULL; -- return -EINVAL; -- } -- -- sk = sock->sk; -- -- 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; -- sk->allocation = GFP_ATOMIC; -- 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_DGRAM\n"); -- return -EINVAL; -- } -- -- sk = sock->sk; -- -- 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; -- sk->allocation = GFP_KERNEL; -- server->data_ready = NULL; -- return 0; --} -- --static void --ncp_msg_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 result; -- unsigned short fs; -- -- fs = get_fs(); -- set_fs(get_ds()); -- -- result = _recvfrom(sock, (void *)packet_buf, 2, 1, 0, -- &sender); -- -- DPRINTK("ncpfs: got message of size %d from:\n", result); -- DPRINTK("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]); -- -- ncp_trigger_message(sk->protinfo.af_ipx.ncp_server); -- -- set_fs(fs); -- } --} -- --int --ncp_catch_message(struct ncp_server *server) --{ -- struct file *file; -- struct inode *inode; -- struct socket *sock; -- struct sock *sk; -- -- if ( (server == NULL) -- || ((file = server->msg_filp) == NULL) -- || ((inode = file->f_inode) == NULL) -- || (!S_ISSOCK(inode->i_mode))) -- { -- printk("ncp_catch_message: did not get valid server!\n"); -- return -EINVAL; -- } -- -- sock = &(inode->u.socket_i); -- -- if (sock->type != SOCK_DGRAM) -- { -- printk("ncp_catch_message: did not get SOCK_DGRAM\n"); -- return -EINVAL; -- } -- -- sk = sock->sk; -- -- if (sk == NULL) -- { -- printk("ncp_catch_message: sk == NULL"); -- return -EINVAL; -- } -- -- DDPRINTK("ncp_catch_message: sk->d_r = %x\n", -- (unsigned int)(sk->data_ready)); -- -- if (sk->data_ready == ncp_msg_data_ready) -- { -- printk("ncp_catch_message: already done\n"); -- return -EINVAL; -- } -- -- sk->data_ready = ncp_msg_data_ready; -- sk->protinfo.af_ipx.ncp_server = server; -- 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) -+static int do_ncp_rpc_call(struct ncp_server *server, int size) - { - struct file *file; - struct inode *inode; -@@ -343,29 +87,24 @@ - char *start = server->packet; - poll_table wait_table; - struct poll_table_entry entry; -- int (*select) (struct inode *, poll_table *); - int init_timeout, max_timeout; - int timeout; - int retrans; - int major_timeout_seen; - int acknowledge_seen; -- char *server_name; - int n; - 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; -+ *((struct ncp_request_header *) (server->packet)); - -+ struct ncp_reply_header reply; - - file = server->ncp_filp; - inode = file->f_inode; -- select = file->f_op->poll; - sock = &inode->u.socket_i; -- if (!sock) -- { -+ if (!sock) { - printk("ncp_rpc_call: socki_lookup failed\n"); - return -EBADF; - } -@@ -374,61 +113,53 @@ - retrans = server->m.retry_count; - major_timeout_seen = 0; - acknowledge_seen = 0; -- server_name = server->m.server_name; - old_mask = current->blocked; - current->blocked |= ~(_S(SIGKILL) - #if 0 -- | _S(SIGSTOP) -+ | _S(SIGSTOP) - #endif -- | ((server->m.flags & NCP_MOUNT_INTR) -- ? ((current->sig->action[SIGINT - 1].sa_handler == SIG_DFL -- ? _S(SIGINT) : 0) -- | (current->sig->action[SIGQUIT - 1].sa_handler == SIG_DFL -- ? _S(SIGQUIT) : 0)) -- : 0)); -+ | ((server->m.flags & NCP_MOUNT_INTR) -+ ? ((current->sig->action[SIGINT - 1].sa_handler == SIG_DFL -+ ? _S(SIGINT) : 0) -+ | (current->sig->action[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) -- { -+ 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)); -+ 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); -+ "seq: %d", -+ request.type, -+ (request.conn_high << 8) + request.conn_low, -+ request.sequence); - DDPRINTK(" func: %d\n", - request.function); - -- result = _sendto(sock, (void *) start, size, 0, 0, -- &(server->m.serv_addr)); -- if (result < 0) -- { -+ result = _send(sock, (void *) start, size); -+ if (result < 0) { - printk("ncp_rpc_call: send error = %d\n", result); - break; - } -- re_select: -+ re_select: - wait_table.nr = 0; - wait_table.entry = &entry; - current->state = TASK_INTERRUPTIBLE; -- if (!select(inode, &wait_table)) -- { -- if (timeout > max_timeout) -- { -+ if (!(file->f_op->poll(file, &wait_table) & POLLIN)) { -+ 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 on " -- "%s\n", server_name); -+ if (acknowledge_seen == 0) { -+ printk("NCP max timeout\n"); - } - timeout = max_timeout; - } -@@ -436,102 +167,87 @@ - schedule(); - remove_wait_queue(entry.wait_address, &entry.wait); - current->state = TASK_RUNNING; -- if (current->signal & ~current->blocked) -- { -+ if (current->signal & ~current->blocked) { - current->timeout = 0; - result = -ERESTARTSYS; - break; - } -- if (!current->timeout) -- { -+ if (!current->timeout) { - if (n < retrans) - continue; -- if (server->m.flags & NCP_MOUNT_SOFT) -- { -- printk("NCP server %s not responding, " -- "timed out\n", server_name); -+ 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 %s not responding, " -- "still trying\n", server_name); -+ if (!major_timeout_seen) { -+ printk("NCP server not responding\n"); - } - major_timeout_seen = 1; - continue; -- } -- else -+ } else - current->timeout = 0; -- } -- else if (wait_table.nr) -+ } else if (wait_table.nr) - remove_wait_queue(entry.wait_address, &entry.wait); - current->state = TASK_RUNNING; - - /* 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 = _recvfrom(sock, (void *)&reply, -- sizeof(reply), 1, MSG_PEEK, NULL); -- if (result < 0) -- { -- if (result == -EAGAIN) -- { -+ result = _recv(sock, (void *) &reply, sizeof(reply), -+ MSG_PEEK | MSG_DONTWAIT); -+ if (result < 0) { -+ if (result == -EAGAIN) { - DPRINTK("ncp_rpc_call: bad select ready\n"); - goto re_select; - } -- if (result == -ECONNREFUSED) -- { -+ if (result == -ECONNREFUSED) { - DPRINTK("ncp_rpc_call: server playing coy\n"); - goto re_select; - } -- if (result != -ERESTARTSYS) -- { -+ if (result != -ERESTARTSYS) { - printk("ncp_rpc_call: recv error = %d\n", -- -result); -+ -result); - } - break; - } -- if ( (result == sizeof(reply)) -- && (reply.type == NCP_POSITIVE_ACK)) -- { -+ if ((result == sizeof(reply)) -+ && (reply.type == NCP_POSITIVE_ACK)) { - /* Throw away the packet */ - DPRINTK("ncp_rpc_call: got positive acknowledge\n"); -- _recvfrom(sock, (void *)&reply, sizeof(reply), 1, 0, -- NULL); -+ _recv(sock, (void *) &reply, sizeof(reply), -+ MSG_DONTWAIT); - 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)))) -- { -+ "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 %s OK\n", server_name); -+ 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. */ -- _recvfrom(sock, (void *)&reply, sizeof(reply), 1, 0, NULL); -+ _recv(sock, (void *) &reply, sizeof(reply), MSG_DONTWAIT); - - DPRINTK("ncp_rpc_call: reply mismatch\n"); - goto re_select; -@@ -540,54 +256,42 @@ - * we have the correct reply, so read into the correct place and - * return it - */ -- result = _recvfrom(sock, (void *)start, server->packet_size, -- 1, 0, NULL); -- if (result < 0) -- { -+ result = _recv(sock, (void *) start, server->packet_size, MSG_DONTWAIT); -+ if (result < 0) { - printk("NCP: notice message: result=%d\n", result); -- } -- else if (result < sizeof(struct ncp_reply_header)) -- { -+ } 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\n", result); - 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) -+static int ncp_do_request(struct ncp_server *server, int size) - { - int result; - -- if (server->lock == 0) -- { -+ if (server->lock == 0) { - printk("ncpfs: Server not locked!\n"); - return -EIO; - } -- -- if (!ncp_conn_valid(server)) -- { -+ if (!ncp_conn_valid(server)) { - return -EIO; - } -- - result = do_ncp_rpc_call(server, size); - - DDPRINTK("do_ncp_rpc_call returned %d\n", result); - -- if (result < 0) -- { -+ if (result < 0) { - /* There was a problem with I/O, so the connections is -- * no longer usable. */ -+ * no longer usable. */ - ncp_invalidate_conn(server); - } - return result; -@@ -596,121 +300,105 @@ - /* 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) -+int ncp_request(struct ncp_server *server, int function) - { - struct ncp_request_header *h -- = (struct ncp_request_header *)(server->packet); -+ = (struct ncp_request_header *) (server->packet); - struct ncp_reply_header *reply -- = (struct ncp_reply_header *)(server->packet); -+ = (struct ncp_reply_header *) (server->packet); - - int request_size = server->current_size -- - sizeof(struct ncp_request_header); -+ - sizeof(struct ncp_request_header); - - int result; - -- if (server->has_subfunction != 0) -- { -- *(__u16 *)&(h->data[0]) = htons(request_size - 2); -+ if (server->has_subfunction != 0) { -+ *(__u16 *) & (h->data[0]) = htons(request_size - 2); - } -- - h->type = NCP_REQUEST; -- -+ - server->sequence += 1; -- h->sequence = server->sequence; -- h->conn_low = (server->connection) & 0xff; -+ 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; -+ h->task = (current->pid) & 0xff; -+ h->function = function; - -- if ((result = ncp_do_request(server, request_size + sizeof(*h))) < 0) -- { -+ 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->completion = reply->completion_code; - server->conn_status = reply->connection_state; -- server->reply_size = result; -+ server->reply_size = result; - server->ncp_reply_size = result - sizeof(struct ncp_reply_header); - - result = reply->completion_code; - -- if (result != 0) -- { -+ if (result != 0) { - DPRINTK("ncp_completion_code: %x\n", result); - } -- return result; -+ return result; - } - --int --ncp_connect(struct ncp_server *server) -+int ncp_connect(struct ncp_server *server) - { - struct ncp_request_header *h -- = (struct ncp_request_header *)(server->packet); -+ = (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->sequence = server->sequence; -+ h->conn_low = 0xff; - h->conn_high = 0xff; -- h->task = (current->pid) & 0xff; -- h->function = 0; -+ h->task = (current->pid) & 0xff; -+ h->function = 0; - -- if ((result = ncp_do_request(server, sizeof(*h))) < 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) -+ -+int ncp_disconnect(struct ncp_server *server) - { - struct ncp_request_header *h -- = (struct ncp_request_header *)(server->packet); -+ = (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->sequence = server->sequence; -+ h->conn_low = (server->connection) & 0xff; - h->conn_high = ((server->connection) & 0xff00) >> 8; -- h->task = (current->pid) & 0xff; -- h->function = 0; -+ h->task = (current->pid) & 0xff; -+ h->function = 0; - - return ncp_do_request(server, sizeof(*h)); - } - --void --ncp_lock_server(struct ncp_server *server) -+void ncp_lock_server(struct ncp_server *server) - { - #if 0 - /* For testing, only 1 process */ -- if (server->lock != 0) -- { -+ if (server->lock != 0) { - DPRINTK("ncpfs: server locked!!!\n"); - } - #endif -- while (server->lock) -+ while (server->lock) - sleep_on(&server->wait); - server->lock = 1; - } - --void --ncp_unlock_server(struct ncp_server *server) -+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); -+ if (server->lock != 1) { -+ printk("ncp_unlock_server: was not locked!\n"); -+ } -+ server->lock = 0; -+ wake_up(&server->wait); - } -- -diff -urN 2.1.29/include/linux/ipx.h 2.1.29-patched/include/linux/ipx.h ---- 2.1.29/include/linux/ipx.h Thu Dec 12 16:14:38 1996 -+++ 2.1.29-patched/include/linux/ipx.h Sun Mar 23 11:28:24 1997 -@@ -1,6 +1,7 @@ - #ifndef _IPX_H_ - #define _IPX_H_ - #include -+#include - #define IPX_NODE_LEN 6 - #define IPX_MTU 576 - -diff -urN 2.1.29/include/linux/ncp.h 2.1.29-patched/include/linux/ncp.h ---- 2.1.29/include/linux/ncp.h Thu Feb 6 11:58:49 1997 -+++ 2.1.29-patched/include/linux/ncp.h Sun Mar 23 13:02:34 1997 -@@ -20,78 +20,42 @@ - #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)); -+ __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)); -+ __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]; --}; -- --struct ncp_filesearch_info { -- __u8 volume_number; -- __u16 directory_id; -- __u16 sequence_no; -- __u8 access_rights; -+ __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]; - }; - --#define NCP_MAX_FILENAME 14 -- - /* these define the attribute byte as seen by NCP */ - #define aRONLY (ntohl(0x01000000)) - #define aHIDDEN (ntohl(0x02000000)) -@@ -105,17 +69,6 @@ - #define AR_EXCLUSIVE (ntohs(0x2000)) - - #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 -@@ -164,34 +117,33 @@ - #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)); -+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 */ -@@ -209,97 +161,36 @@ - #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_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)); -+ 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)); -+ __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 */ -+#endif /* _LINUX_NCP_H */ -diff -urN 2.1.29/include/linux/ncp_fs.h 2.1.29-patched/include/linux/ncp_fs.h ---- 2.1.29/include/linux/ncp_fs.h Thu Feb 6 11:58:49 1997 -+++ 2.1.29-patched/include/linux/ncp_fs.h Sun Mar 23 13:02:43 1997 -@@ -21,22 +21,22 @@ - */ - - struct ncp_ioctl_request { -- unsigned int function; -- unsigned int size; -- char *data; -+ unsigned int function; -+ unsigned int size; -+ char *data; - }; - - struct ncp_fs_info { -- int version; -+ 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 -+ 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; --}; -+ 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) -@@ -53,8 +53,6 @@ - #define NCP_MAXPATHLEN 255 - #define NCP_MAXNAMELEN 14 - --#define NCP_MSG_COMMAND "/sbin/nwmsg" -- - #ifdef __KERNEL__ - - /* The readdir cache size controls how many directory entries are -@@ -62,7 +60,6 @@ - */ - #define NCP_READDIR_CACHE_SIZE 64 - -- - #define NCP_MAX_RPC_TIMEOUT (6*HZ) - - /* Guess, what 0x564c is :-) */ -@@ -84,26 +81,25 @@ - extern int ncp_current_malloced; - - static inline void * --ncp_kmalloc(unsigned int size, int priority) -+ ncp_kmalloc(unsigned int size, int priority) - { -- ncp_malloced += 1; -- ncp_current_malloced += 1; -- return kmalloc(size, priority); -+ ncp_malloced += 1; -+ ncp_current_malloced += 1; -+ return kmalloc(size, priority); - } - --static inline void --ncp_kfree_s(void *obj, int size) -+static inline void ncp_kfree_s(void *obj, int size) - { -- ncp_current_malloced -= 1; -- kfree_s(obj, size); -+ ncp_current_malloced -= 1; -+ kfree_s(obj, size); - } - --#else /* DEBUG_NCP_MALLOC */ -+#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 */ -+#endif /* DEBUG_NCP_MALLOC */ - - #if DEBUG_NCP > 0 - #define DPRINTK(format, args...) printk(format , ## args) -@@ -127,39 +123,35 @@ - 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_conn_logged_in(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_free_dir_cache(void); --int ncp_date_dos2unix(__u16 time, __u16 date); --void ncp_date_unix2dos(int unix_date, __u16 *time, __u16 *date); -+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); -+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 *raw_data, int silent); - extern int init_ncp_fs(void); --void ncp_trigger_message(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); --int ncp_catch_message(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); -+int ncp_mmap(struct inode *inode, struct file *file, struct vm_area_struct *vma); - --#endif /* __KERNEL__ */ -+#endif /* __KERNEL__ */ - --#endif /* _LINUX_NCP_FS_H */ -+#endif /* _LINUX_NCP_FS_H */ -diff -urN 2.1.29/include/linux/ncp_fs_i.h 2.1.29-patched/include/linux/ncp_fs_i.h ---- 2.1.29/include/linux/ncp_fs_i.h Thu Feb 6 11:58:49 1997 -+++ 2.1.29-patched/include/linux/ncp_fs_i.h Sun Mar 23 13:02:43 1997 -@@ -13,21 +13,21 @@ - #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_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; -+ 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; - }; -diff -urN 2.1.29/include/linux/ncp_fs_sb.h 2.1.29-patched/include/linux/ncp_fs_sb.h ---- 2.1.29/include/linux/ncp_fs_sb.h Thu Feb 6 11:58:49 1997 -+++ 2.1.29-patched/include/linux/ncp_fs_sb.h Sun Mar 23 13:02:43 1997 -@@ -17,60 +17,52 @@ - - 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. */ -+ 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 */ -- struct file *msg_filp; /* File pointer to message 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 -+ 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 buffer_size; /* Negotiated bufsize */ - -- int reply_size; /* Size of last reply */ -+ int reply_size; /* Size of last reply */ - -- int packet_size; -+ int packet_size; - unsigned char *packet; /* Here we prepare requests and - receive replies */ - -- int lock; /* To prevent mismatch in protocols. */ -+ int lock; /* To prevent mismatch in protocols. */ - struct wait_queue *wait; - -- int current_size; /* for packet preparation */ -- int has_subfunction; -- int ncp_reply_size; -+ int current_size; /* for packet preparation */ -+ int has_subfunction; -+ int ncp_reply_size; - -- struct ncp_inode_info root; -- char root_path; /* '\0' */ -+ struct ncp_inode_info root; -+ char root_path; /* '\0' */ - }; - --static inline int --ncp_conn_valid(struct ncp_server *server) -+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) -+static inline void ncp_invalidate_conn(struct ncp_server *server) - { - server->conn_status |= 0x01; - } - --#endif /* __KERNEL__ */ -+#endif /* __KERNEL__ */ - - #endif -diff -urN 2.1.29/include/linux/ncp_mount.h 2.1.29-patched/include/linux/ncp_mount.h ---- 2.1.29/include/linux/ncp_mount.h Thu Feb 6 11:58:49 1997 -+++ 2.1.29-patched/include/linux/ncp_mount.h Sun Mar 23 13:02:43 1997 -@@ -13,40 +13,28 @@ - #include - #include - --#define NCP_MOUNT_VERSION 2 -- --#define NCP_USERNAME_LEN (NCP_BINDERY_NAME_LEN) --#define NCP_PASSWORD_LEN 20 -+#define NCP_MOUNT_VERSION 3 - - /* Values for flags */ - #define NCP_MOUNT_SOFT 0x0001 - #define NCP_MOUNT_INTR 0x0002 - --/* Gosh... */ --#define NCP_PATH_MAX 1024 -- - 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[NCP_PATH_MAX+1]; -- unsigned char mounted_vol[NCP_VOLNAME_LEN+1]; -+ uid_t mounted_uid; /* Who may umount() this filesystem? */ -+ pid_t wdog_pid; /* Who cares for our watchdog packets? */ - -+ unsigned char mounted_vol[NCP_VOLNAME_LEN + 1]; - unsigned int time_out; /* How long should I wait after - sending a NCP request? */ -- unsigned int retry_count; /* And how often should I retry? */ -+ unsigned int 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; -+ uid_t uid; -+ gid_t gid; -+ mode_t file_mode; -+ mode_t dir_mode; - }; - - #endif diff --git a/patches/lockup-2.0.28.diff b/patches/lockup-2.0.28.diff deleted file mode 100644 index 13d924e..0000000 --- a/patches/lockup-2.0.28.diff +++ /dev/null @@ -1,44 +0,0 @@ -diff -urN 2.0.11/fs/ncpfs/sock.c linux/fs/ncpfs/sock.c ---- 2.0.28/fs/ncpfs/sock.c Fri Jul 12 08:14:53 1996 -+++ linux/fs/ncpfs/sock.c Thu Aug 8 19:27:26 1996 -@@ -55,7 +55,8 @@ - { - struct iovec iov; - struct msghdr msg; -- -+ int result; -+ - iov.iov_base = (void *)buff; - iov.iov_len = len; - -@@ -65,7 +66,29 @@ - msg.msg_iov = &iov; - msg.msg_iovlen = 1; - -- return sock->ops->sendmsg(sock, &msg, len, nonblock, flags); -+ result = sock->ops->sendmsg(sock, &msg, len, 1, flags); -+ -+ if ((result != -EAGAIN) || (nonblock != 0)) -+ { -+ return result; -+ } -+ -+ /* The following is probably one of the worst sins you can do -+ to a multitasking kernel: active polling. But when you call -+ ipx_sendmsg with nonblock==0, then it will block forever -+ from time to time. I really do not know why. To work around -+ this, I try to send the packet with nonblock=1 and retry -+ it. */ -+ -+ do { -+ /* Before retrying, give others a chance */ -+ current->state = TASK_INTERRUPTIBLE; -+ current->timeout = jiffies + HZ/10; -+ schedule(); -+ result = sock->ops->sendmsg(sock, &msg, len, 1, flags); -+ } while (result == -EAGAIN); -+ -+ return result; - } - - diff --git a/patches/lockup-2.0.30.diff b/patches/lockup-2.0.30.diff new file mode 100644 index 0000000..2d3d346 --- /dev/null +++ b/patches/lockup-2.0.30.diff @@ -0,0 +1,12 @@ +diff -u -urN 2.0.30/net/ipx/af_ipx.c 2.0.30-patched/net/ipx/af_ipx.c +--- 2.0.30/net/ipx/af_ipx.c Wed Nov 27 08:44:21 1996 ++++ 2.0.30-patched/net/ipx/af_ipx.c Mon Jul 14 17:25:12 1997 +@@ -1723,6 +1723,7 @@ + } + sk->rcvbuf=SK_RMEM_MAX; + sk->sndbuf=SK_WMEM_MAX; ++ sk->allocation=GFP_KERNEL; + sk->prot=NULL; /* So we use default free mechanisms */ + skb_queue_head_init(&sk->receive_queue); + skb_queue_head_init(&sk->write_queue); + diff --git a/sutil/Makefile b/sutil/Makefile index 638f2de..56f30b7 100644 --- a/sutil/Makefile +++ b/sutil/Makefile @@ -2,9 +2,17 @@ # Makefile for the linux ncp-filesystem routines. # -UTILS = ncpmount ncpumount nwsfind +include ../Makeinit -CC = gcc +ifdef MOUNT3 +# environ in ncpmount +CCFLAGS += -D_GNU_SOURCE +endif + +O_UTILS = ncpmount.o ncpumount.o nwsfind.o +UTILS = $(O_UTILS:%.o=%) + +CCFLAGS += -D__MAKE_SULIB__ default: make -C .. @@ -15,20 +23,20 @@ install: all for i in $(UTILS); \ do install $$i -m 4755 $(BINDIR); done -$(UTILS): %: %.o libncp.a - $(CC) -o $@ $(addsuffix .o,$@) -L. -lncp -L../lib -lcom_err +$(O_UTILS): %.o: %.c ../lib-static-su/ncplib_err.h + $(CC) $(CFLAGS) $(CCFLAGS) -I../lib-static-su -o $@ -c $< -ncplib.o: ncplib.c ncplib.h - $(CC) $(CFLAGS) -finline-functions -c ncplib.c +$(UTILS): %: %.o ../lib-static-su/libncp.a + $(CC) -o $@ $(addsuffix .o,$@) -L../lib-static-su -lncp -libncp.a: ncplib.o ../lib/ncplib_err.o - ar r libncp.a ncplib.o ../lib/ncplib_err.o +../lib-static-su/libncp.a ../lib-static-su/ncplib_err.h: + make -C ../lib-static-su libncp.a dep: $(CPP) -M $(INCLUDES) *.c > .depend clean: - rm -f *.o *~ libncp.a $(UTILS) + rm -f *.o *~ $(UTILS) mrproper: clean rm -f .depend diff --git a/sutil/ipxlib.h b/sutil/ipxlib.h deleted file mode 100644 index a4ecd0b..0000000 --- a/sutil/ipxlib.h +++ /dev/null @@ -1,93 +0,0 @@ -/* - * ipxlib.h - * - * Copyright (C) 1995 by Volker Lendecke - * - */ - -#ifndef _IPXLIB_H -#define _IPXLIB_H - - -#include -#include -#include -#include -#include - -typedef unsigned long IPXNet; -typedef unsigned short IPXPort; -typedef unsigned char IPXNode[IPX_NODE_LEN]; - -#define IPX_USER_PTYPE (0x00) -#define IPX_RIP_PTYPE (0x01) -#define IPX_SAP_PTYPE (0x04) -#define IPX_AUTO_PORT (0x0000) -#define IPX_SAP_PORT (0x0452) -#define IPX_RIP_PORT (0x0453) - -#define IPX_SAP_GENERAL_QUERY (0x0001) -#define IPX_SAP_GENERAL_RESPONSE (0x0002) -#define IPX_SAP_NEAREST_QUERY (0x0003) -#define IPX_SAP_NEAREST_RESPONSE (0x0004) - -#define IPX_SAP_FILE_SERVER (0x0004) - -struct sap_query { - unsigned short query_type; /* net order */ - unsigned short server_type; /* net order */ -}; - -struct sap_server_ident { - unsigned short server_type __attribute__((packed)); - char server_name[48] __attribute__((packed)); - IPXNet server_network __attribute__((packed)); - IPXNode server_node __attribute__((packed)); - IPXPort server_port __attribute__((packed)); - unsigned short intermediate_network __attribute__((packed)); -}; - -#define IPX_RIP_REQUEST (0x1) -#define IPX_RIP_RESPONSE (0x2) - -struct ipx_rip_packet { - __u16 operation __attribute__((packed)); - struct ipx_rt_def { - __u32 network __attribute__((packed)); - __u16 hops __attribute__((packed)); - __u16 ticks __attribute__((packed)); - } rt[1] __attribute__((packed)); -}; - -#define IPX_BROADCAST_NODE ("\xff\xff\xff\xff\xff\xff") -#define IPX_THIS_NODE ("\0\0\0\0\0\0") -#define IPX_THIS_NET (0) - -#ifndef IPX_NODE_LEN -#define IPX_NODE_LEN (6) -#endif - -void - ipx_print_node(IPXNode node); -void - ipx_print_network(IPXNet net); -void - ipx_print_port(IPXPort port); -void - ipx_print_saddr(struct sockaddr_ipx *sipx); -void - ipx_fprint_node(FILE * file, IPXNode node); -void - ipx_fprint_network(FILE * file, IPXNet net); -void - ipx_fprint_port(FILE * file, IPXPort port); -void - ipx_fprint_saddr(FILE * file, struct sockaddr_ipx *sipx); -int - ipx_sscanf_node(char *buf, unsigned char node[IPX_NODE_LEN]); -void - ipx_assign_node(IPXNode dest, IPXNode src); -int - ipx_node_equal(IPXNode n1, IPXNode n2); - -#endif /* _IPXLIB_H */ diff --git a/sutil/ncplib.c b/sutil/ncplib.c deleted file mode 100644 index d5d96fd..0000000 --- a/sutil/ncplib.c +++ /dev/null @@ -1,1668 +0,0 @@ -/* - * ncplib.c - * - * Copyright (C) 1995, 1996 by Volker Lendecke - * - */ - -#include "ncplib.h" -#include "ncplib_err.h" - -#include -extern pid_t wait(int *); -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -static long - ncp_negotiate_buffersize(struct ncp_conn *conn, - int size, int *target); -static long - ncp_login_object(struct ncp_conn *conn, - const unsigned char *username, - int login_type, - const unsigned char *password); - -static long - ncp_do_close(struct ncp_conn *conn); - -void str_upper(char *name) -{ - while (*name) { - *name = toupper(*name); - name = name + 1; - } -} - -/* I know it's terrible to include a .c file here, but I want to keep - the file nwcrypt.c intact and separate for copyright reasons */ -#include "nwcrypt.c" - -void 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] - ); -} - -void ipx_fprint_network(FILE * file, IPXNet net) -{ - fprintf(file, "%08lX", ntohl(net)); -} - -void ipx_fprint_port(FILE * file, IPXPort port) -{ - fprintf(file, "%04X", ntohs(port)); -} - -void ipx_fprint_saddr(FILE * file, struct sockaddr_ipx *sipx) -{ - ipx_fprint_network(file, sipx->sipx_network); - fprintf(file, ":"); - ipx_fprint_node(file, sipx->sipx_node); - fprintf(file, ":"); - ipx_fprint_port(file, sipx->sipx_port); -} - -void ipx_print_node(IPXNode node) -{ - ipx_fprint_node(stdout, node); -} - -void ipx_print_network(IPXNet net) -{ - ipx_fprint_network(stdout, net); -} - -void ipx_print_port(IPXPort port) -{ - ipx_fprint_port(stdout, port); -} - -void ipx_print_saddr(struct sockaddr_ipx *sipx) -{ - ipx_fprint_saddr(stdout, sipx); -} - -int ipx_sscanf_node(char *buf, unsigned char node[6]) -{ - int i; - int n[6]; - - if ((i = sscanf(buf, "%2x%2x%2x%2x%2x%2x", - &(n[0]), &(n[1]), &(n[2]), - &(n[3]), &(n[4]), &(n[5]))) != 6) { - return i; - } - for (i = 0; i < 6; i++) { - node[i] = n[i]; - } - return 6; -} - -void ipx_assign_node(IPXNode dest, IPXNode src) -{ - memcpy(dest, src, IPX_NODE_LEN); -} - -int ipx_node_equal(IPXNode n1, IPXNode n2) -{ - return memcmp(n1, n2, IPX_NODE_LEN) == 0; -} - -static int ipx_recvfrom(int sock, void *buf, int len, unsigned int flags, - struct sockaddr_ipx *sender, int *addrlen, int timeout, - long *err) -{ - fd_set rd, wr, ex; - struct timeval tv; - int result; - - FD_ZERO(&rd); - FD_ZERO(&wr); - FD_ZERO(&ex); - FD_SET(sock, &rd); - - tv.tv_sec = timeout; - tv.tv_usec = 0; - - if ((result = select(sock + 1, &rd, &wr, &ex, &tv)) == -1) { - *err = errno; - return -1; - } - if (FD_ISSET(sock, &rd)) { - result = recvfrom(sock, buf, len, flags, - (struct sockaddr *) sender, addrlen); - } else { - result = -1; - errno = ETIMEDOUT; - } - if (result < 0) { - *err = errno; - } - return result; -} - -static int ipx_recv(int sock, void *buf, int len, unsigned int flags, int timeout, - long *err) -{ - struct sockaddr_ipx sender; - int addrlen = sizeof(sender); - - return ipx_recvfrom(sock, buf, len, flags, &sender, &addrlen, - timeout, err); -} - -static long ipx_sap_find_nearest(int server_type, struct sockaddr_ipx *result, - char server_name[NCP_BINDERY_NAME_LEN]) -{ - struct sockaddr_ipx addr; - char data[1024]; - int sock; - int opt; - int packets; - int len; - - struct sap_server_ident *ident; - - if ((sock = socket(AF_IPX, SOCK_DGRAM, PF_IPX)) < 0) { - if (errno == EINVAL) { - return NCPL_ET_NO_IPX; - } - return errno; - } - opt = 1; - /* Permit broadcast output */ - if (setsockopt(sock, SOL_SOCKET, SO_BROADCAST, &opt, sizeof(opt)) == -1) { - goto finished; - } - memzero(addr); - addr.sipx_family = AF_IPX; - addr.sipx_network = htonl(0x0); - addr.sipx_port = htons(0x0); - addr.sipx_type = IPX_SAP_PTYPE; - - if (bind(sock, (struct sockaddr *) &addr, sizeof(addr)) == -1) { - if (errno == EADDRNOTAVAIL) { - errno = NCPL_ET_NO_INTERFACE; - } - goto finished; - } - WSET_HL(data, 0, IPX_SAP_NEAREST_QUERY); - WSET_HL(data, 2, server_type); - - memzero(addr); - addr.sipx_family = AF_IPX; - addr.sipx_port = htons(IPX_SAP_PORT); - addr.sipx_type = IPX_SAP_PTYPE; - addr.sipx_network = htonl(0x0); - ipx_assign_node(addr.sipx_node, IPX_BROADCAST_NODE); - - if (sendto(sock, data, 4, 0, - (struct sockaddr *) &addr, sizeof(addr)) < 0) { - goto finished; - } - packets = 5; - do { - long err; - len = ipx_recv(sock, data, 1024, 0, 1, &err); - if (len < 66) { - packets = packets - 1; - continue; - } - } - while ((ntohs(*((__u16 *) data)) != IPX_SAP_NEAREST_RESPONSE) - && (packets > 0)); - - if (packets == 0) { - close(sock); - return NCPL_ET_NO_SERVER; - } - ident = (struct sap_server_ident *) (data + 2); - - result->sipx_family = AF_IPX; - result->sipx_network = ident->server_network; - result->sipx_port = ident->server_port; - ipx_assign_node(result->sipx_node, ident->server_node); - - memcpy(server_name, ident->server_name, sizeof(ident->server_name)); - - errno = 0; - - finished: - close(sock); - return errno; -} - -static int ipx_make_reachable(IPXNet network) -{ - struct rtentry rt_def; - /* Router */ - struct sockaddr_ipx *sr = (struct sockaddr_ipx *) &rt_def.rt_gateway; - /* Target */ - struct sockaddr_ipx *st = (struct sockaddr_ipx *) &rt_def.rt_dst; - - struct ipx_rip_packet rip; - struct sockaddr_ipx addr; - int addrlen; - int sock; - int opt; - int res = -1; - int i; - int packets; - - if (geteuid() != 0) { - errno = EPERM; - return -1; - } - memzero(rip); - - sock = socket(AF_IPX, SOCK_DGRAM, PF_IPX); - - if (sock == -1) { - if (errno == EINVAL) { - return NCPL_ET_NO_IPX; - } - return errno; - } - opt = 1; - /* Permit broadcast output */ - if (setsockopt(sock, SOL_SOCKET, SO_BROADCAST, &opt, sizeof(opt)) != 0) { - goto finished; - } - memzero(addr); - addr.sipx_family = AF_IPX; - addr.sipx_network = htonl(0x0); - addr.sipx_port = htons(0x0); - addr.sipx_type = IPX_RIP_PTYPE; - - if (bind(sock, (struct sockaddr *) &addr, sizeof(addr)) != 0) { - goto finished; - } - addr.sipx_family = AF_IPX; - addr.sipx_port = htons(IPX_RIP_PORT); - addr.sipx_type = IPX_RIP_PTYPE; - addr.sipx_network = htonl(0x0); - ipx_assign_node(addr.sipx_node, IPX_BROADCAST_NODE); - - rip.operation = htons(IPX_RIP_REQUEST); - rip.rt[0].network = htonl(network); - - if (sendto(sock, &rip, sizeof(rip), 0, - (struct sockaddr *) &addr, sizeof(addr)) < 0) { - goto finished; - } - packets = 3; - do { - long err; - int len; - - if (packets == 0) { - goto finished; - } - addrlen = sizeof(struct sockaddr_ipx); - - len = ipx_recvfrom(sock, &rip, sizeof(rip), 0, sr, &addrlen, 1, - &err); - - if (len < sizeof(rip)) { - packets = packets - 1; - continue; - } - } - while (ntohs(rip.operation) != IPX_RIP_RESPONSE); - - if (rip.rt[0].network != htonl(network)) { - goto finished; - } - rt_def.rt_flags = RTF_GATEWAY; - st->sipx_network = htonl(network); - st->sipx_family = AF_IPX; - sr->sipx_family = AF_IPX; - - i = 0; - do { - res = ioctl(sock, SIOCADDRT, &rt_def); - i++; - } - while ((i < 5) && (res < 0) && (errno == EAGAIN)); - - finished: - close(sock); - - if (res != 0) { - errno = ENETUNREACH; - } - return res; -} - -static int install_wdog(struct ncp_conn *conn) -{ - int parent_pid = getpid(); - int pid; - int sock = conn->wdog_sock; - - char buf[1024]; - struct sockaddr_ipx sender; - int sizeofaddr = sizeof(struct sockaddr_ipx); - int pktsize; - - - if ((pid = fork()) < 0) { - return -1; - } - if (pid != 0) { - /* Parent, should go on as usual */ - conn->wdog_pid = pid; - return 0; - } - while (1) { - long err; - /* every 120 seconds we look if our parent is - still alive */ - pktsize = ipx_recvfrom(sock, buf, sizeof(buf), 0, - &sender, &sizeofaddr, 120, &err); - - if (getppid() != parent_pid) { - /* our parent has died, so nothing to do - anymore */ - exit(0); - } - if ((pktsize != 2) - || (buf[1] != '?')) { - continue; - } - buf[1] = 'Y'; - pktsize = sendto(sock, buf, 2, 0, - (struct sockaddr *) &sender, - sizeof(sender)); - } -} - -#define ncp_printf printf - -#define ncp_printf printf - -static void - assert_conn_locked(struct ncp_conn *conn); - -static void assert_conn_not_locked(struct ncp_conn *conn) -{ - if (conn->lock != 0) { - ncp_printf("ncpfs: conn already locked!\n"); - } -} - -static void ncp_lock_conn(struct ncp_conn *conn) -{ - assert_conn_not_locked(conn); - conn->lock = 1; -} - -static void ncp_unlock_conn(struct ncp_conn *conn) -{ - assert_conn_locked(conn); - conn->lock = 0; -} - -static long do_ncp_call(struct ncp_conn *conn, int request_size) -{ - struct ncp_request_header request; - - int result; - int retries = 20; - int len; - long err; - - memcpy(&request, conn->packet, sizeof(request)); - - while (retries > 0) { - struct ncp_reply_header reply; - struct sockaddr_ipx sender; - int sizeofaddr = sizeof(sender); - - retries -= 1; - - result = sendto(conn->ncp_sock, conn->packet, - request_size, - 0, (struct sockaddr *) &(conn->i.addr), - sizeof(conn->i.addr)); - - if (result < 0) { - return errno; - } - re_select: - len = ipx_recvfrom(conn->ncp_sock, - (char *) &reply, sizeof(reply), - MSG_PEEK, &sender, &sizeofaddr, 3, &err); - - if ((len < 0) && (err == ETIMEDOUT)) { - continue; - } - if (len < 0) { - return err; - } - if ( /* Is the sender wrong? */ - (memcmp(&sender.sipx_node, - &(conn->i.addr.sipx_node), 6) != 0) - || (sender.sipx_port != conn->i.addr.sipx_port) - /* Did the sender send a positive acknowledge? */ - || ((len == sizeof(reply)) - && (reply.type == NCP_POSITIVE_ACK)) - /* Did we get a bogus answer? */ - || ((len < sizeof(reply)) - || (reply.type != NCP_REPLY) - || ((request.type != NCP_ALLOC_SLOT_REQUEST) - && ((reply.sequence != request.sequence) - || (reply.conn_low != request.conn_low) - || (reply.conn_high != request.conn_high))))) { - /* Then throw away the packet */ - ipx_recv(conn->ncp_sock, (char *) &reply, sizeof(reply), - 0, 1, &err); - goto re_select; - } - ipx_recv(conn->ncp_sock, conn->packet, NCP_PACKET_SIZE, - 0, 1, &err); - conn->reply_size = len; - return 0; - } - return ETIMEDOUT; -} - -static int ncp_mount_request(struct ncp_conn *conn, int function) -{ - struct ncp_ioctl_request request; - int result; - - assert_conn_locked(conn); - - if (conn->has_subfunction != 0) { - WSET_HL(conn->packet, 7, conn->current_size - - sizeof(struct ncp_request_header) - 2); - } - request.function = function; - request.size = conn->current_size; - request.data = conn->packet; - - if ((result = ioctl(conn->mount_fid, NCP_IOC_NCPREQUEST, &request)) < 0) { - return result; - } - conn->completion = BVAL(conn->packet, 6); - conn->conn_status = BVAL(conn->packet, 7); - conn->ncp_reply_size = result - sizeof(struct ncp_reply_header); - - if ((conn->completion != 0) && (conn->verbose != 0)) { - ncp_printf("ncp_request_error: %d\n", conn->completion); - } - return conn->completion == 0 ? 0 : NCPL_ET_REQUEST_ERROR; -} - -static long ncp_temp_request(struct ncp_conn *conn, int function) -{ - long err; - - assert_conn_locked(conn); - - conn->sequence += 1; - - WSET_LH(conn->packet, 0, NCP_REQUEST); - BSET(conn->packet, 2, conn->sequence); - BSET(conn->packet, 3, (conn->i.connection) & 0xff); - BSET(conn->packet, 5, (conn->i.connection) >> 8); - BSET(conn->packet, 4, 1); - BSET(conn->packet, 6, function); - - if (conn->has_subfunction != 0) { - WSET_HL(conn->packet, 7, conn->current_size - - sizeof(struct ncp_request_header) - 2); - } - if ((err = do_ncp_call(conn, conn->current_size)) != 0) { - return err; - } - conn->completion = BVAL(conn->packet, 6); - conn->conn_status = BVAL(conn->packet, 7); - conn->ncp_reply_size = - conn->reply_size - sizeof(struct ncp_reply_header); - - if ((conn->completion != 0) && (conn->verbose != 0)) { - ncp_printf("ncp_completion_code: %d\n", conn->completion); - } - return conn->completion == 0 ? 0 : NCPL_ET_REQUEST_ERROR; -} - -static long ncp_connect_addr(struct ncp_conn *conn, const struct sockaddr_ipx *target, - int wdog_needed) -{ - struct sockaddr_ipx addr; - int addrlen; - - int ncp_sock, wdog_sock; - long err; - - conn->is_connected = NOT_CONNECTED; - conn->verbose = 0; - - if ((ncp_sock = socket(AF_IPX, SOCK_DGRAM, PF_IPX)) == -1) { - return errno; - } - if ((wdog_sock = socket(AF_IPX, SOCK_DGRAM, PF_IPX)) == -1) { - return errno; - } - addr.sipx_family = AF_IPX; - addr.sipx_port = htons(0x0); - addr.sipx_type = NCP_PTYPE; - addr.sipx_network = IPX_THIS_NET; - ipx_assign_node(addr.sipx_node, IPX_THIS_NODE); - - addrlen = sizeof(addr); - - if ((bind(ncp_sock, (struct sockaddr *) &addr, sizeof(addr)) == -1) - || (getsockname(ncp_sock, (struct sockaddr *) &addr, &addrlen) == -1)) { - int saved_errno = errno; - close(ncp_sock); - close(wdog_sock); - return saved_errno; - } - addr.sipx_port = htons(ntohs(addr.sipx_port) + 1); - - if (bind(wdog_sock, (struct sockaddr *) &addr, sizeof(addr)) == -1) { - int saved_errno = errno; - close(ncp_sock); - close(wdog_sock); - return saved_errno; - } - conn->ncp_sock = ncp_sock; - conn->wdog_sock = wdog_sock; - - conn->sequence = 0; - conn->i.addr = *target; - - WSET_LH(conn->packet, 0, NCP_ALLOC_SLOT_REQUEST); - BSET(conn->packet, 2, conn->sequence); - BSET(conn->packet, 3, 0xff); - BSET(conn->packet, 4, 1); - BSET(conn->packet, 5, 0xff); - BSET(conn->packet, 6, 0); - - if ((err = do_ncp_call(conn, sizeof(struct ncp_request_header))) != 0) { - if ((err != ENETUNREACH) - || (ipx_make_reachable(htonl(target->sipx_network)) != 0) - || ((err = - do_ncp_call(conn, - sizeof(struct ncp_request_header))) != 0)) { - close(ncp_sock); - close(wdog_sock); - return err; - } - } - if (wdog_needed != 0) { - install_wdog(conn); - } else { - conn->wdog_pid = 0; - } - - conn->sequence = 0; - conn->i.connection = - BVAL(conn->packet, 3) + (BVAL(conn->packet, 5) << 8); - conn->is_connected = CONN_TEMPORARY; - - if ((ncp_negotiate_buffersize(conn, 1024, - &(conn->i.buffer_size)) != 0) - || (conn->i.buffer_size < 512) - || (conn->i.buffer_size > 1024)) { - ncp_do_close(conn); - return -1; - } - return 0; -} - -static long ncp_connect_any(struct ncp_conn *conn, int wdog_needed) -{ - struct sockaddr_ipx addr; - char name[NCP_BINDERY_NAME_LEN]; - long result; - - if ((result = ipx_sap_find_nearest(IPX_SAP_FILE_SERVER, - &addr, name)) != 0) { - return result; - } - if ((result = ncp_connect_addr(conn, &addr, wdog_needed)) != 0) { - return result; - } - strcpy(conn->server, name); - return 0; -} - -struct sockaddr_ipx * - ncp_find_fileserver(char *server_name, long *err) -{ - return ncp_find_server(&server_name, NCP_BINDERY_FSERVER, err); -} - -struct sockaddr_ipx * - ncp_find_server(char **server_name, int type, long *err) -{ - char server[NCP_BINDERY_NAME_LEN + 1]; - static char nearest[NCP_BINDERY_NAME_LEN + 1]; - struct nw_property prop; - struct prop_net_address *n_addr = (struct prop_net_address *) ∝ - struct ncp_conn conn; - - static struct sockaddr_ipx result; - - initialize_NCPL_error_table(); - - memset(server, 0, sizeof(server)); - memset(nearest, 0, sizeof(nearest)); - - if (*server_name != NULL) { - if (strlen(*server_name) >= sizeof(server)) { - *err = NCPL_ET_NAMETOOLONG; - return NULL; - } - strcpy(server, *server_name); - str_upper(server); - } - if ((*err = ipx_sap_find_nearest(type, &result, nearest)) != 0) { - return NULL; - } - /* We have to ask the nearest server for our wanted server */ - - memzero(conn); - if ((*err = ncp_connect_addr(&conn, &result, 0)) != 0) { - return NULL; - } - if (*server_name == NULL) { - *server_name = nearest; - ncp_do_close(&conn); - errno = 0; - return &result; - } - /* The following optimization should have been done before - ncp_connect_addr. This would be convenient if there was a - simple way to find out whether there is a route to the - server. Parsing /proc/net/ipx_route is not too nice, so we - just connect to the server and immediately disconnect - again. This way we also find out if the server still has - free connection slots. */ - - if (strcmp(server, nearest) == 0) { - /* Our wanted server answered the SAP GNS request, so - use it */ - ncp_do_close(&conn); - errno = 0; - return &result; - } - if (ncp_read_property_value(&conn, type, server, 1, - "NET_ADDRESS", &prop) != 0) { - ncp_do_close(&conn); - *err = NCPL_ET_HOST_UNKNOWN; - return NULL; - } - if ((*err = ncp_do_close(&conn)) != 0) { - return NULL; - } - result.sipx_family = AF_IPX; - result.sipx_network = n_addr->network; - result.sipx_port = n_addr->port; - ipx_assign_node(result.sipx_node, n_addr->node); - - /* To make the final server reachable, we connect again. See - above. (When can we rely on all users running ipxd??? :-)) */ - memzero(conn); - if (((*err = ncp_connect_addr(&conn, &result, 0)) != 0) - || ((*err = ncp_do_close(&conn)) != 0)) { - return NULL; - } - return &result; -} - -static long ncp_open_temporary(struct ncp_conn *conn, - struct ncp_conn_spec *spec) -{ - struct sockaddr_ipx *addr; - long err; - - if (spec == NULL) { - return ncp_connect_any(conn, 1); - } - if ((addr = ncp_find_fileserver(spec->server, &err)) == NULL) { - return err; - } - if ((err = ncp_connect_addr(conn, addr, 1)) != 0) { - return err; - } - strcpy(conn->server, spec->server); - - if (strlen(spec->user) != 0) { - if (ncp_login_object(conn, spec->user, spec->login_type, - spec->password) != 0) { - ncp_do_close(conn); - return EACCES; - } - strcpy(conn->user, spec->user); - } - return 0; -} - -char * - ncp_find_permanent(const struct ncp_conn_spec *spec) -{ - FILE *mtab; - struct ncp_conn_ent *conn_ent; - char *result = NULL; - int mount_fid; - struct ncp_fs_info i; - - initialize_NCPL_error_table(); - - if ((mtab = fopen(MOUNTED, "r")) == NULL) { - return NULL; - } - while ((conn_ent = ncp_get_conn_ent(mtab)) != NULL) { - if (spec != NULL) { - if ((conn_ent->uid != spec->uid) - || ((strlen(spec->server) != 0) - && (strcasecmp(conn_ent->server, - spec->server) != 0)) - || ((strlen(spec->user) != 0) - && (strcasecmp(conn_ent->user, - spec->user) != 0))) { - continue; - } - } - mount_fid = open(conn_ent->mount_point, O_RDONLY, 0); - if (mount_fid < 0) { - continue; - } - i.version = NCP_GET_FS_INFO_VERSION; - - if (ioctl(mount_fid, NCP_IOC_GET_FS_INFO, &i) < 0) { - close(mount_fid); - continue; - } - close(mount_fid); - result = conn_ent->mount_point; - break; - } - - fclose(mtab); - errno = (result == NULL) ? ENOENT : 0; - return result; -} - -static int ncp_open_permanent(struct ncp_conn *conn, - const struct ncp_conn_spec *spec) -{ - char *mount_point; - - if (conn->is_connected != NOT_CONNECTED) { - errno = EBUSY; - return -1; - } - if ((mount_point = ncp_find_permanent(spec)) == NULL) { - return -1; - } - if (strlen(mount_point) >= sizeof(conn->mount_point)) { - errno = ENAMETOOLONG; - return -1; - } - /* The rest has already been done in ncp_find_permanent, so we - * do not check errors anymore */ - conn->mount_fid = open(mount_point, O_RDONLY, 0); - conn->i.version = NCP_GET_FS_INFO_VERSION; - ioctl(conn->mount_fid, NCP_IOC_GET_FS_INFO, &(conn->i)); - if (spec != NULL) { - strncpy(conn->server, spec->server, sizeof(conn->server)); - strncpy(conn->user, spec->user, sizeof(conn->user)); - } else { - memset(conn->server, '\0', sizeof(conn->server)); - memset(conn->user, '\0', sizeof(conn->user)); - } - strcpy(conn->mount_point, mount_point); - conn->is_connected = CONN_PERMANENT; - return 0; -} - -struct ncp_conn * - ncp_open(struct ncp_conn_spec *spec, long *err) -{ - struct ncp_conn *result; - - initialize_NCPL_error_table(); - - result = malloc(sizeof(struct ncp_conn)); - - if (result == NULL) { - *err = ENOMEM; - return NULL; - } - memzero(*result); - - if (ncp_open_permanent(result, spec) == 0) { - return result; - } - if ((*err = ncp_open_temporary(result, spec)) != 0) { - free(result); - return NULL; - } - return result; -} - - -struct ncp_conn * - ncp_open_mount(const char *mount_point, long *err) -{ - struct ncp_conn *result; - - initialize_NCPL_error_table(); - - if (strlen(mount_point) >= sizeof(result->mount_point)) { - *err = ENAMETOOLONG; - return NULL; - } - result = malloc(sizeof(struct ncp_conn)); - - if (result == NULL) { - *err = ENOMEM; - return NULL; - } - memzero(*result); - - result->is_connected = NOT_CONNECTED; - - result->mount_fid = open(mount_point, O_RDONLY, 0); - if (result->mount_fid < 0) { - free(result); - *err = ENODEV; - return NULL; - } - strcpy(result->mount_point, mount_point); - result->is_connected = CONN_PERMANENT; - - result->i.version = NCP_GET_FS_INFO_VERSION; - - if (ioctl(result->mount_fid, NCP_IOC_GET_FS_INFO, &(result->i)) != 0) { - free(result); - *err = NCPL_ET_NO_NCPFS_FILE; - return NULL; - } - return result; -} - -static long ncp_user_disconnect(struct ncp_conn *conn) -{ - long result; - - conn->sequence += 1; - - WSET_LH(conn->packet, 0, NCP_DEALLOC_SLOT_REQUEST); - BSET(conn->packet, 2, conn->sequence); - BSET(conn->packet, 3, (conn->i.connection) & 0xff); - BSET(conn->packet, 4, 1); - BSET(conn->packet, 5, (conn->i.connection) >> 8); - BSET(conn->packet, 6, 0); - - if ((result = do_ncp_call(conn, sizeof(struct ncp_request_header))) != 0) { - return result; - } - close(conn->ncp_sock); - close(conn->wdog_sock); - - if (conn->wdog_pid != 0) { - kill(conn->wdog_pid, SIGTERM); - wait(NULL); - } - return 0; -} - -static long ncp_do_close(struct ncp_conn *conn) -{ - long result = -1; - - switch (conn->is_connected) { - case CONN_PERMANENT: - result = close(conn->mount_fid); - break; - - case CONN_TEMPORARY: - result = ncp_user_disconnect(conn); - break; - - default: - break; - } - - conn->is_connected = NOT_CONNECTED; - - return result; -} - -long ncp_close(struct ncp_conn *conn) -{ - long result; - if (conn == NULL) { - return 0; - } - if ((result = ncp_do_close(conn)) != 0) { - return result; - } - free(conn); - return 0; -} - -struct ncp_conn_ent * - ncp_get_conn_ent(FILE * filep) -{ - static struct ncp_conn_ent entry; - char server[2 * NCP_BINDERY_NAME_LEN]; - char *user; - struct mntent *mnt_ent; - int fid; - - memzero(server); - memzero(entry); - - while ((mnt_ent = getmntent(filep)) != NULL) { - if (strcmp(mnt_ent->mnt_type, "ncpfs") != 0) { - continue; - } - if (strlen(mnt_ent->mnt_fsname) >= sizeof(server)) { - continue; - } - strcpy(server, mnt_ent->mnt_fsname); - user = strchr(server, '/'); - if (user != NULL) { - *user = '\0'; - user += 1; - if (strlen(user) >= sizeof(entry.user)) { - continue; - } - strcpy(entry.user, user); - } - if ((strlen(server) >= sizeof(entry.server)) - || (strlen(mnt_ent->mnt_dir) >= sizeof(entry.mount_point))) { - continue; - } - strcpy(entry.server, server); - strcpy(entry.mount_point, mnt_ent->mnt_dir); - - fid = open(entry.mount_point, O_RDONLY, 0); - - if (fid == -1) { - continue; - } - if (ioctl(fid, NCP_IOC_GETMOUNTUID, &entry.uid) != 0) { - close(fid); - continue; - } - close(fid); - return &entry; - } - - return NULL; -} - -static struct ncp_conn_spec * - ncp_get_nwc_ent(FILE * nwc) -{ - static struct ncp_conn_spec spec; - char line[512]; - int line_len; - char *user; - char *password; - - memzero(spec); - spec.uid = getuid(); - - while (fgets(line, sizeof(line), nwc) != NULL) { - if ((line[0] == '\n') - || (line[0] == '#')) { - continue; - } - line_len = strlen(line); - if (line[line_len - 1] == '\n') { - line[line_len - 1] = '\0'; - } - user = strchr(line, '/'); - password = strchr(user != NULL ? user : line, ' '); - - if (password != NULL) { - *password = '\0'; - password += 1; - } - if (user != NULL) { - *user = '\0'; - user += 1; - if (strlen(user) >= sizeof(spec.user)) { - continue; - } - strcpy(spec.user, user); - } - if (strlen(line) >= sizeof(spec.server)) { - continue; - } - strcpy(spec.server, line); - - if (password != NULL) { - while (*password == ' ') { - password += 1; - } - - if (strlen(password) >= sizeof(spec.password)) { - continue; - } - strcpy(spec.password, password); - } - return &spec; - } - return NULL; -} - -FILE * - ncp_fopen_nwc(const char *user, const char *mode, long *err) -{ - char path[MAXPATHLEN]; - char *home = NULL; - struct stat st; - - if (mode == NULL) { - mode = "r"; - } - if (user == NULL) { - home = getenv("HOME"); - } else { - struct passwd *pwd; - - if ((pwd = getpwnam(user)) != NULL) { - home = pwd->pw_dir; - } - } - - if ((home == NULL) - || (strlen(home) + sizeof(NWCLIENT) + 2 > sizeof(path))) { - *err = ENAMETOOLONG; - return NULL; - } - strcpy(path, home); - strcat(path, "/"); - strcat(path, NWCLIENT); - - if (stat(path, &st) != 0) { - *err = errno; - return NULL; - } - if ((st.st_mode & (S_IRWXO | S_IRWXG)) != 0) { - *err = NCPL_ET_INVALID_MODE; - return NULL; - } - return fopen(path, mode); -} - -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) -{ - static struct ncp_conn_spec spec; - - struct ncp_conn conn; - - FILE *nwc; - struct ncp_conn_spec *nwc_ent; - - initialize_NCPL_error_table(); - - *err = 0; - memzero(spec); - spec.uid = getuid(); - - if (server != NULL) { - if (strlen(server) >= sizeof(spec.server)) { - *err = NCPL_ET_NAMETOOLONG; - return NULL; - } - strcpy(spec.server, server); - } else { - if ((nwc = ncp_fopen_nwc(NULL, NULL, err)) == NULL) { - *err = NCPL_ET_NO_SERVER; - return NULL; - } - nwc_ent = ncp_get_nwc_ent(nwc); - fclose(nwc); - - if (nwc_ent == NULL) { - *err = NCPL_ET_NO_SPEC; - return NULL; - } - strcpy(spec.server, nwc_ent->server); - strcpy(spec.user, nwc_ent->user); - } - - str_upper(spec.server); - - if (login_necessary == 0) { - memset(spec.user, 0, sizeof(spec.user)); - memset(spec.password, 0, sizeof(spec.password)); - return &spec; - } - if (user != NULL) { - if (strlen(user) >= sizeof(spec.user)) { - *err = NCPL_ET_NAMETOOLONG; - return NULL; - } - strcpy(spec.user, user); - } - str_upper(spec.user); - spec.login_type = NCP_BINDERY_USER; - - if (ncp_open_permanent(&conn, &spec) == 0) { - ncp_do_close(&conn); - return &spec; - } - if (password != NULL) { - if (strlen(password) >= sizeof(spec.password)) { - *err = NCPL_ET_NAMETOOLONG; - return NULL; - } - strcpy(spec.password, password); - } else { - if ((nwc = ncp_fopen_nwc(NULL, NULL, err)) != NULL) { - while ((nwc_ent = ncp_get_nwc_ent(nwc)) != NULL) { - if ((strcasecmp(spec.server, - nwc_ent->server) != 0) - || ((*spec.user != '\0') - && (strcasecmp(spec.user, - nwc_ent->user) != 0))) { - continue; - } - strcpy(spec.user, nwc_ent->user); - strcpy(spec.password, nwc_ent->password); - break; - } - fclose(nwc); - } - } - - if (strlen(spec.user) == 0) { - *err = NCPL_ET_NO_USER; - return NULL; - } - if ((strlen(spec.password) == 0) && (password == NULL)) { - char *password; - if (!(isatty(0) && isatty(1))) { - return NULL; - } - printf("Logging into %s as %s\n", - spec.server, spec.user); - - password = getpass("Password: "); - if (strlen(password) > sizeof(spec.password)) { - return NULL; - } - strcpy(spec.password, password); - } else { - if (strcmp(spec.password, NWC_NOPASSWORD) == 0) { - *spec.password = '\0'; - } - } - - str_upper(spec.server); - str_upper(spec.user); - str_upper(spec.password); - return &spec; -} - -struct ncp_conn * - ncp_initialize_as(int *argc, char **argv, - int login_necessary, int login_type, long *err) -{ - char *server = NULL; - char *user = NULL; - char *password = NULL; - struct ncp_conn_spec *spec; - int i = 1; - - int get_argument(int arg_no, char **target) { - int count = 1; - - if (target != NULL) { - if (arg_no + 1 >= *argc) { - /* No argument to switch */ - errno = EINVAL; - return -1; - } - *target = argv[arg_no + 1]; - count = 2; - } - /* Delete the consumed switch from the argument list - and decrement the argument count */ - while (count + arg_no < *argc) { - argv[arg_no] = argv[arg_no + count]; - arg_no += 1; - } - *argc -= count; - return 0; - } - - initialize_NCPL_error_table(); - - *err = EINVAL; - - while (i < *argc) { - if ((argv[i][0] != '-') - || (strlen(argv[i]) != 2)) { - i += 1; - continue; - } - switch (argv[i][1]) { - case 'S': - if (get_argument(i, &server) != 0) { - return NULL; - } - continue; - case 'U': - if (get_argument(i, &user) != 0) { - return NULL; - } - continue; - case 'P': - if (get_argument(i, &password) != 0) { - return NULL; - } - continue; - case 'n': - if (get_argument(i, 0) != 0) { - return NULL; - } - password = NWC_NOPASSWORD; - continue; - } - i += 1; - } - - spec = ncp_find_conn_spec(server, user, password, login_necessary, - getuid(), err); - - if (spec == NULL) { - if (login_necessary != 0) { - return NULL; - } else { - return ncp_open(NULL, err); - } - } - spec->login_type = login_type; - - if (login_necessary == 0) { - spec->user[0] = '\0'; - } - return ncp_open(spec, err); -} - -struct ncp_conn * - ncp_initialize(int *argc, char **argv, - int login_necessary, long *err) -{ - return ncp_initialize_as(argc, argv, login_necessary, - NCP_BINDERY_USER, err); -} - -static long ncp_request(struct ncp_conn *conn, int function) -{ - switch (conn->is_connected) { - case CONN_PERMANENT: - return ncp_mount_request(conn, function); - case CONN_TEMPORARY: - return ncp_temp_request(conn, function); - default: - } - return ENOTCONN; -} - -/****************************************************************************/ -/* */ -/* Helper functions */ -/* */ -/****************************************************************************/ - -static inline int min(int a, int b) -{ - return (a < b) ? a : b; -} - -static void assert_conn_locked(struct ncp_conn *conn) -{ - if (conn->lock == 0) { - ncp_printf("ncpfs: conn not locked!\n"); - } -} - -static void ncp_add_byte(struct ncp_conn *conn, byte x) -{ - assert_conn_locked(conn); - BSET(conn->packet, conn->current_size, x); - conn->current_size += 1; - return; -} - -static void ncp_add_word_lh(struct ncp_conn *conn, word x) -{ - assert_conn_locked(conn); - WSET_LH(conn->packet, conn->current_size, x); - conn->current_size += 2; - return; -} - -static void ncp_add_dword_lh(struct ncp_conn *conn, dword x) -{ - assert_conn_locked(conn); - DSET_LH(conn->packet, conn->current_size, x); - conn->current_size += 4; - return; -} - -static void ncp_add_word_hl(struct ncp_conn *conn, word x) -{ - assert_conn_locked(conn); - WSET_HL(conn->packet, conn->current_size, x); - conn->current_size += 2; - return; -} - -static void ncp_add_dword_hl(struct ncp_conn *conn, dword x) -{ - assert_conn_locked(conn); - DSET_HL(conn->packet, conn->current_size, x); - conn->current_size += 4; - return; -} - -static void ncp_add_mem(struct ncp_conn *conn, const void *source, int size) -{ - assert_conn_locked(conn); - memcpy(&(conn->packet[conn->current_size]), source, size); - conn->current_size += size; - return; -} - -static void ncp_add_pstring(struct ncp_conn *conn, const char *s) -{ - int len = strlen(s); - assert_conn_locked(conn); - if (len > 255) { - ncp_printf("ncpfs: string too long: %s\n", s); - len = 255; - } - ncp_add_byte(conn, len); - ncp_add_mem(conn, s, len); - return; -} - -static void ncp_init_request(struct ncp_conn *conn) -{ - ncp_lock_conn(conn); - - conn->current_size = sizeof(struct ncp_request_header); - conn->has_subfunction = 0; -} - -static void ncp_init_request_s(struct ncp_conn *conn, int subfunction) -{ - ncp_init_request(conn); - ncp_add_word_lh(conn, 0); /* preliminary size */ - - ncp_add_byte(conn, subfunction); - - conn->has_subfunction = 1; -} - -static char * - ncp_reply_data(struct ncp_conn *conn, int offset) -{ - return &(conn->packet[sizeof(struct ncp_reply_header) + offset]); -} - -static byte - ncp_reply_byte(struct ncp_conn *conn, int offset) -{ - return *(byte *) (ncp_reply_data(conn, offset)); -} - -static word - ncp_reply_word_hl(struct ncp_conn *conn, int offset) -{ - return WVAL_HL(ncp_reply_data(conn, offset), 0); -} - -static word - ncp_reply_word_lh(struct ncp_conn *conn, int offset) -{ - return WVAL_LH(ncp_reply_data(conn, offset), 0); -} - -static dword - ncp_reply_dword_hl(struct ncp_conn *conn, int offset) -{ - return DVAL_HL(ncp_reply_data(conn, offset), 0); -} - -static dword - ncp_reply_dword_lh(struct ncp_conn *conn, int offset) -{ - return DVAL_LH(ncp_reply_data(conn, offset), 0); -} - -/* Here the ncp calls begin - */ - -static long ncp_negotiate_buffersize(struct ncp_conn *conn, - int size, int *target) -{ - long result; - - ncp_init_request(conn); - ncp_add_word_hl(conn, size); - - if ((result = ncp_request(conn, 33)) != 0) { - ncp_unlock_conn(conn); - return result; - } - *target = min(ncp_reply_word_hl(conn, 0), size); - - ncp_unlock_conn(conn); - return 0; -} - -/* - * target is a 8-byte buffer - */ -long ncp_get_encryption_key(struct ncp_conn *conn, - char *target) -{ - long result; - - ncp_init_request_s(conn, 23); - - if ((result = ncp_request(conn, 23)) != 0) { - ncp_unlock_conn(conn); - return result; - } - if (conn->ncp_reply_size < 8) { - ncp_printf("ncp_reply_size %d < 8\n", - conn->ncp_reply_size); - ncp_unlock_conn(conn); - return result; - } - memcpy(target, ncp_reply_data(conn, 0), 8); - ncp_unlock_conn(conn); - return 0; -} - -long ncp_get_bindery_object_id(struct ncp_conn *conn, - __u16 object_type, - const char *object_name, - struct ncp_bindery_object *target) -{ - long result; - ncp_init_request_s(conn, 53); - ncp_add_word_hl(conn, object_type); - ncp_add_pstring(conn, object_name); - - if ((result = ncp_request(conn, 23)) != 0) { - ncp_unlock_conn(conn); - return result; - } - if (conn->ncp_reply_size < 54) { - ncp_printf("ncp_reply_size %d < 54\n", - conn->ncp_reply_size); - ncp_unlock_conn(conn); - return result; - } - target->object_id = ncp_reply_dword_hl(conn, 0); - target->object_type = ncp_reply_word_hl(conn, 4); - memcpy(target->object_name, ncp_reply_data(conn, 6), 48); - ncp_unlock_conn(conn); - return 0; -} - -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) -{ - long result; - ncp_init_request_s(conn, 61); - ncp_add_word_hl(conn, object_type); - ncp_add_pstring(conn, object_name); - ncp_add_byte(conn, segment); - ncp_add_pstring(conn, prop_name); - - if ((result = ncp_request(conn, 23)) != 0) { - ncp_unlock_conn(conn); - return result; - } - memcpy(&(target->value), ncp_reply_data(conn, 0), 128); - target->more_flag = ncp_reply_byte(conn, 128); - target->property_flag = ncp_reply_byte(conn, 129); - ncp_unlock_conn(conn); - return 0; -} - -long ncp_login_encrypted(struct ncp_conn *conn, - const struct ncp_bindery_object *object, - const unsigned char *key, - const unsigned char *passwd) -{ - dword tmpID = htonl(object->object_id); - unsigned char buf[128]; - unsigned char encrypted[8]; - long result; - - shuffle((byte *) & tmpID, passwd, strlen(passwd), buf); - nw_encrypt(key, buf, encrypted); - - ncp_init_request_s(conn, 24); - ncp_add_mem(conn, encrypted, 8); - ncp_add_word_hl(conn, object->object_type); - ncp_add_pstring(conn, object->object_name); - - result = ncp_request(conn, 23); - ncp_unlock_conn(conn); - return result; -} - -long ncp_login_unencrypted(struct ncp_conn *conn, - __u16 object_type, const char *object_name, - const unsigned char *passwd) -{ - long result; - ncp_init_request_s(conn, 20); - ncp_add_word_hl(conn, object_type); - ncp_add_pstring(conn, object_name); - ncp_add_pstring(conn, passwd); - result = ncp_request(conn, 23); - ncp_unlock_conn(conn); - return result; -} - -long ncp_login_user(struct ncp_conn *conn, - const unsigned char *username, - const unsigned char *password) -{ - return ncp_login_object(conn, username, NCP_BINDERY_USER, password); -} - -static long ncp_login_object(struct ncp_conn *conn, - const unsigned char *username, - int login_type, - const unsigned char *password) -{ - long result; - unsigned char ncp_key[8]; - struct ncp_bindery_object user; - - if ((result = ncp_get_encryption_key(conn, ncp_key)) != 0) { - return ncp_login_unencrypted(conn, login_type, username, - password); - } - if ((result = ncp_get_bindery_object_id(conn, login_type, - username, &user)) != 0) { - return result; - } - if ((result = ncp_login_encrypted(conn, &user, - ncp_key, password)) != 0) { - struct nw_property p; - struct ncp_prop_login_control *l - = (struct ncp_prop_login_control *) &p; - - if (conn->completion != NCP_GRACE_PERIOD) { - return result; - } - fprintf(stderr, "Your password has expired\n"); - - if ((result = ncp_read_property_value(conn, NCP_BINDERY_USER, - username, 1, - "LOGIN_CONTROL", - &p)) == 0) { - fprintf(stderr, "You have %d login attempts left\n", - l->GraceLogins); - } - } - return 0; -} - -long ncp_get_broadcast_message(struct ncp_conn *conn, char message[256]) -{ - long result; - int length; - - ncp_init_request_s(conn, 1); - - if ((result = ncp_request(conn, 21)) != 0) { - ncp_unlock_conn(conn); - return result; - } - length = ncp_reply_byte(conn, 0); - message[length] = 0; - memcpy(message, ncp_reply_data(conn, 1), length); - ncp_unlock_conn(conn); - return 0; -} diff --git a/sutil/ncplib.h b/sutil/ncplib.h deleted file mode 100644 index f580835..0000000 --- a/sutil/ncplib.h +++ /dev/null @@ -1,280 +0,0 @@ - - -/* - * ncplib.h - * - * Copyright (C) 1995, 1996 by Volker Lendecke - * - */ - -#ifndef _NCPLIB_H -#define _NCPLIB_H - -#include -#include "ncp.h" -#include -#include -#include -#include - -#include "ipxlib.h" -#include "com_err.h" - -#ifndef memzero -#include -#define memzero(object) memset(&(object), 0, sizeof(object)) -#endif - -typedef __u8 byte; -typedef __u16 word; -typedef __u32 dword; - -#define BVAL(buf,pos) (((__u8 *)(buf))[pos]) -#define PVAL(buf,pos) ((unsigned)BVAL(buf,pos)) -#define BSET(buf,pos,val) (BVAL(buf,pos) = (val)) - -static inline word - WVAL_HL(__u8 * buf, int pos) -{ - return PVAL(buf, pos) << 8 | PVAL(buf, pos + 1); -} -static inline dword - DVAL_HL(__u8 * buf, int pos) -{ - return WVAL_HL(buf, pos) << 16 | WVAL_HL(buf, pos + 2); -} -static inline void WSET_HL(__u8 * buf, int pos, word val) -{ - BSET(buf, pos, val >> 8); - BSET(buf, pos + 1, val & 0xff); -} -static inline void DSET_HL(__u8 * buf, int pos, dword val) -{ - WSET_HL(buf, pos, val >> 16); - WSET_HL(buf, pos + 2, val & 0xffff); -} - - -/* we know that the 386 can handle misalignment and has the "right" - byteorder */ -#if defined(__i386__) - -static inline word - WVAL_LH(__u8 * buf, int pos) -{ - return *((word *) (buf + pos)); -} -static inline dword - DVAL_LH(__u8 * buf, int pos) -{ - return *((dword *) (buf + pos)); -} -static inline void WSET_LH(__u8 * buf, int pos, word val) -{ - *((word *) (buf + pos)) = val; -} -static inline void DSET_LH(__u8 * buf, int pos, dword val) -{ - *((dword *) (buf + pos)) = val; -} - -#else - -static inline word - WVAL_LH(__u8 * buf, int pos) -{ - return PVAL(buf, pos) | PVAL(buf, pos + 1) << 8; -} -static inline dword - DVAL_LH(__u8 * buf, int pos) -{ - return WVAL_LH(buf, pos) | WVAL_LH(buf, pos + 2) << 16; -} -static inline void WSET_LH(__u8 * buf, int pos, word val) -{ - BSET(buf, pos, val & 0xff); - BSET(buf, pos + 1, val >> 8); -} -static inline void DSET_LH(__u8 * buf, int pos, dword val) -{ - WSET_LH(buf, pos, val & 0xffff); - WSET_LH(buf, pos + 2, val >> 16); -} - -#endif - -void - str_upper(char *name); - -enum connect_state { - NOT_CONNECTED = 0, - CONN_PERMANENT, - CONN_TEMPORARY -}; - -struct ncp_conn { - - enum connect_state is_connected; - - char server[NCP_BINDERY_NAME_LEN]; - char user[NCP_BINDERY_NAME_LEN]; - - struct ncp_fs_info i; - - /* Fields for use with permanent connections */ - int mount_fid; - char mount_point[MAXPATHLEN]; - - /* Fields for use with temporary connections */ - int ncp_sock; - int wdog_sock; - int wdog_pid; - __u8 sequence; - int completion; - int conn_status; - int reply_size; - - /* Fields used to setup ncp requests */ - int current_size; - int has_subfunction; - int verbose; - int ncp_reply_size; - - int lock; - - char packet[NCP_PACKET_SIZE]; -}; - -struct ncp_conn_spec { - char server[NCP_BINDERY_NAME_LEN]; - char user[NCP_BINDERY_NAME_LEN]; - uid_t uid; - int login_type; /* NCP_BINDERY_USER / NCP_BINDERY_PSERVER */ - char password[NCP_BINDERY_NAME_LEN]; -}; - -struct ncp_property_info { - __u8 property_name[16]; - __u8 property_flags; - __u8 property_security; - __u32 search_instance; - __u8 value_available_flag; - __u8 more_properties_flag; -}; - -/* ncp_initialize is the main entry point for user programs which want - to connect to a NetWare Server. It looks for -S, -U, -P and -n in - the argument list, opens the connection and removes the arguments - from the list. It was designed after the X Windows init - functions. */ -struct ncp_conn * - ncp_initialize(int *argc, char **argv, - int login_necessary, long *err); - -/* You can login as another object by this procedure. As a first use - pserver comes to mind. */ -struct ncp_conn * - ncp_initialize_as(int *argc, char **argv, - int login_necessary, int login_type, long *err); - - -/* Open a connection */ -struct ncp_conn * - ncp_open(struct ncp_conn_spec *spec, long *err); - -/* Open a connection on an existing mount point */ -struct ncp_conn * - ncp_open_mount(const char *mount_point, long *err); - -/* Find a permanent connection that fits the spec, return NULL if - * there is none. */ -char * - ncp_find_permanent(const struct ncp_conn_spec *spec); - -/* Find the address of a file server */ -struct sockaddr_ipx * - ncp_find_fileserver(char *server_name, long *err); - -/* Find the address of a server */ -struct sockaddr_ipx * - ncp_find_server(char **server_name, int type, long *err); - -/* Detach from a permanent connection or destroy a temporary - connection */ -long - ncp_close(struct ncp_conn *conn); - -/* like getmntent, get_ncp_conn_ent scans /etc/mtab for usable - connections */ - -struct ncp_conn_ent { - char server[NCP_BINDERY_NAME_LEN]; - char user[NCP_BINDERY_NAME_LEN]; - uid_t uid; - char mount_point[MAXPATHLEN]; -}; - -struct ncp_conn_ent * - ncp_get_conn_ent(FILE * filep); - -#define NWCLIENT (".nwclient") -#define NWC_NOPASSWORD ("-") - -/* find an appropriate connection */ - -struct ncp_conn_spec * - ncp_find_conn_spec(const char *server, const char *user, const char *password, - int login_necessary, uid_t uid, long *err); - -long - ncp_get_encryption_key(struct ncp_conn *conn, - char *target); - -struct ncp_station_addr { - __u32 NetWork __attribute__((packed)); - __u8 Node[6] __attribute__((packed)); - __u16 Socket __attribute__((packed)); -}; - -struct ncp_prop_login_control { - __u8 AccountExpireDate[3] __attribute__((packed)); - __u8 Disabled __attribute__((packed)); - __u8 PasswordExpireDate[3] __attribute__((packed)); - __u8 GraceLogins __attribute__((packed)); - __u16 PasswordExpireInterval __attribute__((packed)); - __u8 MaxGraceLogins __attribute__((packed)); - __u8 MinPasswordLength __attribute__((packed)); - __u16 MaxConnections __attribute__((packed)); - __u8 ConnectionTimeMask[42] __attribute__((packed)); - __u8 LastLogin[6] __attribute__((packed)); - __u8 RestrictionMask __attribute__((packed)); - __u8 reserved __attribute__((packed)); - __u32 MaxDiskUsage __attribute__((packed)); - __u16 BadLoginCount __attribute__((packed)); - __u32 BadLoginCountDown __attribute__((packed)); - struct ncp_station_addr LastIntruder __attribute__((packed)); -}; - -long - ncp_read_property_value(struct ncp_conn *conn, - int object_type, const char *object_name, - int segment, const char *prop_name, - struct nw_property *target); - -#define NCP_GRACE_PERIOD (0xdf) - -long - ncp_get_bindery_object_id(struct ncp_conn *conn, - __u16 object_type, - const char *object_name, - struct ncp_bindery_object *target); - -long - ncp_login_user(struct ncp_conn *conn, - const unsigned char *username, - const unsigned char *password); - -long - ncp_get_broadcast_message(struct ncp_conn *conn, char message[256]); - -#endif /* _NCPLIB_H */ diff --git a/sutil/ncpmount.c b/sutil/ncpmount.c index 4d31620..f614922 100644 --- a/sutil/ncpmount.c +++ b/sutil/ncpmount.c @@ -36,45 +36,198 @@ extern pid_t waitpid(pid_t, int *, int); #include #include #include -#include +#include "kernel/ipx.h" #include +#ifdef MOUNT3 #include #include +#endif -#include -#include -#include -#include +#include "kernel/ncp.h" +#include "kernel/ncp_fs.h" +#include "ncpmount.h" #include "ncplib.h" #include "com_err.h" +#include "ncplib_err.h" +#ifdef NDS_SUPPORT +#include "ndslib.h" +#endif + +#if defined(MOUNT2) && defined(MOUNT3) +#define MULTIVERSION_MOUNT 1 +#else +#define MULTIVERSION_MOUNT 0 +#endif + +#if MULTIVERSION_MOUNT +#include +#endif static char *progname; static char mount_point[MAXPATHLEN + 1]; static void usage(void); static void help(void); -static int process_connection(int wdog_fd, int msg_fd); + +#ifdef MOUNT2 +/* Returns 0 if the filesystem is in the kernel after this routine + completes */ +static int +load_ncpfs(void) +{ + FILE *ffs; + char s[1024]; + char *p, *p1; + pid_t pid; + int status; + + /* Check if ncpfs is in the kernel */ + ffs = fopen("/proc/filesystems", "r"); + + if (ffs == NULL) + { + perror("Error: \"/proc/filesystems\" could not be read:"); + return -1; + } + p = NULL; + while (!feof(ffs)) + { + p1 = fgets(s, sizeof(s), ffs); + if (p1) + { + p = strstr(s, "ncpfs"); + if (p) + { + break; + } + } + } + fclose(ffs); + + if (p) + { + return 0; + } + /* system() function without signal handling, from Stevens */ + + if ((pid = fork()) < 0) + { + return 1; + } else if (pid == 0) + { + /* child */ + execl("/sbin/modprobe", "modprobe", "ncpfs", NULL); + _exit(127); /* execl error */ + } else + { + /* parent */ + while (waitpid(pid, &status, 0) < 0) + { + if (errno != EINTR) + { + status = -1; + break; + } + } + } + return status; +} +#endif /* MOUNT2 */ + +struct ncp_mount_data_independent { + int ncp_fd; + int wdog_fd; + int message_fd; + uid_t mounted_uid; + struct sockaddr_ipx serv_addr; + unsigned char *server_name; + unsigned char *mount_point; + unsigned char *mounted_vol; + unsigned int time_out; + unsigned int retry_count; + struct { + unsigned int mount_soft:1; + unsigned int mount_intr:1; + unsigned int mount_strong:1; + unsigned int mount_no_os2:1; + unsigned int mount_no_nfs:1; + } flags; + uid_t uid; + gid_t gid; + mode_t file_mode; + mode_t dir_mode; +}; + +#ifdef MOUNT3 +static int process_connection(const struct ncp_mount_data_independent* mnt); +#endif + +#if MULTIVERSION_MOUNT +int getmountver(void) { + struct utsname name; + int maj, mid; + int ver; + + if (uname(&name)) { + fprintf(stderr, "Cannot get kernel release\n"); + exit(1); + } + if (sscanf(name.release, "%d.%d", &maj, &mid) != 2) { + fprintf(stderr, "Cannot convert kernel release \"%s\" to number\n", name.release); + exit(1); + } + ver = maj*0x10000 + mid*0x100; + if (ver < 0x20100) { +#ifdef MOUNT2 + return 2; +#else + fprintf(stderr, "This kernel requires mount version 2 which is not available\n"); + exit(1); +#endif + } +#ifdef MOUNT3 + return 3; +#else + fprintf(stderr, "This kernel requires mount version 3 which is not available\n"); + exit(1); +#endif +} +#else +#ifdef MOUNT3 +#define getmountver() 3 +#else +#ifdef MOUNT2 +#define getmountver() 2 +#else +#error "You must define at least one of MOUNT2, MOUNT3" +#endif +#endif +#endif /* Check whether user is allowed to mount on the specified mount point */ -static int mount_ok(struct stat *st) +static int +mount_ok(struct stat *st) { - if (!S_ISDIR(st->st_mode)) { + if (!S_ISDIR(st->st_mode)) + { errno = ENOTDIR; return -1; } if ((getuid() != 0) && ((getuid() != st->st_uid) - || ((st->st_mode & S_IRWXU) != S_IRWXU))) { + || ((st->st_mode & S_IRWXU) != S_IRWXU))) + { errno = EPERM; return -1; } return 0; } +#ifdef MOUNT3 /* * This function changes the processes name as shown by the system. * Stolen from Marcin Dalecki's modald :-) */ -static void inststr(char *dst[], int argc, char *src) +static void inststr(char *dst[], int argc, const char *src) { /* stolen from the source to perl 4.036 (assigning to $0) */ char *ptr, *ptr2; @@ -99,17 +252,142 @@ static void inststr(char *dst[], int argc, char *src) dst[count] = NULL; } } +#endif -int main(int argc, char *argv[]) +#ifdef MOUNT2 +int ncp_mount_v2(const char* mount_name, unsigned long flags, const struct ncp_mount_data_independent* data) { + struct ncp_mount_data_v2 datav2; + + if (data->serv_addr.sipx_family != AF_IPX) { + errno = EPROTONOSUPPORT; + return -1; + } + datav2.version = NCP_MOUNT_VERSION_V2; + datav2.ncp_fd = data->ncp_fd; + datav2.wdog_fd = data->wdog_fd; + datav2.message_fd = data->message_fd; + datav2.mounted_uid = data->mounted_uid; + memcpy(&datav2.serv_addr, &data->serv_addr, sizeof(datav2.serv_addr)); + strncpy(datav2.server_name, data->server_name, sizeof(datav2.server_name)); + strncpy(datav2.mount_point, data->mount_point, sizeof(datav2.mount_point)); + strncpy(datav2.mounted_vol, data->mounted_vol, sizeof(datav2.mounted_vol)); + datav2.time_out = data->time_out; + datav2.retry_count = data->retry_count; + datav2.flags = 0; + datav2.flags |= data->flags.mount_soft?NCP_MOUNT2_SOFT:0; + datav2.flags |= data->flags.mount_intr?NCP_MOUNT2_INTR:0; + datav2.flags |= data->flags.mount_strong?NCP_MOUNT2_STRONG:0; + datav2.flags |= data->flags.mount_no_os2?NCP_MOUNT2_NO_OS2:0; + datav2.flags |= data->flags.mount_no_nfs?NCP_MOUNT2_NO_NFS:0; + datav2.uid = data->uid; + datav2.gid = data->gid; + datav2.file_mode = data->file_mode; + datav2.dir_mode = data->dir_mode; + return mount(mount_name, data->mount_point, "ncpfs", flags, (void*) &datav2); +} +#endif + +#ifdef MOUNT3 +int ncp_mount_v3(const char* mount_name, unsigned long flags, const struct ncp_mount_data_independent* data, int argc, char* argv[]) { + struct ncp_mount_data_v3 datav3; + int err; + + datav3.version = NCP_MOUNT_VERSION_V3; + datav3.ncp_fd = data->ncp_fd; + datav3.mounted_uid = data->mounted_uid; + strncpy(datav3.mounted_vol, data->mounted_vol, sizeof(datav3.mounted_vol)); + datav3.time_out = data->time_out; + datav3.retry_count = data->retry_count; + datav3.flags = 0; + datav3.flags |= data->flags.mount_soft?NCP_MOUNT3_SOFT:0; + datav3.flags |= data->flags.mount_intr?NCP_MOUNT3_INTR:0; + datav3.flags |= data->flags.mount_strong?NCP_MOUNT3_STRONG:0; + datav3.flags |= data->flags.mount_no_os2?NCP_MOUNT3_NO_OS2:0; + datav3.flags |= data->flags.mount_no_nfs?NCP_MOUNT3_NO_NFS:0; + datav3.uid = data->uid; + datav3.gid = data->gid; + datav3.file_mode = data->file_mode; + datav3.dir_mode = data->dir_mode; + connect(datav3.ncp_fd, (const struct sockaddr *)&data->serv_addr, sizeof(data->serv_addr)); + datav3.wdog_pid = fork(); + if (datav3.wdog_pid < 0) { + fprintf(stderr, "could not fork: %s\n", strerror(errno)); + exit(1); + } + if (datav3.wdog_pid == 0) { + /* Child */ + inststr(argv, argc, "ncpd"); + process_connection(data); + exit(0); /* Should not return from process_connection */ + } + err=mount(mount_name, data->mount_point, "ncpfs", flags, (void*) &datav3); + if (err) { + /* Mount unsuccesful so we have to kill daemon */ + /* If mount success, kernel kills daemon (at least in 2.1.79) */ + kill(datav3.wdog_pid, SIGTERM); + } + return err; +} +#endif + +int +ncp_mount_specific(struct ncp_conn* conn, int pathNS, const unsigned char* NWpath, int pathlen) { + int result; + +#ifdef NCP_IOC_SETROOT + { + struct ncp_setroot_ioctl sr; + + if (pathlen == 1) { + sr.volNumber = -1; + sr.namespace = -1; + sr.dirEntNum = 0; + } else { + struct nw_info_struct dirinfo; + + result = ncp_obtain_file_or_subdir_info2(conn, pathNS, NW_NS_DOS, + 0x8006, RIM_ALL, 0xFF, 0, 0, NWpath, pathlen, &dirinfo); + if (result) { + return -ENOENT; + } + if (!(dirinfo.attributes & htonl(0x10000000))) { + return -ENOTDIR; + } + sr.volNumber = dirinfo.volNumber; + sr.namespace = NW_NS_DOS; + sr.dirEntNum = dirinfo.dirEntNum; + } + result = ioctl(conn->mount_fid, NCP_IOC_SETROOT, &sr); + if (!result) { + return 0; + } + } +#endif + if ((pathlen != 1) && (*NWpath != 1)) { + fprintf(stderr, "Remote directory is specified but " +#ifdef NCP_IOC_SETROOT + "kernel" +#else + "ncpmount" +#endif + " does not support subdir mounts\n"); + return -ENOPKG; + } + if (ioctl(conn->mount_fid, NCP_IOC_CONN_LOGGED_IN, NULL) != 0) { + return -errno; + } + return 0; +} + +int +main(int argc, char *argv[]) { - struct ncp_mount_data data; + struct ncp_mount_data_independent mdata; struct stat st; char mount_name[256]; int fd, result; - int wdog_fd, msg_fd; struct sockaddr_ipx addr; - struct sockaddr_ipx *server_addr; int addrlen; int upcase_password; @@ -124,43 +402,91 @@ int main(int argc, char *argv[]) char *server = NULL; char *user = NULL; char *password = NULL; - struct ncp_conn_spec *spec; - uid_t conn_uid = getuid(); + struct ncp_conn_spec *spec; struct ncp_conn *conn; int opt; +#ifdef SIGNATURES + int sig_level = -1; +#endif +#ifdef NDS_SUPPORT + int force_bindery_login = 0; +#endif +#ifdef CONFIG_NATIVE_IP + struct sockaddr_in server_in; + const char* server_name = NULL; +#endif + + char *tmp_mount; + int allow_multiple_connections = 0; + + int mount_protocol_version = -1; + + const char* remotepath = "/"; + unsigned char NWpath[512]; + int pathlen = 1; + NWpath[0] = 0; + progname = argv[0]; - memzero(data); + memzero(mdata); memzero(spec); - if (geteuid() != 0) { + mdata.mounted_uid = getuid(); + + if (geteuid() != 0) + { fprintf(stderr, "%s must be installed suid root\n", progname); exit(1); } - data.uid = getuid(); - data.gid = getgid(); + mdata.uid = getuid(); + mdata.gid = getgid(); um = umask(0); umask(um); - data.file_mode = (S_IRWXU | S_IRWXG | S_IRWXO) & ~um; - data.dir_mode = 0; - data.flags |= NCP_MOUNT_SOFT; - data.time_out = 60; - data.retry_count = 5; + mdata.file_mode = (S_IRWXU | S_IRWXG | S_IRWXO) & ~um; + mdata.dir_mode = 0; + mdata.flags.mount_soft = 1; + mdata.flags.mount_intr = 0; + mdata.flags.mount_strong = 0; + mdata.flags.mount_no_os2 = 0; + mdata.flags.mount_no_nfs = 0; + mdata.time_out = 60; + mdata.retry_count = 5; + mdata.mounted_vol = ""; upcase_password = 1; - while ((opt = getopt(argc, argv, "CS:U:c:u:g:f:d:P:nh?vV:t:r:")) - != EOF) { - switch (opt) { + while ((opt = getopt(argc, argv, "CS:U:c:u:g:f:d:P:nh?vV:t:r:" + "sN:" +#ifdef SIGNATURES + "i:" +#endif +#ifdef NDS_SUPPORT + "b" +#endif + "m" +#ifdef MOUNT2 + "2" +#endif +#ifdef MOUNT3 + "3" +#endif +#ifdef CONFIG_NATIVE_IP + "A:" +#endif + )) != EOF) + { + switch (opt) + { case 'C': upcase_password = 0; break; case 'S': - if (strlen(optarg) >= sizeof(spec->server)) { + if (strlen(optarg) >= sizeof(spec->server)) + { fprintf(stderr, "Servername too long:%s\n", optarg); return 1; @@ -168,80 +494,97 @@ int main(int argc, char *argv[]) server = optarg; break; case 'U': - if (strlen(optarg) >= sizeof(spec->user)) { - fprintf(stderr, "Username too long: %s\n", - optarg); - return 1; - } user = optarg; break; case 'c': - if (isdigit(optarg[0])) { - conn_uid = atoi(optarg); - } else { + if (isdigit(optarg[0])) + { + mdata.mounted_uid = atoi(optarg); + } else + { struct passwd *pwd = getpwnam(optarg); - if (pwd == NULL) { + if (pwd == NULL) + { fprintf(stderr, "Unknown user: %s\n", optarg); return 1; } - data.uid = pwd->pw_uid; + mdata.mounted_uid = pwd->pw_uid; } break; case 'u': - if (isdigit(optarg[0])) { - data.uid = atoi(optarg); - } else { + if (isdigit(optarg[0])) + { + mdata.uid = atoi(optarg); + } else + { struct passwd *pwd = getpwnam(optarg); - if (pwd == NULL) { + if (pwd == NULL) + { fprintf(stderr, "Unknown user: %s\n", optarg); return 1; } - data.uid = pwd->pw_uid; + mdata.uid = pwd->pw_uid; } break; case 'g': - if (isdigit(optarg[0])) { - data.gid = atoi(optarg); - } else { + if (isdigit(optarg[0])) + { + mdata.gid = atoi(optarg); + } else + { struct group *grp = getgrnam(optarg); - if (grp == NULL) { + if (grp == NULL) + { fprintf(stderr, "Unknown group: %s\n", optarg); return 1; } - data.gid = grp->gr_gid; + mdata.gid = grp->gr_gid; } break; case 'f': - data.file_mode = strtol(optarg, NULL, 8); + mdata.file_mode = strtol(optarg, NULL, 8); break; case 'd': - data.dir_mode = strtol(optarg, NULL, 8); + mdata.dir_mode = strtol(optarg, NULL, 8); break; case 'P': - if (strlen(optarg) >= sizeof(spec->password)) { + if (strlen(optarg) >= sizeof(spec->password)) + { printf("password too long\n"); exit(1); } password = optarg; break; case 'V': - if (strlen(optarg) >= sizeof(data.mounted_vol)) { - printf("Volume too long: %s\n", optarg); + pathlen = ncp_path_to_NW_format(optarg, NWpath, sizeof(NWpath)); + remotepath = optarg; + if (pathlen < 0) { + fprintf(stderr, "Volume path invalid: %s\n", strerror(-pathlen)); exit(1); + }; + if (pathlen == 1) { + mdata.mounted_vol = ""; + remotepath = "/"; + } else if (*NWpath != 1) { + mdata.mounted_vol = "dummy"; + } else if (strlen(optarg) > NCP_VOLNAME_LEN) { + fprintf(stderr, "Volume too long: %s\n", optarg); + exit(1); + } else { + mdata.mounted_vol=optarg; } - strcpy(data.mounted_vol, optarg); break; case 'n': password = ""; break; case 't': - data.time_out = atoi(optarg); + mdata.time_out = atoi(optarg); break; case 'r': - data.retry_count = atoi(optarg); + mdata.retry_count = atoi(optarg); break; case 'h': case '?': @@ -250,112 +593,247 @@ int main(int argc, char *argv[]) case 'v': fprintf(stderr, "ncpfs version %s\n", NCPFS_VERSION); exit(1); + case 's': + mdata.flags.mount_strong = 1; + break; +#ifdef SIGNATURES + case 'i': + sig_level = atoi(optarg); + if ((sig_level < 0) || (sig_level > 3)) { + fprintf(stderr, "Invalid NCP signature level option `%s' (must be number between 0 and 3)\n", optarg); + exit(1); + } + break; +#endif +#ifdef NDS_SUPPORT + case 'b': + force_bindery_login = 1; + break; +#endif + case 'm': + allow_multiple_connections = 1; + break; +#ifdef MOUNT2 + case '2': + mount_protocol_version = 2; + break; +#endif +#ifdef MOUNT3 + case '3': + mount_protocol_version = 3; + break; +#endif +#ifdef CONFIG_NATIVE_IP + case 'A': + server_name = optarg; + break; +#endif + case 'N': + { + char *inp = optarg; + char *out; + + while ((out = strtok(inp, ",;:"))!=NULL) { + inp=NULL; + if (!strcasecmp(out, "OS2")) + mdata.flags.mount_no_os2=1; + else if (!strcasecmp(out, "LONG")) + mdata.flags.mount_no_os2=1; + else if (!strcasecmp(out, "NFS")) + mdata.flags.mount_no_nfs=1; + else { + fprintf(stderr, "Unknown namespace \"%s\"\n", out); + return 128; + } + } + }; + break; + default: usage(); return -1; } } - - if ((spec = ncp_find_conn_spec(server, user, password, - 1, data.uid, &err)) - == NULL) { + + if (mount_protocol_version < 0) { + mount_protocol_version = getmountver(); + } + if ((spec = ncp_find_conn_spec2(server, user, password, 1, mdata.uid, allow_multiple_connections, &err)) + == NULL) + { com_err(progname, err, "in find_conn_spec"); exit(1); } - if (upcase_password != 0) { + if (upcase_password != 0) + { str_upper(spec->password); } - if (optind != argc - 1) { + if (optind != argc - 1) + { usage(); return -1; } realpath(argv[optind], mount_point); - if (stat(mount_point, &st) == -1) { + if (stat(mount_point, &st) == -1) + { fprintf(stderr, "could not find mount point %s: %s\n", mount_point, strerror(errno)); exit(1); } - if (mount_ok(&st) != 0) { + if (mount_ok(&st) != 0) + { fprintf(stderr, "cannot to mount on %s: %s\n", mount_point, strerror(errno)); exit(1); } -#if NCP_MOUNT_VERSION < 3 -#error "Use Linux 2.1.29 with patch applied !!!" + +#ifdef MOUNT2 + if (mount_protocol_version < 3) { + /* Check if the ncpfs filesystem is in the kernel. If not, attempt + * to load the ncpfs module */ + if (load_ncpfs() != 0) + { + fprintf(stderr, "Error: Unable to load ncpfs, exiting...\n"); + exit(1); + } + } #endif - data.version = NCP_MOUNT_VERSION; - data.mounted_uid = conn_uid; + mdata.server_name = spec->server; - if (data.dir_mode == 0) { - data.dir_mode = data.file_mode; - if ((data.dir_mode & S_IRUSR) != 0) - data.dir_mode |= S_IXUSR; - if ((data.dir_mode & S_IRGRP) != 0) - data.dir_mode |= S_IXGRP; - if ((data.dir_mode & S_IROTH) != 0) - data.dir_mode |= S_IXOTH; + if (mdata.dir_mode == 0) + { + mdata.dir_mode = mdata.file_mode; + if ((mdata.dir_mode & S_IRUSR) != 0) + mdata.dir_mode |= S_IXUSR; + if ((mdata.dir_mode & S_IRGRP) != 0) + mdata.dir_mode |= S_IXGRP; + if ((mdata.dir_mode & S_IROTH) != 0) + mdata.dir_mode |= S_IXOTH; } - if ((server_addr = ncp_find_fileserver(spec->server, &err)) == NULL) { - com_err("ncpmount", err, "when trying to find %s", - spec->server); - exit(1); - } - data.ncp_fd = socket(AF_IPX, SOCK_DGRAM, PF_IPX); - if (data.ncp_fd == -1) { - com_err("ncpmount", err, "opening ncp_socket"); - exit(1); - } - wdog_fd = socket(AF_IPX, SOCK_DGRAM, PF_IPX); - if (wdog_fd == -1) { - fprintf(stderr, "could not open wdog socket: %s\n", - strerror(errno)); - exit(1); - } - memzero(addr); - addr.sipx_type = NCP_PTYPE; +#ifdef CONFIG_NATIVE_IP + if (server_name) { + struct hostent* h; - if (bind(data.ncp_fd, (struct sockaddr *) &addr, sizeof(addr)) == -1) { + h = gethostbyname(server_name); + if (!h) { + fprintf(stderr, "Get host address `%s': ", server_name); + herror(NULL); + return 1; + } + if (h->h_addrtype != AF_INET) { + fprintf(stderr, "Get host address `%s': Not AF_INET\n", server_name); + return 1; + } + if (h->h_length != 4) { + fprintf(stderr, "Get host address `%s': Bad address length\n", server_name); + return 1; + } + server_in.sin_family = h->h_addrtype; + memcpy(&server_in.sin_addr.s_addr, h->h_addr, 4); + server_in.sin_port = htons(0x020C); + memcpy(&mdata.serv_addr, &server_in, sizeof(server_in)); + } else +#endif /* CONFIG_NATIVE_IP */ + { + if ((!allow_multiple_connections)&& + ((tmp_mount = ncp_find_permanent(spec)) != NULL)) + { + fprintf(stderr, + "You already have mounted server %s\nas user " + "%s\non mount point %s\n", spec->server, spec->user, + tmp_mount); + exit(1); + } + if ((err = ncp_find_fileserver(spec->server, (struct sockaddr*)&mdata.serv_addr, sizeof(mdata.serv_addr))) != 0) + { + com_err("ncpmount", err, "when trying to find %s", + spec->server); + exit(1); + } + } + +#ifdef CONFIG_NATIVE_IP + if (mdata.serv_addr.sipx_family == AF_INET) { + mdata.ncp_fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP); + if (mdata.ncp_fd == -1) { + com_err("ncpmount", err, "opening ncp_socket"); + exit(1); + } + mdata.wdog_fd = -1; + mdata.message_fd = -1; + memzero(addr); + addr.sipx_family = AF_INET; + } else +#endif + { + mdata.ncp_fd = socket(AF_IPX, SOCK_DGRAM, PF_IPX); + if (mdata.ncp_fd == -1) + { + com_err("ncpmount", err, "opening ncp_socket"); + exit(1); + } + mdata.wdog_fd = socket(AF_IPX, SOCK_DGRAM, PF_IPX); + if (mdata.wdog_fd == -1) + { + fprintf(stderr, "could not open wdog socket: %s\n", + strerror(errno)); + exit(1); + } + memzero(addr); + addr.sipx_family = AF_IPX; + addr.sipx_type = NCP_PTYPE; + } + if (bind(mdata.ncp_fd, (struct sockaddr *) &addr, sizeof(addr)) == -1) + { fprintf(stderr, "\nbind: %s\n", strerror(errno)); fprintf(stderr, "\nMaybe you want to use \n" - "ipx_configure --auto_interface=on --auto_primary=on\n" + "ipx_configure --auto_interface=on --auto_primary=on\n" "and try again after waiting a minute.\n\n"); exit(1); } - addrlen = sizeof(addr); - if (getsockname(data.ncp_fd, - (struct sockaddr *) &addr, &addrlen) == -1) { - perror("getsockname ncp socket"); - close(data.ncp_fd); - close(wdog_fd); - exit(1); - } - addr.sipx_port = htons(ntohs(addr.sipx_port) + 1); + if (mdata.serv_addr.sipx_family == AF_IPX) { + addrlen = sizeof(addr); - if (bind(wdog_fd, (struct sockaddr *) &addr, sizeof(addr)) == -1) { - fprintf(stderr, "bind(wdog_sock, ): %s\n", - strerror(errno)); - exit(1); - } - msg_fd = socket(AF_IPX, SOCK_DGRAM, PF_IPX); - if (msg_fd == -1) { - fprintf(stderr, "could not open message socket: %s\n", - strerror(errno)); - exit(1); - } - addr.sipx_port = htons(ntohs(addr.sipx_port) + 1); + if (getsockname(mdata.ncp_fd, (struct sockaddr *) &addr, &addrlen) == -1) + { + perror("getsockname ncp socket"); + close(mdata.ncp_fd); + close(mdata.wdog_fd); + exit(1); + } + addr.sipx_port = htons(ntohs(addr.sipx_port) + 1); + + if (bind(mdata.wdog_fd, (struct sockaddr *) &addr, sizeof(addr)) == -1) + { + fprintf(stderr, "bind(wdog_sock, ): %s\n", + strerror(errno)); + exit(1); + } +#if 1 - if (bind(msg_fd, (struct sockaddr *) &addr, sizeof(addr)) == -1) { - fprintf(stderr, "bind(message_sock, ): %s\n", - strerror(errno)); - exit(1); + mdata.message_fd = socket(AF_IPX, SOCK_DGRAM, PF_IPX); + if (mdata.message_fd == -1) + { + fprintf(stderr, "could not open message socket: %s\n", + strerror(errno)); + exit(1); + } + addr.sipx_port = htons(ntohs(addr.sipx_port) + 1); + + if (bind(mdata.message_fd, (struct sockaddr *) &addr, sizeof(addr)) == -1) + { + fprintf(stderr, "bind(message_sock, ): %s\n", + strerror(errno)); + exit(1); + } +#endif } - connect(data.ncp_fd, - (struct sockaddr *) server_addr, sizeof(*server_addr)); + mdata.mount_point = mount_point; flags = MS_MGC_VAL; @@ -363,33 +841,86 @@ int main(int argc, char *argv[]) strcat(mount_name, "/"); strcat(mount_name, spec->user); - data.wdog_pid = fork(); - if (data.wdog_pid < 0) { - fprintf(stderr, "could not fork: %s\n", strerror(errno)); + switch (mount_protocol_version) { +#ifdef MOUNT2 + case 2: + result = ncp_mount_v2(mount_name, flags, &mdata); + break; +#endif +#ifdef MOUNT3 + case 3: + result = ncp_mount_v3(mount_name, flags, &mdata, argc, argv); + break; +#endif + default: + fprintf(stderr, "Unsupported mount protocol version %d\n", mount_protocol_version); + exit(2); + } + if (result < 0) + { + com_err("ncpmount", errno, "in mount(2)"); exit(1); } - if (data.wdog_pid == 0) { - /* Child */ - inststr(argv, argc, "ncpd"); - process_connection(wdog_fd, msg_fd); - } - result = mount(mount_name, mount_point, "ncpfs", flags, (char *) &data); - - if (result < 0) { - printf("mount failed\n"); - exit(1); - } - if ((conn = ncp_open_mount(mount_point, &err)) == NULL) { + if ((err = ncp_open_mount(mount_point, &conn)) != 0) + { com_err("ncpmount", err, "attempt to open mount point"); umount(mount_point); exit(1); } - if ((err = ncp_login_user(conn, spec->user, spec->password)) != 0) { +#ifdef SIGNATURES + if (sig_level >= 0) { + int err = 0; + + err = ncp_renegotiate_connparam(conn, conn->i.buffer_size, (sig_level > 1)? 2:0); +#if 0 + if (conn->sign_wanted) { + if (sig_level < 2) { + err = ncp_renegotiate_connparam(conn, conn->i.buffer_size, 0); + } + } else { + if (sig_level >= 2) { + err = ncp_renegotiate_connparam(conn, conn->i.buffer_size, 2); + } + } +#endif + if (err || ((sig_level == 0) && (conn->sign_wanted)) + || ((sig_level == 3) && (!conn->sign_wanted))) { + fprintf(stderr, "Unable to negotiate requested security level\n"); + umount(mount_point); + exit(1); + } + } +#endif +#ifdef NDS_SUPPORT + if ((!force_bindery_login) && (!nds_get_tree_name(conn, NULL, 0))) + { + if ((err = nds_login_auth(conn, spec->user, spec->password))) + { + if ((err != NCPL_ET_REQUEST_ERROR) || + (conn->completion != NDS_GRACE_PERIOD)) { + com_err("ncpmount", err, "in nds login"); + if (err == NCPL_ET_REQUEST_ERROR) + fprintf(stderr, "NDS error code %d.\n", + conn->completion); + fprintf(stderr, "Login denied.\n"); + ncp_close(conn); + umount(mount_point); + exit(1); + } + fprintf(stderr, "Your password has expired\n"); + } + } + else + { +#endif + if ((err = ncp_login_user(conn, spec->user, spec->password)) != 0) + { struct nw_property p; struct ncp_prop_login_control *l = (struct ncp_prop_login_control *) &p; - if (conn->completion != NCP_GRACE_PERIOD) { + if (conn->completion != NCP_GRACE_PERIOD) + { com_err("ncpmount", err, "in login"); fprintf(stderr, "Login denied\n"); ncp_close(conn); @@ -400,13 +931,18 @@ int main(int argc, char *argv[]) if ((err = ncp_read_property_value(conn, NCP_BINDERY_USER, spec->user, 1, - "LOGIN_CONTROL", &p)) == 0) { + "LOGIN_CONTROL", &p)) == 0) + { fprintf(stderr, "You have %d login attempts left\n", l->GraceLogins); } } - if ((err = ioctl(conn->mount_fid, NCP_IOC_CONN_LOGGED_IN, NULL)) != 0) { - com_err("ncpmount", err, "in logged_indication"); +#ifdef NDS_SUPPORT + } +#endif + if ((err = ncp_mount_specific(conn, NW_NS_DOS, NWpath, pathlen)) != 0) + { + fprintf(stderr, "Cannot access path \"%s\": %s\n", remotepath, strerror(-err)); ncp_close(conn); umount(mount_point); exit(1); @@ -420,27 +956,32 @@ int main(int argc, char *argv[]) ment.mnt_freq = 0; ment.mnt_passno = 0; - if ((fd = open(MOUNTED "~", O_RDWR | O_CREAT | O_EXCL, 0600)) == -1) { + if ((fd = open(MOUNTED "~", O_RDWR | O_CREAT | O_EXCL, 0600)) == -1) + { fprintf(stderr, "Can't get " MOUNTED "~ lock file"); exit(1); } close(fd); - if ((mtab = setmntent(MOUNTED, "a+")) == NULL) { + if ((mtab = setmntent(MOUNTED, "a+")) == NULL) + { fprintf(stderr, "Can't open " MOUNTED); exit(1); } - if (addmntent(mtab, &ment) == 1) { + if (addmntent(mtab, &ment) == 1) + { fprintf(stderr, "Can't write mount entry"); exit(1); } - if (fchmod(fileno(mtab), 0644) == -1) { + if (fchmod(fileno(mtab), 0644) == -1) + { fprintf(stderr, "Can't set perms on " MOUNTED); exit(1); } endmntent(mtab); - if (unlink(MOUNTED "~") == -1) { + if (unlink(MOUNTED "~") == -1) + { fprintf(stderr, "Can't remove " MOUNTED "~"); exit(1); } @@ -453,7 +994,8 @@ static void usage(void) printf("Try `%s -h' for more information\n", progname); } -static void help(void) +static void +help(void) { printf("\n"); printf("usage: %s [options] mount-point\n", progname); @@ -463,9 +1005,9 @@ static void help(void) "-V volume Volume to mount, for NFS re-export\n" "-u uid uid the mounted files get\n" "-g gid gid the mounted files get\n" - "-f mode permission the files get (octal notation)\n" + "-f mode permission the files get (octal notation)\n" "-d mode permission the dirs get (octal notation)\n" - "-c uid uid to identify the connection to mount on\n" + "-c uid uid to identify the connection to mount on\n" " Only makes sense for root\n" "-t time_out Waiting time (in 1/100s) to wait for\n" " an answer from the server. Default: 60\n" @@ -475,18 +1017,30 @@ static void help(void) "-n Do not use any password\n" " If neither -P nor -n are given, you are\n" " asked for a password.\n" + "-s Enable renaming/deletion of read-only files\n" "-h print this help text\n" "-v print ncpfs version number\n" +#ifdef NDS_SUPPORT + "-b Force bindery login to NDS servers\n" +#endif +#ifdef SIGNATURES + "-i level Signature level, 0=never, 1=supported, 2=preferred, 3=required\n" +#endif + "-m Allow multiple logins to server\n" + "-N os2,nfs Do not use specified namespaces on mounted volume\n" "\n"); } +#ifdef MOUNT3 + /* 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) +static int +term_chk (char *tty, int *msgsokP, time_t * atimeP, int *showerror) { struct stat s; char path[MAXPATHLEN]; @@ -514,51 +1068,57 @@ static int term_chk(char *tty, int *msgsokP, time_t * atimeP, int *showerror) * Special case for writing to yourself - ignore the terminal you're * writing from, unless that's the only terminal with messages enabled. */ -static int search_utmp(char *user, char *tty) +static int +search_utmp (char *user, char *tty) { struct utmp u; time_t bestatime, atime; int ufd, nloggedttys, nttys, msgsok, user_is_me; - char atty[sizeof(u.ut_line) + 1]; + char atty[sizeof (u.ut_line) + 1]; - if ((ufd = open(_PATH_UTMP, O_RDONLY)) < 0) { - perror("utmp"); + 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) { + 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'; + (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 (term_chk (atty, &msgsok, &atime, 0)) + continue; /* bad term? skip */ if (!msgsok) - continue; /* skip ttys with msgs off */ + continue; /* skip ttys with msgs off */ if (u.ut_type != USER_PROCESS) - continue; /* it's not a valid entry */ + continue; /* it's not a valid entry */ ++nttys; - if (atime > bestatime) { + if (atime > bestatime) + { bestatime = atime; - (void) strcpy(tty, atty); + (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; + } + (void) close (ufd); + if (nloggedttys == 0) + { + (void) fprintf (stderr, "write: %s is not logged in\n", user); + return -1; + } + return 0; } -static void msg_received(void) +static void +msg_received (void) { struct ncp_conn *conn; char message[256]; @@ -571,9 +1131,9 @@ static void msg_received(void) struct mntent *mnt; long err; - openlog("nwmsg", LOG_PID, LOG_LPR); + openlog ("nwmsg", LOG_PID, LOG_LPR); - if ((conn = ncp_open_mount(mount_point, &err)) == NULL) { + if ((err = ncp_open_mount(mount_point, &conn)) != 0) { return; } if (ncp_get_broadcast_message(conn, message) != 0) { @@ -630,27 +1190,46 @@ static void msg_received(void) return; } -static void process_msg_packet(int msg_fd) +/* MSG_DONTWAIT defined and module can run only on 2.1.x kernel */ +#if defined(MSG_DONTWAIT) && !defined(MOUNT2) +#define recvfrom_notm(fd,buf,ln,sender,addrlen) recvfrom(fd,buf,ln,MSG_DONTWAIT,sender,addrlen) +#else +int recvfrom_notm(int fd, void* buf, size_t len, struct sockaddr* sender, size_t* addrlen) { + int ret; + int flg; + + flg = fcntl(fd, F_GETFL); + if (flg == -1) return -1; + fcntl(fd, F_SETFL, flg | O_NONBLOCK); + ret = recvfrom(fd, buf, len, 0, sender, addrlen); + fcntl(fd, F_SETFL, flg); + return ret; +} +#endif + +static void +process_msg_packet (int msg_fd) { struct sockaddr_ipx sender; int addrlen = sizeof(sender); char buf[1024]; - if (recvfrom(msg_fd, buf, sizeof(buf), MSG_DONTWAIT, + if (recvfrom_notm(msg_fd, buf, sizeof(buf), (struct sockaddr *) &sender, &addrlen) <= 0) { return; } msg_received(); } -static void process_wdog_packet(int wdog_fd) +static void +process_wdog_packet (int wdog_fd) { struct sockaddr_ipx sender; int addrlen = sizeof(sender); char buf[2]; - if (recvfrom(wdog_fd, buf, sizeof(buf), MSG_DONTWAIT, - (struct sockaddr *) &sender, &addrlen) < sizeof(buf)) { + if (recvfrom_notm(wdog_fd, buf, sizeof(buf), + (struct sockaddr *) &sender, &addrlen) < (int)sizeof(buf)) { return; } if (buf[1] != '?') { @@ -660,14 +1239,48 @@ static void process_wdog_packet(int wdog_fd) sendto(wdog_fd, buf, 2, 0, (struct sockaddr *) &sender, addrlen); } -static int process_connection(int wdog_fd, int msg_fd) +static int +process_connection (const struct ncp_mount_data_independent* mnt) { int i; int result; int max; + int wdog_fd = mnt->wdog_fd; + int msg_fd = mnt->message_fd; chdir("/"); setsid(); + +#ifdef CONFIG_NATIVE_IP + if (wdog_fd == -1) { + unsigned char buf[]={0x3E, 0x3E, 0, 0, 0, 0, 0, 0, 0, 'Y'}; + struct ncp_fs_info fsinfo; + int fd, err; + int ncp_fd = mnt->ncp_fd; + + for (i = 0; i < NR_OPEN; i++) { + if (i == ncp_fd) continue; + close(i); + } + /* we sleep here because of mount(2) must have enough time to run */ + sleep(180); /* 3 min. */ + fd = open(mnt->mount_point, O_RDONLY); + if (fd < 0) return 1; /* Give up */ + fsinfo.version = NCP_GET_FS_INFO_VERSION; + err = ioctl(fd, NCP_IOC_GET_FS_INFO, &fsinfo); + close(fd); + if (err) return 1; /* Give up */ + buf[3] = buf[8] = fsinfo.connection&0xFF; + buf[5] = buf[7] = (fsinfo.connection>>8)&0xFF; + + while (1) { + send(ncp_fd, buf, sizeof(buf), 0); + sleep(180); /* 3 min. */ + } + return 0; + } +#endif + for (i = 0; i < NR_OPEN; i++) { if ((i == wdog_fd) || (i == msg_fd)) { continue; @@ -694,4 +1307,7 @@ static int process_connection(int wdog_fd, int msg_fd) process_msg_packet(msg_fd); } } + return 0; } + +#endif diff --git a/sutil/ncpmount.h b/sutil/ncpmount.h new file mode 100644 index 0000000..a12df9e --- /dev/null +++ b/sutil/ncpmount.h @@ -0,0 +1,76 @@ +/* + * ncp_mount.h + * + * Copyright (C) 1995, 1996 by Volker Lendecke + * + */ + +#ifndef __NCPMOUNT_H__ +#define __NCPMOUNT_H__ + +#include "ncp.h" + +#define NCP_MOUNT_VERSION_V2 2 + +/* Values for flags */ +#define NCP_MOUNT2_SOFT 0x0001 +#define NCP_MOUNT2_INTR 0x0002 +#define NCP_MOUNT2_STRONG 0x0004 +#define NCP_MOUNT2_NO_OS2 0x0008 +#define NCP_MOUNT2_NO_NFS 0x0010 + +#define PATH_MAX_V20 1024 /* PATH_MAX for 2.0 kernel */ + +struct ncp_mount_data_v2 { + int version; + unsigned int ncp_fd; /* The socket to the ncp port */ + unsigned int wdog_fd; /* Watchdog packets come here */ + unsigned int message_fd; /* Message notifications come here */ + __ker20_uid_t mounted_uid; /* Who may umount() this filesystem? */ + + struct sockaddr_ipx serv_addr; + unsigned char server_name[NCP_BINDERY_NAME_LEN]; + + unsigned char mount_point[PATH_MAX_V20+1]; + unsigned char mounted_vol[NCP_VOLNAME_LEN+1]; + + unsigned int time_out; /* How long should I wait after + sending a NCP request? */ + unsigned int retry_count; /* And how often should I retry? */ + unsigned int flags; + + __ker20_uid_t uid; + __ker20_gid_t gid; + __ker20_mode_t file_mode; + __ker20_mode_t dir_mode; +}; + +#define NCP_MOUNT_VERSION_V3 3 + +/* Values for flags */ +#define NCP_MOUNT3_SOFT 0x0001 +#define NCP_MOUNT3_INTR 0x0002 +#define NCP_MOUNT3_STRONG 0x0004 +#define NCP_MOUNT3_NO_OS2 0x0008 +#define NCP_MOUNT3_NO_NFS 0x0010 + +struct ncp_mount_data_v3 { + int version; + unsigned int ncp_fd; /* The socket to the ncp port */ + __ker21_uid_t mounted_uid; /* Who may umount() this filesystem? */ + __ker21_pid_t wdog_pid; /* Who cares for our watchdog packets? */ + + unsigned char mounted_vol[NCP_VOLNAME_LEN + 1]; + unsigned int time_out; /* How long should I wait after + sending a NCP request? */ + unsigned int retry_count; /* And how often should I retry? */ + unsigned int flags; + + __ker21_uid_t uid; + __ker21_gid_t gid; + __ker21_mode_t file_mode; + __ker21_mode_t dir_mode; +}; + +#endif /* __NCPMOUNT_H__ */ + diff --git a/sutil/ncpumount.c b/sutil/ncpumount.c index ba5bfb2..1d59847 100644 --- a/sutil/ncpumount.c +++ b/sutil/ncpumount.c @@ -16,7 +16,7 @@ #include #include #include - /* #include *//* generates a warning here */ +/* #include */ /* generates a warning here */ extern pid_t waitpid(pid_t, int *, int); #include #include @@ -27,36 +27,37 @@ extern pid_t waitpid(pid_t, int *, int); #include #include -#include -#include -#include -#include -#include +#include "ncplib.h" static char *progname; -static void usage(void) +static void +usage(void) { printf("usage: %s mount-point\n", progname); } -static int umount_ok(const char *mount_point) +static int +umount_ok(const char *mount_point) { int fid = open(mount_point, O_RDONLY, 0); uid_t mount_uid; - if (fid == -1) { + if (fid == -1) + { fprintf(stderr, "Could not open %s: %s\n", mount_point, strerror(errno)); return -1; } - if (ioctl(fid, NCP_IOC_GETMOUNTUID, &mount_uid) != 0) { + if (ncp_get_mount_uid(fid, &mount_uid) != 0) + { fprintf(stderr, "%s probably not ncp-filesystem\n", mount_point); return -1; } if ((getuid() != 0) - && (mount_uid != getuid())) { + && (mount_uid != getuid())) + { fprintf(stderr, "You are not allowed to umount %s\n", mount_point); return -1; @@ -71,7 +72,7 @@ static int umount_ok(const char *mount_point) is not a legal pathname for ``/dev/fd0.'' Anything we cannot parse we return unmodified. */ char * - canonicalize(const char *path) +canonicalize(const char *path) { char *canonical = malloc(PATH_MAX + 1); @@ -81,7 +82,8 @@ char * if (realpath(path, canonical)) return canonical; - if (strlen(path) > PATH_MAX) { + if (strlen(path) > PATH_MAX) + { return NULL; } strcpy(canonical, path); @@ -89,7 +91,8 @@ char * } -int main(int argc, char *argv[]) +int +main(int argc, char *argv[]) { int fd; @@ -101,70 +104,83 @@ int main(int argc, char *argv[]) progname = argv[0]; - if (geteuid() != 0) { + if (geteuid() != 0) + { fprintf(stderr, "%s must be installed suid root\n", progname); exit(1); } - if (argc != 2) { + if (argc != 2) + { usage(); exit(1); } mount_point = canonicalize(argv[1]); - if (mount_point == NULL) { + if (mount_point == NULL) + { fprintf(stderr, "Invalid mount point: %s\n", argv[1]); exit(1); } - if (umount_ok(mount_point) != 0) { + if (umount_ok(mount_point) != 0) + { fprintf(stderr, "You are not allowed to umount %s\n", mount_point); exit(1); } - if (umount(mount_point) != 0) { + if (umount(mount_point) != 0) + { fprintf(stderr, "Could not umount %s: %s\n", mount_point, strerror(errno)); exit(1); } - if ((fd = open(MOUNTED "~", O_RDWR | O_CREAT | O_EXCL, 0600)) == -1) { + if ((fd = open(MOUNTED "~", O_RDWR | O_CREAT | O_EXCL, 0600)) == -1) + { fprintf(stderr, "Can't get " MOUNTED "~ lock file"); return 1; } close(fd); - if ((mtab = setmntent(MOUNTED, "r")) == NULL) { + if ((mtab = setmntent(MOUNTED, "r")) == NULL) + { fprintf(stderr, "Can't open " MOUNTED ": %s\n", strerror(errno)); return 1; } #define MOUNTED_TMP MOUNTED".tmp" - if ((new_mtab = setmntent(MOUNTED_TMP, "w")) == NULL) { + if ((new_mtab = setmntent(MOUNTED_TMP, "w")) == NULL) + { fprintf(stderr, "Can't open " MOUNTED_TMP ": %s\n", strerror(errno)); endmntent(mtab); return 1; } - while ((mnt = getmntent(mtab)) != NULL) { - if (strcmp(mnt->mnt_dir, mount_point) != 0) { + while ((mnt = getmntent(mtab)) != NULL) + { + if (strcmp(mnt->mnt_dir, mount_point) != 0) + { addmntent(new_mtab, mnt); } } endmntent(mtab); - if (fchmod(fileno(new_mtab), S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH) < 0) { + if (fchmod(fileno(new_mtab), S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH) < 0) + { fprintf(stderr, "Error changing mode of %s: %s\n", MOUNTED_TMP, strerror(errno)); exit(1); } endmntent(new_mtab); - if (rename(MOUNTED_TMP, MOUNTED) < 0) { + if (rename(MOUNTED_TMP, MOUNTED) < 0) + { fprintf(stderr, "Cannot rename %s to %s: %s\n", MOUNTED, MOUNTED_TMP, strerror(errno)); exit(1); } - if (unlink(MOUNTED "~") == -1) { + if (unlink(MOUNTED "~") == -1) + { fprintf(stderr, "Can't remove " MOUNTED "~"); return 1; } diff --git a/sutil/nwcrypt.c b/sutil/nwcrypt.c deleted file mode 100644 index a0474e1..0000000 --- a/sutil/nwcrypt.c +++ /dev/null @@ -1,198 +0,0 @@ -/*$********************************************************* - $* - $* This code has been taken from DDJ 11/93, from an - $* article by Pawel Szczerbina. - $* - $* Password encryption routines follow. - $* Converted to C from Barry Nance's Pascal - $* prog published in the March -93 issue of Byte. - $* - $* Adapted to be useable for ncpfs by - $* Volker Lendecke in - $* October 1995. - $* - $********************************************************* */ - -/**************************************************************************** - -I read that Novell is not very open when it comes to technical details -of the Netware Core Protocol. This might be especially true for the -encryption stuff. I took the necessary code from Dr. Dobb's Journal -11/93, Undocumented Corner. I asked Jon Erickson about -the legal status of this piece of code: - - ---- -Date: Thu, 12 Oct 1995 13:44:18 +0100 -From: Volker Lendecke -To: jon@ddj.com -Subject: legal status of your source code? - - -Hello! - -I hope that you're the right one to write to, you are the first on your WWW -server. If you are not, could you please forward this message to the right -person? Thanks. - -I'm currently exploring the possibility to write a free (in the GNU GPL -sense) NCP filesystem, which would allow me to access a novell server -transparently. For that I would like to use the encryption functions you -published in DDJ 11/93, Undocumented Corner. I would make some cosmetic -changes, such as other indentations, minor code changes and so on. But I do -not know if that allows me to publish this code under GPL. One alternative -would be to publish a diff against your listing, but that would probably -contain much of your code as well, and it would be very inconvenient for -the average user. - -I think that you have some kind of standard procedure for such a -case. Please tell me what I should do. - -Many thanks in advance, - - Volker - - +=================================================================+ - ! Volker Lendecke Internet: lendecke@namu01.gwdg.de ! - ! D-37081 Goettingen, Germany ! - +=================================================================+ - --- - - -I got the following answer: - ---- -From: Jon Erickson -X-Mailer: SCO System V Mail (version 3.2) -To: lendecke@namu01.gwdg.de -Subject: Re: legal status of your source code? -Date: Thu, 12 Oct 95 5:42:56 PDT - -Volker, -Code from Dr. Dobb's Journal related articles is provided for -anyone to use. Clearly, the author of the article should be -given credit. -Jon Erickson - ---- - -With this answer in mind, I took the code and made it a bit more -C-like. The original seemed to be translated by a mechanical pascal->c -translator. Jon's answer encouraged me to publish nwcrypt.c under the -GPL. If anybody who knows more about copyright and sees any problems -with this, please tell me. -****************************************************************************/ - -/******************* Data types ***************************/ -typedef unsigned char buf32[32]; -typedef unsigned char buf16[16]; -typedef unsigned char buf8[8]; -typedef unsigned char buf4[4]; - -static unsigned char encrypttable[256] = -{0x7, 0x8, 0x0, 0x8, 0x6, 0x4, 0xE, 0x4, 0x5, 0xC, 0x1, 0x7, 0xB, 0xF, 0xA, 0x8, - 0xF, 0x8, 0xC, 0xC, 0x9, 0x4, 0x1, 0xE, 0x4, 0x6, 0x2, 0x4, 0x0, 0xA, 0xB, 0x9, - 0x2, 0xF, 0xB, 0x1, 0xD, 0x2, 0x1, 0x9, 0x5, 0xE, 0x7, 0x0, 0x0, 0x2, 0x6, 0x6, - 0x0, 0x7, 0x3, 0x8, 0x2, 0x9, 0x3, 0xF, 0x7, 0xF, 0xC, 0xF, 0x6, 0x4, 0xA, 0x0, - 0x2, 0x3, 0xA, 0xB, 0xD, 0x8, 0x3, 0xA, 0x1, 0x7, 0xC, 0xF, 0x1, 0x8, 0x9, 0xD, - 0x9, 0x1, 0x9, 0x4, 0xE, 0x4, 0xC, 0x5, 0x5, 0xC, 0x8, 0xB, 0x2, 0x3, 0x9, 0xE, - 0x7, 0x7, 0x6, 0x9, 0xE, 0xF, 0xC, 0x8, 0xD, 0x1, 0xA, 0x6, 0xE, 0xD, 0x0, 0x7, - 0x7, 0xA, 0x0, 0x1, 0xF, 0x5, 0x4, 0xB, 0x7, 0xB, 0xE, 0xC, 0x9, 0x5, 0xD, 0x1, - 0xB, 0xD, 0x1, 0x3, 0x5, 0xD, 0xE, 0x6, 0x3, 0x0, 0xB, 0xB, 0xF, 0x3, 0x6, 0x4, - 0x9, 0xD, 0xA, 0x3, 0x1, 0x4, 0x9, 0x4, 0x8, 0x3, 0xB, 0xE, 0x5, 0x0, 0x5, 0x2, - 0xC, 0xB, 0xD, 0x5, 0xD, 0x5, 0xD, 0x2, 0xD, 0x9, 0xA, 0xC, 0xA, 0x0, 0xB, 0x3, - 0x5, 0x3, 0x6, 0x9, 0x5, 0x1, 0xE, 0xE, 0x0, 0xE, 0x8, 0x2, 0xD, 0x2, 0x2, 0x0, - 0x4, 0xF, 0x8, 0x5, 0x9, 0x6, 0x8, 0x6, 0xB, 0xA, 0xB, 0xF, 0x0, 0x7, 0x2, 0x8, - 0xC, 0x7, 0x3, 0xA, 0x1, 0x4, 0x2, 0x5, 0xF, 0x7, 0xA, 0xC, 0xE, 0x5, 0x9, 0x3, - 0xE, 0x7, 0x1, 0x2, 0xE, 0x1, 0xF, 0x4, 0xA, 0x6, 0xC, 0x6, 0xF, 0x4, 0x3, 0x0, - 0xC, 0x0, 0x3, 0x6, 0xF, 0x8, 0x7, 0xB, 0x2, 0xD, 0xC, 0x6, 0xA, 0xA, 0x8, 0xD}; - -static buf32 encryptkeys = -{0x48, 0x93, 0x46, 0x67, 0x98, 0x3D, 0xE6, 0x8D, - 0xB7, 0x10, 0x7A, 0x26, 0x5A, 0xB9, 0xB1, 0x35, - 0x6B, 0x0F, 0xD5, 0x70, 0xAE, 0xFB, 0xAD, 0x11, - 0xF4, 0x47, 0xDC, 0xA7, 0xEC, 0xCF, 0x50, 0xC0}; - - -static void shuffle1(buf32 temp, unsigned char *target) -{ - short b4; - unsigned char b3; - int s, b2, i; - - b4 = 0; - - for (b2 = 0; b2 <= 1; ++b2) { - for (s = 0; s <= 31; ++s) { - b3 = (temp[s] + b4) ^ (temp[(s + b4) & 31] - encryptkeys[s]); - b4 = b4 + b3; - temp[s] = b3; - } - } - - for (i = 0; i <= 15; ++i) { - target[i] = encrypttable[temp[2 * i]] - | (encrypttable[temp[2 * i + 1]] << 4); - } -} - - -static void shuffle(const unsigned char *lon, const unsigned char *buf, int buflen, - unsigned char *target) -{ - int b2, d, s; - buf32 temp; - - while ((buflen > 0) - && (buf[buflen - 1] == 0)) { - buflen = buflen - 1; - } - - for (s = 0; s < 32; s++) { - temp[s] = 0; - } - - d = 0; - while (buflen >= 32) { - for (s = 0; s <= 31; ++s) { - temp[s] = temp[s] ^ buf[d]; - d = d + 1; - } - buflen = buflen - 32; - } - b2 = d; - if (buflen > 0) { - for (s = 0; s <= 31; ++s) { - if (d + buflen == b2) { - b2 = d; - temp[s] = temp[s] ^ encryptkeys[s]; - } else { - temp[s] = temp[s] ^ buf[b2]; - b2 = b2 + 1; - } - } - } - for (s = 0; s <= 31; ++s) - temp[s] = temp[s] ^ lon[s & 3]; - - shuffle1(temp, target); -} - - -static void nw_encrypt(const unsigned char *fra, - const unsigned char *buf, - unsigned char *til) -{ - buf32 k; - int s; - - shuffle(&(fra[0]), buf, 16, &(k[0])); - shuffle(&(fra[4]), buf, 16, &(k[16])); - - for (s = 0; s <= 15; ++s) - k[s] = k[s] ^ k[31 - s]; - - for (s = 0; s <= 7; ++s) - til[s] = k[s] ^ k[15 - s]; -} diff --git a/sutil/nwsfind.c b/sutil/nwsfind.c index 2766fd3..d2e4fdd 100644 --- a/sutil/nwsfind.c +++ b/sutil/nwsfind.c @@ -13,25 +13,30 @@ #include #include #include +#include static char *progname; -static void usage(void) +static void +usage(void) { fprintf(stderr, "usage: %s [server]\n", progname); } -static void help(void) +static void +help(void) { printf("\n"); printf("usage: %s [server]\n", progname); printf("\n" "-t Server type, default: File server\n" + "-a server is in form ::\n" "-h Print this help text\n" "\n"); } -static void swallow_error(const char *name, long code, const char *format, va_list arg) +static void +swallow_error(const char *name, long code, const char *format, va_list arg) { printf("%s ", error_message(code)); vfprintf(stdout, format, arg); @@ -39,12 +44,15 @@ static void swallow_error(const char *name, long code, const char *format, va_li return; } -int main(int argc, char *argv[]) +int +main(int argc, char *argv[]) { - char *server = NULL; + const char *server = NULL; int object_type = NCP_BINDERY_FSERVER; - struct sockaddr_ipx *result; + struct sockaddr_ipx addr; + struct ncp_conn *conn; long err; + int is_address = 0; int opt; @@ -52,11 +60,16 @@ int main(int argc, char *argv[]) set_com_err_hook(swallow_error); - while ((opt = getopt(argc, argv, "t:")) != EOF) { - switch (opt) { + while ((opt = getopt(argc, argv, "at:")) != EOF) + { + switch (opt) + { case 't': object_type = atoi(optarg); break; + case 'a': + is_address = 1; + break; case 'h': case '?': help(); @@ -67,24 +80,47 @@ int main(int argc, char *argv[]) } } - if (optind < argc - 1) { + if (optind < argc - 1) + { usage(); exit(1); } - if (optind == argc - 1) { - server = argv[optind]; - if (strlen(server) >= NCP_BINDERY_NAME_LEN) { - com_err(argv[0], ENAMETOOLONG, "server name too long"); + if (is_address) + { + if ((optind > argc - 1) || + ipx_sscanf_saddr(argv[optind], &addr)) + { + usage(); exit(1); } + if ((!(conn = ncp_open_addr((struct sockaddr*)&addr, &err))) || + (err = ncp_close(conn))) {; + } + else + { + server = argv[optind]; + } + } + else + { + if (optind == argc - 1) + { + server = argv[optind]; + if (strlen(server) >= NCP_BINDERY_NAME_LEN) + { + com_err(argv[0], ENAMETOOLONG, "server name too long"); + exit(1); + } + } + err = ncp_find_server(&server, object_type, (struct sockaddr*)&addr, sizeof(addr)); } - result = ncp_find_server(&server, object_type, &err); - if (result == NULL) { + if (err != 0) + { com_err(argv[0], err, "when trying to find server"); exit(1); } - ipx_print_saddr(result); + ipx_print_saddr(&addr); printf(" %s\n", server); return 0; } diff --git a/util/Makefile b/util/Makefile index 98dfd1e..09b6b50 100644 --- a/util/Makefile +++ b/util/Makefile @@ -2,21 +2,30 @@ # Makefile for the linux ncp-filesystem routines. # -USERUTILS = slist pqlist nwfsinfo pserver nprint nsend ncopy nwpasswd -USERUTILS += nwbols nwbocreate nwborm nwboprops -USERUTILS += nwbpcreate nwbprm nwbpvalues nwbpadd nwbpset -USERUTILS += nwgrant nwrevoke nwuserlist nwrights nwauth -USERUTILS += nwfstime nwvolinfo nwtrustee +include ../Makeinit + +O_USERUTILS = slist.o pqlist.o nwfsinfo.o pserver.o nprint.o nsend.o \ + ncopy.o nwpasswd.o nwbols.o nwbocreate.o nwborm.o nwboprops.o \ + pqstat.o pqrm.o nwbpcreate.o nwbprm.o nwbpvalues.o nwbpadd.o \ + nwbpset.o nwgrant.o nwrevoke.o nwuserlist.o nwrights.o nwauth.o \ + nwfstime.o nwvolinfo.o nwtrustee.o nwpurge.o +ifdef MOUNT2 +O_SBINUTILS = nwmsg.o +endif + +USERUTILS = $(O_USERUTILS:%.o=%) +SBINUTILS = $(O_SBINUTILS:%.o=%) UTILS = $(USERUTILS) $(SBINUTILS) ncptest -CC = gcc - ifeq ($(HAVE_ELF),yes) -NCP_LIB = libncp.so.1.0 +NCP_LIB = libncp.so +NCPLIB_DIR = ../lib-shared +LIBDEP = $(NCPLIB_DIR)/$(NCP_LIB) else NCP_LIB = libncp.a -LIBDEP = ../lib/libncp.a +NCPLIB_DIR = ../lib-static +LIBDEP = $(NCPLIB_DIR)/$(NCP_LIB) endif default: @@ -30,11 +39,20 @@ install: all for i in $(SBINUTILS); \ do install $$i -m 755 $(SBINDIR); done +../lib-static/libncp.a: + make -C ../lib-static libncp.a + +../lib-shared/libncp.so: + make -C ../lib-shared libncp.so + +$(O_USERUTILS) $(O_SBINUTILS) ncptest.o: %.o: %.c + $(CC) $(CFLAGS) $(CCFLAGS) -o $@ -c $< + $(UTILS): %: %.o $(LIBDEP) - $(CC) -o $@ $(addsuffix .o,$@) -L../lib -lncp + $(CC) $(CFLAGS) -o $@ $(addsuffix .o,$@) -L$(NCPLIB_DIR) -lncp ipx_probe: ipx_probe.c - $(CC) $(CFLAGS) -o ipx_probe ipx_probe.c + $(CC) $(CFLAGS) $(CCFLAGS) -o ipx_probe ipx_probe.c dep: $(CPP) -M $(INCLUDES) *.c > .depend diff --git a/util/ipx_probe b/util/ipx_probe deleted file mode 100755 index 4869a8f..0000000 Binary files a/util/ipx_probe and /dev/null differ diff --git a/util/ipx_probe.c b/util/ipx_probe.c index 48ae8ac..de2a435 100644 --- a/util/ipx_probe.c +++ b/util/ipx_probe.c @@ -22,23 +22,25 @@ static char *progname; int verbose = 0; -static void usage() +static void +usage () { - fprintf(stderr, "usage: %s [options]\n", progname); - fprintf(stderr, "type '%s -h' for help\n", progname); + fprintf (stderr, "usage: %s [options]\n", progname); + fprintf (stderr, "type '%s -h' for help\n", progname); } -static void help() +static void +help () { - printf("\n" - "Probe an interface for ipx networks\n" - "\n"); - printf("usage: %s [options]\n", progname); - printf("\n" - "-v Verbose output\n" - "-i interface Interface to probe, default: eth0\n" - "-t timeout Seconds to wait for answer, default: 3\n" - "-h Print this help text\n\n"); + printf ("\n" + "Probe an interface for ipx networks\n" + "\n"); + printf ("usage: %s [options]\n", progname); + printf ("\n" + "-v Verbose output\n" + "-i interface Interface to probe, default: eth0\n" + "-t timeout Seconds to wait for answer, default: 3\n" + "-h Print this help text\n\n"); } #define IPX_SAP_PTYPE (0x04) @@ -48,360 +50,407 @@ static void help() #define BVAL(buf,pos) (((__u8 *)(buf))[pos]) #define BSET(buf,pos,val) (BVAL(buf,pos) = (val)) -static inline void WSET_HL(__u8 * buf, int pos, __u16 val) +static inline void +WSET_HL (__u8 * buf, int pos, __u16 val) { - BSET(buf, pos, val >> 8); - BSET(buf, pos + 1, val & 0xff); + BSET (buf, pos, val >> 8); + BSET (buf, pos + 1, val & 0xff); } -struct frame_type { - char *ft_name; - unsigned char ft_val; +struct frame_type +{ + char *ft_name; + unsigned char ft_val; }; static struct frame_type frame_types[] = { - { - "802.2", IPX_FRAME_8022 - } - , + { + "802.2", IPX_FRAME_8022 + } + , #ifdef IPX_FRAME_TR_8022 - { - "802.2TR", IPX_FRAME_TR_8022 - } - , + { + "802.2TR", IPX_FRAME_TR_8022 + } + , #endif - { - "802.3", IPX_FRAME_8023 - } - , - { - "SNAP", IPX_FRAME_SNAP - } - , - { - "EtherII", IPX_FRAME_ETHERII - } + { + "802.3", IPX_FRAME_8023 + } + , + { + "SNAP", IPX_FRAME_SNAP + } + , + { + "EtherII", IPX_FRAME_ETHERII + } }; #define NFTYPES (sizeof(frame_types)/sizeof(struct frame_type)) static char * - frame_name(int frame_type) +frame_name (int frame_type) { - int i; - for (i = 0; i < NFTYPES; i++) { - if (frame_types[i].ft_val == frame_type) { - return frame_types[i].ft_name; - } + int i; + for (i = 0; i < NFTYPES; i++) + { + if (frame_types[i].ft_val == frame_type) + { + return frame_types[i].ft_name; } - return NULL; + } + return NULL; } -static int ipx_recvfrom(int sock, void *buf, int len, unsigned int flags, - struct sockaddr_ipx *sender, int *addrlen, int timeout, - long *err) +static int +ipx_recvfrom (int sock, void *buf, int len, unsigned int flags, + struct sockaddr_ipx *sender, int *addrlen, int timeout, + long *err) { - fd_set rd, wr, ex; - struct timeval tv; - int result; + fd_set rd, wr, ex; + struct timeval tv; + int result; - FD_ZERO(&rd); - FD_ZERO(&wr); - FD_ZERO(&ex); - FD_SET(sock, &rd); + FD_ZERO (&rd); + FD_ZERO (&wr); + FD_ZERO (&ex); + FD_SET (sock, &rd); - tv.tv_sec = timeout; - tv.tv_usec = 0; + tv.tv_sec = timeout; + tv.tv_usec = 0; - if ((result = select(sock + 1, &rd, &wr, &ex, &tv)) == -1) { - *err = errno; - return -1; - } - if (FD_ISSET(sock, &rd)) { - result = recvfrom(sock, buf, len, flags, - (struct sockaddr *) sender, addrlen); - } else { - result = -1; - errno = ETIMEDOUT; - } - if (result < 0) { - *err = errno; - } - return result; + if ((result = select (sock + 1, &rd, &wr, &ex, &tv)) == -1) + { + *err = errno; + return -1; + } + if (FD_ISSET (sock, &rd)) + { + result = recvfrom (sock, buf, len, flags, + (struct sockaddr *) sender, addrlen); + } + else + { + result = -1; + errno = ETIMEDOUT; + } + if (result < 0) + { + *err = errno; + } + return result; } -static int ipx_recv(int sock, void *buf, int len, unsigned int flags, int timeout, - long *err) +static int +ipx_recv (int sock, void *buf, int len, unsigned int flags, int timeout, + long *err) { - struct sockaddr_ipx sender; - int addrlen = sizeof(sender); + struct sockaddr_ipx sender; + int addrlen = sizeof (sender); - return ipx_recvfrom(sock, buf, len, flags, &sender, &addrlen, - timeout, err); + return ipx_recvfrom (sock, buf, len, flags, &sender, &addrlen, + timeout, err); } -static int probe_frame(char *interface, int frame_type, int timeout, unsigned long *net) +static int +probe_frame (char *interface, int frame_type, int timeout, unsigned long *net) { - int i, sock, opt; - int result; - long err; - char errmsg[strlen(progname) + 20]; - char data[1024]; + int i, sock, opt; + int result; + long err; + char errmsg[strlen (progname) + 20]; + char data[1024]; - static struct ifreq id; - struct sockaddr_ipx *sipx = (struct sockaddr_ipx *) &id.ifr_addr; + static struct ifreq id; + struct sockaddr_ipx *sipx = (struct sockaddr_ipx *) &id.ifr_addr; - if (verbose != 0) { - printf("probing %s on %s -- ", frame_name(frame_type), - interface); - fflush(stdout); + if (verbose != 0) + { + printf ("probing %s on %s -- ", frame_name (frame_type), + interface); + fflush (stdout); + } + sock = socket (AF_IPX, SOCK_DGRAM, AF_IPX); + if (sock < 0) + { + int old_errno = errno; + + sprintf (errmsg, "%s: socket", progname); + perror (errmsg); + if (old_errno == -EINVAL) + { + fprintf (stderr, "Probably you have no IPX support in " + "your kernel\n"); } - sock = socket(AF_IPX, SOCK_DGRAM, AF_IPX); - if (sock < 0) { - int old_errno = errno; + close (sock); + return -1; + } + memset (&id, 0, sizeof (id)); + strncpy (id.ifr_name, interface, sizeof (id.ifr_name) - 1); + sipx->sipx_family = AF_IPX; + sipx->sipx_action = IPX_CRTITF; + sipx->sipx_special = IPX_PRIMARY; + sipx->sipx_network = 0L; + sipx->sipx_type = frame_type; - sprintf(errmsg, "%s: socket", progname); - perror(errmsg); - if (old_errno == -EINVAL) { - fprintf(stderr, "Probably you have no IPX support in " - "your kernel\n"); - } - close(sock); - return -1; - } - memset(&id, 0, sizeof(id)); - strncpy(id.ifr_name, interface, sizeof(id.ifr_name) - 1); - sipx->sipx_family = AF_IPX; - sipx->sipx_action = IPX_CRTITF; - sipx->sipx_special = IPX_PRIMARY; - sipx->sipx_network = 0L; - sipx->sipx_type = frame_type; + i = 0; + do + { + result = ioctl (sock, SIOCSIFADDR, &id); + i++; + } + while ((i < 5) && (result < 0) && (errno == EAGAIN)); - i = 0; - do { - result = ioctl(sock, SIOCSIFADDR, &id); - i++; - } - while ((i < 5) && (result < 0) && (errno == EAGAIN)); + if (result < 0) + { + int old_errno = errno; + close (sock); + errno = old_errno; + return result; + } + /* We do a GNS request on the new socket. If something comes + back, we assume that the frame type is valid. */ - if (result < 0) { - int old_errno = errno; - close(sock); - errno = old_errno; - return result; - } - /* We do a GNS request on the new socket. If something comes - back, we assume that the frame type is valid. */ + opt = 1; + if ((result = setsockopt (sock, SOL_SOCKET, + SO_BROADCAST, &opt, sizeof (opt))) < 0) + { + int old_errno = errno; + close (sock); + errno = old_errno; + return result; + } + memset (&id, 0, sizeof (id)); + sipx->sipx_family = AF_IPX; + sipx->sipx_network = htonl (0x0); + sipx->sipx_port = htons (0x0); + sipx->sipx_type = IPX_SAP_PTYPE; - opt = 1; - if ((result = setsockopt(sock, SOL_SOCKET, - SO_BROADCAST, &opt, sizeof(opt))) < 0) { - int old_errno = errno; - close(sock); - errno = old_errno; - return result; - } - memset(&id, 0, sizeof(id)); - sipx->sipx_family = AF_IPX; - sipx->sipx_network = htonl(0x0); - sipx->sipx_port = htons(0x0); - sipx->sipx_type = IPX_SAP_PTYPE; + if ((result = bind (sock, (struct sockaddr *) sipx, + sizeof (*sipx))) < 0 - 1) + { + int old_errno = errno; + close (sock); + errno = old_errno; + return result; + } + WSET_HL (data, 0, IPX_SAP_NEAREST_QUERY); + WSET_HL (data, 2, 4); - if ((result = bind(sock, (struct sockaddr *) sipx, - sizeof(*sipx))) < 0 - 1) { - int old_errno = errno; - close(sock); - errno = old_errno; - return result; - } - WSET_HL(data, 0, IPX_SAP_NEAREST_QUERY); - WSET_HL(data, 2, 4); + memset (&id, 0, sizeof (id)); + sipx->sipx_family = AF_IPX; + sipx->sipx_port = htons (IPX_SAP_PORT); + sipx->sipx_type = IPX_SAP_PTYPE; + sipx->sipx_network = htonl (0x0); + memcpy (sipx->sipx_node, IPX_BROADCAST_NODE, 6); - memset(&id, 0, sizeof(id)); - sipx->sipx_family = AF_IPX; - sipx->sipx_port = htons(IPX_SAP_PORT); - sipx->sipx_type = IPX_SAP_PTYPE; - sipx->sipx_network = htonl(0x0); - memcpy(sipx->sipx_node, IPX_BROADCAST_NODE, 6); + if ((result = sendto (sock, data, 4, 0, (struct sockaddr *) sipx, + sizeof (*sipx))) < 0) + { + int old_errno = errno; + close (sock); + errno = old_errno; + return result; + } + result = ipx_recv (sock, data, 1024, 0, timeout, &err); - if ((result = sendto(sock, data, 4, 0, (struct sockaddr *) sipx, - sizeof(*sipx))) < 0) { - int old_errno = errno; - close(sock); - errno = old_errno; - return result; - } - result = ipx_recv(sock, data, 1024, 0, timeout, &err); + if (result > 0) + { + struct sockaddr_ipx sipx; + int namelen = sizeof (sipx); - if (result > 0) { - struct sockaddr_ipx sipx; - int namelen = sizeof(sipx); + if (getsockname (sock, (struct sockaddr *) &sipx, + &namelen) < 0) + { + fprintf (stderr, "%s: Could not find socket address\n", + progname); + exit (1); + } + *net = ntohl (sipx.sipx_network); + } + memset (&id, 0, sizeof (id)); + strncpy (id.ifr_name, interface, sizeof (id.ifr_name) - 1); + sipx->sipx_family = AF_IPX; + sipx->sipx_action = IPX_DLTITF; + sipx->sipx_network = 0L; + sipx->sipx_type = frame_type; + result = ioctl (sock, SIOCSIFADDR, &id); + close (sock); - if (getsockname(sock, (struct sockaddr *) &sipx, - &namelen) < 0) { - fprintf(stderr, "%s: Could not find socket address\n", - progname); - exit(1); - } - *net = ntohl(sipx.sipx_network); + if (result < 0) + { + fprintf (stderr, "%s: could not delete interface\n", + progname); + exit (1); + } + if (err == ETIMEDOUT) + { + if (verbose != 0) + { + printf ("no network found\n"); } - memset(&id, 0, sizeof(id)); - strncpy(id.ifr_name, interface, sizeof(id.ifr_name) - 1); - sipx->sipx_family = AF_IPX; - sipx->sipx_action = IPX_DLTITF; - sipx->sipx_network = 0L; - sipx->sipx_type = frame_type; - result = ioctl(sock, SIOCSIFADDR, &id); - close(sock); - - if (result < 0) { - fprintf(stderr, "%s: could not delete interface\n", - progname); - exit(1); - } - if (err == ETIMEDOUT) { - if (verbose != 0) { - printf("no network found\n"); - } - return -1; - } - if (verbose != 0) { - printf("found IPX network %8.8lX\n", *net); - } - return 0; + return -1; + } + if (verbose != 0) + { + printf ("found IPX network %8.8lX\n", *net); + } + return 0; } -static int file_lines(char *name) +static int +file_lines (char *name) { - FILE *f = fopen(name, "r"); - char buf[100]; - int lines = 0; + FILE *f = fopen (name, "r"); + char buf[100]; + int lines = 0; - if (f == NULL) { - return -errno; - } - while (fgets(buf, sizeof(buf), f) != NULL) { - lines += 1; - } - fclose(f); - return lines; + if (f == NULL) + { + return -errno; + } + while (fgets (buf, sizeof (buf), f) != NULL) + { + lines += 1; + } + fclose (f); + return lines; } -static int ipx_interfaces(void) +static int +ipx_interfaces (void) { - int result = file_lines("/proc/net/ipx_interface"); - if (result == 0) { - result = -EIO; - } - return result - 1; + int result = file_lines ("/proc/net/ipx_interface"); + if (result == 0) + { + result = -EIO; + } + return result - 1; } -static int ipx_auto_off(void) +static int +ipx_auto_off (void) { - int s; - char errmsg[strlen(progname) + 20]; - int val = 0; + int s; + char errmsg[strlen (progname) + 20]; + int val = 0; - s = socket(AF_IPX, SOCK_DGRAM, AF_IPX); - if (s < 0) { - int old_errno = errno; + s = socket (AF_IPX, SOCK_DGRAM, AF_IPX); + if (s < 0) + { + int old_errno = errno; - sprintf(errmsg, "%s: socket", progname); - perror(errmsg); - if (old_errno == -EINVAL) { - fprintf(stderr, "Probably you have no IPX support in " - "your kernel\n"); - } - close(s); - return -1; + sprintf (errmsg, "%s: socket", progname); + perror (errmsg); + if (old_errno == -EINVAL) + { + fprintf (stderr, "Probably you have no IPX support in " + "your kernel\n"); } - sprintf(errmsg, "%s: ioctl", progname); + close (s); + return -1; + } + sprintf (errmsg, "%s: ioctl", progname); - if (ioctl(s, SIOCAIPXPRISLT, &val) < 0) { - perror(errmsg); - close(s); - return -1; - } - if (ioctl(s, SIOCAIPXITFCRT, &val) < 0) { - perror(errmsg); - close(s); - return -1; - } - close(s); - return 0; + if (ioctl (s, SIOCAIPXPRISLT, &val) < 0) + { + perror (errmsg); + close (s); + return -1; + } + if (ioctl (s, SIOCAIPXITFCRT, &val) < 0) + { + perror (errmsg); + close (s); + return -1; + } + close (s); + return 0; } -int main(int argc, char *argv[]) +int +main (int argc, char *argv[]) { - int interfaces; - char *interface = "eth0"; - int opt; - int timeout = 3; + int interfaces; + char *interface = "eth0"; + int opt; + int timeout = 3; - unsigned long network[5] = - {0,}; + unsigned long network[5] = + {0,}; - progname = argv[0]; + progname = argv[0]; - while ((opt = getopt(argc, argv, "vi:ht:")) != EOF) { - switch (opt) { - case 'v': - verbose = 1; - break; - case 'i': - interface = optarg; - break; - case 't': - timeout = atoi(optarg); - break; - case 'h': - help(); - exit(1); - default: - usage(); - exit(1); - } + while ((opt = getopt (argc, argv, "vi:ht:")) != EOF) + { + switch (opt) + { + case 'v': + verbose = 1; + break; + case 'i': + interface = optarg; + break; + case 't': + timeout = atoi (optarg); + break; + case 'h': + help (); + exit (1); + default: + usage (); + exit (1); } + } - if (ipx_auto_off() < 0) { - exit(1); - } - interfaces = ipx_interfaces(); - if (interfaces > 0) { - fprintf(stderr, "%s must be run with no interfaces configured." - " Found %d interface%s.\n", - progname, interfaces, - interfaces == 1 ? "" : "s"); - exit(1); - } - if (interfaces < 0) { - fprintf(stderr, "%s: %s\n", progname, strerror(interfaces)); - exit(1); - } - probe_frame(interface, IPX_FRAME_8022, timeout, &(network[0])); - probe_frame(interface, IPX_FRAME_8023, timeout, &(network[1])); - probe_frame(interface, IPX_FRAME_SNAP, timeout, &(network[2])); - probe_frame(interface, IPX_FRAME_ETHERII, timeout, &(network[3])); + if (ipx_auto_off () < 0) + { + exit (1); + } + interfaces = ipx_interfaces (); + if (interfaces > 0) + { + fprintf (stderr, "%s must be run with no interfaces configured." + " Found %d interface%s.\n", + progname, interfaces, + interfaces == 1 ? "" : "s"); + exit (1); + } + if (interfaces < 0) + { + fprintf (stderr, "%s: %s\n", progname, strerror (interfaces)); + exit (1); + } + probe_frame (interface, IPX_FRAME_8022, timeout, &(network[0])); + probe_frame (interface, IPX_FRAME_8023, timeout, &(network[1])); + probe_frame (interface, IPX_FRAME_SNAP, timeout, &(network[2])); + probe_frame (interface, IPX_FRAME_ETHERII, timeout, &(network[3])); - if (verbose == 0) { - if (network[0] != 0) { - printf("%s %8.8lX\n", - frame_name(IPX_FRAME_8022), network[0]); - } - if (network[1] != 0) { - printf("%s %8.8lX\n", - frame_name(IPX_FRAME_8023), network[1]); - } - if (network[2] != 0) { - printf("%s %8.8lX\n", - frame_name(IPX_FRAME_SNAP), network[2]); - } - if (network[3] != 0) { - printf("%s %8.8lX\n", - frame_name(IPX_FRAME_ETHERII), network[3]); - } + if (verbose == 0) + { + if (network[0] != 0) + { + printf ("%s %8.8lX\n", + frame_name (IPX_FRAME_8022), network[0]); } - return 0; + if (network[1] != 0) + { + printf ("%s %8.8lX\n", + frame_name (IPX_FRAME_8023), network[1]); + } + if (network[2] != 0) + { + printf ("%s %8.8lX\n", + frame_name (IPX_FRAME_SNAP), network[2]); + } + if (network[3] != 0) + { + printf ("%s %8.8lX\n", + frame_name (IPX_FRAME_ETHERII), network[3]); + } + } + return 0; } diff --git a/util/ncopy.c b/util/ncopy.c index 1127d0d..9bf82ad 100644 --- a/util/ncopy.c +++ b/util/ncopy.c @@ -23,9 +23,10 @@ #include #include #include "ncplib.h" +#include - -struct NCPMountRec { +struct NCPMountRec +{ char *mountDir; char *server; struct ncp_conn *conn; @@ -70,7 +71,8 @@ static struct sigaction sTermSig; /**************************************************************************** * */ -static void usage() +static void +usage(void) { fprintf(stderr, "usage: %s [-V]\n", ProgramName); fprintf(stderr, " %s [-vn] [-s amt] sourcefile destinationfile|directory\n", ProgramName); @@ -84,17 +86,19 @@ static void usage() * Return pointer to original string if no "/" in string. (except at end) */ static const char * - myBaseName(const char *path) +myBaseName(const char *path) { const char *p; - for (p = &path[strlen(path)]; p != path; p--) { /* skip ENDING "/" chars */ + for (p = &path[strlen(path)]; p != path; p--) + { /* skip ENDING "/" chars */ if (*p && *p != '/') break; } if (p == path) return p; - for (; p != path || *p == '/'; p--) { + for (; p != path || *p == '/'; p--) + { if (*p == '/') return ++p; } @@ -105,7 +109,7 @@ static const char * * */ static const char * - notDir(const char *path) +notDir(const char *path) { struct stat buf; static const char *notDirectory = "not a directory"; @@ -120,12 +124,15 @@ static const char * /**************************************************************************** * */ -static int handleOptions(const int argc, char *const argv[]) +static int +handleOptions(const int argc, char *const argv[]) { int opt; - while ((opt = getopt(argc, argv, "vVns:")) != EOF) { - switch (opt) { + while ((opt = getopt(argc, argv, "vVns:")) != EOF) + { + switch (opt) + { case 'V': /* Version */ optVersion = 1; @@ -142,7 +149,8 @@ static int handleOptions(const int argc, char *const argv[]) case 's': /* Nice Factor */ optNiceFactorSel = 1; optNiceFactor = atoi(optarg); - if (optNiceFactor < 1) { + if (optNiceFactor < 1) + { fprintf(stderr, "%s: -s option requires positive numeric argument > 0\n", ProgramName); return 1; @@ -160,18 +168,22 @@ static int handleOptions(const int argc, char *const argv[]) /**************************************************************************** * TODO: if recursive flag last MUST be a directory, even if only 2 args. */ -static int validateFileArgs(const int argc, char *const argv[]) +static int +validateFileArgs(const int argc, char *const argv[]) { const char *p; - if (argc == 0) { + if (argc == 0) + { fprintf(stderr, "%s: No arguments specified.\n", ProgramName); return 1; } - if (argc == 1) { + if (argc == 1) + { fprintf(stderr, "%s: No destination specified.\n", ProgramName); return 1; } - if ((argc > 2) && (p = notDir(argv[argc - 1]))) { /* last arg MUST be dir */ + if ((argc > 2) && (p = notDir(argv[argc - 1]))) + { /* last arg MUST be dir */ fprintf(stderr, "%s: %s: %s\n", ProgramName, argv[argc - 1], p); return 1; } @@ -182,7 +194,7 @@ static int validateFileArgs(const int argc, char *const argv[]) * Duplicate a string. */ char * - duplicateStr(const char *InStr) +duplicateStr(const char *InStr) { char *dup; if (!InStr) @@ -196,31 +208,38 @@ char * /**************************************************************************** * load a table of ncpfs mount points. */ -int loadMountTable() +int +loadMountTable(void) { FILE *mountedFile; struct mntent *mountEntry = NULL; ncpCount = 0; - if ((mountedFile = fopen(MOUNTED, "r")) == NULL) { + if ((mountedFile = fopen(MOUNTED, "r")) == NULL) + { fprintf(stderr, "ncopy: cannot open %s, %s\n", MOUNTED, strerror(errno)); return 1; } - while ((mountEntry = getmntent(mountedFile)) != NULL) { + while ((mountEntry = getmntent(mountedFile)) != NULL) + { if (!strcmp(mountEntry->mnt_type, "ncpfs")) ncpCount++; } - if (ncpCount) { + if (ncpCount) + { NcpMountTable = (struct NCPMountRec *) malloc(ncpCount * sizeof(struct NCPMountRec)); - if (!NcpMountTable) { + if (!NcpMountTable) + { fprintf(stderr, "Out of memory\n"); fclose(mountedFile); return 1; } fseek(mountedFile, 0, SEEK_SET); ncpCount = 0; - while ((mountEntry = getmntent(mountedFile)) != NULL) { - if (!strcmp(mountEntry->mnt_type, "ncpfs")) { + while ((mountEntry = getmntent(mountedFile)) != NULL) + { + if (!strcmp(mountEntry->mnt_type, "ncpfs")) + { NcpMountTable[ncpCount].mountDir = duplicateStr(mountEntry->mnt_dir); NcpMountTable[ncpCount].server = duplicateStr(mountEntry->mnt_fsname); @@ -236,13 +255,16 @@ int loadMountTable() /**************************************************************************** * Releases the table of ncpfs mount points. */ -void releaseMountTable() +void +releaseMountTable(void) { int loop; if (!ncpCount) return; - for (loop = ncpCount; loop; loop--, ncpCount--) { - if (NcpMountTable[loop - 1].conn) { + for (loop = ncpCount; loop; loop--, ncpCount--) + { + if (NcpMountTable[loop - 1].conn) + { ncp_close(NcpMountTable[loop - 1].conn); NcpMountTable[loop - 1].conn = NULL; } @@ -257,14 +279,16 @@ void releaseMountTable() * the file. * Returns -1 if the files do not reference the same server. */ -int ncpIndex(const char *InputFile, const char *OutputFile) +int +ncpIndex(const char *InputFile, const char *OutputFile) { int loop; char *mountDir; if (!ncpCount) return -1; - for (loop = 0; loop < ncpCount; loop++) { + for (loop = 0; loop < ncpCount; loop++) + { mountDir = NcpMountTable[loop].mountDir; if (!strncmp(mountDir, InputFile, strlen(mountDir)) && !strncmp(mountDir, OutputFile, strlen(mountDir))) @@ -278,40 +302,46 @@ int ncpIndex(const char *InputFile, const char *OutputFile) * Does a regular buffered file copy. * This is used if we cannot use the Netware file copy. */ -int normalFileCopy(const char *InputFile, const char *OutputFile, - char *Buffer, int BufferSize, - const char *paramInputFile, - const char *paramOutputFile) +int +normalFileCopy(const char *InputFile, const char *OutputFile, + char *Buffer, int BufferSize, + const char *paramInputFile, + const char *paramOutputFile) { int fdIn, fdOut; long fileSize, totalSize; struct stat statBuf; fdIn = open(InputFile, O_RDONLY); - if (fdIn == -1) { + if (fdIn == -1) + { fprintf(stderr, "%s: Cannot open %s, %s\n", ProgramName, paramInputFile, strerror(errno)); return 1; } - if (fstat(fdIn, &statBuf)) { + if (fstat(fdIn, &statBuf)) + { fprintf(stderr, "%s: Cannot stat %s, %s\n", ProgramName, paramInputFile, strerror(errno)); close(fdIn); return 1; } - if (S_ISDIR(statBuf.st_mode)) { + if (S_ISDIR(statBuf.st_mode)) + { close(fdIn); fprintf(stderr, "%s: %s: omitting directory\n", ProgramName, paramInputFile); return 0; /* At this point, don't consider this a fatal error */ } fdOut = open(OutputFile, O_CREAT | O_TRUNC | O_WRONLY, statBuf.st_mode); - if (fdOut == -1) { + if (fdOut == -1) + { fprintf(stderr, "%s: Cannot create %s, %s\n", ProgramName, paramOutputFile, strerror(errno)); close(fdIn); return 1; } fileSize = lseek(fdIn, 0, SEEK_END); - if (fileSize < 0) { + if (fileSize < 0) + { fprintf(stderr, "%s: lseek error on %s, %s\n", ProgramName, paramInputFile, strerror(errno)); close(fdOut); @@ -319,16 +349,19 @@ int normalFileCopy(const char *InputFile, const char *OutputFile, return 1; } lseek(fdIn, 0, SEEK_SET); - if (optVerbose) { + if (optVerbose) + { printf("Normal copy: %s -> %s 0%%", paramInputFile, paramOutputFile); fflush(stdout); } totalSize = fileSize; - while (fileSize) { + while (fileSize) + { int currentMove; int writeAmt; currentMove = (fileSize > BufferSize) ? BufferSize : fileSize; - if (read(fdIn, Buffer, currentMove) != currentMove) { + if (read(fdIn, Buffer, currentMove) != currentMove) + { fprintf(stderr, "%s: Error reading %s, %s\n", ProgramName, paramInputFile, strerror(errno)); close(fdIn); @@ -336,13 +369,15 @@ int normalFileCopy(const char *InputFile, const char *OutputFile, return 1; } writeAmt = write(fdOut, Buffer, currentMove); - if (writeAmt < 0) { + if (writeAmt < 0) + { fprintf(stderr, "%s: Error writing %s, %s\n", ProgramName, paramOutputFile, strerror(errno)); close(fdIn); close(fdOut); return 1; - } else if (writeAmt == 0) { + } else if (writeAmt == 0) + { fprintf(stderr, "%s: Out of space on destination device writing %s\n", ProgramName, OutputFile); close(fdIn); @@ -350,7 +385,8 @@ int normalFileCopy(const char *InputFile, const char *OutputFile, return 1; } fileSize -= currentMove; - if (optVerbose) { + if (optVerbose) + { printf("\rNormal copy: %s -> %s %ld%%", paramInputFile, paramOutputFile, (100 - (fileSize * 100 / totalSize))); fflush(stdout); } @@ -367,10 +403,11 @@ int normalFileCopy(const char *InputFile, const char *OutputFile, * Netware file names need to be all upper case. */ char * - upString(char *str) +upString(char *str) { char *alias = str; - while (*alias) { + while (*alias) + { *alias = toupper(*alias); ++alias; } @@ -381,10 +418,12 @@ char * * Locates the first occurrance of a single character in the input string. * returns -1 if the character is not found. */ -int stringPosition(const char *str, char token) +int +stringPosition(const char *str, char token) { const char *alias = str; - while (*alias) { + while (*alias) + { if (*alias == token) return alias - str; alias++; @@ -398,7 +437,8 @@ int stringPosition(const char *str, char token) * This will mangle the input "FileString", leaving just the file name * component in it when it is finished. */ -int getDirHandle(struct ncp_conn *conn, char *FileString, __u8 * NewDirHandle) +int +getDirHandle(struct ncp_conn *conn, char *FileString, __u8 * NewDirHandle) { struct nw_info_struct info1, info2; int currentLevel = 0; @@ -406,20 +446,25 @@ int getDirHandle(struct ncp_conn *conn, char *FileString, __u8 * NewDirHandle) struct nw_info_struct *parentInfo = NULL; struct nw_info_struct *currentInfo = NULL; - while ((k = stringPosition(FileString, '/')) >= 0) { + while ((k = stringPosition(FileString, '/')) >= 0) + { FileString[k] = 0; - if (!currentLevel) { + if (!currentLevel) + { parentInfo = NULL; currentInfo = &info1; - } else if (currentLevel % 2) { + } else if (currentLevel % 2) + { parentInfo = &info1; currentInfo = &info2; - } else { + } else + { parentInfo = &info2; currentInfo = &info1; } if (ncp_do_lookup(conn, parentInfo, FileString, - currentInfo) != 0) { + currentInfo) != 0) + { fprintf(stderr, "%s: Ncp lookup failed on directory %s--%s\n", ProgramName, FileString, strerror(errno)); return 1; @@ -429,7 +474,8 @@ int getDirHandle(struct ncp_conn *conn, char *FileString, __u8 * NewDirHandle) } if (ncp_alloc_short_dir_handle(conn, currentInfo, NCP_ALLOC_TEMPORARY, - NewDirHandle) != 0) { + NewDirHandle) != 0) + { fprintf(stderr, "%s: Ncp alloc dir handle failed--%s\n", ProgramName, strerror(errno)); return 1; @@ -441,10 +487,11 @@ int getDirHandle(struct ncp_conn *conn, char *FileString, __u8 * NewDirHandle) /**************************************************************************** * Interfaces with the ncplib to do the netware copy of the file. */ -int netwareCopyFile(int ncpMountIndex, const char *sourcefile, - const char *destfile, - const char *paramInputFile, - const char *paramOutputFile) +int +netwareCopyFile(int ncpMountIndex, const char *sourcefile, + const char *destfile, + const char *paramInputFile, + const char *paramOutputFile) { __u8 source_dir_handle; __u8 dest_dir_handle; @@ -465,10 +512,12 @@ int netwareCopyFile(int ncpMountIndex, const char *sourcefile, /* Establish a connection to a Netware mount point if one is not already established. */ - if (!NcpMountTable[ncpMountIndex].conn) { - NcpMountTable[ncpMountIndex].conn = - ncp_open_mount(NcpMountTable[ncpMountIndex].mountDir, &err); - if (err) { + if (!NcpMountTable[ncpMountIndex].conn) + { + err = ncp_open_mount(NcpMountTable[ncpMountIndex].mountDir, + &NcpMountTable[ncpMountIndex].conn); + if (err) + { com_err(ProgramName, err, "opening ncp connection on mount point %s", NcpMountTable[ncpMountIndex].mountDir); return 2; @@ -481,7 +530,8 @@ int netwareCopyFile(int ncpMountIndex, const char *sourcefile, stroffset = strlen(NcpMountTable[ncpMountIndex].mountDir) + 1; sourceDup = duplicateStr(sourcefile + stroffset); destDup = duplicateStr(destfile + stroffset); - if (!sourceDup || !destDup) { + if (!sourceDup || !destDup) + { fprintf(stderr, "%s: Malloc failed duplicating file names\n", ProgramName); return 2; @@ -491,14 +541,16 @@ int netwareCopyFile(int ncpMountIndex, const char *sourcefile, /* Get Handles to the input and output directories */ if (getDirHandle(sourceconn, sourceDup, &source_dir_handle) || - getDirHandle(sourceconn, destDup, &dest_dir_handle)) { + getDirHandle(sourceconn, destDup, &dest_dir_handle)) + { free(sourceDup); free(destDup); return 1; } /* Open the input and output files. */ if (ncp_open_file(sourceconn, source_dir_handle, sourceDup, 0, AR_READ, - &source_file) != 0) { + &source_file) != 0) + { fprintf(stderr, "%s: Cannot open %s--%s\n", ProgramName, paramInputFile, strerror(errno)); free(sourceDup); @@ -506,7 +558,8 @@ int netwareCopyFile(int ncpMountIndex, const char *sourcefile, return 1; } if (ncp_create_file(sourceconn, dest_dir_handle, destDup, - source_file.file_attributes, &dest_file) != 0) { + source_file.file_attributes, &dest_file) != 0) + { fprintf(stderr, "%s: Cannot create %s--%s\n", ProgramName, paramOutputFile, strerror(errno)); ncp_close_file(sourceconn, source_file.file_id); @@ -523,7 +576,8 @@ int netwareCopyFile(int ncpMountIndex, const char *sourcefile, free(destDup); retValue = 0; - if (optVerbose) { + if (optVerbose) + { printf("NetWare copy: %s -> %s 0%%", paramInputFile, paramOutputFile); fflush(stdout); } @@ -533,24 +587,28 @@ int netwareCopyFile(int ncpMountIndex, const char *sourcefile, sourceOff = 0; retryCount = 0; - while (amtLeft && retryCount < MaxNcopyRetries) { + while (amtLeft && retryCount < MaxNcopyRetries) + { int ncopyRetValue; if (amtLeft > CopyBlockSize) thisMove = CopyBlockSize; else thisMove = amtLeft; /* If we are being nice and we've copied enough blocks, go to sleep */ - if (optNice) { - if (BlocksCopied == optNiceFactor) { + if (optNice) + { + if (BlocksCopied == optNiceFactor) + { sleep(NiceSleepTime); BlocksCopied = 0; } else ++BlocksCopied; } ncopyRetValue = ncp_copy_file(sourceconn, source_file.file_id, - dest_file.file_id, sourceOff, sourceOff, + dest_file.file_id, sourceOff, sourceOff, thisMove, &amountCopied); - if (ncopyRetValue != 0) { + if (ncopyRetValue != 0) + { /* In my testing this only happens when you run out of space on the server. Netware seems to wait a bit before reporting space recently @@ -559,7 +617,8 @@ int netwareCopyFile(int ncpMountIndex, const char *sourcefile, retryCount++; amountCopied = thisMove = 0; } - if (amountCopied != thisMove) { + if (amountCopied != thisMove) + { fprintf(stderr, "%s: Warning, amountCopied (%u) != thisMove (%u)\n", ProgramName, (unsigned int) amountCopied, (unsigned int) thisMove); } @@ -569,7 +628,8 @@ int netwareCopyFile(int ncpMountIndex, const char *sourcefile, #endif amtLeft -= amountCopied; sourceOff += amountCopied; - if (optVerbose) { + if (optVerbose) + { printf("\rNetWare copy: %s -> %s %ld%%", paramInputFile, paramOutputFile, (100 - (long) ((float) amtLeft / (float) totalSize * 100.0))); if (retryCount) @@ -581,7 +641,8 @@ int netwareCopyFile(int ncpMountIndex, const char *sourcefile, retValue = 1; if (optVerbose) printf("\n"); - if (ncp_close_file(sourceconn, dest_file.file_id) != 0) { + if (ncp_close_file(sourceconn, dest_file.file_id) != 0) + { fprintf(stderr, "%s: Close failed for %s\n", ProgramName, paramOutputFile); retValue = 1; } @@ -590,16 +651,19 @@ int netwareCopyFile(int ncpMountIndex, const char *sourcefile, CurrentConn = NULL; CurrentFile = NULL; - if (ncp_close_file(sourceconn, source_file.file_id) != 0) { + if (ncp_close_file(sourceconn, source_file.file_id) != 0) + { fprintf(stderr, "%s: Close failed for %s\n", ProgramName, paramInputFile); retValue = 1; } - if (ncp_dealloc_dir_handle(sourceconn, dest_dir_handle) != 0) { + if (ncp_dealloc_dir_handle(sourceconn, dest_dir_handle) != 0) + { fprintf(stderr, "%s: Dealloc dir handle error for %s\n", ProgramName, paramOutputFile); retValue = 1; } - if (ncp_dealloc_dir_handle(sourceconn, source_dir_handle) != 0) { + if (ncp_dealloc_dir_handle(sourceconn, source_dir_handle) != 0) + { fprintf(stderr, "%s: Dealloc dir handle error for %s\n", ProgramName, paramInputFile); retValue = 1; @@ -612,8 +676,9 @@ int netwareCopyFile(int ncpMountIndex, const char *sourcefile, * Decides whether to use the traditional file copy or the netware remote * file copy. */ -int copyFiles(const char *realsource, const char *realdestination, - const char *paraminputfile, const char *paramoutputfile) +int +copyFiles(const char *realsource, const char *realdestination, + const char *paraminputfile, const char *paramoutputfile) { int oldUMask; char fileBuffer[24000]; @@ -623,7 +688,7 @@ int copyFiles(const char *realsource, const char *realdestination, printf("Real Source '%s'\n" "Real Dest '%s'\n" "Param Src '%s'\n" - "Param Dest '%s'\n", realsource, realdestination, paraminputfile, + "Param Dest '%s'\n", realsource, realdestination, paraminputfile, paramoutputfile); #endif @@ -657,7 +722,8 @@ int copyFiles(const char *realsource, const char *realdestination, * Is it failure if destination fails? * Do we Stay in the loop? */ -static int copyRealPaths(const char *source, const char *destination) +static int +copyRealPaths(const char *source, const char *destination) { char realsource[MAXPATHLEN * 2]; char realdestination[MAXPATHLEN * 2]; @@ -665,18 +731,21 @@ static int copyRealPaths(const char *source, const char *destination) char filePart[MAXPATHLEN + 1]; const char *p; - if (realpath(source, realsource) == 0) { /* the source must at least exist */ + if (realpath(source, realsource) == 0) + { /* the source must at least exist */ fprintf(stderr, "%s: %s: %s\n", ProgramName, source, strerror(errno)); return 1; /* indicate a "source" problem */ } - if (realpath(destination, realdestination) == 0) { /* dest file missing? OK */ + if (realpath(destination, realdestination) == 0) + { /* dest file missing? OK */ strncpy(dirPart, destination, MAXPATHLEN); /* but "dirpart" must work */ dirPart[MAXPATHLEN] = 0; p = myBaseName(dirPart); strcpy(filePart, p); dirPart[p - dirPart] = 0; /* isolates "directory" part from "file part" */ - if (realpath(dirPart, realdestination) == 0) { + if (realpath(dirPart, realdestination) == 0) + { fprintf(stderr, "%s: %s: %s\n", ProgramName, dirPart, strerror(errno)); return 2; /* indicate a "destination" problem */ @@ -701,7 +770,8 @@ static int copyRealPaths(const char *source, const char *destination) * if argc > 2 last parameter is a directory * by validateFileArgs() */ -static int handleFileArgs(int argc, char *const argv[]) +static int +handleFileArgs(int argc, char *const argv[]) { int loop; const char *destination; @@ -711,10 +781,12 @@ static int handleFileArgs(int argc, char *const argv[]) char destinationfile[MAXPATHLEN * 2]; destination = argv[argc - 1]; /* get LAST argument */ - for (loop = 0; loop < (argc - 1); loop++) { /* all file arguments, but last */ + for (loop = 0; loop < (argc - 1); loop++) + { /* all file arguments, but last */ strncpy(destinationfile, destination, MAXPATHLEN); destinationfile[MAXPATHLEN] = 0; - if ((argc > 2) || (!notDir(argv[argc - 1]))) { /* destination is a dir */ + if ((argc > 2) || (!notDir(argv[argc - 1]))) + { /* destination is a dir */ if (*destinationfile != '/' || *(destinationfile + 1)) strcat(destinationfile, "/"); baseNamePtr = myBaseName(argv[loop]); /* get the file name */ @@ -731,41 +803,48 @@ static int handleFileArgs(int argc, char *const argv[]) /**************************************************************************** * */ -static void handleSignals(int sigNumber) +static void +handleSignals(int sigNumber) { /* Ignore Signal Handling while cleaning up */ /* SIGHUP */ sHangupSig.sa_handler = SIG_IGN; - if (sigaction(SIGHUP, &sHangupSig, NULL) == -1) { + if (sigaction(SIGHUP, &sHangupSig, NULL) == -1) + { fprintf(stderr, "%s: Reset to ignore SIGHUP signal failed: %s", ProgramName, strerror(errno)); } /* SIGINT */ sInterruptSig.sa_handler = SIG_IGN; - if (sigaction(SIGINT, &sInterruptSig, NULL) == -1) { + if (sigaction(SIGINT, &sInterruptSig, NULL) == -1) + { fprintf(stderr, "%s: Reset to ignore SIGINT signal failed: %s", ProgramName, strerror(errno)); } /* SIGQUIT */ sQuitSig.sa_handler = SIG_IGN; - if (sigaction(SIGQUIT, &sQuitSig, NULL) == -1) { + if (sigaction(SIGQUIT, &sQuitSig, NULL) == -1) + { fprintf(stderr, "%s: Reset to ignore SIGQUIT signal failed: %s", ProgramName, strerror(errno)); } /* SIGTERM */ sTermSig.sa_handler = SIG_IGN; - if (sigaction(SIGTERM, &sTermSig, NULL) == -1) { + if (sigaction(SIGTERM, &sTermSig, NULL) == -1) + { fprintf(stderr, "%s: Reset to ignore SIGTERM signal failed: %s", ProgramName, strerror(errno)); } /* If we don't close the ncp output file, we have to ncpumount and ncpmount before we can get rid of it. */ - if (OutputOpen) { + if (OutputOpen) + { /* Issue a warning if we cannot close the file */ /* If an error occurs we probably have to umount/mount to remove the file */ - if (ncp_close_file(CurrentConn, CurrentFile->file_id) != 0) { + if (ncp_close_file(CurrentConn, CurrentFile->file_id) != 0) + { fprintf(stderr, "%s: unclean close of output file", ProgramName); } OutputOpen = 0; @@ -776,48 +855,57 @@ static void handleSignals(int sigNumber) /**************************************************************************** * We'll trap Hangup, Interrupt, Quit or Terminate */ -static int trapSignals() +static int +trapSignals(void) { - if (sigaction(SIGHUP, NULL, &sHangupSig)) { /* init structure fields */ + if (sigaction(SIGHUP, NULL, &sHangupSig)) + { /* init structure fields */ fprintf(stderr, "%s: Get HANGUP signal action failed: %s", ProgramName, strerror(errno)); return 1; } sHangupSig.sa_handler = handleSignals; - if (sigaction(SIGHUP, &sHangupSig, NULL) == -1) { + if (sigaction(SIGHUP, &sHangupSig, NULL) == -1) + { fprintf(stderr, "%s: Reset HANGUP signal action failed: %s", ProgramName, strerror(errno)); return 1; } - if (sigaction(SIGINT, NULL, &sInterruptSig)) { /* init structure fields */ + if (sigaction(SIGINT, NULL, &sInterruptSig)) + { /* init structure fields */ fprintf(stderr, "%s: Get INTERRUPT signal action failed: %s", ProgramName, strerror(errno)); return 1; } sInterruptSig.sa_handler = handleSignals; - if (sigaction(SIGINT, &sInterruptSig, NULL) == -1) { + if (sigaction(SIGINT, &sInterruptSig, NULL) == -1) + { fprintf(stderr, "%s: Reset INTERRUPT signal action failed: %s", ProgramName, strerror(errno)); return 1; } - if (sigaction(SIGQUIT, NULL, &sQuitSig)) { /* init structure fields */ + if (sigaction(SIGQUIT, NULL, &sQuitSig)) + { /* init structure fields */ fprintf(stderr, "%s: Get QUIT signal action failed: %s", ProgramName, strerror(errno)); return 1; } sQuitSig.sa_handler = handleSignals; - if (sigaction(SIGQUIT, &sQuitSig, NULL) == -1) { + if (sigaction(SIGQUIT, &sQuitSig, NULL) == -1) + { fprintf(stderr, "%s: Reset QUIT signal action failed: %s", ProgramName, strerror(errno)); return 1; } - if (sigaction(SIGTERM, NULL, &sTermSig)) { /* init structure fields */ + if (sigaction(SIGTERM, NULL, &sTermSig)) + { /* init structure fields */ fprintf(stderr, "%s: Get TERMINATE signal action failed: %s", ProgramName, strerror(errno)); return 1; } sTermSig.sa_handler = handleSignals; - if (sigaction(SIGTERM, &sTermSig, NULL) == -1) { + if (sigaction(SIGTERM, &sTermSig, NULL) == -1) + { fprintf(stderr, "%s: Reset TERMINATE signal action failed: %s", ProgramName, strerror(errno)); return 1; @@ -828,20 +916,24 @@ static int trapSignals() /**************************************************************************** * */ -int main(int argc, char *const argv[]) +int +main(int argc, char *const argv[]) { int returnCode; ProgramName = argv[0]; - if (handleOptions(argc, argv)) { /* bad option, missing option parameter */ + if (handleOptions(argc, argv)) + { /* bad option, missing option parameter */ usage(); return 1; } - if (optVersion) { /* only option not requiring any arguments */ + if (optVersion) + { /* only option not requiring any arguments */ printf("%s version %s\n", ProgramName, VersionStr); return 0; } - if (validateFileArgs(argc - optind, argv + optind)) { + if (validateFileArgs(argc - optind, argv + optind)) + { usage(); return 1; } diff --git a/util/ncptest.c b/util/ncptest.c index 7afd222..6e5a02f 100644 --- a/util/ncptest.c +++ b/util/ncptest.c @@ -1,4 +1,3 @@ - /* * ncptest.c * @@ -20,7 +19,7 @@ #include #include #include - /* #include *//* generates a warning here */ + /* #include *//* generates a warning here */ extern pid_t waitpid(pid_t, int *, int); #include #include @@ -30,16 +29,16 @@ extern pid_t waitpid(pid_t, int *, int); #include #include #include -#include +#include "kernel/ipx.h" -#include -#include -#include -#include +#include "kernel/fs.h" +#include "kernel/ncp.h" +#include "kernel/ncp_fs.h" #include "ncplib.h" -void test_connlist(struct ncp_conn *conn) +void +test_connlist(struct ncp_conn *conn) { __u8 conn_list[256] = {0,}; @@ -50,92 +49,110 @@ void test_connlist(struct ncp_conn *conn) return; } -void test_send(struct ncp_conn *conn) +void +test_send(struct ncp_conn *conn) { __u8 conn_list[256] = {0,}; int no; if (ncp_get_connlist(conn, NCP_BINDERY_USER, "ME", &no, - conn_list) != 0) { + conn_list) != 0) + { no = 0; } - if (no > 0) { + if (no > 0) + { ncp_send_broadcast(conn, no, conn_list, "Hallo"); } return; } -void test_create(struct ncp_conn *conn) +void +test_create(struct ncp_conn *conn) { struct nw_info_struct sys; struct nw_info_struct me; __u8 dir_handle; struct ncp_file_info new_file; - if (ncp_do_lookup(conn, NULL, "SYS", &sys) != 0) { + if (ncp_do_lookup(conn, NULL, "SYS", &sys) != 0) + { printf("lookup error\n"); return; } - if (ncp_do_lookup(conn, &sys, "ME", &me) != 0) { + if (ncp_do_lookup(conn, &sys, "ME", &me) != 0) + { printf("lookup public error\n"); return; } if (ncp_alloc_short_dir_handle(conn, &me, NCP_ALLOC_TEMPORARY, - &dir_handle) != 0) { + &dir_handle) != 0) + { printf("alloc_dir_handle error\n"); return; } if (ncp_create_file(conn, dir_handle, "BLUB.TXT", 0, - &new_file) != 0) { + &new_file) != 0) + { printf("create error\n"); return; } - if (ncp_dealloc_dir_handle(conn, dir_handle) != 0) { + if (ncp_dealloc_dir_handle(conn, dir_handle) != 0) + { printf("dealloc error\n"); return; } } -int test_change(struct ncp_conn *conn) +int +test_change(struct ncp_conn *conn) { long result; unsigned char ncp_key[8]; struct ncp_bindery_object user; - if ((result = ncp_get_encryption_key(conn, ncp_key)) != 0) { + if ((result = ncp_get_encryption_key(conn, ncp_key)) != 0) + { return result; } if ((result = ncp_get_bindery_object_id(conn, 1, - "ME", &user)) != 0) { + "ME", &user)) != 0) + { return result; } if ((result = ncp_change_login_passwd(conn, &user, ncp_key, - "MEE", "ME")) != 0) { + "MEE", "ME")) != 0) + { return result; } return 0; } -void test_readdir(struct ncp_conn *conn) +void +test_readdir(struct ncp_conn *conn) { struct nw_info_struct sys; struct nw_info_struct blub; struct ncp_search_seq seq; struct nw_info_struct entry; - if (ncp_do_lookup(conn, NULL, "SYS", &sys) != 0) { + if (ncp_do_lookup(conn, NULL, "SYS", &sys) != 0) + { printf("lookup error\n"); return; } - if (ncp_do_lookup(conn, &sys, "BLUB", &blub) != 0) { + if (ncp_do_lookup(conn, &sys, "BLUB", &blub) != 0) + { printf("lookup blub error\n"); return; } - if (ncp_initialize_search(conn, &sys, 0, &seq) != 0) { + if (ncp_initialize_search(conn, &sys, 0, &seq) != 0) + { printf("init error\n"); return; } - while (ncp_search_for_file_or_subdir(conn, &seq, &entry) == 0) { + while (ncp_search_for_file_or_subdir(conn, &seq, &entry) == 0) + { struct nw_info_struct nfs; printf("found: %s\n", entry.entryName); if (ncp_obtain_file_or_subdir_info(conn, NW_NS_DOS, NW_NS_NFS, @@ -143,7 +160,8 @@ void test_readdir(struct ncp_conn *conn) entry.volNumber, entry.DosDirNum, NULL, - &nfs) == 0) { + &nfs) == 0) + { printf("nfs name: %s\n", nfs.entryName); } if (ncp_obtain_file_or_subdir_info(conn, NW_NS_DOS, NW_NS_OS2, @@ -151,30 +169,35 @@ void test_readdir(struct ncp_conn *conn) entry.volNumber, entry.DosDirNum, NULL, - &nfs) == 0) { + &nfs) == 0) + { printf("os2 name: %s\n", nfs.entryName); } } } -void test_rights(struct ncp_conn *conn) +void +test_rights(struct ncp_conn *conn) { struct nw_info_struct sys; struct nw_info_struct me; __u16 rights; - if (ncp_do_lookup(conn, NULL, "SYS", &sys) != 0) { + if (ncp_do_lookup(conn, NULL, "SYS", &sys) != 0) + { printf("lookup error\n"); return; } - if (ncp_do_lookup(conn, &sys, "ME", &me) != 0) { + if (ncp_do_lookup(conn, &sys, "ME", &me) != 0) + { printf("lookup me error\n"); return; } if (ncp_get_eff_directory_rights(conn, 0, 0, 0x8006, - sys.volNumber, sys.DosDirNum, NULL, - &rights) != 0) { + sys.volNumber, sys.DosDirNum, NULL, + &rights) != 0) + { printf("get sys rights error\n"); return; } @@ -182,7 +205,8 @@ void test_rights(struct ncp_conn *conn) if (ncp_get_eff_directory_rights(conn, 0, 0, 0x8006, me.volNumber, me.DosDirNum, NULL, - &rights) != 0) { + &rights) != 0) + { printf("get me rights error\n"); return; } @@ -190,12 +214,14 @@ void test_rights(struct ncp_conn *conn) return; } -int main(int argc, char *argv[]) +int +main(int argc, char *argv[]) { struct ncp_conn *conn; long err; - if ((conn = ncp_initialize(&argc, argv, 1, &err)) == NULL) { + if ((conn = ncp_initialize(&argc, argv, 1, &err)) == NULL) + { com_err(argv[0], err, "in ncp_initialize"); return 1; } diff --git a/util/nprint.c b/util/nprint.c index 9e04aac..76a0b40 100644 --- a/util/nprint.c +++ b/util/nprint.c @@ -22,7 +22,8 @@ static void usage(void); static void help(void); -void main(int argc, char *argv[]) +int +main(int argc, char *argv[]) { struct ncp_conn *conn; @@ -50,11 +51,13 @@ void main(int argc, char *argv[]) memzero(q); if ((argc == 2) - && (strcmp(argv[1], "-h") == 0)) { + && (strcmp(argv[1], "-h") == 0)) + { help(); exit(0); } - if ((conn = ncp_initialize(&argc, argv, 1, &err)) == NULL) { + if ((conn = ncp_initialize(&argc, argv, 1, &err)) == NULL) + { com_err(argv[0], err, "when initializing connection"); exit(1); } @@ -75,8 +78,10 @@ void main(int argc, char *argv[]) pj.Rows = htons(80); strcpy(pj.FnameHeader, "stdin"); - while ((opt = getopt(argc, argv, "h?q:d:p:b:f:l:r:c:t:F:TN")) != EOF) { - switch (opt) { + while ((opt = getopt(argc, argv, "h?q:d:p:b:f:l:r:c:t:F:TN")) != EOF) + { + switch (opt) + { case 'h': case '?': help(); @@ -85,38 +90,45 @@ void main(int argc, char *argv[]) case 'p': /* Path */ pj.CtrlFlags |= PRINT_BANNER; - if (strlen(optarg) >= sizeof(pj.Path)) { + if (strlen(optarg) >= sizeof(pj.Path)) + { strncpy(pj.Path, optarg, sizeof(pj.Path)); - } else { + } else + { strcpy(pj.Path, optarg); } break; case 'b': /* Banner Name */ pj.CtrlFlags |= PRINT_BANNER; - if (strlen(optarg) >= sizeof(pj.BannerName)) { + if (strlen(optarg) >= sizeof(pj.BannerName)) + { strncpy(pj.BannerName, optarg, sizeof(pj.BannerName)); - } else { + } else + { strcpy(pj.BannerName, optarg); } break; case 'f': /* File Name in Banner */ pj.CtrlFlags |= PRINT_BANNER; - if (strlen(optarg) >= sizeof(pj.FnameBanner)) { + if (strlen(optarg) >= sizeof(pj.FnameBanner)) + { strncpy(pj.FnameBanner, optarg, sizeof(pj.FnameBanner)); - } else { + } else + { strcpy(pj.FnameBanner, optarg); } break; case 'l': /* lines, default: 66 */ - if ((atoi(optarg) < 0) || (atoi(optarg) > 65535)) { + if ((atoi(optarg) < 0) || (atoi(optarg) > 65535)) + { fprintf(stderr, - "invalid line number: %s\n", optarg); + "invalid line number: %s\n", optarg); break; } pj.Lines = htons(atoi(optarg)); @@ -124,9 +136,10 @@ void main(int argc, char *argv[]) break; case 'r': /* rows, default: 80 */ - if ((atoi(optarg) < 0) || (atoi(optarg) > 65535)) { + if ((atoi(optarg) < 0) || (atoi(optarg) > 65535)) + { fprintf(stderr, - "invalid row number: %s\n", optarg); + "invalid row number: %s\n", optarg); break; } pj.Rows = htons(atoi(optarg)); @@ -134,7 +147,8 @@ void main(int argc, char *argv[]) break; case 'c': /* copies, default: 1 */ - if ((atoi(optarg) < 0) || (atoi(optarg) > 65000)) { + if ((atoi(optarg) < 0) || (atoi(optarg) > 65000)) + { fprintf(stderr, "invalid copies: %s\n", optarg); break; @@ -144,7 +158,8 @@ void main(int argc, char *argv[]) break; case 't': /* tab size, default: 8 */ - if ((atoi(optarg) < 0) || (atoi(optarg) > 255)) { + if ((atoi(optarg) < 0) || (atoi(optarg) > 255)) + { fprintf(stderr, "invalid tab size: %s\n", optarg); break; @@ -162,16 +177,18 @@ void main(int argc, char *argv[]) break; case 'F': /* Form number, default: 0 */ - if ((atoi(optarg) < 0) || (atoi(optarg) > 255)) { + if ((atoi(optarg) < 0) || (atoi(optarg) > 255)) + { fprintf(stderr, - "invalid form number: %s\n", optarg); + "invalid form number: %s\n", optarg); break; } j.j.JobType = htons(atoi(optarg)); break; case 'q': /* Queue name to print on, default: '*' */ - if (strlen(optarg) >= NCP_BINDERY_NAME_LEN) { + if (strlen(optarg) >= NCP_BINDERY_NAME_LEN) + { printf("queue name too long: %s\n", optarg); ncp_close(conn); @@ -182,10 +199,12 @@ void main(int argc, char *argv[]) case 'd': /* Job Description */ pj.CtrlFlags |= PRINT_BANNER; - if (strlen(optarg) >= sizeof(j.j.JobTextDescription)) { + if (strlen(optarg) >= sizeof(j.j.JobTextDescription)) + { strncpy(j.j.JobTextDescription, optarg, sizeof(j.j.JobTextDescription)); - } else { + } else + { strcpy(j.j.JobTextDescription, optarg); } break; @@ -197,34 +216,43 @@ void main(int argc, char *argv[]) } } - if (optind != argc - 1) { + if (optind != argc - 1) + { usage(); ncp_close(conn); exit(1); } file_name = argv[optind]; - if (strcmp(file_name, "-") == 0) { + if (strcmp(file_name, "-") == 0) + { file = 0; /* stdin */ - } else { + } else + { file = open(file_name, O_RDONLY, 0); - if (file < 0) { + if (file < 0) + { perror("could not open file"); ncp_close(conn); exit(1); } - if (strlen(file_name) >= sizeof(pj.FnameHeader)) { + if (strlen(file_name) >= sizeof(pj.FnameHeader)) + { strncpy(pj.FnameHeader, file_name, sizeof(pj.FnameHeader)); - } else { + } else + { strcpy(pj.FnameHeader, file_name); } - if (strlen(pj.FnameBanner) == 0) { - if (strlen(file_name) >= sizeof(pj.FnameBanner)) { + if (strlen(pj.FnameBanner) == 0) + { + if (strlen(file_name) >= sizeof(pj.FnameBanner)) + { strncpy(pj.FnameBanner, file_name, sizeof(pj.FnameBanner)); - } else { + } else + { strcpy(pj.FnameBanner, file_name); } } @@ -235,24 +263,29 @@ void main(int argc, char *argv[]) str_upper(queue); if (ncp_scan_bindery_object(conn, 0xffffffff, NCP_BINDERY_PQUEUE, - queue, &q) != 0) { + queue, &q) != 0) + { printf("could not find queue %s\n", queue); ncp_close(conn); exit(1); } - if (ncp_create_queue_job_and_file(conn, q.object_id, &j) != 0) { + if (ncp_create_queue_job_and_file(conn, q.object_id, &j) != 0) + { printf("create error\n"); ncp_close(conn); exit(1); } written = 0; - do { + do + { read_this_time = read(file, buf, sizeof(buf)); - if (read_this_time < 0) { + if (read_this_time < 0) + { break; } if (ncp_write(conn, j.file_handle, - written, read_this_time, buf) < read_this_time) { + written, read_this_time, buf) < read_this_time) + { break; } written += read_this_time; @@ -261,19 +294,22 @@ void main(int argc, char *argv[]) close(file); - if (ncp_close_file_and_start_job(conn, q.object_id, &j) != 0) { + if (ncp_close_file_and_start_job(conn, q.object_id, &j) != 0) + { printf("close error\n"); } ncp_close(conn); - return; + return 0; } -static void usage(void) +static void +usage(void) { fprintf(stderr, "usage: %s [options] file\n", progname); } -static void help(void) +static void +help(void) { printf("\n"); printf("usage: %s [options] file\n", progname); diff --git a/util/nsend.c b/util/nsend.c index d359cce..3af5a23 100644 --- a/util/nsend.c +++ b/util/nsend.c @@ -12,22 +12,27 @@ #include #include "ncplib.h" -int main(int argc, char **argv) +int +main(int argc, char **argv) { struct ncp_conn *conn; __u8 conn_list[256] = {0,}; int no_conn; + int conn_list2[256]; + int i; char *message = NULL; char *user = NULL; long err; - if ((conn = ncp_initialize(&argc, argv, 1, &err)) == NULL) { + if ((conn = ncp_initialize(&argc, argv, 1, &err)) == NULL) + { com_err(argv[0], err, "when initializing"); exit(1); } - if (argc != 3) { + if (argc != 3) + { fprintf(stderr, "usage: %s [options] user message\n", argv[0]); ncp_close(conn); exit(1); @@ -36,20 +41,31 @@ int main(int argc, char **argv) message = argv[2]; if ((err = ncp_get_connlist(conn, NCP_BINDERY_USER, user, &no_conn, - conn_list)) != 0) { + conn_list)) != 0) + { com_err(argv[0], err, "in get_connlist"); ncp_close(conn); exit(1); } - if (no_conn == 0) { + if (no_conn == 0) + { fprintf(stderr, "No connection found for %s\n", user); ncp_close(conn); exit(1); } - if ((err = ncp_send_broadcast(conn, no_conn, conn_list, message)) != 0) { - com_err(argv[0], err, "in send_broadcast"); - ncp_close(conn); - exit(1); + for (i=0; icompletion == 0xFB) + err = ncp_send_broadcast(conn, no_conn, conn_list, message); + if (err) + { + com_err(argv[0], err, "in send_broadcast"); + ncp_close(conn); + exit(1); + } } ncp_close(conn); return 0; diff --git a/util/nwauth.c b/util/nwauth.c index 2df39e0..6882352 100644 --- a/util/nwauth.c +++ b/util/nwauth.c @@ -14,12 +14,14 @@ static char *progname; -static void usage(void) +static void +usage(void) { fprintf(stderr, "usage: %s [options]\n", progname); } -static void help(void) +static void +help(void) { printf("\n"); printf("usage: %s [options]\n", progname); @@ -31,18 +33,21 @@ static void help(void) "\n"); } -static void swallow_error(const char *s, long x, const char *t, va_list arg) +static void +swallow_error(const char *s, long x, const char *t, va_list arg) { return; } -int main(int argc, char *argv[]) +int +main(int argc, char *argv[]) { struct ncp_conn_spec *spec; struct ncp_conn *conn; char *server = NULL; char *object_name = NULL; int object_type = NCP_BINDERY_USER; + struct sockaddr_ipx addr; long err; char *str; @@ -51,11 +56,14 @@ int main(int argc, char *argv[]) progname = argv[0]; - if (!isatty(0)) { + if (!isatty(0)) + { set_com_err_hook(swallow_error); } - while ((opt = getopt(argc, argv, "h?S:U:t:")) != EOF) { - switch (opt) { + while ((opt = getopt(argc, argv, "h?S:U:t:")) != EOF) + { + switch (opt) + { case 'S': server = optarg; break; @@ -78,31 +86,37 @@ int main(int argc, char *argv[]) spec = ncp_find_conn_spec(server, object_name, "", 1, getuid(), &err); - if (spec == NULL) { + if (spec == NULL) + { com_err(argv[0], err, "when trying to find server"); exit(1); } - if (ncp_find_fileserver(spec->server, &err) == NULL) { + if ((err = ncp_find_fileserver(spec->server, (struct sockaddr*)&addr, sizeof(addr))) != 0) + { com_err(argv[0], err, "when trying to find server"); exit(1); } spec->login_type = object_type; memset(spec->password, 0, sizeof(spec->password)); - if (isatty(0)) { + if (isatty(0)) + { str = getpass("Enter password: "); - if (strlen(str) >= sizeof(spec->password)) { + if (strlen(str) >= sizeof(spec->password)) + { printf("Password too long\n"); exit(1); } strcpy(spec->password, str); - } else { + } else + { fgets(spec->password, sizeof(spec->password), stdin); } str_upper(spec->password); - if ((conn = ncp_open(spec, &err)) == NULL) { + if ((conn = ncp_open(spec, &err)) == NULL) + { com_err(argv[0], err, "when trying to open connection"); exit(1); } diff --git a/util/nwbocreate.c b/util/nwbocreate.c index b2a4643..794c3ad 100644 --- a/util/nwbocreate.c +++ b/util/nwbocreate.c @@ -13,12 +13,14 @@ static char *progname; -static void usage(void) +static void +usage(void) { fprintf(stderr, "usage: %s [options]\n", progname); } -static void help(void) +static void +help(void) { printf("\n"); printf("usage: %s [options]\n", progname); @@ -37,27 +39,34 @@ static void help(void) "\n"); } -static int parse_security(const char *security) +static int +parse_security(const char *security) { - if (strcasecmp(security, "anyone") == 0) { + if (strcasecmp(security, "anyone") == 0) + { return 0; } - if (strcasecmp(security, "logged") == 0) { + if (strcasecmp(security, "logged") == 0) + { return 1; } - if (strcasecmp(security, "object") == 0) { + if (strcasecmp(security, "object") == 0) + { return 2; } - if (strcasecmp(security, "supervisor") == 0) { + if (strcasecmp(security, "supervisor") == 0) + { return 3; } - if (strcasecmp(security, "netware") == 0) { + if (strcasecmp(security, "netware") == 0) + { return 4; } return -1; } -int main(int argc, char *argv[]) +int +main(int argc, char *argv[]) { struct ncp_conn *conn; char *object_name = NULL; @@ -72,12 +81,15 @@ int main(int argc, char *argv[]) progname = argv[0]; - if ((conn = ncp_initialize(&argc, argv, 1, &err)) == NULL) { + if ((conn = ncp_initialize(&argc, argv, 1, &err)) == NULL) + { com_err(argv[0], err, "when initializing"); goto finished; } - while ((opt = getopt(argc, argv, "h?o:t:r:w:")) != EOF) { - switch (opt) { + while ((opt = getopt(argc, argv, "h?o:t:r:w:")) != EOF) + { + switch (opt) + { case 'o': object_name = optarg; str_upper(object_name); @@ -87,7 +99,8 @@ int main(int argc, char *argv[]) break; case 'r': read_sec = parse_security(optarg); - if (read_sec < 0) { + if (read_sec < 0) + { fprintf(stderr, "%s: Wrong read security\n" "Must be one of anyone, logged, " @@ -98,7 +111,8 @@ int main(int argc, char *argv[]) break; case 'w': write_sec = parse_security(optarg); - if (write_sec < 0) { + if (write_sec < 0) + { fprintf(stderr, "%s: Wrong write security\n" "Must be one of anyone, logged, " @@ -117,20 +131,24 @@ int main(int argc, char *argv[]) } } - if (object_type < 0) { + if (object_type < 0) + { fprintf(stderr, "%s: You must specify an object type\n", argv[0]); goto finished; } - if (object_name == NULL) { + if (object_name == NULL) + { fprintf(stderr, "%s: You must specify an object name\n", argv[0]); goto finished; } if (ncp_create_bindery_object(conn, object_type, object_name, - (write_sec << 4) + read_sec, 0) != 0) { + (write_sec << 4) + read_sec, 0) != 0) + { fprintf(stderr, "%s: Could not create the object\n", argv[0]); - } else { + } else + { result = 0; } diff --git a/util/nwbols.c b/util/nwbols.c index c551328..1ecdcca 100644 --- a/util/nwbols.c +++ b/util/nwbols.c @@ -15,13 +15,15 @@ static char *progname; -static void usage(void) +static void +usage(void) { fprintf(stderr, "usage: %s [options] pattern\n", progname); return; } -static void help(void) +static void +help(void) { printf("\n"); printf("usage: %s [options]\n", progname); @@ -39,7 +41,8 @@ static void help(void) "\n"); } -int main(int argc, char **argv) +int +main(int argc, char **argv) { struct ncp_conn *conn; struct ncp_bindery_object o; @@ -55,12 +58,15 @@ int main(int argc, char **argv) progname = argv[0]; - if ((conn = ncp_initialize(&argc, argv, 1, &err)) == NULL) { + if ((conn = ncp_initialize(&argc, argv, 1, &err)) == NULL) + { com_err(argv[0], err, "when initializing"); return 1; } - while ((opt = getopt(argc, argv, "h?vt:o:")) != EOF) { - switch (opt) { + while ((opt = getopt(argc, argv, "h?vt:o:")) != EOF) + { + switch (opt) + { case 'h': case '?': help(); @@ -80,26 +86,31 @@ int main(int argc, char **argv) } } - if (optind < argc) { + if (optind < argc) + { usage(); exit(1); } - for (p = pattern; *p != '\0'; p++) { + for (p = pattern; *p != '\0'; p++) + { *p = toupper(*p); } o.object_id = 0xffffffff; while (ncp_scan_bindery_object(conn, o.object_id, - type, pattern, &o) == 0) { + type, pattern, &o) == 0) + { found = 1; - if (verbose != 0) { + if (verbose != 0) + { printf("%s %08X %04X %d %02X %d\n", o.object_name, (unsigned int) o.object_id, (unsigned int) o.object_type, o.object_flags, o.object_security, o.object_has_prop); - } else { + } else + { printf("%s %08X %04X\n", o.object_name, (unsigned int) o.object_id, (unsigned int) o.object_type); diff --git a/util/nwboprops.c b/util/nwboprops.c index 0e91765..790850a 100644 --- a/util/nwboprops.c +++ b/util/nwboprops.c @@ -13,12 +13,14 @@ static char *progname; -static void usage(void) +static void +usage(void) { fprintf(stderr, "usage: %s [options]\n", progname); } -static void help(void) +static void +help(void) { printf("\n"); printf("usage: %s [options]\n", progname); @@ -36,7 +38,8 @@ static void help(void) "\n"); } -int main(int argc, char *argv[]) +int +main(int argc, char *argv[]) { struct ncp_conn *conn; char *object_name = NULL; @@ -51,12 +54,15 @@ int main(int argc, char *argv[]) progname = argv[0]; - if ((conn = ncp_initialize(&argc, argv, 1, &err)) == NULL) { + if ((conn = ncp_initialize(&argc, argv, 1, &err)) == NULL) + { com_err(argv[0], err, "when initializing"); goto finished; } - while ((opt = getopt(argc, argv, "h?o:t:v")) != EOF) { - switch (opt) { + while ((opt = getopt(argc, argv, "h?o:t:v")) != EOF) + { + switch (opt) + { case 'o': object_name = optarg; str_upper(object_name); @@ -77,12 +83,14 @@ int main(int argc, char *argv[]) } } - if (object_type < 0) { + if (object_type < 0) + { fprintf(stderr, "%s: You must specify an object type\n", argv[0]); goto finished; } - if (object_name == NULL) { + if (object_name == NULL) + { fprintf(stderr, "%s: You must specify an object name\n", argv[0]); goto finished; @@ -90,13 +98,16 @@ int main(int argc, char *argv[]) info.search_instance = 0xffffffff; while (ncp_scan_property(conn, object_type, object_name, - info.search_instance, "*", &info) == 0) { - if (verbose != 0) { + info.search_instance, "*", &info) == 0) + { + if (verbose != 0) + { printf("%s %d %02x %d\n", info.property_name, info.property_flags, info.property_security, info.value_available_flag); - } else { + } else + { printf("%s\n", info.property_name); } } diff --git a/util/nwborm.c b/util/nwborm.c index 88e911e..f0dc321 100644 --- a/util/nwborm.c +++ b/util/nwborm.c @@ -13,12 +13,14 @@ static char *progname; -static void usage(void) +static void +usage(void) { fprintf(stderr, "usage: %s [options]\n", progname); } -static void help(void) +static void +help(void) { printf("\n"); printf("usage: %s [options]\n", progname); @@ -35,7 +37,8 @@ static void help(void) "\n"); } -int main(int argc, char *argv[]) +int +main(int argc, char *argv[]) { struct ncp_conn *conn; char *object_name = NULL; @@ -48,12 +51,15 @@ int main(int argc, char *argv[]) progname = argv[0]; - if ((conn = ncp_initialize(&argc, argv, 1, &err)) == NULL) { + if ((conn = ncp_initialize(&argc, argv, 1, &err)) == NULL) + { com_err(argv[0], err, "when initializing"); goto finished; } - while ((opt = getopt(argc, argv, "h?o:t:")) != EOF) { - switch (opt) { + while ((opt = getopt(argc, argv, "h?o:t:")) != EOF) + { + switch (opt) + { case 'o': object_name = optarg; str_upper(object_name); @@ -71,19 +77,23 @@ int main(int argc, char *argv[]) } } - if (object_type < 0) { + if (object_type < 0) + { fprintf(stderr, "%s: You must specify an object type\n", argv[0]); goto finished; } - if (object_name == NULL) { + if (object_name == NULL) + { fprintf(stderr, "%s: You must specify an object name\n", argv[0]); goto finished; } - if (ncp_delete_bindery_object(conn, object_type, object_name) != 0) { + if (ncp_delete_bindery_object(conn, object_type, object_name) != 0) + { fprintf(stderr, "%s: Could not delete the object\n", argv[0]); - } else { + } else + { result = 0; } diff --git a/util/nwbpadd.c b/util/nwbpadd.c index adaaf52..77283fd 100644 --- a/util/nwbpadd.c +++ b/util/nwbpadd.c @@ -13,12 +13,14 @@ static char *progname; -static void usage(void) +static void +usage(void) { fprintf(stderr, "usage: %s [options]\n", progname); } -static void help(void) +static void +help(void) { printf("\n"); printf("usage: %s [options] [values]\n", progname); @@ -36,15 +38,16 @@ static void help(void) "value value to be added\n" "\n" "If property is of type SET, value is an object id (hex)\n" - "Otherwise, value is either a string value to be written, or\n" - "a count of bytes to be written. The latter is assumed if\n" - "more than one value argument is given. The count is decimal,\n" + "Otherwise, value is either a string value to be written, or\n" + "a count of bytes to be written. The latter is assumed if\n" + "more than one value argument is given. The count is decimal,\n" "and the following arguments are interpreted as bytes in\n" "hexadecimal notation.\n" "\n"); } -int main(int argc, char *argv[]) +int +main(int argc, char *argv[]) { struct ncp_conn *conn; char *object_name = NULL; @@ -58,12 +61,15 @@ int main(int argc, char *argv[]) progname = argv[0]; - if ((conn = ncp_initialize(&argc, argv, 1, &err)) == NULL) { + if ((conn = ncp_initialize(&argc, argv, 1, &err)) == NULL) + { com_err(argv[0], err, "when initializing"); goto finished; } - while ((opt = getopt(argc, argv, "h?o:t:p:v:")) != EOF) { - switch (opt) { + while ((opt = getopt(argc, argv, "h?o:t:p:v:")) != EOF) + { + switch (opt) + { case 'o': object_name = optarg; str_upper(object_name); @@ -73,7 +79,8 @@ int main(int argc, char *argv[]) break; case 'p': property_name = optarg; - if (strlen(property_name) > 15) { + if (strlen(property_name) > 15) + { fprintf(stderr, "%s: Property Name too long\n", argv[0]); exit(1); @@ -93,22 +100,26 @@ int main(int argc, char *argv[]) } } - if (object_type < 0) { + if (object_type < 0) + { fprintf(stderr, "%s: You must specify an object type\n", argv[0]); goto finished; } - if (object_name == NULL) { + if (object_name == NULL) + { fprintf(stderr, "%s: You must specify an object name\n", argv[0]); goto finished; } - if (property_name == NULL) { + if (property_name == NULL) + { fprintf(stderr, "%s: You must specify a property name\n", argv[0]); goto finished; } - if (optind > argc - 1) { + if (optind > argc - 1) + { fprintf(stderr, "%s: You must specify a property value\n", argv[0]); goto finished; @@ -117,35 +128,41 @@ int main(int argc, char *argv[]) optind += 1; if (ncp_scan_property(conn, object_type, object_name, - 0xffffffff, property_name, &info) != 0) { + 0xffffffff, property_name, &info) != 0) + { fprintf(stderr, "%s: Could not find property\n", argv[0]); goto finished; } - if ((info.property_flags & 2) != 0) { + if ((info.property_flags & 2) != 0) + { /* Property is of type SET */ struct ncp_bindery_object o; - if (optind != argc) { + if (optind != argc) + { fprintf(stderr, "%s: For the SET property %s, you must" " specify an object id as value\n", progname, property_name); goto finished; } if (ncp_get_bindery_object_name(conn, - ntohl(strtol(value, NULL, 16)), - &o) != 0) { + ntohl(strtol(value, NULL, 16)), + &o) != 0) + { fprintf(stderr, "%s: %s is not a valid object id\n", progname, value); goto finished; } if (ncp_add_object_to_set(conn, object_type, object_name, property_name, - o.object_type, o.object_name) != 0) { + o.object_type, o.object_name) != 0) + { fprintf(stderr, "%s: could not add object %s\n", progname, o.object_name); goto finished; } - } else { + } else + { /* Property is of type ITEM */ char contents[255 * 128]; int segno = 1; @@ -153,42 +170,50 @@ int main(int argc, char *argv[]) memset(contents, 0, sizeof(contents)); - if (optind == argc) { + if (optind == argc) + { /* value is the string to add */ length = strlen(value); - if (length >= sizeof(contents)) { + if (length >= sizeof(contents)) + { fprintf(stderr, "%s: Value too long\n", progname); goto finished; } strcpy(contents, value); - } else { + } else + { /* value is the byte count */ int i; length = atoi(value); - if (length >= sizeof(contents)) { + if (length >= sizeof(contents)) + { fprintf(stderr, "%s: Value too long\n", progname); goto finished; } - if (optind != argc - length) { + if (optind != argc - length) + { fprintf(stderr, "%s: Byte count does not match" " number of bytes\n", progname); goto finished; } i = 0; - while (optind < argc) { + while (optind < argc) + { contents[i] = strtol(argv[optind], NULL, 16); i += 1; optind += 1; } } - for (segno = 1; segno <= 255; segno++) { + for (segno = 1; segno <= 255; segno++) + { struct nw_property segment; int offset = (segno - 1) * 128; - if (offset > length) { + if (offset > length) + { /* everything written */ break; } @@ -197,7 +222,8 @@ int main(int argc, char *argv[]) if (ncp_write_property_value(conn, object_type, object_name, property_name, - segno, &segment) != 0) { + segno, &segment) != 0) + { fprintf(stderr, "%s: Could not write " "property\n", progname); goto finished; diff --git a/util/nwbpcreate.c b/util/nwbpcreate.c index b58d0b9..f7394da 100644 --- a/util/nwbpcreate.c +++ b/util/nwbpcreate.c @@ -13,12 +13,14 @@ static char *progname; -static void usage(void) +static void +usage(void) { fprintf(stderr, "usage: %s [options]\n", progname); } -static void help(void) +static void +help(void) { printf("\n"); printf("usage: %s [options]\n", progname); @@ -39,27 +41,34 @@ static void help(void) "\n"); } -static int parse_security(const char *security) +static int +parse_security(const char *security) { - if (strcasecmp(security, "anyone") == 0) { + if (strcasecmp(security, "anyone") == 0) + { return 0; } - if (strcasecmp(security, "logged") == 0) { + if (strcasecmp(security, "logged") == 0) + { return 1; } - if (strcasecmp(security, "object") == 0) { + if (strcasecmp(security, "object") == 0) + { return 2; } - if (strcasecmp(security, "supervisor") == 0) { + if (strcasecmp(security, "supervisor") == 0) + { return 3; } - if (strcasecmp(security, "netware") == 0) { + if (strcasecmp(security, "netware") == 0) + { return 4; } return -1; } -int main(int argc, char *argv[]) +int +main(int argc, char *argv[]) { struct ncp_conn *conn; char *object_name = NULL; @@ -76,12 +85,15 @@ int main(int argc, char *argv[]) progname = argv[0]; - if ((conn = ncp_initialize(&argc, argv, 1, &err)) == NULL) { + if ((conn = ncp_initialize(&argc, argv, 1, &err)) == NULL) + { com_err(argv[0], err, "when initializing"); goto finished; } - while ((opt = getopt(argc, argv, "h?o:t:p:sr:w:")) != EOF) { - switch (opt) { + while ((opt = getopt(argc, argv, "h?o:t:p:sr:w:")) != EOF) + { + switch (opt) + { case 'o': object_name = optarg; str_upper(object_name); @@ -91,7 +103,8 @@ int main(int argc, char *argv[]) break; case 'p': property_name = optarg; - if (strlen(property_name) > 15) { + if (strlen(property_name) > 15) + { fprintf(stderr, "%s: Property Name too long\n", argv[0]); exit(1); @@ -103,7 +116,8 @@ int main(int argc, char *argv[]) break; case 'r': read_sec = parse_security(optarg); - if (read_sec < 0) { + if (read_sec < 0) + { fprintf(stderr, "%s: Wrong read security\n" "Must be one of anyone, logged, " @@ -114,7 +128,8 @@ int main(int argc, char *argv[]) break; case 'w': write_sec = parse_security(optarg); - if (write_sec < 0) { + if (write_sec < 0) + { fprintf(stderr, "%s: Wrong write security\n" "Must be one of anyone, logged, " @@ -133,17 +148,20 @@ int main(int argc, char *argv[]) } } - if (object_type < 0) { + if (object_type < 0) + { fprintf(stderr, "%s: You must specify an object type\n", argv[0]); goto finished; } - if (object_name == NULL) { + if (object_name == NULL) + { fprintf(stderr, "%s: You must specify an object name\n", argv[0]); goto finished; } - if (property_name == NULL) { + if (property_name == NULL) + { fprintf(stderr, "%s: You must specify a property name\n", argv[0]); goto finished; @@ -151,9 +169,11 @@ int main(int argc, char *argv[]) if (ncp_create_property(conn, object_type, object_name, property_name, property_is_set ? 2 : 0, - (write_sec << 4) + read_sec) != 0) { + (write_sec << 4) + read_sec) != 0) + { fprintf(stderr, "%s: Could not create the property\n", argv[0]); - } else { + } else + { result = 0; } diff --git a/util/nwbprm.c b/util/nwbprm.c index 48c5fde..baa37b2 100644 --- a/util/nwbprm.c +++ b/util/nwbprm.c @@ -13,12 +13,14 @@ static char *progname; -static void usage(void) +static void +usage(void) { fprintf(stderr, "usage: %s [options] [pattern]\n", progname); } -static void help(void) +static void +help(void) { printf("\n"); printf("usage: %s [options]\n", progname); @@ -36,7 +38,8 @@ static void help(void) "\n"); } -int main(int argc, char *argv[]) +int +main(int argc, char *argv[]) { struct ncp_conn *conn; char *object_name = NULL; @@ -50,12 +53,15 @@ int main(int argc, char *argv[]) progname = argv[0]; - if ((conn = ncp_initialize(&argc, argv, 1, &err)) == NULL) { + if ((conn = ncp_initialize(&argc, argv, 1, &err)) == NULL) + { com_err(argv[0], err, "when initializing"); goto finished; } - while ((opt = getopt(argc, argv, "h?o:t:p:")) != EOF) { - switch (opt) { + while ((opt = getopt(argc, argv, "h?o:t:p:")) != EOF) + { + switch (opt) + { case 'o': object_name = optarg; str_upper(object_name); @@ -65,7 +71,8 @@ int main(int argc, char *argv[]) break; case 'p': property_name = optarg; - if (strlen(property_name) > 15) { + if (strlen(property_name) > 15) + { fprintf(stderr, "%s: Property Name too long\n", argv[0]); exit(1); @@ -82,25 +89,30 @@ int main(int argc, char *argv[]) } } - if (object_type < 0) { + if (object_type < 0) + { fprintf(stderr, "%s: You must specify an object type\n", argv[0]); goto finished; } - if (object_name == NULL) { + if (object_name == NULL) + { fprintf(stderr, "%s: You must specify an object name\n", argv[0]); goto finished; } - if (property_name == NULL) { + if (property_name == NULL) + { fprintf(stderr, "%s: You must specify a property name\n", argv[0]); goto finished; } if (ncp_delete_property(conn, object_type, object_name, - property_name) != 0) { + property_name) != 0) + { fprintf(stderr, "%s: Could not delete the property\n", argv[0]); - } else { + } else + { result = 0; } diff --git a/util/nwbpset.c b/util/nwbpset.c index eba285d..091a592 100644 --- a/util/nwbpset.c +++ b/util/nwbpset.c @@ -13,12 +13,14 @@ static char *progname; -static void usage(void) +static void +usage(void) { fprintf(stderr, "usage: %s [options]\n", progname); } -static void help(void) +static void +help(void) { printf("\n"); printf("usage: %s [options] [values]\n", progname); @@ -33,16 +35,18 @@ static void help(void) } static char * - get_line(char *buf, int len, FILE * stream) +get_line(char *buf, int len, FILE * stream) { char *result = fgets(buf, len, stream); - if (result != NULL) { + if (result != NULL) + { buf[strlen(buf) - 1] = '\0'; /* remove newline */ } return result; } -int main(int argc, char *argv[]) +int +main(int argc, char *argv[]) { struct ncp_conn *conn; char object_name[49]; @@ -57,12 +61,15 @@ int main(int argc, char *argv[]) progname = argv[0]; - if ((conn = ncp_initialize(&argc, argv, 1, &err)) == NULL) { + if ((conn = ncp_initialize(&argc, argv, 1, &err)) == NULL) + { com_err(argv[0], err, "when initializing"); goto finished; } - while ((opt = getopt(argc, argv, "h?")) != EOF) { - switch (opt) { + while ((opt = getopt(argc, argv, "h?")) != EOF) + { + switch (opt) + { case 'h': case '?': help(); @@ -74,88 +81,104 @@ int main(int argc, char *argv[]) } memset(buf, 0, sizeof(buf)); - if (get_line(buf, sizeof(buf), stdin) == NULL) { + if (get_line(buf, sizeof(buf), stdin) == NULL) + { fprintf(stderr, "Illegal format on stdin\n"); goto finished; } object_type = strtoul(buf, NULL, 16); memset(object_name, 0, sizeof(object_name)); - if (get_line(object_name, sizeof(object_name), stdin) == NULL) { + if (get_line(object_name, sizeof(object_name), stdin) == NULL) + { fprintf(stderr, "Illegal format on stdin\n"); goto finished; } memset(property_name, 0, sizeof(property_name)); - if (get_line(property_name, sizeof(property_name), stdin) == NULL) { + if (get_line(property_name, sizeof(property_name), stdin) == NULL) + { fprintf(stderr, "Illegal format on stdin\n"); goto finished; } memset(buf, 0, sizeof(buf)); - if (get_line(buf, sizeof(buf), stdin) == NULL) { + if (get_line(buf, sizeof(buf), stdin) == NULL) + { fprintf(stderr, "Illegal format on stdin\n"); goto finished; } property_flag = (atoi(buf) & 3); memset(buf, 0, sizeof(buf)); - if (get_line(buf, sizeof(buf), stdin) == NULL) { + if (get_line(buf, sizeof(buf), stdin) == NULL) + { fprintf(stderr, "Illegal format on stdin\n"); goto finished; } property_security = (strtoul(buf, NULL, 16) & 0xff); if (ncp_scan_property(conn, object_type, object_name, - 0xffffffff, property_name, &info) == 0) { + 0xffffffff, property_name, &info) == 0) + { /* Property already exists */ - if ((property_flag & 2) != (info.property_flags & 2)) { + if ((property_flag & 2) != (info.property_flags & 2)) + { fprintf(stderr, "Tried to write %s property\n", (property_flag & 2) != 0 ? "SET over existing ITEM" : "ITEM over existing SET"); goto finished; } - if (info.property_security != property_security) { + if (info.property_security != property_security) + { if (ncp_change_property_security(conn, object_type, object_name, property_name, - property_security) != 0) { + property_security) != 0) + { fprintf(stderr, "Could not change " "property security\n"); goto finished; } } - } else { + } else + { if (ncp_create_property(conn, object_type, object_name, property_name, property_flag, - property_security) != 0) { + property_security) != 0) + { fprintf(stderr, "Could not create property\n"); goto finished; } } - if ((property_flag & 2) == 0) { + if ((property_flag & 2) == 0) + { /* ITEM property */ - int i; + size_t i; int length; int segno; char property_value[255 * 128]; memset(property_value, 0, sizeof(property_value)); - for (i = 0; i < sizeof(property_value); i++) { - if (get_line(buf, sizeof(buf), stdin) == NULL) { + for (i = 0; i < sizeof(property_value); i++) + { + if (get_line(buf, sizeof(buf), stdin) == NULL) + { break; } property_value[i] = strtoul(buf, NULL, 16); } length = i - 1; - for (segno = 1; segno <= 255; segno++) { + for (segno = 1; segno <= 255; segno++) + { struct nw_property segment; int offset = (segno - 1) * 128; - if (offset > length) { + if (offset > length) + { /* everything written */ break; } @@ -164,30 +187,36 @@ int main(int argc, char *argv[]) if (ncp_write_property_value(conn, object_type, object_name, property_name, - segno, &segment) != 0) { + segno, &segment) != 0) + { fprintf(stderr, "Could not write property\n"); goto finished; } } - } else { + } else + { /* SET property */ - while (get_line(buf, sizeof(buf), stdin) != NULL) { + while (get_line(buf, sizeof(buf), stdin) != NULL) + { int element_type = strtoul(buf, NULL, 16); char element_name[49]; memset(element_name, 0, sizeof(element_name)); if (get_line(element_name, sizeof(element_name), - stdin) == NULL) { + stdin) == NULL) + { fprintf(stderr, "Illegal format on stdin\n"); goto finished; } if (ncp_add_object_to_set(conn, object_type, - object_name, property_name, + object_name, property_name, element_type, - element_name) != 0) { - if (conn->completion != 0xE9) { /* object already - in set */ + element_name) != 0) + { + if (conn->completion != 0xE9) /* object already + in set */ + { fprintf(stderr, "Could not add object " "to set\n"); goto finished; diff --git a/util/nwbpvalues.c b/util/nwbpvalues.c index 203f6ab..9245bff 100644 --- a/util/nwbpvalues.c +++ b/util/nwbpvalues.c @@ -17,12 +17,14 @@ static char *progname; static void print_property(char *prop_name, __u8 * val, int segments); -static void usage(void) +static void +usage(void) { fprintf(stderr, "usage: %s [options]\n", progname); } -static void help(void) +static void +help(void) { printf("\n"); printf("usage: %s [options]\n", progname); @@ -42,7 +44,8 @@ static void help(void) "\n"); } -int main(int argc, char *argv[]) +int +main(int argc, char *argv[]) { struct ncp_conn *conn; char *object_name = NULL; @@ -62,12 +65,15 @@ int main(int argc, char *argv[]) progname = argv[0]; - if ((conn = ncp_initialize(&argc, argv, 1, &err)) == NULL) { + if ((conn = ncp_initialize(&argc, argv, 1, &err)) == NULL) + { com_err(argv[0], err, "when initializing"); goto finished; } - while ((opt = getopt(argc, argv, "h?o:t:p:vc")) != EOF) { - switch (opt) { + while ((opt = getopt(argc, argv, "h?o:t:p:vc")) != EOF) + { + switch (opt) + { case 'o': object_name = optarg; str_upper(object_name); @@ -77,7 +83,8 @@ int main(int argc, char *argv[]) break; case 'p': property_name = optarg; - if (strlen(property_name) > 15) { + if (strlen(property_name) > 15) + { fprintf(stderr, "%s: Property Name too long\n", argv[0]); exit(1); @@ -100,77 +107,95 @@ int main(int argc, char *argv[]) } } - if (object_type < 0) { + if (object_type < 0) + { fprintf(stderr, "%s: You must specify an object type\n", argv[0]); goto finished; } - if (object_name == NULL) { + if (object_name == NULL) + { fprintf(stderr, "%s: You must specify an object name\n", argv[0]); goto finished; } - if (property_name == NULL) { + if (property_name == NULL) + { fprintf(stderr, "%s: You must specify a property name\n", argv[0]); goto finished; } if (ncp_scan_property(conn, object_type, object_name, - 0xffffffff, property_name, &info) != 0) { + 0xffffffff, property_name, &info) != 0) + { fprintf(stderr, "%s: Could not find property\n", argv[0]); goto finished; } segno = 1; while (ncp_read_property_value(conn, object_type, object_name, - segno, property_name, &segment) == 0) { + segno, property_name, &segment) == 0) + { memcpy(&(property_value[(segno - 1) * 128]), segment.value, 128); - if ((segment.more_flag == 0) || (segno == 255)) { + if ((segment.more_flag == 0) || (segno == 255)) + { break; } segno += 1; } - if (canonical != 0) { + if (canonical != 0) + { printf("%-4.4x\n%s\n", object_type, object_name); printf("%s\n%d\n%x\n", info.property_name, info.property_flags, info.property_security); } - if ((info.property_flags & 2) == 0) { + if ((info.property_flags & 2) == 0) + { /* ITEM property */ - if (canonical != 0) { + if (canonical != 0) + { int i; - for (i = 0; i < segno * 128; i++) { + for (i = 0; i < segno * 128; i++) + { printf("%-2.2x\n", property_value[i]); } - } else { + } else + { print_property(property_name, property_value, segno); } - } else { + } else + { int objects = 32 * segno; __u32 *value = (__u32 *) property_value; int i = 0; - while (i < objects) { + while (i < objects) + { struct ncp_bindery_object o; - if ((value[i] == 0) || (value[i] == 0xffffffff)) { + if ((value[i] == 0) || (value[i] == 0xffffffff)) + { /* Continue with next segment */ i = ((i / 32) + 1) * 32; continue; } if (ncp_get_bindery_object_name(conn, ntohl(value[i]), - &o) == 0) { - if (canonical != 0) { + &o) == 0) + { + if (canonical != 0) + { printf("%-4.4x\n%s\n", - (unsigned int) o.object_type, + (unsigned int) o.object_type, o.object_name); - } else if (verbose != 0) { + } else if (verbose != 0) + { printf("%s %08X %04X\n", o.object_name, (unsigned int) o.object_id, - (unsigned int) o.object_type); - } else { + (unsigned int) o.object_type); + } else + { printf("%s\n", o.object_name); } } @@ -184,20 +209,25 @@ int main(int argc, char *argv[]) return result; } -static void print_unknown(__u8 * val) +static void +print_unknown(__u8 * val) { int j = (128 / 16); - while (1) { + while (1) + { int i; - for (i = 0; i < 16; i++) { + for (i = 0; i < 16; i++) + { printf("%02X ", val[i]); } printf(" ["); - for (i = 0; i < 16; i++) { + for (i = 0; i < 16; i++) + { printf("%c", isprint(val[i]) ? val[i] : '.'); } j -= 1; - if (j == 0) { + if (j == 0) + { printf("]\n"); return; } @@ -206,24 +236,29 @@ static void print_unknown(__u8 * val) } } -static void print_string(__u8 * val) +static void +print_string(__u8 * val) { puts(val); } static char * - print_station_addr(char *fmt, struct ncp_station_addr *addr, char *buff) +print_station_addr(const char *fmt, const struct ncp_station_addr *addr, char *buff) { char *ret = buff; - while (*fmt != 0) { - switch (*fmt) { + while (*fmt != 0) + { + switch (*fmt) + { case '%': - switch (*(++fmt)) { + switch (*(++fmt)) + { case 'N': /* node */ { int i; - for (i = 0; i < 6; buff += 2, i++) { + for (i = 0; i < 6; buff += 2, i++) + { sprintf(buff, "%02X", addr->Node[i]); } } @@ -233,7 +268,7 @@ static char * buff += 4; break; case 'L': /* Lan */ - sprintf(buff, "%08lX", htonl(addr->NetWork)); + sprintf(buff, "%08X", (u_int32_t)htonl(addr->NetWork)); buff += 8; break; case '%': @@ -241,7 +276,8 @@ static char * default: break; } - if (*fmt) { + if (*fmt) + { fmt++; } break; @@ -253,35 +289,41 @@ static char * return ret; } -void print_login_control(__u8 * val) +void +print_login_control(__u8 * val) { int i, j, mask; char buff[32]; struct ncp_prop_login_control *a = (struct ncp_prop_login_control *) val; - static char *days[] + static const char *days[] = {"Sun", "Mon", "Tue", "Wen", "Thu", "Fri", "Sat"}; if (a->LastLogin[2] || a->LastLogin[1] || a->LastLogin[0] || - a->LastLogin[3] || a->LastLogin[4] || a->LastLogin[5]) { + a->LastLogin[3] || a->LastLogin[4] || a->LastLogin[5]) + { printf("Last Login: %d.%d.%02d at %2d:%02d:%02d\n", a->LastLogin[2], a->LastLogin[1], a->LastLogin[0], a->LastLogin[3], a->LastLogin[4], a->LastLogin[5]); - } else { + } else + { printf("Never logged in\n"); } - if (a->Disabled != 0) { + if (a->Disabled != 0) + { printf(" --- Account disabled ---\n"); } if (a->AccountExpireDate[2] || a->AccountExpireDate[1] || - a->AccountExpireDate[0]) { + a->AccountExpireDate[0]) + { printf("Account expires on: %d.%d.%d\n", a->AccountExpireDate[2], a->AccountExpireDate[1], a->AccountExpireDate[0]); } if (a->PasswordExpireDate[2] || a->PasswordExpireDate[1] || - a->PasswordExpireDate[0]) { + a->PasswordExpireDate[0]) + { printf("Password expires on: %d.%d.%d\n", a->PasswordExpireDate[2], a->PasswordExpireDate[1], @@ -291,51 +333,64 @@ void print_login_control(__u8 * val) printf("PasswortChangeInterval : %d days\n", ntohs(a->PasswordExpireInterval)); } - if ((a->RestrictionMask & 2) != 0) { + if ((a->RestrictionMask & 2) != 0) + { printf("New password must be different when changing\n"); } - if ((a->RestrictionMask & 1) != 0) { + if ((a->RestrictionMask & 1) != 0) + { printf("User ist not allowed to change password\n"); } printf("Minimal password length : %d\n", a->MinPasswordLength); - if (ntohs(a->MaxConnections) != 0) { + if (ntohs(a->MaxConnections) != 0) + { printf("Maximum no of connections: %d\n", ntohs(a->MaxConnections)); } - if (a->MaxDiskUsage != 0xFFFFFF7FL) { - printf("Maximum DiskQuota : %8ld blocks\n", - ntohl(a->MaxDiskUsage)); + if (a->MaxDiskUsage != 0xFFFFFF7FL) + { + printf("Maximum DiskQuota : %8d blocks\n", + (u_int32_t)ntohl(a->MaxDiskUsage)); } printf("Failed Logins: %5d\n", ntohs(a->BadLoginCount)); - if (a->BadLoginCountDown != 0L) { - printf("Account disabled still %8ld seconds\n", - ntohl(a->BadLoginCountDown)); + if (a->BadLoginCountDown != 0L) + { + printf("Account disabled still %8d seconds\n", + (u_int32_t)ntohl(a->BadLoginCountDown)); } - if (a->LastIntruder.NetWork != 0L) { + if (a->LastIntruder.NetWork != 0L) + { printf("Last \'intruder\' address: %s\n", print_station_addr("(%L): %N[%S]", &(a->LastIntruder), buff)); } - if (a->RestrictionMask & 0xFC) { + if (a->RestrictionMask & 0xFC) + { printf("RestrictionMask : %02X\n", a->RestrictionMask); } - for (i = 0; i < 42; i++) { - if (a->ConnectionTimeMask[i] != 0xFF) { + for (i = 0; i < 42; i++) + { + if (a->ConnectionTimeMask[i] != 0xFF) + { i = 101; } } - if (i < 100) { + if (i < 100) + { return; } val = a->ConnectionTimeMask; printf("Time restrictions: 1 1 1 1 1 1 1 1 1 1 2 2 2 2 ]\n"); printf(" Day [0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 ]\n"); - for (i = 0; i < 7; i++) { + for (i = 0; i < 7; i++) + { printf(" %s [", days[i]); - for (j = 0; j < 6; j++) { - for (mask = 1; mask < 0x100; mask <<= 1) { + for (j = 0; j < 6; j++) + { + for (mask = 1; mask < 0x100; mask <<= 1) + { putchar((*val & mask) ? '*' : ' '); } val++; @@ -344,7 +399,8 @@ void print_login_control(__u8 * val) } } -void print_addr(__u8 * val) +void +print_addr(__u8 * val) { char buff[50]; print_station_addr("(%L): %N[%S]", @@ -352,11 +408,12 @@ void print_addr(__u8 * val) printf("%s\n", buff); } -static struct { - char *pname; +static const struct +{ + const char *pname; void (*func) (__u8 *); -} formats[] = - +} +formats[] = { { "DESCRIPTION", print_string @@ -395,23 +452,28 @@ static struct { } }; -static void print_property(char *prop_name, __u8 * val, int segments) +static void +print_property(char *prop_name, __u8 * val, int segments) { int i; void (*f) (__u8 *); - for (i = 0; formats[i].pname != NULL; i++) { - if (strcasecmp(prop_name, formats[i].pname) == 0) { + for (i = 0; formats[i].pname != NULL; i++) + { + if (strcasecmp(prop_name, formats[i].pname) == 0) + { break; } } f = formats[i].func; - if (f != NULL) { + if (f != NULL) + { f(val); return; } - for (i = 0; i < segments; i++) { + for (i = 0; i < segments; i++) + { printf("Segment: %03d\n", i + 1); print_unknown(&(val[i * 128])); printf("\n"); diff --git a/util/nwfsinfo.c b/util/nwfsinfo.c index b15910e..af0ebec 100644 --- a/util/nwfsinfo.c +++ b/util/nwfsinfo.c @@ -14,12 +14,14 @@ static char *progname; -static void usage(void) +static void +usage(void) { fprintf(stderr, "usage: %s [pattern]\n", progname); } -static void help(void) +static void +help(void) { printf("\n"); printf("usage: %s [options]\n", progname); @@ -33,7 +35,8 @@ static void help(void) "\n"); } -static void print_info(struct ncp_file_server_info *info) +static void +print_info(struct ncp_file_server_info *info) { printf("\n"); printf("Fileservername %-48.48s\n", info->ServerName); @@ -67,7 +70,8 @@ static void print_info(struct ncp_file_server_info *info) return; } -int main(int argc, char **argv) +int +main(int argc, char **argv) { struct ncp_conn *conn; int opt; @@ -75,12 +79,15 @@ int main(int argc, char **argv) progname = argv[0]; - if ((conn = ncp_initialize(&argc, argv, 0, &err)) == NULL) { + if ((conn = ncp_initialize(&argc, argv, 0, &err)) == NULL) + { com_err(argv[0], err, "when initializing"); return 1; } - while ((opt = getopt(argc, argv, "h?dti")) != EOF) { - switch (opt) { + while ((opt = getopt(argc, argv, "h?dti")) != EOF) + { + switch (opt) + { case 'h': case '?': help(); @@ -91,15 +98,18 @@ int main(int argc, char **argv) char *s; if (ncp_get_file_server_description_strings(conn, - strings) - != 0) { + strings) + != 0) + { perror("could not get strings"); ncp_close(conn); return 1; } s = strings; - while (s < strings + 512) { - if (strlen(s) == 0) { + while (s < strings + 512) + { + if (strlen(s) == 0) + { break; } puts(s); @@ -111,7 +121,8 @@ int main(int argc, char **argv) { time_t t; - if (ncp_get_file_server_time(conn, &t) != 0) { + if (ncp_get_file_server_time(conn, &t) != 0) + { perror("could not get server time"); ncp_close(conn); return 1; @@ -122,7 +133,8 @@ int main(int argc, char **argv) case 'i': { struct ncp_file_server_info info; - if (ncp_get_file_server_information(conn, &info) != 0) { + if (ncp_get_file_server_information(conn, &info) != 0) + { perror("Could not get server information"); ncp_close(conn); return 1; diff --git a/util/nwfstime.c b/util/nwfstime.c index c1e53a2..eb9f152 100644 --- a/util/nwfstime.c +++ b/util/nwfstime.c @@ -13,12 +13,14 @@ static char *progname; -static void usage(void) +static void +usage(void) { fprintf(stderr, "usage: %s [pattern]\n", progname); } -static void help(void) +static void +help(void) { printf("\n"); printf("usage: %s [options]\n", progname); @@ -34,7 +36,8 @@ static void help(void) "\n"); } -int main(int argc, char **argv) +int +main(int argc, char **argv) { struct ncp_conn *conn; int opt; @@ -44,12 +47,15 @@ int main(int argc, char **argv) progname = argv[0]; - if ((conn = ncp_initialize(&argc, argv, 1, &err)) == NULL) { + if ((conn = ncp_initialize(&argc, argv, 1, &err)) == NULL) + { com_err(argv[0], err, "when initializing"); return 1; } - while ((opt = getopt(argc, argv, "h?s")) != EOF) { - switch (opt) { + while ((opt = getopt(argc, argv, "h?s")) != EOF) + { + switch (opt) + { case 'h': case '?': help(); @@ -65,15 +71,19 @@ int main(int argc, char **argv) finished: - if (set != 0) { + if (set != 0) + { time(&t); - if ((err = ncp_set_file_server_time(conn, &t)) != 0) { + if ((err = ncp_set_file_server_time(conn, &t)) != 0) + { com_err(argv[0], err, "when setting file server time"); ncp_close(conn); return 1; } - } else { - if ((err = ncp_get_file_server_time(conn, &t)) != 0) { + } else + { + if ((err = ncp_get_file_server_time(conn, &t)) != 0) + { com_err(argv[0], err, "when getting file server time"); ncp_close(conn); return 1; diff --git a/util/nwgrant.c b/util/nwgrant.c index 7394474..1226fed 100644 --- a/util/nwgrant.c +++ b/util/nwgrant.c @@ -13,12 +13,14 @@ static char *progname; -static void usage(void) +static void +usage(void) { fprintf(stderr, "usage: %s [options]\n", progname); } -static void help(void) +static void +help(void) { printf("\n"); printf("usage: %s [options] file/directory\n", progname); @@ -38,7 +40,8 @@ static void help(void) "\n"); } -int main(int argc, char *argv[]) +int +main(int argc, char *argv[]) { struct ncp_conn *conn; char *object_name = NULL; @@ -52,12 +55,15 @@ int main(int argc, char *argv[]) progname = argv[0]; - if ((conn = ncp_initialize(&argc, argv, 1, &err)) == NULL) { + if ((conn = ncp_initialize(&argc, argv, 1, &err)) == NULL) + { com_err(argv[0], err, "when initializing"); goto finished; } - while ((opt = getopt(argc, argv, "h?o:t:r:")) != EOF) { - switch (opt) { + while ((opt = getopt(argc, argv, "h?o:t:r:")) != EOF) + { + switch (opt) + { case 'o': object_name = optarg; str_upper(object_name); @@ -78,34 +84,40 @@ int main(int argc, char *argv[]) } } - if (object_type < 0) { + if (object_type < 0) + { fprintf(stderr, "%s: You must specify an object type\n", argv[0]); goto finished; } - if (object_name == NULL) { + if (object_name == NULL) + { fprintf(stderr, "%s: You must specify an object name\n", argv[0]); goto finished; } - if (rights < 0) { + if (rights < 0) + { fprintf(stderr, "%s: You must specify a rights mask\n", progname); goto finished; } - if (optind != argc - 1) { + if (optind != argc - 1) + { fprintf(stderr, "%s: You must specify a directory\n", progname); goto finished; } path = argv[optind]; - if (ncp_get_bindery_object_id(conn, object_type, object_name, &o) != 0) { + if (ncp_get_bindery_object_id(conn, object_type, object_name, &o) != 0) + { fprintf(stderr, "%s: Could not find object %s\n", progname, object_name); goto finished; } - if (ncp_add_trustee(conn, 0, path, o.object_id, rights) != 0) { + if (ncp_add_trustee(conn, 0, path, o.object_id, rights) != 0) + { fprintf(stderr, "%s: Could not add trustee rights\n", progname); goto finished; } diff --git a/util/nwmsg.c b/util/nwmsg.c new file mode 100644 index 0000000..6fc9089 --- /dev/null +++ b/util/nwmsg.c @@ -0,0 +1,215 @@ +/* + * nwmsg.c + * + * Fetch NetWare broadcast messages and write to the user + * + * Copyright (C) 1996 by Volker Lendecke + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "ncplib.h" +#include + +static int search_utmp(char *user, char *tty); + +static char *progname; + +int +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; + + + 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 ((err = ncp_open_mount(mount_point, &conn)) != 0) + { + 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); + fclose(tty_file); + fclose(mtab); + return 0; +} + +/* 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; +} diff --git a/util/nwpasswd.c b/util/nwpasswd.c index d6bedc1..2ef6234 100644 --- a/util/nwpasswd.c +++ b/util/nwpasswd.c @@ -13,12 +13,14 @@ static char *progname; -static void usage(void) +static void +usage(void) { fprintf(stderr, "usage: %s [options]\n", progname); } -static void help(void) +static void +help(void) { printf("\n"); printf("usage: %s [options]\n", progname); @@ -32,7 +34,8 @@ static void help(void) } -int main(int argc, char *argv[]) +int +main(int argc, char *argv[]) { struct ncp_conn_spec *spec; struct ncp_conn *conn; @@ -53,8 +56,10 @@ int main(int argc, char *argv[]) progname = argv[0]; - while ((opt = getopt(argc, argv, "h?S:U:O:t:")) != EOF) { - switch (opt) { + while ((opt = getopt(argc, argv, "h?S:U:O:t:")) != EOF) + { + switch (opt) + { case 'S': server = optarg; break; @@ -79,13 +84,16 @@ int main(int argc, char *argv[]) spec = ncp_find_conn_spec(server, user_name, "", 1, getuid(), &err); - if (spec == NULL) { + if (spec == NULL) + { com_err(argv[0], err, "trying to find server"); exit(1); } - if (!object_name) { + if (!object_name) + { object_name = spec->user; - } else { + } else + { strcpy(buf_obj_name, object_name); object_name = buf_obj_name; str_upper(object_name); @@ -95,28 +103,33 @@ int main(int argc, char *argv[]) printf("Changing password for user %s on server %s\n", object_name, spec->server); - if (object_name == spec->user) { + if (object_name == spec->user) + { str = getpass("Enter old password: "); - } else { + } else + { char sx[80]; sprintf(sx, "Enter password for %s: ", spec->user); str = getpass(sx); } - if (strlen(str) >= sizeof(oldpass)) { + if (strlen(str) >= sizeof(oldpass)) + { printf("Password too long\n"); exit(1); } strcpy(oldpass, str); str = getpass("Enter new password: "); - if (strlen(str) >= sizeof(newpass1)) { + if (strlen(str) >= sizeof(newpass1)) + { printf("Password too long\n"); exit(1); } strcpy(newpass1, str); str = getpass("Re-Enter new password: "); - if (strlen(str) >= sizeof(newpass2)) { + if (strlen(str) >= sizeof(newpass2)) + { printf("Password too long\n"); exit(1); } @@ -126,22 +139,27 @@ int main(int argc, char *argv[]) str_upper(newpass1); str_upper(newpass2); - if (strcmp(newpass1, newpass2) != 0) { + if (strcmp(newpass1, newpass2) != 0) + { printf("You mistype the new password, try again\n"); exit(1); } strcpy(spec->password, oldpass); - if ((conn = ncp_open(spec, &err)) == NULL) { + if ((conn = ncp_open(spec, &err)) == NULL) + { com_err(argv[0], err, "when trying to open connection"); exit(1); } - if (object_name != spec->user) { + if (object_name != spec->user) + { if (!(err = ncp_get_bindery_object_id(conn, 1, spec->user, &user)) - && !(err = ncp_login_user(conn, spec->user, oldpass))) { + && !(err = ncp_login_user(conn, spec->user, oldpass))) + { *oldpass = '\0'; - } else { + } else + { com_err(argv[0], err, "not own password"); } } @@ -149,7 +167,8 @@ int main(int argc, char *argv[]) || ((err = ncp_get_bindery_object_id(conn, 1, object_name, &user)) != 0) || ((err = ncp_change_login_passwd(conn, &user, ncp_key, - oldpass, newpass1)) != 0)) { + oldpass, newpass1)) != 0)) + { com_err(argv[0], err, "trying to change password"); } ncp_close(conn); diff --git a/util/nwpurge.c b/util/nwpurge.c new file mode 100644 index 0000000..a6c7ad8 --- /dev/null +++ b/util/nwpurge.c @@ -0,0 +1,127 @@ +#include +#include + +void usage(void) { + printf( +"usage: nwpurge [options] [directory]\n" +"\n" +"-h Print this help text\n" +"-a Purge files in subdirectories\n" +"-l Do not purge files\n" +"-s Silent mode\n" +"\n" +"directory Directory to purge\n" +"\n" +); +} + +int subdirs = 0; +int show = 1; +int purge = 1; +int files = 0; +int failures = 0; + +void processpurge(struct ncp_conn* conn, int volume, __u32 directory_id) { + struct ncp_deleted_file info; + char tmp[1024]; + + if (show) { + if (!ncp_ns_get_full_name(conn, NW_NS_DOS, NW_NS_DOS, + 1, volume, directory_id, NULL, 0, + tmp, sizeof(tmp))) { + printf("%s\n", tmp); + } + } + + info.seq = -1; + while (!ncp_ns_scan_salvageable_file(conn, NW_NS_DOS, + 1, volume, directory_id, NULL, 0, + &info, tmp, sizeof(tmp))) { + if (show) { + printf("%8s%s\n", "", tmp); + } + files++; + if (purge) { + if (ncp_ns_purge_file(conn, &info)) { + failures++; + if (!show) { + printf("%8s%s\n", "", tmp); + } + printf("%8s-- failed\n", ""); + } + } + } + if (show) printf("\n"); + if (subdirs) { + struct nw_info_struct dir; + struct ncp_search_seq seq; + + dir.volNumber = volume; + dir.DosDirNum = directory_id; + if (!ncp_initialize_search(conn, &dir, NW_NS_DOS, &seq)) { + while (!ncp_search_for_file_or_subdir2(conn, + SA_SUBDIR_ALL, + /* RIM_ATTRIBUTES | */ RIM_DIRECTORY, + &seq, + &dir)) { + processpurge(conn, dir.volNumber, dir.DosDirNum); + } + } + + } +} + +int main(int argc, char* argv[]) { + const char* path; + struct ncp_conn* conn; + int err; + int c; + + while ((c = getopt(argc, argv, "ahls")) != -1) { + switch (c) { + case '?': + case ':':break; + case 'a':subdirs = 1; + break; + case 'h':usage(); exit(2); + case 'l':purge = 0; + break; + case 's':show = 0; + break; + default: fprintf(stderr, "Unexpected option `-%c'\n", c); + break; + } + } + if (optind < argc) { + path = argv[optind++]; + } else { + path = "."; + } + err = ncp_open_mount(path, &conn); + if (err) { + com_err("nwpurge", err, "in ncp_open_mount"); + exit(1); + } + processpurge(conn, conn->i.volume_number, conn->i.directory_id); + + files = files-failures; + if (!files) { + printf("No files were"); + } else if (files == 1) { + printf("1 file was"); + } else { + printf("%d files were", files); + } + printf(" purged from server.\n"); + if (failures) { + if (failures == 1) { + printf("1 file was not purged due to error."); + } else { + printf("%d files were not purged due to errors.", failures); + } + } + + ncp_close(conn); + return 0; +} + diff --git a/util/nwrevoke.c b/util/nwrevoke.c index 91e83b3..e2a5e65 100644 --- a/util/nwrevoke.c +++ b/util/nwrevoke.c @@ -13,12 +13,14 @@ static char *progname; -static void usage(void) +static void +usage(void) { fprintf(stderr, "usage: %s [options]\n", progname); } -static void help(void) +static void +help(void) { printf("\n"); printf("usage: %s [options] file/directory\n", progname); @@ -37,7 +39,8 @@ static void help(void) "\n"); } -int main(int argc, char *argv[]) +int +main(int argc, char *argv[]) { struct ncp_conn *conn; char *object_name = NULL; @@ -50,12 +53,15 @@ int main(int argc, char *argv[]) progname = argv[0]; - if ((conn = ncp_initialize(&argc, argv, 1, &err)) == NULL) { + if ((conn = ncp_initialize(&argc, argv, 1, &err)) == NULL) + { com_err(argv[0], err, "when initializing"); goto finished; } - while ((opt = getopt(argc, argv, "h?o:t:")) != EOF) { - switch (opt) { + while ((opt = getopt(argc, argv, "h?o:t:")) != EOF) + { + switch (opt) + { case 'o': object_name = optarg; str_upper(object_name); @@ -73,29 +79,34 @@ int main(int argc, char *argv[]) } } - if (object_type < 0) { + if (object_type < 0) + { fprintf(stderr, "%s: You must specify an object type\n", argv[0]); goto finished; } - if (object_name == NULL) { + if (object_name == NULL) + { fprintf(stderr, "%s: You must specify an object name\n", argv[0]); goto finished; } - if (optind != argc - 1) { + if (optind != argc - 1) + { fprintf(stderr, "%s: You must specify a directory\n", progname); goto finished; } path = argv[optind]; - if (ncp_get_bindery_object_id(conn, object_type, object_name, &o) != 0) { + if (ncp_get_bindery_object_id(conn, object_type, object_name, &o) != 0) + { fprintf(stderr, "%s: Could not find object %s\n", progname, object_name); goto finished; } - if (ncp_delete_trustee(conn, 0, path, o.object_id) != 0) { + if (ncp_delete_trustee(conn, 0, path, o.object_id) != 0) + { fprintf(stderr, "%s: Could not remove trustee rights\n", progname); goto finished; diff --git a/util/nwrights.c b/util/nwrights.c index 11fb9f5..b632875 100644 --- a/util/nwrights.c +++ b/util/nwrights.c @@ -13,12 +13,14 @@ static char *progname; -static void usage(void) +static void +usage(void) { fprintf(stderr, "usage: %s [options]\n", progname); } -static void help(void) +static void +help(void) { printf("\n"); printf("usage: %s [options] file/directory\n", progname); @@ -29,10 +31,11 @@ static void help(void) "\n"); } -int main(int argc, char *argv[]) +int +main(int argc, char *argv[]) { struct ncp_conn *conn = NULL; - char *path = "."; + const char *path = "."; long err; int result = 1; int opt; @@ -40,8 +43,10 @@ int main(int argc, char *argv[]) progname = argv[0]; - while ((opt = getopt(argc, argv, "h?")) != EOF) { - switch (opt) { + while ((opt = getopt(argc, argv, "h?")) != EOF) + { + switch (opt) + { case 'h': case '?': help(); @@ -52,21 +57,25 @@ int main(int argc, char *argv[]) } } - if (optind > argc) { + if (optind > argc) + { usage(); goto finished; } - if (optind == argc - 1) { + if (optind == argc - 1) + { path = argv[optind]; } - if ((conn = ncp_open_mount(path, &err)) == NULL) { + if ((err = ncp_open_mount(path, &conn)) != 0) + { com_err(argv[0], err, "when initializing"); goto finished; } if ((err = ncp_get_eff_directory_rights(conn, 0, 0, 0x8006, conn->i.volume_number, - conn->i.directory_id, NULL, - &rights)) != 0) { + conn->i.directory_id, NULL, + &rights)) != 0) + { com_err(argv[0], err, "when finding rights"); goto finished; } @@ -81,28 +90,36 @@ int main(int argc, char *argv[]) ((rights & NCP_PERM_SEARCH) != 0) ? 'F' : ' ', ((rights & NCP_PERM_OWNER) != 0) ? 'A' : ' '); - if ((rights & NCP_PERM_SUPER) != 0) { + if ((rights & NCP_PERM_SUPER) != 0) + { printf("(S): You have SUPERVISOR rights\n"); } - if ((rights & NCP_PERM_READ) != 0) { + if ((rights & NCP_PERM_READ) != 0) + { printf("(R): You may READ from files\n"); } - if ((rights & NCP_PERM_WRITE) != 0) { + if ((rights & NCP_PERM_WRITE) != 0) + { printf("(W): You may WRITE to files\n"); } - if ((rights & NCP_PERM_CREATE) != 0) { + if ((rights & NCP_PERM_CREATE) != 0) + { printf("(C): You may CREATE files\n"); } - if ((rights & NCP_PERM_DELETE) != 0) { + if ((rights & NCP_PERM_DELETE) != 0) + { printf("(E): You may ERASE files\n"); } - if ((rights & NCP_PERM_MODIFY) != 0) { + if ((rights & NCP_PERM_MODIFY) != 0) + { printf("(M): You may MODIFY directory\n"); } - if ((rights & NCP_PERM_SEARCH) != 0) { + if ((rights & NCP_PERM_SEARCH) != 0) + { printf("(F): You may SCAN for files\n"); } - if ((rights & NCP_PERM_OWNER) != 0) { + if ((rights & NCP_PERM_OWNER) != 0) + { printf("(A): You may change ACCESS control\n"); } result = 0; diff --git a/util/nwtrustee.c b/util/nwtrustee.c index 6ab9524..c253d43 100644 --- a/util/nwtrustee.c +++ b/util/nwtrustee.c @@ -15,13 +15,15 @@ static char *progname; -static void usage(void) +static void +usage(void) { fprintf(stderr, "usage: %s [options] pattern\n", progname); return; } -static void help(void) +static void +help(void) { printf("\n"); printf("usage: %s [options]\n", progname); @@ -42,7 +44,8 @@ static void help(void) "\n"); } -int fromhex(char c) +int +fromhex(char c) { c -= '0'; if (c > 9) @@ -50,7 +53,8 @@ int fromhex(char c) return c & 15; } -int main(int argc, char **argv) +int +main(int argc, char **argv) { struct ncp_conn *conn; struct ncp_bindery_object bobj; @@ -65,12 +69,15 @@ int main(int argc, char **argv) progname = argv[0]; - if ((conn = ncp_initialize(&argc, argv, 1, &err)) == NULL) { + if ((conn = ncp_initialize(&argc, argv, 1, &err)) == NULL) + { com_err(argv[0], err, "when initializing"); return 1; } - while ((opt = getopt(argc, argv, "h?vl:L:o:O:t:")) != EOF) { - switch (opt) { + while ((opt = getopt(argc, argv, "h?vl:L:o:O:t:")) != EOF) + { + switch (opt) + { case 'h': case '?': help(); @@ -79,7 +86,8 @@ int main(int argc, char **argv) vid = atoi(optarg); break; case 'L': - if (ncp_get_volume_number(conn, optarg, &vid)) { + if (ncp_get_volume_number(conn, optarg, &vid)) + { ncp_close(conn); return 1; } @@ -87,16 +95,19 @@ int main(int argc, char **argv) case 'o': oid = 0; - while (*optarg) { + while (*optarg) + { oid = (oid << 4) | fromhex(*optarg); optarg++; } break; case 'O': - for (p = optarg; *p != 0; p++) { + for (p = optarg; *p != 0; p++) + { *p = toupper(*p); } - if (ncp_get_bindery_object_id(conn, type, optarg, &bobj)) { + if (ncp_get_bindery_object_id(conn, type, optarg, &bobj)) + { ncp_close(conn); return 1; } @@ -114,25 +125,30 @@ int main(int argc, char **argv) } } - if (optind < argc) { + if (optind < argc) + { usage(); exit(1); } nextp = 0; - while (!ncp_get_trustee(conn, oid, vid, ppath, &trust, &nextp)) { + while (!ncp_get_trustee(conn, oid, vid, ppath, &trust, &nextp)) + { if (!nextp) break; printf("%s ", ppath); - if (verbose) { + if (verbose) + { strcpy(ppath, "[ R W O C E A F M ]"); p = ppath + 2; - for (type = 1; type < 256; type <<= 1) { + for (type = 1; type < 256; type <<= 1) + { if (!(trust & type)) *p = ' '; p += 2; } printf("%s\n", ppath); - } else { + } else + { printf("%X\n", trust); } } diff --git a/util/nwuserlist.c b/util/nwuserlist.c index fc7fb04..43ad78c 100644 --- a/util/nwuserlist.c +++ b/util/nwuserlist.c @@ -13,22 +13,26 @@ static char *progname; -static void usage(void) +static void +usage(void) { fprintf(stderr, "usage: %s [pattern]\n", progname); } -static void str_trim_right(char *s, char c) +static void +str_trim_right(char *s, char c) { int len = strlen(s) - 1; - while ((len > 0) && (s[len] == c)) { + while ((len > 0) && (s[len] == c)) + { s[len] = '\0'; len -= 1; } } -static void help(void) +static void +help(void) { printf("\n"); printf("usage: %s [options]\n", progname); @@ -39,7 +43,8 @@ static void help(void) "\n"); } -int main(int argc, char **argv) +int +main(int argc, char **argv) { struct ncp_conn *conn; int opt; @@ -52,12 +57,15 @@ int main(int argc, char **argv) progname = argv[0]; - if ((conn = ncp_initialize(&argc, argv, 1, &err)) == NULL) { + if ((conn = ncp_initialize(&argc, argv, 1, &err)) == NULL) + { com_err(argv[0], err, "when initializing"); goto finished; } - while ((opt = getopt(argc, argv, "h?a")) != EOF) { - switch (opt) { + while ((opt = getopt(argc, argv, "h?a")) != EOF) + { + switch (opt) + { case 'h': case '?': help(); @@ -71,22 +79,26 @@ int main(int argc, char **argv) } } - if (ncp_get_file_server_information(conn, &info) != 0) { + if (ncp_get_file_server_information(conn, &info) != 0) + { perror("Could not get server information"); ncp_close(conn); return 1; } - if (isatty(1)) { - if (print_addr == 0) { + if (isatty(1)) + { + if (print_addr == 0) + { printf("\n%-6s%-21s%-12s\n" - "---------------------------------------------" + "---------------------------------------------" "------\n", "Conn", "User name", "Login time"); - } else { + } else + { printf("\n%-6s%-21s%-27s%-12s\n" - "---------------------------------------------" + "---------------------------------------------" "---------------------------------\n", "Conn", "User name", @@ -94,18 +106,21 @@ int main(int argc, char **argv) "Login time"); } } - for (i = 1; i <= info.MaximumServiceConnections; i++) { + for (i = 1; i <= info.MaximumServiceConnections; i++) + { char name[49]; name[48] = '\0'; if (ncp_get_stations_logged_info(conn, i, &user, - &login_time) != 0) { + &login_time) != 0) + { continue; } memcpy(name, user.object_name, 48); str_trim_right(name, ' '); printf("%4d: %-20s ", i, name); - if (print_addr != 0) { + if (print_addr != 0) + { struct sockaddr_ipx addr; __u8 conn_type; diff --git a/util/nwvolinfo.c b/util/nwvolinfo.c index f08413a..2ee0908 100644 --- a/util/nwvolinfo.c +++ b/util/nwvolinfo.c @@ -15,13 +15,15 @@ static char *progname; -static void usage(void) +static void +usage(void) { fprintf(stderr, "usage: %s [options] pattern\n", progname); return; } -static void help(void) +static void +help(void) { printf("\n"); printf("usage: %s [options]\n", progname); @@ -38,12 +40,13 @@ static void help(void) "\n"); } -int main(int argc, char **argv) +int +main(int argc, char **argv) { struct ncp_conn *conn; struct ncp_volume_info o; - char *volname = "SYS"; + const char *volname = "SYS"; long err; int opt; int numk; @@ -51,12 +54,15 @@ int main(int argc, char **argv) progname = argv[0]; - if ((conn = ncp_initialize(&argc, argv, 1, &err)) == NULL) { + if ((conn = ncp_initialize(&argc, argv, 1, &err)) == NULL) + { com_err(argv[0], err, "when initializing"); return 1; } - while ((opt = getopt(argc, argv, "h?Nv:")) != EOF) { - switch (opt) { + while ((opt = getopt(argc, argv, "h?Nv:")) != EOF) + { + switch (opt) + { case 'h': case '?': help(); @@ -73,19 +79,23 @@ int main(int argc, char **argv) } } - if (optind < argc) { + if (optind < argc) + { usage(); exit(1); } - if (ncp_get_volume_number(conn, volname, &opt)) { + if (ncp_get_volume_number(conn, volname, &opt)) + { exit(1); } - if (ncp_get_volume_info_with_number(conn, opt, &o)) { + if (ncp_get_volume_info_with_number(conn, opt, &o)) + { exit(1); } numk = o.sectors_per_block / 2; o.free_blocks += o.purgeable_blocks; - if (type) { + if (type) + { printf("%d %d %d %d %d %d\n", o.total_blocks * numk, o.free_blocks * numk, @@ -93,7 +103,8 @@ int main(int argc, char **argv) o.not_yet_purgeable_blocks * numk, o.total_dir_entries, o.available_dir_entries); - } else { + } else + { printf("Total : %dK\n", o.total_blocks * numk); printf("Free : %dK\n", o.free_blocks * numk); printf("Purgable : %dK\n", o.purgeable_blocks * numk); diff --git a/util/pqlist.c b/util/pqlist.c index 671ad2f..26ad308 100644 --- a/util/pqlist.c +++ b/util/pqlist.c @@ -12,7 +12,8 @@ #include #include "ncplib.h" -int main(int argc, char **argv) +int +main(int argc, char **argv) { struct ncp_conn *conn; struct ncp_bindery_object q; @@ -23,22 +24,27 @@ int main(int argc, char **argv) char *p; long err; - if ((conn = ncp_initialize(&argc, argv, 1, &err)) == NULL) { + if ((conn = ncp_initialize(&argc, argv, 1, &err)) == NULL) + { com_err(argv[0], err, "when initializing"); return 1; } - if (argc > 2) { + if (argc > 2) + { fprintf(stderr, "usage: %s [options] [pattern]\n", argv[0]); return 1; } - if (argc == 2) { + if (argc == 2) + { pattern = argv[1]; } - for (p = pattern; *p != '\0'; p++) { + for (p = pattern; *p != '\0'; p++) + { *p = toupper(*p); } - if (isatty(1)) { + if (isatty(1)) + { printf("\nServer: %s\n", conn->server); printf("%-52s%-10s\n" "-----------------------------------------------" @@ -49,13 +55,15 @@ int main(int argc, char **argv) q.object_id = 0xffffffff; while (ncp_scan_bindery_object(conn, q.object_id, - NCP_BINDERY_PQUEUE, pattern, &q) == 0) { + NCP_BINDERY_PQUEUE, pattern, &q) == 0) + { found = 1; printf("%-52s", q.object_name); printf("%08X\n", (unsigned int) q.object_id); } - if ((found == 0) && (isatty(1))) { + if ((found == 0) && (isatty(1))) + { printf("No queues found\n"); } ncp_close(conn); diff --git a/util/pqrm.c b/util/pqrm.c new file mode 100644 index 0000000..e5a0dc2 --- /dev/null +++ b/util/pqrm.c @@ -0,0 +1,71 @@ +/* + * pqrm.c + * + * Remove job from a print queue on a server + * + * Copyright (C) 1998 by Petr Vandrovec, David Woodhouse + * Derived from pqlist.c, (C) 1996 Volker Lendecke + * + */ + +#include +#include +#include +#include +#include "ncplib.h" + +int +main(int argc, char **argv) +{ + struct ncp_conn *conn; + struct ncp_bindery_object q; + long err; + int i; + + if ((conn = ncp_initialize(&argc, argv, 1, &err)) == NULL) + { + com_err(argv[0], err, "when initializing"); + return 1; + } + + if (argc < 3) + { + fprintf(stderr, "usage: %s [ ...]\n", argv[0]); + return 1; + } + + + if (ncp_get_bindery_object_id(conn, NCP_BINDERY_PQUEUE, + argv[1], &q) != 0) + { + printf("Queue \"%s\" on server %s not found.\n", + argv[1], conn->server); + ncp_close(conn); + exit(1); + + } + + for (i=2; i +#include +#include +#include +#include +#include "ncplib.h" + +/* move this to library ? */ +int +ncp_time_to_tm(struct tm* out, __u8* netwareTime) +{ + struct tm tmp; + + tmp.tm_year = netwareTime[0]; + if (tmp.tm_year < 80) tmp.tm_year += 100; + tmp.tm_mon = netwareTime[1]-1; + if ((tmp.tm_mon < 0) || (tmp.tm_mon >= 12)) return 1; + tmp.tm_mday = netwareTime[2]; + if ((tmp.tm_mday < 1) || (tmp.tm_mday >= 32)) return 1; + tmp.tm_hour = netwareTime[3]; + if (tmp.tm_hour >= 24) return 1; + tmp.tm_min = netwareTime[4]; + if (tmp.tm_min >= 60) return 1; + tmp.tm_sec = netwareTime[5]; + if (tmp.tm_sec >= 60) return 1; + memcpy(out, &tmp, sizeof(tmp)); + return 0; +} + +int +ncp_cmp_time(struct tm* tm1, struct tm* tm2) +{ +#undef XTST +#define XTST(Y) if (tm1->tm_##Y## != tm2->tm_##Y##) { \ + return (tm1->tm_##Y## > tm2->tm_##Y##) ? 1 : -1; \ + } + XTST(year); + XTST(mon); + XTST(mday); + XTST(hour); + XTST(min); + XTST(sec); +#undef XTST + return 0; +} + +int +main(int argc, char **argv) +{ + struct ncp_conn *conn; + struct ncp_bindery_object q,u; + unsigned long maxqlen=~0; + long err; + + __u32 qlen, idl1,idl2, job_id; + struct nw_queue_job_entry j; + + if ((conn = ncp_initialize(&argc, argv, 1, &err)) == NULL) + { + com_err(argv[0], err, "when initializing"); + return 1; + } + + if (argc == 3) + { + char *end; + + maxqlen=strtoul(argv[2], &end, 10); + if (*end != 0) + argc = 4; + + } + if (argc < 2 || argc > 3) + { + fprintf(stderr, "usage: %s []\n", argv[0]); + return 1; + } + + + if (ncp_get_bindery_object_id(conn, NCP_BINDERY_PQUEUE, + argv[1], &q) != 0) + { + printf("Queue \"%s\" on server %s not found.\n", + argv[1], conn->server); + ncp_close(conn); + exit(1); + + } + + if (isatty(1)) + { + printf("\nServer: %s\tQueue: %s\tQueue ID: %8.8X\n", conn->server, q.object_name, q.object_id); + printf(" %5s %-12s %-32s %-7s %-4s %-8s\n" + + "-----------------------------------------------" + "--------------------------------\n", + "Seq","Name", + "Description", "Status", "Form", "Job ID"); + } + + + if ((err=ncp_get_queue_length(conn, q.object_id, &qlen)) != 0) + { + if (conn->completion == 0xD3) { + fprintf(stderr, "You have insufficient rights to list queue jobs\n"); + } else { + com_err(argv[0], err, ": cannot get queue length"); + } + ncp_close(conn); + exit(1); + } +/* printf("There are %d jobs in the queue.\n",qlen); */ + + idl1=1; + job_id =0; + + if ((err=ncp_get_queue_job_ids(conn, q.object_id, 1, + &idl1, &idl2, &job_id)) != 0) + { + printf("Error getting queue jobs ids: %ld\n",err); + ncp_close(conn); + exit(1); + } + +/* printf("First queue job ID is %8X\n",job_id);*/ + + while (maxqlen-- && job_id && (ncp_get_queue_job_info(conn, q.object_id, job_id, &j) == 0)) + { + const char* jst; + + char user[50]; + if ((ncp_get_bindery_object_name + (conn, ntohl(j.ClientObjectID), &u)) + == 0) + { + memcpy(user,u.object_name,48); + user[48]=0; + } + else + { + sprintf(user,""); + } + + j.JobFileName[j.FileNameLen]=0; + + if (j.JobControlFlags & 0xC0) { + jst = "Held"; + } else if (j.JobControlFlags & 0x20) { + jst = "Adding"; + } else if (j.ServerStation) { + jst = "Active"; + } else { + struct tm jobtime; + + jst = "Ready"; + if (!ncp_time_to_tm(&jobtime, j.TargetExecTime)) { + time_t ltime; + struct tm* loctime; + + time(<ime); + loctime = localtime(<ime); + + if (ncp_cmp_time(&jobtime, loctime) >= 0) + jst = "Waiting"; + } + } + + printf(" %5d %-12s %-32.32s %-7s %4d %08X\n", + j.JobPosition, user, j.JobTextDescription, jst, ntohs(j.JobType), j.JobNumber); + if (j.next == job_id) + job_id = 0; + else job_id = j.next; + } + + ncp_close(conn); + return 0; +} + diff --git a/util/pserver.c b/util/pserver.c index ebf4fbc..dda76d0 100644 --- a/util/pserver.c +++ b/util/pserver.c @@ -18,7 +18,8 @@ #include #include "ncplib.h" -struct nw_queue { +struct nw_queue +{ struct ncp_conn *conn; char queue_name[NCP_BINDERY_NAME_LEN]; @@ -40,13 +41,15 @@ static int static int poll_queue(struct nw_queue *q); -static void usage(void) +static void +usage(void) { fprintf(stderr, "usage: %s [options] file\n", progname); exit(1); } -static void help(void) +static void +help(void) { printf("\n"); printf("usage: %s [options]\n", progname); @@ -69,7 +72,8 @@ static void help(void) #define NCP_BINDERY_PSERVER (0x0007) #endif -static void terminate_handler() +static void +terminate_handler(int dummy) { signal(SIGTERM, terminate_handler); signal(SIGINT, terminate_handler); @@ -77,13 +81,16 @@ static void terminate_handler() } /* Daemon_init is taken from Stevens, Adv. Unix programming */ -static int daemon_init(void) +static int +daemon_init(void) { pid_t pid; - if ((pid = fork()) < 0) { + if ((pid = fork()) < 0) + { return -1; - } else if (pid != 0) { + } else if (pid != 0) + { exit(0); /* parent vanishes */ } /* child process */ @@ -96,7 +103,8 @@ static int daemon_init(void) return 0; } -int main(int argc, char *argv[]) +int +main(int argc, char *argv[]) { struct ncp_conn *conn; int poll_timeout = 30; @@ -113,32 +121,40 @@ int main(int argc, char *argv[]) progname = argv[0]; - for (i = 1; i < argc; i += 1) { + for (i = 1; i < argc; i += 1) + { if ((strcmp(argv[i], "-h") == 0) - || (strcmp(argv[i], "-?") == 0)) { + || (strcmp(argv[i], "-?") == 0)) + { help(); exit(0); } } - for (i = 1; i < argc; i += 1) { - if (strcmp(argv[i], "-d") == 0) { + for (i = 1; i < argc; i += 1) + { + if (strcmp(argv[i], "-d") == 0) + { debug = 1; break; } } - if (debug == 0) { + if (debug == 0) + { daemon_init(); openlog("pserver", LOG_PID, LOG_LPR); } if ((conn = ncp_initialize_as(&argc, argv, 1, - NCP_BINDERY_PSERVER, &err)) == NULL) { + NCP_BINDERY_PSERVER, &err)) == NULL) + { com_err(argv[0], err, "when initializing"); return 1; } - while ((opt = getopt(argc, argv, "q:c:j:t:dh")) != EOF) { - switch (opt) { + while ((opt = getopt(argc, argv, "q:c:j:t:dh")) != EOF) + { + switch (opt) + { case 'q': queue_name = optarg; break; @@ -162,17 +178,20 @@ int main(int argc, char *argv[]) } } - if (argc != optind) { + if (argc != optind) + { usage(); return -1; } memzero(q); - if (queue_name == NULL) { + if (queue_name == NULL) + { fprintf(stderr, "You must specify a queue\n"); return 1; } - if (init_queue(conn, queue_name, command, &q) != 0) { + if (init_queue(conn, queue_name, command, &q) != 0) + { perror("Could not init queue"); ncp_close(conn); return 1; @@ -183,12 +202,15 @@ int main(int argc, char *argv[]) signal(SIGTERM, terminate_handler); signal(SIGINT, terminate_handler); - while (1) { + while (1) + { if ((poll_queue(&q) != 0) - && (term_request == 0)) { + && (term_request == 0)) + { continue; } - if (term_request != 0) { + if (term_request != 0) + { break; } sleep(poll_timeout); @@ -200,8 +222,9 @@ int main(int argc, char *argv[]) return 0; } -static int init_queue(struct ncp_conn *conn, char *queue_name, char *command, - struct nw_queue *q) +static int +init_queue(struct ncp_conn *conn, char *queue_name, char *command, + struct nw_queue *q) { struct ncp_bindery_object obj; @@ -211,14 +234,16 @@ static int init_queue(struct ncp_conn *conn, char *queue_name, char *command, q->command = command; if (ncp_get_bindery_object_id(conn, NCP_BINDERY_PQUEUE, - queue_name, &obj) != 0) { + queue_name, &obj) != 0) + { fprintf(stderr, "Queue %s not found\n", queue_name); return -1; } q->queue_id = obj.object_id; memcpy(q->queue_name, obj.object_name, sizeof(q->queue_name)); - if (ncp_attach_to_queue(conn, q->queue_id) != 0) { + if (ncp_attach_to_queue(conn, q->queue_id) != 0) + { fprintf(stderr, "Could not attach to queue %s\n", queue_name); return -1; @@ -227,48 +252,50 @@ static int init_queue(struct ncp_conn *conn, char *queue_name, char *command, } -void build_command(struct nw_queue *q, struct queue_job *j, - char *target, int target_size) +void +build_command(struct nw_queue *q, struct queue_job *j, + char *target, int target_size, char *user) { char *s = q->command; char *target_end = target + target_size; - void add_string(char *s) { + void add_string(const char *s) + { int len = strlen(s); - if (target + len + 1 > target_end) { + if (target + len + 1 > target_end) + { len = target_end - target - 1; } strncpy(target, s, len); target += len; } - memset(target, 0, target_size); - while ((*s != 0) && (target < target_end)) { - if (*s != '%') { + while ((*s != 0) && (target < target_end)) + { + if (*s != '%') + { *target = *s; target += 1; s += 1; continue; } - switch (*(s + 1)) { + switch (*(s + 1)) + { case '%': *target = '%'; target += 1; + break; case 'u': - { - char *user; - struct ncp_bindery_object u; - if (ncp_get_bindery_object_name - (q->conn, j->j.ClientObjectID, &u) - == 0) { - user = u.object_name; - } else { - user = "*UNKNOWN USER*"; - } - add_string(user); - } + add_string(user); + break; + case 'd': + if (j->j.JobTextDescription[0]) + add_string(j->j.JobTextDescription); + else + add_string("No Description"); + break; default: *target = '%'; *(target + 1) = *(s + 1); @@ -281,26 +308,52 @@ void build_command(struct nw_queue *q, struct queue_job *j, -static int poll_queue(struct nw_queue *q) +static int +poll_queue(struct nw_queue *q) { struct queue_job job; int fd[2]; int pid; + int retcode; + struct ncp_bindery_object u; + char user[50]; if (ncp_service_queue_job(q->conn, q->queue_id, q->job_type, - &job) != 0) { + &job) != 0) + { /* No job for us */ return 0; } - if (pipe(fd) < 0) { + + if (ncp_get_queue_job_info(q->conn, q->queue_id, job.j.JobNumber, &job.j) != 0) + { + job.j.JobTextDescription[0]=0; + } + + if ((retcode=ncp_get_bindery_object_name + (q->conn, htonl(job.j.ClientObjectID), &u)) + == 0) + { + memcpy(user,u.object_name,48); + user[48]=0; + } + else + { + sprintf(user,""); + } + + if (pipe(fd) < 0) + { syslog(LOG_ERR, "pipe error: %m"); goto fail; } - if ((pid = fork()) < 0) { + if ((pid = fork()) < 0) + { syslog(LOG_ERR, "fork error: %m"); goto fail; } - if (pid > 0) { + if (pid > 0) + { /* parent */ char buf[1024]; size_t result; @@ -309,34 +362,41 @@ static int poll_queue(struct nw_queue *q) close(fd[0]); /* close read end */ while ((result = ncp_read(q->conn, job.file_handle, offset, - sizeof(buf), buf)) > 0) { + sizeof(buf), buf)) > 0) + { offset += result; - if (write(fd[1], buf, result) != result) { + if (write(fd[1], buf, result) != result) + { goto fail; } } close(fd[1]); /* and close write end */ - if (waitpid(pid, NULL, 0) < 0) { + if (waitpid(pid, NULL, 0) < 0) + { syslog(LOG_ERR, "waitpid: %m\n"); } - } else { + } else + { /* child */ char command[2048]; close(fd[1]); /* close write end */ - if (fd[0] != STDIN_FILENO) { - if (dup2(fd[0], STDIN_FILENO) != STDIN_FILENO) { + if (fd[0] != STDIN_FILENO) + { + if (dup2(fd[0], STDIN_FILENO) != STDIN_FILENO) + { syslog(LOG_ERR, "dup2 error: %m\n"); close(fd[0]); exit(1); } close(fd[0]); } - build_command(q, &job, command, sizeof(command)); + + build_command(q, &job, command, sizeof(command), user); execl("/bin/sh", "sh", "-c", command, NULL); syslog(LOG_ERR, "exec error: %m\n"); diff --git a/util/slist.c b/util/slist.c index cf00d1d..fe9ae14 100644 --- a/util/slist.c +++ b/util/slist.c @@ -14,7 +14,8 @@ #include #include -void main(int argc, char *argv[]) +int +main(int argc, char *argv[]) { struct ncp_conn *conn; struct ncp_bindery_object obj; @@ -24,22 +25,27 @@ void main(int argc, char *argv[]) char *p; long err; - if (argc > 2) { + if (argc > 2) + { printf("usage: %s [pattern]\n", argv[0]); exit(1); } - if (argc == 2) { + if (argc == 2) + { pattern = argv[1]; } - for (p = pattern; *p != '\0'; p++) { + for (p = pattern; *p != '\0'; p++) + { *p = toupper(*p); } - if ((conn = ncp_open(NULL, &err)) == NULL) { + if ((conn = ncp_open(NULL, &err)) == NULL) + { com_err(argv[0], err, "in ncp_open"); exit(1); } - if (isatty(1)) { + if (isatty(1)) + { printf("\n%-52s%-10s%-12s\n" "-----------------------------------------------" "---------------------------\n", @@ -51,7 +57,8 @@ void main(int argc, char *argv[]) while (ncp_scan_bindery_object(conn, obj.object_id, NCP_BINDERY_FSERVER, pattern, - &obj) == 0) { + &obj) == 0) + { struct nw_property prop; struct prop_net_address *naddr = (struct prop_net_address *) ∝ @@ -61,8 +68,9 @@ void main(int argc, char *argv[]) printf("%-52s", obj.object_name); if (ncp_read_property_value(conn, NCP_BINDERY_FSERVER, - obj.object_name, 1, "NET_ADDRESS", - &prop) == 0) { + obj.object_name, 1, "NET_ADDRESS", + &prop) == 0) + { ipx_print_network(naddr->network); printf(" "); ipx_print_node(naddr->node); @@ -70,8 +78,10 @@ void main(int argc, char *argv[]) printf("\n"); } - if ((found == 0) && (isatty(1))) { + if ((found == 0) && (isatty(1))) + { printf("No servers found\n"); } ncp_close(conn); + return 0; }